Shadow mapping
This commit is contained in:
110
main.cc
110
main.cc
@@ -63,8 +63,8 @@ int main(int argc, char *argv[])
|
||||
window = SDL_CreateWindow("SDL2 Test",
|
||||
SDL_WINDOWPOS_UNDEFINED,
|
||||
SDL_WINDOWPOS_UNDEFINED,
|
||||
640,
|
||||
480,
|
||||
1680,
|
||||
1050,
|
||||
/*SDL_WINDOW_FULLSCREEN_DESKTOP |*/ SDL_WINDOW_OPENGL);
|
||||
|
||||
if (!window) {
|
||||
@@ -131,11 +131,35 @@ int main(int argc, char *argv[])
|
||||
std::printf("Warning: extension GL_EXT_texture_filter_anisotropic not supported\n");
|
||||
Texture2D redTex("textures/red.png");
|
||||
Texture2D whiteTex("textures/white.png");
|
||||
|
||||
const unsigned lights = 2;
|
||||
const unsigned shadowMapSize = 512;
|
||||
glm::mat4 shadowProj = glm::perspectiveFov(90.0f, static_cast<float>(shadowMapSize),
|
||||
static_cast<float>(shadowMapSize), 1.0f, 128.0f);
|
||||
std::vector<TextureCubeMap> shadowMaps;
|
||||
for(unsigned i = 0;i < lights;++i) {
|
||||
shadowMaps.emplace_back(shadowMapSize);
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, static_cast<GLint>(GL_LESS));
|
||||
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, static_cast<GLint>(GL_COMPARE_REF_TO_TEXTURE));
|
||||
}
|
||||
|
||||
const glm::vec3 lightPos[lights] = {glm::vec3(2.0, -2.0, 10.0),
|
||||
glm::vec3(2.0, 2.0, 10.0)};
|
||||
// const glm::vec3 lightColor[lights] = {glm::vec3(1.0, 0.9, 0.8),
|
||||
// glm::vec3(0.0, 1.0, 0.0)};
|
||||
// const float lightIntensity[lights] = {75.0f, 25.0f};
|
||||
|
||||
|
||||
Framebuffer shadowFB;
|
||||
|
||||
VertexShader vs{fileToString("shaders/textured.vs")};
|
||||
FragmentShader fs{fileToString("shaders/textured.fs")};
|
||||
Program prog(vs, fs);
|
||||
|
||||
Program prog{vs, fs};
|
||||
|
||||
VertexShader shadowVs{fileToString("shaders/shadow.vs")};
|
||||
FragmentShader shadowFs{fileToString("shaders/shadow.fs")};
|
||||
Program shadowProg{shadowVs, shadowFs};
|
||||
|
||||
prog.use();
|
||||
glUniformMatrix4fv(prog.getUniformLocation("projection_matrix"), 1, GL_FALSE,
|
||||
glm::value_ptr(proj));
|
||||
@@ -143,6 +167,13 @@ int main(int argc, char *argv[])
|
||||
glm::value_ptr(view));
|
||||
glUniform1i(prog.getUniformLocation("texBase"), 0);
|
||||
|
||||
const GLint shadowMapTUs[] = {1, 2};
|
||||
glUniform1iv(prog.getUniformLocation("texShadowMaps"), 2, shadowMapTUs);
|
||||
|
||||
shadowProg.use();
|
||||
glUniformMatrix4fv(prog.getUniformLocation("projection_matrix"), 1, GL_FALSE,
|
||||
glm::value_ptr(shadowProj));
|
||||
|
||||
Object box(vboManager, "objects/woodbox.obj", prog);
|
||||
Object pyramid(vboManager, "objects/pyramid.obj", prog);
|
||||
Object plane(vboManager, "objects/plane.obj", prog);
|
||||
@@ -165,18 +196,87 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
// Draw shadow maps
|
||||
GLint origVP[4];
|
||||
glGetIntegerv(GL_VIEWPORT, origVP);
|
||||
glViewport(0, 0, shadowMapSize, shadowMapSize);
|
||||
shadowProg.use();
|
||||
shadowFB.bind();
|
||||
glPolygonOffset(1.1f, 4.0f);
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
glEnable(GL_POLYGON_OFFSET_LINE);
|
||||
glEnable(GL_POLYGON_OFFSET_POINT);
|
||||
for (unsigned light = 0;light < lights;++light) {
|
||||
for (unsigned i = 0;i < 6;++i) {
|
||||
GLenum const face[6] = {GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
|
||||
GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z};
|
||||
|
||||
const glm::vec3 dir[6] = {glm::vec3(1.0f, 0.0f, 0.0f),
|
||||
glm::vec3(-1.0f, 0.0f, 0.0f),
|
||||
glm::vec3(0.0f, 1.0f, 0.0f),
|
||||
glm::vec3(0.0f, -1.0f, 0.0f),
|
||||
glm::vec3(0.0f, 0.0f, 1.0f),
|
||||
glm::vec3(0.0f, 0.0f, -1.0f)};
|
||||
const glm::vec3 up[6] = {glm::vec3(0.0f, 1.0f, 0.0f),
|
||||
glm::vec3(0.0f, -1.0f, 0.0f),
|
||||
glm::vec3(1.0f, 0.0f, 0.0f),
|
||||
glm::vec3(-1.0f, 0.0f, 0.0f),
|
||||
glm::vec3(0.0f, 1.0f, 0.0f),
|
||||
glm::vec3(0.0f, -1.0f, 0.0f)};
|
||||
|
||||
shadowMaps[light].bind();
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
|
||||
face[i], shadowMaps[light].getID(), 0);
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
glm::mat4 view = glm::lookAt(lightPos[light],
|
||||
lightPos[light]+dir[i],
|
||||
up[i]);
|
||||
glUniformMatrix4fv(prog.getUniformLocation("view_matrix"), 1, GL_FALSE,
|
||||
glm::value_ptr(view));
|
||||
|
||||
glm::mat4 model = glm::translate(glm::vec3(0.5f, 0.5f, -0.5f)) *
|
||||
glm::rotate(SDL_GetTicks()*0.001f, glm::vec3(1.0f, 0.0f, 0.0f)) *
|
||||
glm::translate(glm::vec3(-0.5f, -0.5f, 0.5f));
|
||||
box.draw(model, &shadowProg);
|
||||
plane.draw(glm::translate(glm::vec3(2.0f, -2.5f, 0.0f))*
|
||||
glm::rotate(0.35f, glm::vec3(0.0f, 1.0f, 0.0f)), &shadowProg);
|
||||
pyramid.draw(glm::translate(glm::vec3(-2.0f, 0.0f, 0.0f)), &shadowProg);
|
||||
}
|
||||
}
|
||||
|
||||
GLsync fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, UnusedMask());
|
||||
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
glViewport(origVP[0], origVP[1], origVP[2], origVP[3]);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
glDisable(GL_POLYGON_OFFSET_LINE);
|
||||
glDisable(GL_POLYGON_OFFSET_POINT);
|
||||
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
shadowMaps[1].bind();
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
shadowMaps[0].bind();
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
glm::mat4 model = glm::translate(glm::vec3(0.5f, 0.5f, -0.5f)) *
|
||||
glm::rotate(SDL_GetTicks()*0.001f, glm::vec3(1.0f, 0.0f, 0.0f)) *
|
||||
glm::translate(glm::vec3(-0.5f, -0.5f, 0.5f));
|
||||
cubeTex.bind();
|
||||
|
||||
// Shadow maps must be rendered before real drawing can begin
|
||||
glClientWaitSync(fence, SyncObjectMask(), 0xffffffffu);
|
||||
glDeleteSync(fence);
|
||||
|
||||
box.draw(model);
|
||||
whiteTex.bind();
|
||||
plane.draw(glm::translate(glm::vec3(2.0f, -2.5f, 0.0f))*
|
||||
glm::rotate(0.35f, glm::vec3(0.0f, 1.0f, 0.0f)));
|
||||
glm::rotate(0.35f, glm::vec3(0.0f, 1.0f, 0.0f)));
|
||||
redTex.bind();
|
||||
pyramid.draw(glm::translate(glm::vec3(-2.0f, 0.0f, 0.0f)));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user