I am trying to do a basic shadow map but for some reason, It doesn't render properly.
Video of the Problem
I render the house using a flat shader:
int shadowMapWidth = WINDOW_SIZE_X * (int)SHADOW_MAP_RATIO;
int shadowMapHeight = WINDOW_SIZE_Y * (int)SHADOW_MAP_RATIO;
// Rendering into the shadow texture.
glActiveTexture(GL_TEXTURE0);
CALL_GL(glBindTexture(GL_TEXTURE_2D, shadowTexture));
// Bind the framebuffer.
CALL_GL(glBindFramebuffer(GL_FRAMEBUFFER, shadowFBO));
//Clear it
CALL_GL(glClear(GL_DEPTH_BUFFER_BIT));
CALL_GL(glViewport(0, 0, shadowMapWidth, shadowMapHeight));
CALL_GL(glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE));
//Render stuff
flatShader.use();
flatShader["baseColor"] = glm::vec4(1.0f,1.0f,1.0f,1.0f);
flatShader["pvm"] = projectionMatrix*pointLight.viewMatrix*cursor.modelMatrix;
cursor.draw(); //binds the vao and draws
// Revert for the scene.
CALL_GL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
CALL_GL(glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE));
CALL_GL(glViewport(0, 0, WINDOW_SIZE_X, WINDOW_SIZE_Y));
Notice that I only render the house. I don't render the floor in the depth-buffer pass.
Following this I render the quad that represents the floor using the following shader pair:
/* [VERT] */
#version 330
in vec3 in_Position;
in vec2 in_TexCoord;
uniform mat4 shadowMatrix;
uniform mat4 mvp;
out vec2 UV;
out vec4 shadowProj;
void main()
{
gl_Position = mvp*vec4(in_Position,1.0);
shadowProj = shadowMatrix*vec4(in_Position,1.0);
UV = in_TexCoord;
}
And the Fragment Shader:
/* [FRAG] */
#version 330
in vec2 UV;
in vec4 shadowProj;
out vec4 fragColor;
uniform sampler2D texturex;
uniform sampler2DShadow shadowMap;
void main()
{
fragColor = vec4(texture(texturex, UV).rgb,1);
float shadow = 1.0;
shadow = textureProj(shadowMap,shadowProj);
fragColor *= shadow;
}
I then draw the house again in color and ... the floor:
textureShader.use();
glUniform1i(baseImageLoc, 0); //Texture unit 0 is for base images.
glUniform1i(shadowMapLoc, 1); //Texture unit 1 is for shadow maps.
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, floorTexture);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, shadowTexture);
textureShader["shadowMatrix"] = projectionMatrix*pointLight.viewMatrix*floorMatrix;
textureShader["mvp"] = projectionMatrix*viewMatrix*floorMatrix;
CALL_GL(glBindVertexArray(floorVAO));
CALL_GL(glDrawArrays(GL_TRIANGLES,0,18));
glfwSwapBuffers();
Has anybody seen this behavior before? Any idea what could be wrong? By the way, the light's coordinates place it directly on top of the house so the shadow should be directly below the house on the floor (but it ends up sideways).
For reference here is how I generate the shadow FBO:
int shadowMapWidth = WINDOW_SIZE_X * (int)SHADOW_MAP_RATIO;
int shadowMapHeight = WINDOW_SIZE_Y * (int)SHADOW_MAP_RATIO;
glGenTextures(1, &shadowTexture);
glBindTexture(GL_TEXTURE_2D, shadowTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadowMapWidth, shadowMapHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
glTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT,shadowMapWidth,shadowMapHeight,0,GL_DEPTH_COMPONENT,GL_FLOAT,NULL);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_COMPARE_MODE,GL_COMPARE_R_TO_TEXTURE);
glBindTexture(GL_TEXTURE_2D, 0); //unbind the texture
glGenFramebuffers(1, &shadowFBO);
glBindFramebuffer(GL_FRAMEBUFFER, shadowFBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, shadowTexture, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{ printf("GL_FRAMEBUFFER_COMPLETE error 0x%x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); }
glClearDepth(1.0f); glEnable(GL_DEPTH_TEST);
// Needed when rendering the shadow map. This will avoid artifacts.
glPolygonOffset(1.0f, 0.0f); glBindFramebuffer(GL_FRAMEBUFFER, 0);
//to convert the texture coordinates to -1 ~ 1
GLfloat biasMatrixf[] = {
0.5f, 0.0f, 0.0f, 0.0f,
0.0f, 0.5f, 0.0f, 0.0f,
0.0f, 0.0f, 0.5f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f };
biasMatrix = glm::make_mat4(biasMatrixf);
It looks like you forgot to multiply your shadow matrix by the bias matrix.
Related
I am following the tutorial from learnopengl.com to make a game engine.
I am using stb_image.h to load the textures, and my own header file to compile and link the shaders.
I got to the part in Getting Started/Textures where the container.jpg texture is supposed to fill up the rectangle on the window. But whenever I compile and run the code the texture does not appear anywhere in the window. This is my texture loading code:
// Load and create a texture
unsigned int texture1;
glGenTextures(1, &texture1);
glBindTexture(GL_TEXTURE_2D, texture1);
// Set the texture wrapping parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// Set texture filtering parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Load image, create texture, and generate minmaps
int width, height, nrChannels;
unsigned char* data = stbi_load("C:\\Users\\Lucas\\OneDrive\\Desktop\\C++ Projects\\Working Game Engine\\container.jpg", &width, &height, &nrChannels, 0);
if (data) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
}
else {
std::cout << "Failed to load texture(s)\n";
}
These are the quad's coords:
float vertices[] = {
// Positions // Colors // Texture Coords
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f
};
unsigned int indices[] = {
0, 1, 3,
1, 2, 3
};
Render code:
// Process inputs
processInput(window);
// Render
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// Bind Texture
glBindTexture(GL_TEXTURE_2D, texture1);
// Render Container
ourShader.use();
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
// Swap buffers and poll IO events (Key pressed/released, mouse moved etc.)
glfwSwapBuffers(window);
glfwPollEvents();
Vertex shader code:
#version 460 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;
out vec3 ourColor;
out vec2 TexCoord;
void main()
{
gl_Position = vec4(aPos, 1.0);
ourColor = aColor;
TexCoord = vec2(aTexCoord.x, aTexCoord.y);
}
Fragment shader code:
#version 460 core
out vec4 FragColor;
in vec3 ourColor;
in vec2 TexCoord;
uniform sampler2D texture1;
void main()
{
FragColor = texture(texture1, TexCoord);
}
Note that no error codes are returned from the image loader or shader compilers.
The rectangle appears like this.
You need to update the texture1 uniform like this:
glUniform1i(glGetUniformLocation(program_id, "texture1"), 0);
So it turns out I didn't glEnableVertexAttribArray(); the texture coords. Quite embarrassing.
Program compiles fine. Quads print. Trying to insert a 32 bit png, but it only prints a white box. What am I doing wrong? I've spent a few days trying to figure it out doing countless tutorials. I don't want to give up.
GLfloat cancelButtonVert[]
{
0.1367f, -0.928f, 0.0f, 0.0f, 0.0f,
0.4833f, -0.928f, 0.0f, 1.0f, 0.0f,
0.4833f, -0.744f, 0.0f, 1.0f, 1.0f,
0.1367f, -0.744f, 0.0f, 0.0f, 1.0f
};
const unsigned int buttonIndices[]
{
0, 1, 2,
2, 3, 0,
};
......
It's all set up with in classes and functions, but I will try to show the whole draw.
.....
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(m_vertices[0]) * 5, 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(m_vertices[0]) * 5, (void*)(sizeof(m_vertices[0]) * 3));
glEnableVertexAttribArray(1);
.....
void Texture::loadTexture()
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
unsigned char *texData = stbi_load(m_fileLocation.c_str(), &m_width, &m_height, &m_bitDepth, 0);
if (!texData)
{
printf("Failed to find: %s\n", m_fileLocation.c_str());
return;
}
glGenTextures(1, &m_textureId);
glBindTexture(GL_TEXTURE_2D, m_textureId);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData);
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
stbi_image_free(texData);
}
void Texture::useTexture()
{
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_textureId);
}
shaderList[0].useShader();
uniformModel = shaderList[0].getModelLocation();
uniformTexture = shaderList[0].getUniformTexture();
//Draw Boxes
model = glm::mat4();
model = glm::translate(model, glm::vec3(0.0f, 0.0f, 0.0f));
model = glm::scale(model, glm::vec3(1.0f, 1.0f, 1.0f));
glUniformMatrix4fv(uniformModel, 3, GL_FALSE, glm::value_ptr(model));
cancelButton.useTexture();
glUniform1i(uniformTexture, 0);
meshlist[0]->renderMesh();
The fragment shader.
#version 330
in vec4 vCol;
in vec2 TexCoord;
out vec4 color;
uniform sampler2D theTexture;
void main()
{
color = texture(theTexture, TexCoord);
}
The Vertex Shader.
#version 330
layout (location = 0) in vec3 pos;
layout (location = 1) in vec2 tex;
out vec4 vCol;
out vec2 TexCoord;
uniform mat4 model;
uniform mat4 projection;
void main()
{
gl_Position = projection * model * vec4(pos, 1.0);
vCol = vec4(clamp(pos, 0.0f, 1.0f), 1.0f);
TexCoord = tex;
}
Projection was out of wack. The reason I was getting all of those 1281 and 12 82 GLerrors was the fact that I was calling the wrong vector index, so I could see a draw. I saw a draw and assumed I was heading in the right direction.
If I called what I knew was right, all the drawing happened off screen.
What I did was delete the projection matrix in my shader since all I wanted was a 2d rendering of a gui window with calculated pixel ratios in a calculated position.
I will keep model in the shader if I want to tweak things in the future.
All of your help made me a better programmer. #Rabbid76 all of your suggestions were things I needed to do. Ty all.
Corrected Shader
#version 330
layout (location = 0) in vec3 pos;
layout (location = 1) in vec2 tex;
out vec4 vCol;
out vec2 TexCoord;
uniform mat4 model;
void main()
{
gl_Position = model * vec4(pos, 1.0);
vCol = vec4(clamp(pos, 0.0f, 1.0f), 1.0f);
TexCoord = tex;
}
I'm having a bit of trouble with my frame buffers in my OpenGL C++ application. There are no errors thrown (I get GL_FRAMEBUFFER_COMPLETE when I call glCheckFramebufferStatus), however when I render my FBO texture all I see is a black screen. I've searched for numerous hours and redone it multiple times to no avail, so I'm finally turning to you guys for some help. Below is all the relevant code. I hope you guys can spot something that my tired eyes couldn't. Thank you.
Initialization code:
glGenFramebuffers(1, &m_fbo);
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
m_texture = new Texture(width, height);
//glBindTexture(GL_TEXTURE_2D, m_texture->GetID());
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture->GetID(), 0);
glGenRenderbuffers(1, &m_depth);
glBindRenderbuffer(GL_RENDERBUFFER, m_depth);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depth);
GLuint status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
CheckError(status);
Texture init code:
unsigned char* imageData = fileName != "" ? stbi_load(fileName.c_str(), &width, &height, &numComponents, 4) : 0;
if (imageData == NULL && fileName != "")
std::cerr << "Texture loading failed for texture: " << fileName << std::endl;
glGenTextures(1, &m_texture);
glBindTexture(GL_TEXTURE_2D, m_texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
glBindTexture(GL_TEXTURE_2D, 0);
if (fileName != "") stbi_image_free(imageData);
Texture bind code:
glActiveTexture(GL_TEXTURE0 + unit);
glBindTexture(GL_TEXTURE_2D, m_texture);
Framebuffer bind code:
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
glViewport(0, 0, m_width, m_height);
Main code:
fbo.BindFramebuffer();
display.Clear(1.0f, 0.0f, 0.0f, 1.0f);
fboShader.Bind();
fboShader.Update(transform2, camera);
texture.Bind(0);
mesh2.Draw();
display.Bind();
display.Clear(0.0f, 0.0f, 0.9f, 1.0f);
shader.Bind();
shader.Update(transform, camera);
fbo.BindFramebufferTexture(0);
mesh3.Draw();
FBO shader code
Fragment:
#version 330
varying vec2 texCoord0;
varying vec3 normal0;
varying vec3 position0;
uniform sampler2D diffuse;
out vec4 outputColor;
void main()
{
outputColor = vec4(normal0, 1.0);
//gl_FragColor = vec4(normal0, 1.0);
}
Vertex:
#version 330
attribute vec3 position;
attribute vec2 texCoord;
attribute vec3 normal;
varying vec2 texCoord0;
varying vec3 normal0;
varying vec3 position0;
uniform mat4 transform;
void main()
{
gl_Position = transform * vec4(position, 1.0);
texCoord0 = texCoord;
normal0 = (transform * vec4(normal, 0.0)).xyz;
position0 = gl_Position.xyz;
}
What I should see is a box (mesh3) with a monkeyhead the color of its normals (mesh2) and red background on it, but all I get is black. I really appreciate any help!
I want to use a 1d texture (color ramp) to texture a simple triangle.
My fragment shader looks like this:
#version 420
uniform sampler1D colorRamp;
in float height;
out vec4 FragColor;
void main()
{
FragColor = texture(colorRamp, height).rgba;
}
My vertex shader looks like this:
#version 420
layout(location = 0) in vec3 position;
out float height;
void main()
{
height = (position.y + 0.75f) / (2 * 0.75f);
gl_Position = vec4( position, 1.0);
}
When drawing the triangle I proceed this way (I removed error checking form code for better readability):
glUseProgram(program_);
GLuint samplerLocation = glGetUniformLocation(program_, name.toCString());
glUniform1i(samplerLocation, currentTextureUnit_);
glActiveTexture( GL_TEXTURE0 + currentTextureUnit_ );
glBindTexture(GL_TEXTURE_1D, textureId);
Unfortunately my triangle is only black. Any ideas how to solve this issue?
I am pretty sure that the assigned texture is filled with proper data since I read it back with glGetTexImage and checked it. Do I need to call other functions to bind and activited the texture? I have almost the same code for 2d textures which is working.
When I change the shader code this way:
#version 420
uniform sampler1D colorRamp;
in float height;
out vec4 FragColor;
void main()
{
FragColor = vec4(height, height, height, 1.0); // change!
}
I get this output:
I prepared some demo source code that reproduces the error. The source can be found here.
It generates the following output:
The 1d texture is created this way - with only red pixels:
static GLuint Create1DTexture()
{
GLuint textureId_;
// generate the specified number of texture objects
glGenTextures(1, &textureId_);
assert(glGetError() == GL_NO_ERROR);
// bind texture
glBindTexture(GL_TEXTURE_1D, textureId_);
assert(glGetError() == GL_NO_ERROR);
// tells OpenGL how the data that is going to be uploaded is aligned
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
assert(glGetError() == GL_NO_ERROR);
float data[] =
{
1.0f, 0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f
};
glTexImage1D(
GL_TEXTURE_1D, // Specifies the target texture. Must be GL_TEXTURE_1D or GL_PROXY_TEXTURE_1D.
0, // Specifies the level-of-detail number. Level 0 is the base image level. Level n is the nth mipmap reduction image.
GL_RGBA32F,
3*sizeof(float)*4,
0, // border: This value must be 0.
GL_RGBA,
GL_FLOAT,
data
);
assert(glGetError() == GL_NO_ERROR);
// texture sampling/filtering operation.
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT);
assert(glGetError() == GL_NO_ERROR);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_REPEAT);
assert(glGetError() == GL_NO_ERROR);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
assert(glGetError() == GL_NO_ERROR);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
assert(glGetError() == GL_NO_ERROR);
glBindTexture(GL_TEXTURE_1D, 0);
assert(glGetError() == GL_NO_ERROR);
return textureId_;
}
Texture binding is done this way:
GLuint samplerLocation = glGetUniformLocation(rc.ToonHandle, "ColorRamp");
glUniform1i(samplerLocation, 0);
glActiveTexture(GL_TEXTURE0 + 0);
glBindTexture(GL_TEXTURE_1D, rc.texure1d);
Found the bug:
glTexImage1D(
GL_TEXTURE_1D, // Specifies the target texture. Must be GL_TEXTURE_1D or GL_PROXY_TEXTURE_1D.
0, // Specifies the level-of-detail number. Level 0 is the base image level. Level n is the nth mipmap reduction image.
GL_RGBA32F,
3/*3*sizeof(float)*4*/, // bug fix!!!!
0, // border: This value must be 0.
GL_RGBA,
GL_FLOAT,
data
);
I am trying to implement shadow mapping in our game project. I am using render to texture technique with two pass rendering. I have created a FBO first and bound a texture for depth component only. In the first pass, I enable this FBO, disable texture and render my scene from light POV. In the second pass, I pass the depth texture to the shader and render the scene normally. I perform the shadow related calculation in the shader.
But, my code is not working correctly. I am not able to see any shadow. Also, when I render both pass, I see a multiple drawing of the whole world trailing one after another if my camera is looking above a certain angle : 45. If I look below that angle, the rendering looks ok. What may be the source of this problem?
. If I disable the first pass, the world looks darker but the trailing scene is gone. I have also attached my codes below.
I have also another confusion. I have disabled texture for the first shadowmap pass. But I send the texture coordinates with my vertex coordinates to the VBO. Will that cause any problem?
FBO Initialization
LightPosition = glm::vec3(50.0f, 40.0f, 50.0f);
upVector = glm::vec3(0.0f, 1.0f, 0.0f);
glGenTextures(1, &m_shadowMap);
glBindTexture(GL_TEXTURE_2D, m_shadowMap);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32,
WindowWidth, WindowHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glBindTexture(GL_TEXTURE_2D, 0);
glGenFramebuffers(1, &m_fbo);
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
glDrawBuffers(0, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_shadowMap, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (Status != GL_FRAMEBUFFER_COMPLETE) {
printf("FB error, status: 0x%x\n", Status);
return false;
}
return true;
Shadow Map Pass:
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, 0);
glViewport(0, 0, windowWidth, windowHeight);
glBindFramebuffer(GL_FRAMEBUFFER, shadowMapFBO.m_fbo);
glClear(GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glm::mat4 lightProjection = glm::perspective(45.0f,
1.0f * windowWidth / windowHeight, 0.125f, 1000.0f);
glGetFloatv(GL_PROJECTION_MATRIX, shadowMapFBO.LightProjectionMatrix);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glm::mat4 lightModelView = glm::lookAt(shadowMapFBO.LightPosition,
glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
glGetFloatv(GL_MODELVIEW_MATRIX, shadowMapFBO.LightModelViewMatrix);
glm::mat4 lmvp = lightProjection * lightModelView;
glCullFace(GL_FRONT);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
glUniform1i(Shader::id_uniform_layer, 0);
world->render(lmvp);
printGLError();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
Render Pass:
static glm::vec3 cCameraPosition = glm::vec3(0.0f, 5.0f, 10.0f);
static glm::vec3 cLightPosition = glm::vec3(50.0f, 40.0f, 50.0f);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, windowWidth, windowHeight);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glm::mat4 modelView = player->getView();
float viewAngle = 45.0f;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glm::mat4 projection = glm::perspective(viewAngle,
1.0f * windowWidth / windowHeight, 0.01f, 1000.0f);
glm::mat4 mvp = projection * modelView;
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, shadowMapFBO.m_shadowMap);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glTranslatef(0.5f, 0.5f, 0.5f);
glScalef(0.5f, 0.5f, 0.5f);
glMultMatrixf(shadowMapFBO.LightProjectionMatrix);
glMultMatrixf(shadowMapFBO.LightModelViewMatrix);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, id_texture_blocks);
glUseProgram(Shader::id_program);
glUniform3fv(Shader::id_uniform_lightPosition, 1,
glm::value_ptr(cLightPosition));
glUniform3fv(Shader::id_uniform_CameraPosition, 1,
glm::value_ptr(*(player->getCoordinates())));
//Enabling color write (previously disabled for light POV z-buffer rendering)
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glUniform1i(Shader::id_shader_shadow, 1);
glUniformMatrix4fv(Shader::id_uniform_mvp, 1, GL_FALSE, glm::value_ptr(mvp));
glEnable(GL_POLYGON_OFFSET_FILL);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glUniform1i(Shader::id_uniform_layer, 0);
world->render(mvp);
printGLError();
Vertex Shader:
attribute vec4 coordinates;
uniform mat4 mvp;
//Fragment shader forward variables.
varying vec4 voxel;
//shadow map
// Used for shadow lookup
varying vec4 ShadowCoord;
uniform vec3 LightPosition, CameraPosition;
varying vec3 LightDirection, LightDirectionReflected, CameraDirection, Normal;
void main(void) {
//shadow map
LightDirection = LightPosition - gl_Vertex.xyz;
LightDirectionReflected = reflect(-LightDirection, gl_Normal);
CameraDirection = CameraPosition - gl_Vertex.xyz;
Normal = gl_Normal;
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_TexCoord[1] = gl_TextureMatrix[1] * gl_Vertex;
voxel = coordinates;
//Calculates projection on xyz.
gl_Position = mvp * vec4(coordinates.xyz, 1);
}
Fragment Shader:
#extension GL_EXT_gpu_shader4 : enable
//Rendering layer.
uniform int layer;
//Colors.
uniform float colorRed;
uniform float colorGreen;
uniform float colorBlue;
uniform float colorAlpha;
//Fog density.
uniform float fogDensity;
varying vec4 voxel;
uniform sampler2D texture;
const float N_TEXTURES = 32.0;
//////////////////////shadow map
uniform sampler2DShadow ShadowMap;
varying vec4 ShadowCoord;
varying vec3 LightDirection, LightDirectionReflected, CameraDirection, Normal;
void main(void) {
vec2 coord2d;
float intensity;
vec4 color = texture2D(texture, coord2d);
float z = gl_FragCoord.z / gl_FragCoord.w;
float fog = clamp(exp(-fogDensity * z * z), 0.2, 1.0);
color.xyz = color.xyz * intensity;
//shadow map
float Shadow = shadow2DProj(ShadowMap, gl_TexCoord[1]).r;
float NdotLD = max(dot(normalize(LightDirection), Normal), 0.0) * Shadow;
float Spec = pow(max(dot(normalize(LightDirectionReflected), normalize(CameraDirection)), 0.0), 32.0) * Shadow;
color.xyz = color.xyz * (0.25 + NdotLD * 0.75 + Spec);
//Final color.
vec4 fogColor = vec4(colorRed, colorGreen, colorBlue, colorAlpha);
gl_FragColor = mix(fogColor, color, fog);
}
At a glance it looks like you're not using glClear so the sky is whatever was in the last frame, or at least its not working. What's the alpha value of the glClearColor?