Skip to content

Commit

Permalink
Use cubemap for skyboxes
Browse files Browse the repository at this point in the history
  • Loading branch information
Vincent Lejeune committed Feb 26, 2014
1 parent 4d6b110 commit 61ea376
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 3 deletions.
4 changes: 4 additions & 0 deletions src/graphics/irr_driver.cpp
Expand Up @@ -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]);
Expand All @@ -1180,6 +1182,8 @@ scene::ISceneNode *IrrDriver::addSkyBox(const std::vector<video::ITexture*>
void IrrDriver::suppressSkyBox()
{
SkyboxTextures.clear();
glDeleteTextures(1, &SkyboxCubeMap);
SkyboxCubeMap = 0;
}

// ----------------------------------------------------------------------------
Expand Down
3 changes: 3 additions & 0 deletions src/graphics/irr_driver.hpp
Expand Up @@ -115,6 +115,8 @@ class IrrDriver : public IEventReceiver, public NoCopy
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
Expand Down Expand Up @@ -225,6 +227,7 @@ class IrrDriver : public IEventReceiver, public NoCopy
~IrrDriver();
void initDevice();
void reset();
void generateSkyboxCubemap();
void renderSkybox();
void setPhase(STKRenderingPass);
STKRenderingPass getPhase() const;
Expand Down
53 changes: 50 additions & 3 deletions src/graphics/render.cpp
Expand Up @@ -918,13 +918,56 @@ 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;

scene::ICameraSceneNode *camera = m_scene_manager->getActiveCamera();
if (!cubevao)
createcubevao();
if (!SkyboxCubeMap)
generateSkyboxCubemap();
glBindVertexArray(cubevao);
glDisable(GL_CULL_FACE);
assert(SkyboxTextures.size() == 6);
Expand All @@ -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);
Expand Down
28 changes: 28 additions & 0 deletions src/graphics/shaders.cpp
Expand Up @@ -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();
Expand Down Expand Up @@ -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);
}
}


Expand Down
11 changes: 11 additions & 0 deletions src/graphics/shaders.hpp
Expand Up @@ -280,6 +280,17 @@ class DisplaceShader
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
Expand Down

0 comments on commit 61ea376

Please sign in to comment.