Related
I've been trying to implement shadow mapping into my OpenGL engine in SFML 2.2, and they don't seem to be rendering right. I believe I narrowed down the issue to the ortho projection used to calculate the shadows.
/* before the main loop, creating the depth buffer for shadow mapping */
glm::vec3 lightPos(glm::vec3(-45.f, 45.f, -40.f));
const GLuint SHADOW_WIDTH = 1024, SHADOW_HEIGHT = 1024;
GLuint depthMapFBO;
glGenFramebuffers(1, &depthMapFBO);
GLuint depthMap;
glGenTextures(1, &depthMap);
glBindTexture(GL_TEXTURE_2D, depthMap);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
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_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
GLfloat borderColor[] = { 1.0, 1.0, 1.0, 1.0 };
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthMap, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
/* in the main loop, sending information to the appropiate shaders and setting viewports */
glm::mat4 lightProjection, lightView;
glm::mat4 lightSpaceMatrix;
GLfloat near_plane = 1.f, far_plane = 300.f;
lightProjection = glm::ortho(-10.f, 10.f, -10.f, 10.f, near_plane, far_plane);
lightView = glm::lookAt(lightPos, glm::vec3(0.0f), glm::vec3(0.0, 1.0, 0.0));
lightSpaceMatrix = lightProjection * lightView;
glUseProgram(simpleDepthShader);
glUniformMatrix4fv(glGetUniformLocation(simpleDepthShader, "lightSpaceMat"), 1, GL_FALSE, glm::value_ptr(lightSpaceMatrix));
glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
glClear(GL_DEPTH_BUFFER_BIT);
RenderScene();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// reset viewport, and display the scene as normal
glViewport(0, 0, window.getSize().x, window.getSize().y);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUniform3fv(glGetUniformLocation(lightingShader, "lightPos_shade"), 1, &lightPos[0]);
glUniform3fv(glGetUniformLocation(lightingShader, "viewPos"), 1, &getPos()[0]);
glUniformMatrix4fv(glGetUniformLocation(lightingShader, "lightSpaceMat"), 1, GL_FALSE, glm::value_ptr(lightSpaceMatrix));
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, depthMap);
RenderScene();
I've applied the view and projection matrix to the camera to see what the light sees, and this was the result (along with the view from the depth buffer).
Here's what the scene looks like with the shadows (which the shadow for the stall doesn't even cast onto itself for some reason).
It seems that your shader doesn't fetch your shadow pixels correctly.
When you transform your vertices with your light matrix they are in the [-1, 1] range, but texture sampling is in the range [0, 1].
http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-16-shadow-mapping/
[Objectives] I need to write to a CubeMap's specific mipmap level in OpenGL 4+. Each mipmap levels is blurrier the deeper the level is.
[Problem] The problem is that I have the same image over all mipmap levels if I write only on level 0, and nothing at all if I try to write only on other mipmap level.
[Update] I'm pretty sure the problem is textureLod always clamp to the base LOD 0. Whatever mipmap level I try to get through it, it returns the base LOD.
Here is my cubemap generation (I'm trying to have 6 mipmap levels, counting the base):
GLuint PreFilteredEnvTex;
glGenTextures(1, &PreFilteredEnvTex);
glBindTexture(GL_TEXTURE_CUBE_MAP, PreFilteredEnvTex);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 5);
for (int i = 0; i < 6; ++i)
{
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, 512, 512, 0, GL_RGB, GL_FLOAT, 0);
}
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
Utils::checkGlError("Generate PreFilteredEnvMap");
And here an example of my attempt to write to each mipmap levels :
//Compute pre filtered environnement maps
glDisable(GL_CULL_FACE);
glDisable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glBindFramebuffer(GL_FRAMEBUFFER, fboManager["fx"]);
glViewport(0, 0, screenWidth, screenHeight);
glClear(GL_COLOR_BUFFER_BIT);
const int MIPMAPLEVELS = 6;
const int MIPMAPBASELEVELSIZE = 512;
int MipMapTextureSize;
glBindVertexArray(vaoManager["cube"]);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, skybox->texture_id);
Shader* PreEnvFilter = shaderManager["PreEnvFilter"];
PreEnvFilter->use();
glm::vec3 EyePosition = glm::vec3(0.f);
// Light space matrices
glm::mat4 CubeMapProjection = glm::perspective(glm::radians(90.f), 1.f, 1.f, 100.f);
std::vector<glm::mat4> worldToLight;
worldToLight.push_back(CubeMapProjection * glm::lookAt(EyePosition, EyePosition + glm::vec3(1.0, 0.0, 0.0), glm::vec3(0.0, -1.0, 0.0)));
worldToLight.push_back(CubeMapProjection * glm::lookAt(EyePosition, EyePosition + glm::vec3(-1.0, 0.0, 0.0), glm::vec3(0.0, -1.0, 0.0)));
worldToLight.push_back(CubeMapProjection * glm::lookAt(EyePosition, EyePosition + glm::vec3(0.0, 1.0, 0.0), glm::vec3(0.0, 0.0, 1.0)));
worldToLight.push_back(CubeMapProjection * glm::lookAt(EyePosition, EyePosition + glm::vec3(0.0, -1.0, 0.0), glm::vec3(0.0, 0.0, -1.0)));
worldToLight.push_back(CubeMapProjection * glm::lookAt(EyePosition, EyePosition + glm::vec3(0.0, 0.0, 1.0), glm::vec3(0.0, -1.0, 0.0)));
worldToLight.push_back(CubeMapProjection * glm::lookAt(EyePosition, EyePosition + glm::vec3(0.0, 0.0, -1.0), glm::vec3(0.0, -1.0, 0.0)));
for (GLuint i = 0; i < 6; ++i)
PreEnvFilter->SetMatrix4(("ViewMatrix[" + to_string(i) + "]").c_str(), worldToLight[i]);
PreEnvFilter->SetInt("EnvMapSampler", 0);
PreEnvFilter->SetMatrix4("Model", glm::mat4());
//For each faces compute all mipmaps levels
for (unsigned int j = 0; j < MIPMAPLEVELS; ++j)
{
//For each mipmap level, render the filtered environnement in it
MipMapTextureSize = std::max(1, MIPMAPBASELEVELSIZE / (1 << j));
glViewport(0, 0, MipMapTextureSize, MipMapTextureSize);
//glViewport(0, 0, MIPMAPBASELEVELSIZE, MIPMAPBASELEVELSIZE);
float roughness = (j + 0.5f) / MIPMAPLEVELS;
PreEnvFilter->SetFloat("Roughness", roughness);
//Bind to the current buffer
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, PreFilteredEnvTex, j);
glDrawElements(GL_TRIANGLES, 12 * 3, GL_UNSIGNED_INT, (void*)0);
}
PreEnvFilter->unuse();
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
Utils::checkGlError("Initialize PreFilteredEnvMap");
I'm sure my shader is working, because if I'm looping over all mipmap levels and drawing only to the base level I have a good looking result :
The result if I'm only writing to level 0 for all mipmap levels
The cubemap is printed with the following fragment shader (TexCoords is modified according to the face I want to draw) :
#version 430
uniform int MipMapLevel;
uniform samplerCube CubeMap;
in vec3 TexCoords;
out vec4 Color;
void main()
{
Color = textureLod(CubeMap, TexCoords, MipMapLevel);
}
And if I'm writing to all mipmap levels, I have the same image on all mipmap levels (actually if I write only to level 0 I have the same result on all mipmap levels as well )
Same result, different mipmap levels
My conclusion is as followed :
My mipmap generation is not good, but I've read the specs and glGenerateMipmap should have done the job
I have a problem when trying to bind the mipmap level throught glFramebufferTexture, but once again it doesn't seems wrong to me
My shader to draw the cubemap is not working as I think it should ? I've never used textureLod before, but as far as I know, I am using it right here, right ?
If someone as already done something similar, I would really appreciate some help ! After all the time I spent on it, I'm still not able to do this simple thing in OpenGL when I did it whithout problems in DX11 :(
P.S : OpenGL does not report any errors
After trying almost everything, I've finally make it works by generating my cubemap as follow :
GLuint PreFilteredEnvTex;
glGenTextures(1, &PreFilteredEnvTex);
glBindTexture(GL_TEXTURE_CUBE_MAP, PreFilteredEnvTex);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 5);
for (int i = 0; i < 6; ++i)
{
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F, 512, 512, 0, GL_RGB, GL_FLOAT, 0);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
I've change the min filter to GL_LINEAR_MIPMAP_LINEAR and call glGenerateMipmap at the end, instead of doing like in this link.
Thanks for your interest :)
I have been trying draw a hut (as a cylinder with a cone on top) and add a brick txture to the wall and a roof-tile texture to the roof. However, I am only getting the first texture that I load (the bricks).
Here is my code (Please note that I have tried to switch between textures using glActiveTexture):
void drawCylinder()
{
int width, height;
unsigned char * data_for_wall = SOIL_load_image("./bricks.jpg", &width, &height, NULL, 0);
glDisable(GL_LIGHTING);
glGenTextures( 2, textures );
glActiveTexture(GL_TEXTURE0);
glEnable( GL_TEXTURE_2D );
glBindTexture(GL_TEXTURE_2D, textures[0]);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// Generate mipmaps, by the way.
glGenerateMipmap(GL_TEXTURE_2D);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, width, height, GL_RGB, GL_UNSIGNED_BYTE, data_for_wall);
for(float theta = 0.0; theta <= 360.0; theta += 10.0 )
{
//colors[k] = color4(0.69, 0.35, 0.0, 1.0); //This color is brown.
tex_coords[global_index]=vec2(theta*DegreesToRadians, 0.0);
float x = 0.15*sin(theta*DegreesToRadians);
float y = 0.15*cos(theta*DegreesToRadians);
points[global_index] = Translate(0.6, 0.0, 0.35)*point4(x, 0.0, y, 1.0);
// This is the
// bottom of the cylinder. The points are plotted in a full circle. The first three numbers are the x,y and z values
// respectively. The last number (ie. 1.0) is not important - it just converts to homogeneous coordinates.
++global_index;
tex_coords[global_index] = vec2(theta*DegreesToRadians, 0.25);
points[global_index] = Translate(0.6, 0.0, 0.35)*point4(x, 0.25, y, 1.0);
// This is the
// top of the cylinder
++global_index;
}
}
//The roof of the hut
void drawCone()
{
int width, height;
unsigned char * data_for_roof = SOIL_load_image("./roof_tiles.jpg", &width, &height, NULL, 0);
glDisable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE1);
glBindTexture( GL_TEXTURE_2D, textures[1] );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// Generate mipmaps, by the way.
glGenerateMipmap(GL_TEXTURE_2D);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, width, height, GL_RGB, GL_UNSIGNED_BYTE, data_for_roof);
int index = 0;
int l = 0;
for(float theta = 0.0; theta <= 360.0; theta += 10.0)
{
tex_coords[global_index]=vec2(theta*DegreesToRadians, 0.25);
points[global_index] = Translate(0.6, 0.0, 0.35)*point4(0.0, 0.5, 0.0, 1.0); // This is the top of the cone.
++global_index;
tex_coords[global_index] = vec2(theta*DegreesToRadians, 0.5);
points[global_index] = Translate(0.6, 0.0, 0.35)*point4(0.25*sin(theta*DegreesToRadians), 0.25, 0.25*cos(theta*DegreesToRadians), 1.0);
// This is the
// bottom of the cone.
++global_index;
}
}
And here is the display function:
void
display( void )
{
mat4 mv = Translate(0.0, -0.065, -rad)*RotateX(Theta[0])*RotateY(Theta[1])*RotateZ(Theta[2]);
mat4 p = Perspective(10.0, aspectRatio, zNear, zFar);
glUniformMatrix4fv( matrix_loc, 1, GL_TRUE, mv );
glUniformMatrix4fv( projection_loc, 1, GL_TRUE, p );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glUniform3fv( theta, 1, Theta );
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textures[0]);
glDrawArrays( GL_TRIANGLE_STRIP, 0, 74 );
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, textures[1]);
glDrawArrays( GL_TRIANGLE_STRIP, 74, 74);
glutSwapBuffers();
}
I am not sure if it is important to include the fragment shader but I will do it anyways:
#version 150
in vec2 texCoord;
out vec4 fColor;
uniform sampler2D texture;
void main()
{
fColor = texture2D( texture, texCoord );
}
I have been struggling for hours to get this right. Does anyone know what I have done wrong?
glActiveTexture() is used to set the texture slot that you are binding a texture to when multi-texturing (rendering more than one texture in a single pass). For example, you might have one texture for a texture map, another for normal map and so on.
However, you are not multi-texturing, because you render the walls and the cone in separate passes (i.e. two separate calls to glDrawArrays()), and your shader only uses a single texture per pass. So within each pass you are only rendering a single texture, which will be in slot 0.
If you set the active texture to GL_TEXTURE1 and then call glBindTexture() then the texture will be bound to slot 1, and slot 0 will remain unchanged.
So, set the active texture slot to 0 both times. Remove this line from your display() function:
glActiveTexture(GL_TEXTURE1);
Well, I've done a test to see if it works the shadowmapping using two light source. Something is wrong, the first shadowmap make a correct shade, but the second shadowmap not. This is the complete code.
FUNCTIONS
void setupMatrices(float position_x,float position_y,float position_z,float lookAt_x,float lookAt_y,float lookAt_z){
glLoadIdentity();
gluLookAt(position_x,position_y,position_z,lookAt_x,lookAt_y,lookAt_z,0,1,0);
}
void setTextureMatrix1(){
static double modelView[16];
static double projection[16];
const GLdouble bias[16] = {0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5, 1.0};
glGetDoublev(GL_MODELVIEW_MATRIX, modelView);
glGetDoublev(GL_PROJECTION_MATRIX, projection);
glMatrixMode(GL_TEXTURE);
glActiveTexture(GL_TEXTURE6);
glLoadIdentity();
glLoadMatrixd(bias);
glMultMatrixd (projection);
glMultMatrixd (modelView);
glMatrixMode(GL_MODELVIEW);
}
void setTextureMatrix2(){
static double modelView[16];
static double projection[16];
const GLdouble bias[16] = {0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5, 1.0};
glGetDoublev(GL_MODELVIEW_MATRIX, modelView);
glGetDoublev(GL_PROJECTION_MATRIX, projection);
glMatrixMode(GL_TEXTURE);
glActiveTexture(GL_TEXTURE7);
glLoadIdentity();
glLoadMatrixd(bias);
glMultMatrixd (projection);
glMultMatrixd (modelView);
glMatrixMode(GL_MODELVIEW);
}
void startTranslate1(float x,float y,float z){
glPushMatrix();
glTranslatef(x,y,z);
glMatrixMode(GL_TEXTURE);
glActiveTextureARB(GL_TEXTURE6);
glPushMatrix();
glTranslatef(x,y,z);
}
void startTranslate2(float x,float y,float z){
glPushMatrix();
glTranslatef(x,y,z);
glMatrixMode(GL_TEXTURE);
glActiveTextureARB(GL_TEXTURE7);
glPushMatrix();
glTranslatef(x,y,z);
}
void endTranslate(){
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
void drawObjects1(){
glColor4f(0.3f,0.3f,0.3f,1);
glBegin(GL_QUADS);
glVertex3f(-35,2,-35);
glVertex3f(-35,2, 15);
glVertex3f( 15,2, 15);
glVertex3f( 15,2,-35);
glEnd();
glColor4f(0.9f,0.9f,0.9f,1);
startTranslate1(0,4,-5);
glutSolidCube(4);
endTranslate();
}
void drawObjects2(){
glColor4f(0.3f,0.3f,0.3f,1);
glBegin(GL_QUADS);
glVertex3f(-35,2,-35);
glVertex3f(-35,2, 15);
glVertex3f( 15,2, 15);
glVertex3f( 15,2,-35);
glEnd();
glColor4f(0.9f,0.9f,0.9f,1);
startTranslate2(0,4,-5);
glutSolidCube(4);
endTranslate();
}
MAIN
int main(){
GLuint depthTextureId;
glGenTextures(1, &depthTextureId);
glBindTexture(GL_TEXTURE_2D, depthTextureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadowMapWidth, shadowMapHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);
GLuint fboId;
GLenum FBOstatus;
glGenFramebuffersEXT(1, &fboId);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D, depthTextureId, 0);
FBOstatus = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if(FBOstatus != GL_FRAMEBUFFER_COMPLETE_EXT)return 1;
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
/////////////////////////////////////////////////////////////////////
GLuint depthTextureId2;
glGenTextures(1, &depthTextureId2);
glBindTexture(GL_TEXTURE_2D, depthTextureId2);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadowMapWidth, shadowMapHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);
GLuint fboId2;
GLenum FBOstatus2;
glGenFramebuffersEXT(1, &fboId2);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId2);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D, depthTextureId2, 0);
FBOstatus2 = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if(FBOstatus2 != GL_FRAMEBUFFER_COMPLETE_EXT)return 1;
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
GLfloat angulo = 0.0;
GLfloat posZ = 0.0;
glEnable(GL_CULL_FACE);
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
MAIN LOOP
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,fboId);
glViewport(0,0,640,480);
glClear(GL_DEPTH_BUFFER_BIT);
glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
setupMatrices(5.0,15.0,0.0,-5.0,0.0,-5.0);
glCullFace(GL_FRONT);
drawObjects1();
setTextureMatrix1();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,fboId2);
glViewport(0,0,640,480);
glClear(GL_DEPTH_BUFFER_BIT);
glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
setupMatrices(p_light[0],p_light[1],p_light[2],l_light[0],l_light[1],l_light[2]);
glCullFace(GL_FRONT);
drawObjects2();
setTextureMatrix2();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0);
glViewport(0,0,640,480);
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
glUseProgram(p);
glUniform1i(shadowMapUniform,6);
glActiveTexture(GL_TEXTURE6);
glBindTexture(GL_TEXTURE_2D,depthTextureId);
glUniform1i(shadowMapUniform2,7);
glActiveTexture(GL_TEXTURE7);
glBindTexture(GL_TEXTURE_2D,depthTextureId2);
glCullFace(GL_BACK);
setupMatrices(p_camera[0],p_camera[1],p_camera[2],l_camera[0],l_camera[1],l_camera[2]);
drawObjects1();
glBindTexture(GL_TEXTURE_2D,0);
glUseProgram(0);
VERTEX SHADER
varying vec4 ShadowCoord1;
varying vec4 ShadowCoord2;
void main(){
ShadowCoord1 = gl_TextureMatrix[6] * gl_Vertex;
ShadowCoord2 = gl_TextureMatrix[7] * gl_Vertex;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_FrontColor = gl_Color;
}
FRAGMENT SHADER
uniform sampler2D ShadowMap;
uniform sampler2D ShadowMap2;
varying vec4 ShadowCoord1;
varying vec4 ShadowCoord2;
varying vec3 pvertice;
void main(){
vec4 shadowCoordinateWdivide1 = ShadowCoord1 / ShadowCoord1.w ;
vec4 shadowCoordinateWdivide2 = ShadowCoord2 / ShadowCoord2.w ;
shadowCoordinateWdivide1.z += 0.0001;
shadowCoordinateWdivide2.z += 0.0001;
float distanceFromLight1 = texture2D(ShadowMap,shadowCoordinateWdivide1.st).z;
float distanceFromLight2 = texture2D(ShadowMap2,shadowCoordinateWdivide2.st).z;
float shadow1 = 1.0;
if (ShadowCoord1.w > 0.0){
shadow1 = distanceFromLight1 < shadowCoordinateWdivide1.z ? 0.5 : 1.0 ;
}
float shadow2 = 1.0;
if (ShadowCoord2.w > 0.0){
shadow2 = distanceFromLight2 < shadowCoordinateWdivide2.z ? 0.5 : 1.0 ;
}
gl_FragColor = mix(shadow1,shadow2,0.5) * gl_Color;
}
What is wrong? This looks like...
If I try to move around the object it looks bad.
While with a single light in the same position it looks like this.
If I try to move around the object this looks good.
Thanks.
Those bias impact self shadowing, try setting them a bit higher.
shadowCoordinateWdivide1.z += 0.0001;
shadowCoordinateWdivide2.z += 0.0001;
It seems like if i use texture(texture0,textCoord) for one time and then i try to use it again with an other texture texture(texture1,textCoord); it returns (0,0,0,0); and i just dont know why .
In my program it seems to be an order of workines ,if the depht works than the others wont ,
if i dont use the depth than only the color works and so on .( Depht , Color , Normal , Pos , Shine is the order)
this is the fragment shader :
uniform sampler2D tex0;
uniform sampler2D tex1;
uniform sampler2D tex2;
uniform sampler2D tex3;
uniform sampler2D depht;
void main()
{
float UNIT = 1./640. ;
//vec4 depht = texture(depht,gl_TexCoord[0].st);
vec4 color = texture(tex0,gl_TexCoord[0].st);
vec4 norma = texture(tex1,gl_TexCoord[0].st);
vec4 posit = texture(tex2,gl_TexCoord[0].st);
vec4 shine = texture(tex3,gl_TexCoord[0].st);
if(false){
gl_FragColor=( texture2D(tex0,gl_TexCoord[0].st +vec2(0,0))+
texture2D(tex0,gl_TexCoord[0].st +vec2(0,-UNIT))+
texture2D(tex0,gl_TexCoord[0].st +vec2(UNIT,-UNIT))+
texture2D(tex0,gl_TexCoord[0].st +vec2(UNIT,0))+
texture2D(tex0,gl_TexCoord[0].st +vec2(UNIT,UNIT))+
texture2D(tex0,gl_TexCoord[0].st +vec2(0,UNIT))+
texture2D(tex0,gl_TexCoord[0].st +vec2(-UNIT,UNIT))+
texture2D(tex0,gl_TexCoord[0].st +vec2(-UNIT,0))+
texture2D(tex0,gl_TexCoord[0].st +vec2(-UNIT,-UNIT)))/9.;
}else{
gl_FragColor=(norma+color);
}
}
this is the binding part :
fbotest.drawFBO();
DEFERRED.UseNow();
DrawGLScene();
fbotest.readFBO();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
DEFERRED2.UseNow();
//glBlendFunc (GL_ONE, GL_ONE);
glEnable( GL_BLEND );
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, fbotest.Color);
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, fbotest.Normal);
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, fbotest.Pos);
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, fbotest.Shine);
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE4);
glBindTexture(GL_TEXTURE_2D, fbotest.Depht);
glEnable(GL_TEXTURE_2D);
glUniform1i(glGetUniformLocation(DEFERRED2.PR,"tex0"),0);
glUniform1i(glGetUniformLocation(DEFERRED2.PR,"tex1"),1);
glUniform1i(glGetUniformLocation(DEFERRED2.PR,"tex2"),2);
glUniform1i(glGetUniformLocation(DEFERRED2.PR,"tex3"),3);
glUniform1i(glGetUniformLocation(DEFERRED2.PR,"depht"),4);
glLoadIdentity();
glBegin(GL_QUADS);
glMultiTexCoord2f(GL_TEXTURE0, 1.0, 0.0);
glMultiTexCoord2f(GL_TEXTURE1, 1.0, 0.0);
glMultiTexCoord2f(GL_TEXTURE2, 1.0, 0.0);
glMultiTexCoord2f(GL_TEXTURE3, 1.0, 0.0);
glMultiTexCoord2f(GL_TEXTURE4, 1.0, 0.0);
glVertex3f( 1,-1,-3);
glMultiTexCoord2f(GL_TEXTURE0, 1.0, 1.0);
glMultiTexCoord2f(GL_TEXTURE1, 1.0, 1.0);
glMultiTexCoord2f(GL_TEXTURE2, 1.0, 1.0);
glMultiTexCoord2f(GL_TEXTURE3, 1.0, 1.0);
glMultiTexCoord2f(GL_TEXTURE4, 1.0, 1.0);
glVertex3f( 1,1 ,-3);
glMultiTexCoord2f(GL_TEXTURE0, 0.0, 1.0);
glMultiTexCoord2f(GL_TEXTURE1, 0.0, 1.0);
glMultiTexCoord2f(GL_TEXTURE2, 0.0, 1.0);
glMultiTexCoord2f(GL_TEXTURE3, 0.0, 1.0);
glMultiTexCoord2f(GL_TEXTURE4, 0.0, 1.0);
glVertex3f( -1,1,-3);
glMultiTexCoord2f(GL_TEXTURE0, 0.0, 0.0);
glMultiTexCoord2f(GL_TEXTURE1, 0.0, 0.0);
glMultiTexCoord2f(GL_TEXTURE2, 0.0, 0.0);
glMultiTexCoord2f(GL_TEXTURE3, 0.0, 0.0);
glMultiTexCoord2f(GL_TEXTURE4, 0.0, 0.0);
glVertex3f(-1,-1,-3);
glEnd();
glActiveTextureARB(GL_TEXTURE4);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTextureARB(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTextureARB(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTextureARB(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTextureARB(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, 0);
glDisable( GL_BLEND );
and this is may FBO class :
class deferred{
public :
unsigned int FBO;
unsigned int Depht;
unsigned int Color;
unsigned int Normal;
unsigned int Pos;
unsigned int Shine;
deferred();
void initFBO();
void readFBO();
void drawFBO();
};
void deferred::readFBO(){
glBindFramebuffer(GL_DRAW_FRAMEBUFFER,0);
glBindFramebuffer(GL_READ_FRAMEBUFFER,FBO);
}
void deferred::drawFBO(){
glBindFramebuffer(GL_READ_FRAMEBUFFER,0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER,FBO);
}
deferred::deferred(){
FBO =0;
Depht =0;
Color =0;
Normal =0;
Pos =0;
Shine =0;
}
void deferred::initFBO(){
glGenFramebuffers(1, &FBO);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FBO);
glGenTextures(1,&Depht );
glGenTextures(1,&Color );
glGenTextures(1,&Normal);
glGenTextures(1,&Pos );
glGenTextures(1,&Shine );
int WindowWidth = Ww;
int WindowHeight= Wh;
glBindTexture(GL_TEXTURE_2D, Color);
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB32F, WindowWidth, WindowHeight, 0, GL_RGB, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, Color, 0);
glBindTexture(GL_TEXTURE_2D, Normal);
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB32F, WindowWidth, WindowHeight, 0, GL_RGB, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, Normal, 0);
glBindTexture(GL_TEXTURE_2D, Pos);
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB32F, WindowWidth, WindowHeight, 0, GL_RGB, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, Pos, 0);
glBindTexture(GL_TEXTURE_2D, Shine);
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB32F, WindowWidth, WindowHeight, 0, GL_RGB, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, Shine, 0);
glBindTexture(GL_TEXTURE_2D, Depht);
glTexImage2D (GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, WindowWidth, WindowHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, Depht, 0);
GLenum DrawBuffers[] = { GL_COLOR_ATTACHMENT0,
GL_COLOR_ATTACHMENT1,
GL_COLOR_ATTACHMENT2,
GL_COLOR_ATTACHMENT3};
glDrawBuffers(4, DrawBuffers);
GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (Status != GL_FRAMEBUFFER_COMPLETE) {
cout <<"Frame Buffer ERROR : "<< Status << "\n" ;
}
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
}
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, 0);
glUniform1i(glGetUniformLocation(DEFERRED2.PR,"tex0"),0);
Try changing these to look like this. GL_TEXTURE_2D should be enabled when binding. ALso the ID at the end of glBindTexture shoulder go up - 0 1 2 3 4 5. I'm not sure what your values are returning. Then you send that data each time with glUinform1i which will bind the texture bound at 0.
I've changed this :
void deferred::readFBO(){
glBindFramebuffer(GL_DRAW_FRAMEBUFFER,0);
glBindFramebuffer(GL_READ_FRAMEBUFFER,FBO);
}
void deferred::drawFBO(){
glBindFramebuffer(GL_READ_FRAMEBUFFER,0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER,FBO);
}
with this :
> void deferred::readFBO(){
> glBindFramebuffer(GL_DRAW_FRAMEBUFFER,0);
> glBindFramebuffer(GL_READ_FRAMEBUFFER,FBO);
>
> glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
> glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, 0, 0);
> glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, 0, 0);
> glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, 0, 0);
> glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT , GL_TEXTURE_2D, 0, 0);
}
>
> void deferred::drawFBO(){
> glBindFramebuffer(GL_READ_FRAMEBUFFER,0);
> glBindFramebuffer(GL_DRAW_FRAMEBUFFER,FBO);
>
> glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, Color , 0);
> glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, Normal, 0);
> glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, Pos , 0);
> glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, Shine , 0);
> glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT , GL_TEXTURE_2D, Depht , 0);
}
and now it works . I belive it is a litle slow even if i dont see any changes in framerates and i dont quite know why i cant let the textures binded to the framebuffer , but yea it solved the problem .