Use cubemap for skyboxes
This commit is contained in:
parent
4d6b110e56
commit
61ea376ff2
@ -1171,7 +1171,9 @@ scene::ISceneNode *IrrDriver::addSkyDome(video::ITexture *texture,
|
||||
scene::ISceneNode *IrrDriver::addSkyBox(const std::vector<video::ITexture*>
|
||||
&texture)
|
||||
{
|
||||
assert(texture.size() == 6);
|
||||
SkyboxTextures = texture;
|
||||
SkyboxCubeMap = 0;
|
||||
return m_scene_manager->addSkyBoxSceneNode(texture[0], texture[1],
|
||||
texture[2], texture[3],
|
||||
texture[4], texture[5]);
|
||||
@ -1180,6 +1182,8 @@ scene::ISceneNode *IrrDriver::addSkyBox(const std::vector<video::ITexture*>
|
||||
void IrrDriver::suppressSkyBox()
|
||||
{
|
||||
SkyboxTextures.clear();
|
||||
glDeleteTextures(1, &SkyboxCubeMap);
|
||||
SkyboxCubeMap = 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -115,6 +115,8 @@ private:
|
||||
core::matrix4 m_ViewMatrix, m_InvViewMatrix, m_ProjMatrix, m_InvProjMatrix, m_ProjViewMatrix, m_InvProjViewMatrix;
|
||||
|
||||
std::vector<video::ITexture *> SkyboxTextures;
|
||||
GLuint SkyboxCubeMap;
|
||||
|
||||
|
||||
/** Flag to indicate if a resolution change is pending (which will be
|
||||
* acted upon in the next update). None means no change, yes means
|
||||
@ -225,6 +227,7 @@ public:
|
||||
~IrrDriver();
|
||||
void initDevice();
|
||||
void reset();
|
||||
void generateSkyboxCubemap();
|
||||
void renderSkybox();
|
||||
void setPhase(STKRenderingPass);
|
||||
STKRenderingPass getPhase() const;
|
||||
|
@ -918,6 +918,47 @@ static void createcubevao()
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * 6 * sizeof(int), indices, GL_STATIC_DRAW);
|
||||
}
|
||||
|
||||
#define MAX2(a, b) ((a) > (b) ? (a) : (b))
|
||||
|
||||
void IrrDriver::generateSkyboxCubemap()
|
||||
{
|
||||
|
||||
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
||||
|
||||
glGenTextures(1, &SkyboxCubeMap);
|
||||
|
||||
GLint w = 0, h = 0;
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
{
|
||||
w = MAX2(w, SkyboxTextures[i]->getOriginalSize().Width);
|
||||
h = MAX2(h, SkyboxTextures[i]->getOriginalSize().Height);
|
||||
}
|
||||
|
||||
const unsigned texture_permutation[] = { 2, 3, 0, 1, 5, 4 };
|
||||
char *rgba = new char[w * h * 4];
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
{
|
||||
unsigned idx = texture_permutation[i];
|
||||
|
||||
video::IImage* image = getVideoDriver()->createImageFromData(
|
||||
SkyboxTextures[idx]->getColorFormat(),
|
||||
SkyboxTextures[idx]->getSize(),
|
||||
SkyboxTextures[idx]->lock(),
|
||||
false
|
||||
);
|
||||
SkyboxTextures[idx]->unlock();
|
||||
|
||||
image->copyToScaling(rgba, w, h);
|
||||
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, SkyboxCubeMap);
|
||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid*)rgba);
|
||||
image->drop();
|
||||
}
|
||||
delete[] rgba;
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||
}
|
||||
|
||||
|
||||
void IrrDriver::renderSkybox()
|
||||
{
|
||||
if (SkyboxTextures.empty()) return;
|
||||
@ -925,6 +966,8 @@ void IrrDriver::renderSkybox()
|
||||
scene::ICameraSceneNode *camera = m_scene_manager->getActiveCamera();
|
||||
if (!cubevao)
|
||||
createcubevao();
|
||||
if (!SkyboxCubeMap)
|
||||
generateSkyboxCubemap();
|
||||
glBindVertexArray(cubevao);
|
||||
glDisable(GL_CULL_FACE);
|
||||
assert(SkyboxTextures.size() == 6);
|
||||
@ -937,13 +980,17 @@ void IrrDriver::renderSkybox()
|
||||
core::matrix4 scale;
|
||||
scale.setScale(core::vector3df(viewDistance, viewDistance, viewDistance));
|
||||
transform *= translate * scale;
|
||||
core::matrix4 invtransform;
|
||||
transform.getInverse(invtransform);
|
||||
|
||||
for (unsigned i = 0; i < 6; i++)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, static_cast<irr::video::COpenGLTexture*>(SkyboxTextures[i])->getOpenGLTextureName());
|
||||
glUseProgram(MeshShader::ObjectUnlitShader::Program);
|
||||
MeshShader::ObjectUnlitShader::setUniforms(transform, 0);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, SkyboxCubeMap);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glUseProgram(MeshShader::SkyboxShader::Program);
|
||||
MeshShader::SkyboxShader::setUniforms(transform, invtransform, core::vector2df(UserConfigParams::m_width, UserConfigParams::m_height), 0);
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (GLvoid*) (6 * i * sizeof(int)));
|
||||
}
|
||||
glBindVertexArray(0);
|
||||
|
@ -260,6 +260,7 @@ void Shaders::loadShaders()
|
||||
MeshShader::ShadowShader::init();
|
||||
MeshShader::RefShadowShader::init();
|
||||
MeshShader::GrassShadowShader::init();
|
||||
MeshShader::SkyboxShader::init();
|
||||
ParticleShader::FlipParticleRender::init();
|
||||
ParticleShader::HeightmapSimulationShader::init();
|
||||
ParticleShader::SimpleParticleRender::init();
|
||||
@ -1028,6 +1029,33 @@ namespace MeshShader
|
||||
glUniform2f(uniform_dir2, dir2X, dir2Y);
|
||||
glUniform1i(uniform_tex, TU_tex);
|
||||
}
|
||||
|
||||
GLuint SkyboxShader::Program;
|
||||
GLuint SkyboxShader::attrib_position;
|
||||
GLuint SkyboxShader::attrib_texcoord;
|
||||
GLuint SkyboxShader::uniform_MVP;
|
||||
GLuint SkyboxShader::uniform_tex;
|
||||
GLuint SkyboxShader::uniform_screen;
|
||||
GLuint SkyboxShader::uniform_InvProjView;
|
||||
|
||||
void SkyboxShader::init()
|
||||
{
|
||||
Program = LoadProgram(file_manager->getAsset("shaders/object_pass2.vert").c_str(), file_manager->getAsset("shaders/sky.frag").c_str());
|
||||
attrib_position = glGetAttribLocation(Program, "Position");
|
||||
attrib_texcoord = glGetAttribLocation(Program, "Texcoord");
|
||||
uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix");
|
||||
uniform_InvProjView = glGetUniformLocation(Program, "InvProjView");
|
||||
uniform_tex = glGetUniformLocation(Program, "tex");
|
||||
uniform_screen = glGetUniformLocation(Program, "screen");
|
||||
}
|
||||
|
||||
void SkyboxShader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &InvProjView, const core::vector2df &screen, unsigned TU_tex)
|
||||
{
|
||||
glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer());
|
||||
glUniformMatrix4fv(uniform_InvProjView, 1, GL_FALSE, InvProjView.pointer());
|
||||
glUniform1i(uniform_tex, TU_tex);
|
||||
glUniform2f(uniform_screen, screen.X, screen.Y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -280,6 +280,17 @@ public:
|
||||
static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &ModelViewMatrix, float dirX, float dirY, float dir2X, float dir2Y, unsigned TU_tex);
|
||||
};
|
||||
|
||||
class SkyboxShader
|
||||
{
|
||||
public:
|
||||
static GLuint Program;
|
||||
static GLuint attrib_position, attrib_texcoord;
|
||||
static GLuint uniform_MVP, uniform_InvProjView, uniform_tex, uniform_screen;
|
||||
|
||||
static void init();
|
||||
static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &InvProjView, const core::vector2df &screen, unsigned TU_tex);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace ParticleShader
|
||||
|
Loading…
Reference in New Issue
Block a user