Use dedicated function to handle sky textures

This commit is contained in:
Benau 2021-04-14 09:34:59 +08:00
parent c5bbefd476
commit 7496609bfa
18 changed files with 230 additions and 100 deletions

View File

@ -141,7 +141,8 @@ include $(CLEAR_VARS)
LOCAL_MODULE := graphics_engine
LOCAL_PATH := .
LOCAL_CPP_FEATURES += rtti
LOCAL_SRC_FILES := $(wildcard ../lib/graphics_engine/src/*.c)
LOCAL_SRC_FILES := $(wildcard ../lib/graphics_engine/src/*.c) \
$(wildcard ../lib/graphics_engine/src/*.cpp)
LOCAL_CFLAGS := -I../lib/graphics_engine/include
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)

View File

@ -1,5 +1,8 @@
include_directories("${PROJECT_SOURCE_DIR}/lib/graphics_engine/include")
include_directories("${PROJECT_SOURCE_DIR}/lib/irrlicht/include")
add_library(graphics_engine STATIC
src/gl.c
src/vulkan.c
src/ge_main.cpp
src/ge_texture.cpp
)

View File

@ -0,0 +1,19 @@
#ifndef HEADER_GE_MAIN_HPP
#define HEADER_GE_MAIN_HPP
#include <IVideoDriver.h>
namespace GE
{
struct GEConfig
{
bool m_disable_npot_texture;
};
void init(irr::video::IVideoDriver* driver);
irr::video::IVideoDriver* getDriver();
GEConfig* getGEConfig();
void deinit();
}
#endif

View File

@ -0,0 +1,16 @@
#ifndef HEADER_GE_TEXTURE_HPP
#define HEADER_GE_TEXTURE_HPP
#include <string>
#include <ITexture.h>
#include <IImage.h>
namespace GE
{
irr::video::ITexture* createFontTexture(const std::string& name);
irr::video::ITexture* createTexture(irr::video::IImage* img);
irr::video::IImage* getResizedImage(const std::string& path);
irr::video::ITexture* createTexture(const std::string& path);
}; // GE
#endif

View File

@ -0,0 +1,27 @@
#include "ge_main.hpp"
namespace GE
{
irr::video::IVideoDriver* g_driver = NULL;
GEConfig g_config = {};
void init(irr::video::IVideoDriver* driver)
{
g_driver = driver;
}
irr::video::IVideoDriver* getDriver()
{
return g_driver;
}
GEConfig* getGEConfig()
{
return &g_config;
}
void deinit()
{
}
}

View File

@ -0,0 +1,45 @@
#include "ge_main.hpp"
#include "ge_texture.hpp"
#include <IVideoDriver.h>
#include <IAttributes.h>
namespace GE
{
using namespace irr;
video::IImage* getResizedImage(const std::string& path)
{
video::IImage* image = getDriver()->createImageFromFile(path.c_str());
if (image == NULL)
return NULL;
core::dimension2du img_size = image->getDimension();
bool has_npot = !getGEConfig()->m_disable_npot_texture &&
getDriver()->queryFeature(video::EVDF_TEXTURE_NPOT);
core::dimension2du tex_size = img_size.getOptimalSize(!has_npot);
const core::dimension2du& max_size = getDriver()->getDriverAttributes().
getAttributeAsDimension2d("MAX_TEXTURE_SIZE");
if (tex_size.Width > max_size.Width)
tex_size.Width = max_size.Width;
if (tex_size.Height > max_size.Height)
tex_size.Height = max_size.Height;
if (image->getColorFormat() != video::ECF_A8R8G8B8 ||
tex_size != img_size)
{
video::IImage* new_texture = getDriver()->createImage(
video::ECF_A8R8G8B8, tex_size);
if (tex_size != img_size)
image->copyToScaling(new_texture);
else
image->copyTo(new_texture);
image->drop();
return new_texture;
}
return image;
}
}

View File

@ -192,11 +192,15 @@ public:
//! Get name of texture (in most cases this is the filename)
const io::SNamedPath& getName() const { return NamedPath; }
void setName(const char* name) { NamedPath = io::SNamedPath(name); }
//! return open gl texture name
virtual u64 getTextureHandler() const = 0;
virtual u32 getTextureSize() const { return 0; }
virtual void updateTexture(void* data, ECOLOR_FORMAT format, u32 w, u32 h, u32 x, u32 y) {}
protected:
//! Helper function, helps to get the desired texture creation format from the flags.

View File

@ -66,8 +66,6 @@ public:
virtual void resetPostProcessing() {}
virtual void giveBoost(unsigned int cam_index) {}
virtual void addSkyBox(const std::vector<irr::video::ITexture*> &texture,
const std::vector<irr::video::ITexture*> &spherical_harmonics_textures) {}
virtual void removeSkyBox() {}
//FIXME: these three methods should not appear in the public Renderer interface

View File

@ -24,6 +24,7 @@
#include "graphics/glwrap.hpp"
#include "graphics/graphics_restrictions.hpp"
#include "guiengine/engine.hpp"
#include <ge_main.hpp>
bool CentralVideoSettings::m_supports_sp = true;
@ -94,6 +95,9 @@ void CentralVideoSettings::init()
std::string card((char*)(glGetString(GL_RENDERER)));
std::string vendor((char*)(glGetString(GL_VENDOR)));
GraphicsRestrictions::init(driver, card, vendor);
GE::getGEConfig()->m_disable_npot_texture =
GraphicsRestrictions::isDisabled(
GraphicsRestrictions::GR_NPOT_TEXTURES);
if (GraphicsRestrictions::isDisabled(GraphicsRestrictions::GR_FORCE_LEGACY_DEVICE))
{

View File

@ -95,6 +95,10 @@
#endif
#endif
#ifndef SERVER_ONLY
#include <ge_main.hpp>
#endif
#ifdef ENABLE_RECORDER
#include <chrono>
#include <openglrecorder.h>
@ -622,6 +626,9 @@ void IrrDriver::initDevice()
m_scene_manager = m_device->getSceneManager();
m_gui_env = m_device->getGUIEnvironment();
m_video_driver = m_device->getVideoDriver();
#ifndef SERVER_ONLY
GE::init(m_video_driver);
#endif
B3DMeshLoader* b3dl = new B3DMeshLoader(m_scene_manager);
m_scene_manager->addExternalMeshLoader(b3dl);
@ -1588,12 +1595,6 @@ scene::IAnimatedMeshSceneNode *IrrDriver::addAnimatedMesh(scene::IAnimatedMesh *
scene::ISceneNode *IrrDriver::addSkyBox(const std::vector<video::ITexture*> &texture,
const std::vector<video::ITexture*> &spherical_harmonics_textures)
{
#ifndef SERVER_ONLY
assert(texture.size() == 6);
m_renderer->addSkyBox(texture, spherical_harmonics_textures);
#endif
return m_scene_manager->addSkyBoxSceneNode(texture[0], texture[1],
texture[2], texture[3],
texture[4], texture[5]);

View File

@ -657,8 +657,8 @@ void ShaderBasedRenderer::giveBoost(unsigned int cam_index)
}
// ----------------------------------------------------------------------------
void ShaderBasedRenderer::addSkyBox(const std::vector<video::ITexture*> &texture,
const std::vector<video::ITexture*> &spherical_harmonics_textures)
void ShaderBasedRenderer::addSkyBox(const std::vector<video::IImage*> &texture,
const std::vector<video::IImage*> &spherical_harmonics_textures)
{
m_skybox = new Skybox(texture);
if(spherical_harmonics_textures.size() == 6)

View File

@ -87,8 +87,8 @@ public:
void resetPostProcessing() OVERRIDE;
void giveBoost(unsigned int cam_index) OVERRIDE;
void addSkyBox(const std::vector<irr::video::ITexture*> &texture,
const std::vector<irr::video::ITexture*> &spherical_harmonics_textures) OVERRIDE;
void addSkyBox(const std::vector<irr::video::IImage*> &texture,
const std::vector<irr::video::IImage*> &spherical_harmonics_textures);
void removeSkyBox() OVERRIDE;
const SHCoefficients* getSHCoefficients() const OVERRIDE;
GLuint getRenderTargetTexture(TypeRTT which) const OVERRIDE;

View File

@ -147,8 +147,8 @@ void Skybox::generateCubeMapFromTextures()
unsigned size = 0;
for (unsigned i = 0; i < 6; i++)
{
size = std::max(size, m_skybox_textures[i]->getSize().Width);
size = std::max(size, m_skybox_textures[i]->getSize().Height);
size = std::max(size, m_skybox_textures[i]->getDimension().Width);
size = std::max(size, m_skybox_textures[i]->getDimension().Height);
}
const unsigned texture_permutation[] = { 2, 3, 0, 1, 5, 4 };
@ -158,9 +158,18 @@ void Skybox::generateCubeMapFromTextures()
for (unsigned i = 0; i < 6; i++)
{
unsigned idx = texture_permutation[i];
video::IImage* img = static_cast<STKTexture*>
(m_skybox_textures[idx])->getTextureImage();
assert(img != NULL);
video::IImage* img = m_skybox_textures[idx];
#if defined(USE_GLES2)
uint8_t* data = (uint8_t*)img->lock();
for (unsigned int j = 0; j <
img->getDimension().Width * img->getDimension().Height; j++)
{
uint8_t tmp_val = data[j * 4];
data[j * 4] = data[j * 4 + 2];
data[j * 4 + 2] = tmp_val;
}
#endif
img->copyToScaling(rgba[i], size, size);
if (i == 2 || i == 3)
@ -176,6 +185,7 @@ void Skybox::generateCubeMapFromTextures()
}
delete[] tmp;
}
img->drop();
glBindTexture(GL_TEXTURE_CUBE_MAP, m_cube_map);
@ -315,8 +325,9 @@ Out of legacy the sequence of textures maps to:
- 6th texture maps to GL_TEXTURE_CUBE_MAP_POSITIVE_Z
* \param skybox_textures sequence of 6 textures.
*/
Skybox::Skybox(const std::vector<video::ITexture *> &skybox_textures)
Skybox::Skybox(const std::vector<video::IImage *> &skybox_textures)
{
m_cube_map = 0;
m_skybox_textures = skybox_textures;
#if !defined(USE_GLES2)
@ -341,11 +352,10 @@ Skybox::~Skybox()
// ----------------------------------------------------------------------------
void Skybox::render(const scene::ICameraSceneNode *camera) const
{
if (m_skybox_textures.empty())
if (m_cube_map == 0)
return;
glEnable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
assert(m_skybox_textures.size() == 6);
if (CVS->isDeferredEnabled())
{

View File

@ -28,8 +28,8 @@
class Skybox
{
private:
/** The 6 skybox textures */
std::vector<irr::video::ITexture *> m_skybox_textures;
/** The 6 skybox images */
std::vector<irr::video::IImage *> m_skybox_textures;
/** The skybox texture id */
GLuint m_cube_map;
@ -42,7 +42,7 @@ private:
void generateSpecularCubemap ();
public:
Skybox(const std::vector<irr::video::ITexture *> &skybox_textures);
Skybox(const std::vector<irr::video::IImage *> &skybox_textures);
~Skybox();
void render(const irr::scene::ICameraSceneNode *camera) const;

View File

@ -22,7 +22,6 @@
#include "graphics/central_settings.hpp"
#endif
#include "graphics/irr_driver.hpp"
#include "graphics/stk_texture.hpp"
#include "utils/log.hpp"
#include <algorithm>
@ -514,7 +513,7 @@ printf( "#### SH ; Coeffs B ; %f %f %f %f %f %f %f %f\n", m_SH_coeff->blue_SH_co
} // projectSH
// ----------------------------------------------------------------------------
SphericalHarmonics::SphericalHarmonics(const std::vector<video::ITexture *> &spherical_harmonics_textures)
SphericalHarmonics::SphericalHarmonics(const std::vector<video::IImage *> &spherical_harmonics_textures)
{
m_SH_coeff = new SHCoefficients;
setTextures(spherical_harmonics_textures);
@ -539,7 +538,7 @@ SphericalHarmonics::~SphericalHarmonics()
/** Compute spherical harmonics coefficients from 6 textures */
void SphericalHarmonics::setTextures(const std::vector<video::ITexture *> &spherical_harmonics_textures)
void SphericalHarmonics::setTextures(const std::vector<video::IImage *> &spherical_harmonics_textures)
{
assert(spherical_harmonics_textures.size() == 6);
@ -551,8 +550,8 @@ void SphericalHarmonics::setTextures(const std::vector<video::ITexture *> &spher
for (unsigned i = 0; i < 6; i++)
{
sh_w = std::max(sh_w, m_spherical_harmonics_textures[i]->getSize().Width);
sh_h = std::max(sh_h, m_spherical_harmonics_textures[i]->getSize().Height);
sh_w = std::max(sh_w, m_spherical_harmonics_textures[i]->getDimension().Width);
sh_h = std::max(sh_h, m_spherical_harmonics_textures[i]->getDimension().Height);
}
for (unsigned i = 0; i < 6; i++)
@ -561,19 +560,8 @@ void SphericalHarmonics::setTextures(const std::vector<video::ITexture *> &spher
for (unsigned i = 0; i < 6; i++)
{
unsigned idx = texture_permutation[i];
video::IImage* img = static_cast<STKTexture*>
(m_spherical_harmonics_textures[idx])->getTextureImage();
assert(img != NULL);
img->copyToScaling(sh_rgba[i], sh_w, sh_h);
#if defined(USE_GLES2)
// Code here assume color format is BGRA
for (unsigned int j = 0; j < sh_w * sh_h; j++)
{
char tmp_val = sh_rgba[i][j * 4];
sh_rgba[i][j * 4] = sh_rgba[i][j * 4 + 2];
sh_rgba[i][j * 4 + 2] = tmp_val;
}
#endif
m_spherical_harmonics_textures[idx]->copyToScaling(sh_rgba[i], sh_w, sh_h);
m_spherical_harmonics_textures[idx]->drop();
} //for (unsigned i = 0; i < 6; i++)
generateSphericalHarmonics(sh_rgba, sh_w);

View File

@ -41,7 +41,7 @@ class SphericalHarmonics
{
private:
/** The 6 spherical harmonics textures */
std::vector<irr::video::ITexture *> m_spherical_harmonics_textures;
std::vector<irr::video::IImage *> m_spherical_harmonics_textures;
/** Ambient light is used for tracks without spherical harmonics textures */
irr::video::SColor m_ambient;
@ -52,11 +52,11 @@ private:
void generateSphericalHarmonics(unsigned char *sh_rgba[6], unsigned int edge_size);
public:
SphericalHarmonics(const std::vector<irr::video::ITexture *> &spherical_harmonics_textures);
SphericalHarmonics(const std::vector<irr::video::IImage *> &spherical_harmonics_textures);
SphericalHarmonics(const irr::video::SColor &ambient);
~SphericalHarmonics();
void setTextures(const std::vector<irr::video::ITexture *> &spherical_harmonics_textures);
void setTextures(const std::vector<irr::video::IImage *> &spherical_harmonics_textures);
void setAmbientLight(const irr::video::SColor &ambient);
inline const SHCoefficients* getCoefficients() const { return m_SH_coeff; }

View File

@ -40,6 +40,7 @@
#include "graphics/particle_kind.hpp"
#include "graphics/particle_kind_manager.hpp"
#include "graphics/render_target.hpp"
#include "graphics/shader_based_renderer.hpp"
#include "graphics/shader_files_manager.hpp"
#include "graphics/stk_tex_manager.hpp"
#include "graphics/sp/sp_base.hpp"
@ -95,6 +96,11 @@
#include <sstream>
#include <wchar.h>
#ifndef SERVER_ONLY
#include <ge_main.hpp>
#include <ge_texture.hpp>
#endif
using namespace irr;
@ -412,20 +418,13 @@ void Track::cleanup()
for(unsigned int i=0; i<m_sky_textures.size(); i++)
{
m_sky_textures[i]->drop();
if(m_sky_textures[i]->getReferenceCount()==1)
irr_driver->removeTexture(m_sky_textures[i]);
video::ITexture* tex = (video::ITexture*)m_sky_textures[i];
tex->drop();
if (tex->getReferenceCount() == 1)
irr_driver->removeTexture(tex);
}
m_sky_textures.clear();
for (unsigned int i = 0; i<m_spherical_harmonics_textures.size(); i++)
{
m_spherical_harmonics_textures[i]->drop();
if (m_spherical_harmonics_textures[i]->getReferenceCount() == 1)
irr_driver->removeTexture(m_spherical_harmonics_textures[i]);
}
m_spherical_harmonics_textures.clear();
if(m_cache_track)
material_manager->makeMaterialsPermanent();
else
@ -2094,10 +2093,23 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
#ifndef SERVER_ONLY
if(m_sky_type==SKY_BOX && m_sky_textures.size() == 6)
{
//if (m_spherical_harmonics_textures.size() > 0)
m_all_nodes.push_back(irr_driver->addSkyBox(m_sky_textures, m_spherical_harmonics_textures));
//else
// m_all_nodes.push_back(irr_driver->addSkyBox(m_sky_textures, m_sky_textures));
if (CVS->isGLSL())
{
std::vector<video::IImage*> sky;
for (void* t : m_sky_textures)
sky.push_back((video::IImage*)t);
std::vector<video::IImage*> sh;
for (void* t : m_spherical_harmonics_textures)
sh.push_back((video::IImage*)t);
SP::getRenderer()->addSkyBox(sky, sh);
}
else
{
std::vector<video::ITexture*> textures;
for (void* t : m_sky_textures)
textures.push_back((video::ITexture*)t);
m_all_nodes.push_back(irr_driver->addSkyBox(textures, {}));
}
}
else if(m_sky_type==SKY_COLOR)
{
@ -2253,15 +2265,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
#ifndef SERVER_ONLY
if (CVS->isGLSL())
{
for (video::ITexture* t : m_sky_textures)
{
t->drop();
}
m_sky_textures.clear();
for (video::ITexture* t : m_spherical_harmonics_textures)
{
t->drop();
}
m_spherical_harmonics_textures.clear();
}
#endif // !SERVER_ONLY
@ -2430,27 +2434,28 @@ void Track::handleSky(const XMLNode &xml_node, const std::string &filename)
std::string s;
xml_node.get("texture", &s);
std::vector<std::string> v = StringUtils::split(s, ' ');
for(unsigned int i=0; i<v.size(); i++)
for (unsigned int i = 0; i<v.size(); i++)
{
video::ITexture* t = NULL;
void* obj = NULL;
#ifndef SERVER_ONLY
if (CVS->isGLSL())
{
t = STKTexManager::getInstance()->getTexture(v[i],
(TexConfig*)NULL/*tex_config*/, true/*no_upload*/);
video::IImage* img = getSkyTexture(v[i]);
obj = img;
}
else
#endif // !SERVER_ONLY
{
t = irr_driver->getTexture(v[i]);
}
if (t)
{
#ifndef SERVER_ONLY
if (!CVS->isGLSL())
#endif // !SERVER_ONLY
video::ITexture* t = irr_driver->getTexture(v[i]);
if (t)
{
t->grab();
m_sky_textures.push_back(t);
obj = t;
}
}
if (obj)
{
m_sky_textures.push_back(obj);
}
else
{
@ -2458,6 +2463,7 @@ void Track::handleSky(const XMLNode &xml_node, const std::string &filename)
v[i].c_str());
}
} // for i<v.size()
if(m_sky_textures.size()!=6)
{
Log::error("track",
@ -2474,27 +2480,14 @@ void Track::handleSky(const XMLNode &xml_node, const std::string &filename)
std::string sh_textures;
xml_node.get("sh-texture", &sh_textures);
v = StringUtils::split(sh_textures, ' ');
#ifndef SERVER_ONLY
for (unsigned int i = 0; i<v.size(); i++)
{
video::ITexture* t = NULL;
#ifndef SERVER_ONLY
if (CVS->isGLSL())
video::IImage* img = getSkyTexture(v[i]);
if (img)
{
t = STKTexManager::getInstance()->getTexture(v[i],
(TexConfig*)NULL/*tex_config*/, true/*no_upload*/);
}
else
#endif // !SERVER_ONLY
{
t = irr_driver->getTexture(v[i]);
}
if (t)
{
#ifndef SERVER_ONLY
if (!CVS->isGLSL())
#endif // !SERVER_ONLY
t->grab();
m_spherical_harmonics_textures.push_back(t);
m_spherical_harmonics_textures.push_back(img);
}
else
{
@ -2502,6 +2495,8 @@ void Track::handleSky(const XMLNode &xml_node, const std::string &filename)
v[i].c_str());
}
} // for i<v.size()
#endif // !SERVER_ONLY
}
else if (xml_node.getName() == "sky-color")
{
@ -2925,3 +2920,21 @@ void Track::cleanChildTrack()
delete child_track;
m_current_track[PT_CHILD] = NULL;
} // cleanChildTrack
//-----------------------------------------------------------------------------
video::IImage* Track::getSkyTexture(std::string path) const
{
#ifdef SERVER_ONLY
return NULL;
#else
if (path.find('/') == std::string::npos)
{
io::path relative_path = file_manager->searchTexture(path).c_str();
if (relative_path.empty())
return NULL;
path = file_manager->getFileSystem()->getAbsolutePath(relative_path)
.c_str();
}
return GE::getResizedImage(path);
#endif
} // getSkyTexture

View File

@ -253,9 +253,9 @@ private:
/** A list of the textures for the sky to use. It contains one texture
* in case of a dome, and 6 textures for a box. */
std::vector<video::ITexture*> m_sky_textures;
std::vector<void*> m_sky_textures;
std::vector<video::ITexture*> m_spherical_harmonics_textures;
std::vector<void*> m_spherical_harmonics_textures;
/** Used if m_sky_type is SKY_COLOR only */
irr::video::SColor m_sky_color;
@ -405,6 +405,7 @@ private:
void handleSky(const XMLNode &root, const std::string &filename);
void freeCachedMeshVertexBuffer();
void copyFromMainProcess();
video::IImage* getSkyTexture(std::string path) const;
public:
/** Static function to get the current track. NULL if no current