OpenGL & GLM Translation matrix stretched [duplicate] - c++

This question already has an answer here:
Matrix / vector multiplication order
(1 answer)
Closed 4 years ago.
I've been following a tutorial(for java which i'm adapting to c++) to write a game using OpenGL but I'm having an issue at the translation matrix part. My sprite gets stretched when I change it's position:
positon {-1.0f, 0.0f, 0.0f}
position {0, 0, 0}
I don't have any experience with graphics programming so I really have no idea of what went wrong. Here is my code:
Shaders:
// VERTEX
#shader vertex
#version 330 core
layout(location = 0) in vec4 position;
layout(location = 1) in vec2 texCoord;
out vec2 v_TexCoord;
uniform mat4 u_TransformationMatrix;
void main() {
gl_Position = position * u_TransformationMatrix;
v_TexCoord = texCoord;
};
// FRAGMENT
#shader fragment
#version 330 core
layout(location = 0) out vec4 color;
in vec2 v_TexCoord;
uniform vec4 u_Color;
uniform sampler2D u_Texture;
void main() {
vec4 texColor = texture(u_Texture, v_TexCoord);
color = texColor;
};
Calculation of the matrix:
static glm::mat4 createTransformationMatrix(glm::vec3 translation, glm::vec3 rotation, float scale) {
glm::mat4 matrix(1.f);
matrix = glm::translate(matrix, translation);
matrix = glm::rotate(matrix, glm::radians(rotation.x), glm::vec3(1.f, 0.f, 0.f));
matrix = glm::rotate(matrix, glm::radians(rotation.y), glm::vec3(0.f, 1.f, 0.f));
matrix = glm::rotate(matrix, glm::radians(rotation.z), glm::vec3(0.f, 0.f, 1.f));
matrix = glm::scale(matrix, glm::vec3(scale));
return matrix;
}
Rendering code:
void Render(const Renderer &renderer, Shader *shader) {
shader->SetUniformMatrix4f("u_TransformationMatrix", Math::createTransformationMatrix(position, rotation, scale));
model.Render(renderer, *shader);
}
Texture loading code:
Texture::Texture(const std::string & path, bool useTiling) : m_RendererId(0), m_FilePath(path), m_LocalBuffer(nullptr), m_Width(0), m_Height(0), m_BPP(0)
{
stbi_set_flip_vertically_on_load(false);
m_LocalBuffer = stbi_load(path.c_str(), &m_Width, &m_Height, &m_BPP, 4/*RGBA*/);
glGenTextures(1, &m_RendererId);
glBindTexture(GL_TEXTURE_2D, m_RendererId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, useTiling ? GL_REPEAT : GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, useTiling ? GL_REPEAT : GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_Width, m_Height, 0/*b*/, GL_RGBA, GL_UNSIGNED_BYTE, m_LocalBuffer);
glBindTexture(GL_TEXTURE_2D, 0);
if (m_LocalBuffer)
stbi_image_free(m_LocalBuffer);
}

The multiplication order in the shader is wrong. Replace
gl_Position = position * u_TransformationMatrix;
with
gl_Position = u_TransformationMatrix * position;
Matrix multiplications are not commutative.

Related

Issues writing to Framebuffer (Color attachments always black)

I'm trying to use a framebuffer as a Geometry Buffer for deferred shading. I'm having issues with writing and reading from the framebuffer's color attachments.
All I am trying to do is verify that my framebuffer's color attachments have some data. I do this by binding one of the color attachments and drawing a fullscreen quad. Each color attachment results in a fully black screen even though I've verified that my uniform variables are receiving the data they need.
My framebuffer is setup as follows:
glGenFramebuffers(1, &FBOID);
glBindFramebuffer(GL_FRAMEBUFFER, FBOID);
int WIDTH = windowDetails->width;
int HEIGHT = windowDetails->height;
glGenTextures(1, &gPosition);
glBindTexture(GL_TEXTURE_2D, gPosition);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, WIDTH, HEIGHT, 0, GL_RGBA, 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_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gPosition, 0);
glGenTextures(1, &gAlbedo);
glBindTexture(GL_TEXTURE_2D, gAlbedo);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, WIDTH, HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, gAlbedo, 0);
glGenTextures(1, &gNormal);
glBindTexture(GL_TEXTURE_2D, gNormal);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, WIDTH, HEIGHT, 0, GL_RGBA, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, gNormal, 0);
glGenTextures(1, &gEffects);
glBindTexture(GL_TEXTURE_2D, gEffects);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, WIDTH, HEIGHT, 0, GL_RGB, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, gEffects, 0);
GLuint attachments[4] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 };
glDrawBuffers(4, attachments);
glGenRenderbuffers(1, &zBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, zBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, WIDTH, HEIGHT);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, zBuffer);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
std::cout << "Framebuffer not complete !" << std::endl;
}
Every frame, I will bind this framebuffer and draw to it using my geometry shader. Then I will bind a test shader to check if the contents of the color attachements have some data by binding all of the color attachments to their own texture unit and passing one of them to the test shader:
glDisable(GL_BLEND); // No blend for deffered rendering
glEnable(GL_DEPTH_TEST); // Enable depth testing for scene render
glBindFramebuffer(GL_FRAMEBUFFER, FBOID); // Start drawing to FBO
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(gShader);
SubmittedGeometry& geometry = defferedGeometry[0];
glm::mat4 projViewModel = projection * view * geometry.transform;
glm::mat4& prevProjViewModel = prevProjViewModels.count(geometry.handle) <= 0 ? projViewModel : prevProjViewModels.at(geometry.handle);
prevProjViewModels.insert({ geometry.handle, projViewModel });
glUniformMatrix4fv(matModelLoc, geometry.transform);
glUniformMatrix4fv(matProjViewLoc, projViewModel);
glUniformMatrix4fv(matPrevProjeViewLoc, prevProjViewModel);
// Bind albedo textures
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, albedoTexID);
glUniform1i(albedoLoc, 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, normalTexID);
glUniform1i(normalLoc, 1);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, roughnessTexID);
glUniform1i(rougnessLoc, 2);
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, metalnessTexID);
glUniform1i(metalnessLoc, 3);
glActiveTexture(GL_TEXTURE4);
glBindTexture(GL_TEXTURE_2D, aoTexID);
glUniform1i(aoLoc, 4);
glBindVertexArray(geometry.vaoID);
glDrawElements(GL_TRIANGLES, geometry.indices, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
glBindFramebuffer(GL_FRAMEBUFFER, 0); // Done drawing to FBO
// Test FBO color attachments
glUseProgram(testShaderID);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, gPosition);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, gAlbedo);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, gNormal);
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, gEffects);
glUniform1i(testTextureLoc, 1);
quad->Draw();
Assigning the testTexture sampler with 0, 1, 2, or 3 all result in a black screen.
Geometry Shader:
VERTEX SHADER
#version 420
layout (location = 0) in vec3 vPosition;
layout (location = 1) in vec3 vNormal;
layout (location = 2) in vec2 vTextureCoordinates;
layout (location = 3) in vec3 vBiNormal;
layout (location = 4) in vec3 vTangent;
uniform mat4 uMatModel;
uniform mat4 uMatView;
uniform mat4 uMatProjection;
uniform mat4 uMatProjViewModel;
uniform mat4 uMatPrevProjViewModel;
out vec3 mViewPosition;
out vec2 mTextureCoordinates;
out vec3 mNormal;
out vec4 mFragPosition;
out vec4 mPrevFragPosition;
void main()
{
// Translate to view space
vec4 viewFragmentPosition = uMatView * uMatModel * vec4(vPosition, 1.0f);
mViewPosition = viewFragmentPosition.xyz;
mTextureCoordinates = vTextureCoordinates;
// Apply transformation to normal
mat3 matNormal = transpose(inverse(mat3(uMatView * uMatModel)));
mNormal = matNormal * vNormal;
mFragPosition = uMatProjViewModel * vec4(vPosition, 1.0f);
mPrevFragPosition = uMatPrevProjViewModel * vec4(vPosition, 1.0f);
gl_Position = uMatProjection * viewFragmentPosition;
};
FRAGMENT SHADER
#version 420
layout (location = 0) out vec4 gPosition;
layout (location = 1) out vec4 gAlbedo;
layout (location = 2) out vec4 gNormal;
layout (location = 3) out vec3 gEffects;
in vec3 mViewPosition;
in vec2 mTextureCoordinates;
in vec3 mNormal;
in vec4 mFragPosition;
in vec4 mPrevFragPosition;
uniform sampler2D uAlbedoTexture1;
uniform sampler2D uNormalTexture;
uniform sampler2D uRoughnessTexture;
uniform sampler2D uMetalnessTexture;
uniform sampler2D uAmbientOcculsionTexture;
const float nearPlane = 1.0f;
const float farPlane = 1000.0f;
float LinearizeDepth(float depth);
vec3 ComputeTextureNormal(vec3 viewNormal, vec3 textureNormal);
void main()
{
vec3 normal = normalize(texture(uNormalTexture, mTextureCoordinates).rgb * 2.0f - 1.0f); // Sample normal texture and convert values in range from -1.0 to 1.0
vec2 fragPos = (mFragPosition.xy / mFragPosition.w) * 0.5f + 0.5f;
vec2 prevFragPos = (mPrevFragPosition.xy / mPrevFragPosition.w) * 0.5f + 0.5f;
gPosition = vec4(mViewPosition, LinearizeDepth(gl_FragCoord.z)); // Set position with adjusted depth
gAlbedo.rgb = vec3(texture(uAlbedoTexture1, mTextureCoordinates)); // Sample and assign albedo rgb colors
gAlbedo.a = vec3(texture(uRoughnessTexture, mTextureCoordinates)).r; // Sample and assign roughness value
gNormal.rgb = ComputeTextureNormal(mNormal, normal); // Assign normal
gNormal.a = vec3(texture(uMetalnessTexture, mTextureCoordinates)).r; // Sample and assign metalness value
gEffects.r = vec3(texture(uAmbientOcculsionTexture, mTextureCoordinates)).r;
gEffects.gb = fragPos - prevFragPos;
}
float LinearizeDepth(float depth)
{
float z = depth * 2.0f - 1.0f;
return (2.0f * nearPlane * farPlane) / (farPlane + nearPlane - z * (farPlane - nearPlane));
}
vec3 ComputeTextureNormal(vec3 viewNormal, vec3 textureNormal)
{
// Get partial derivatives
vec3 dPosX = dFdx(mViewPosition);
vec3 dPosY = dFdy(mViewPosition);
vec2 dTexX = dFdx(mTextureCoordinates);
vec2 dTexY = dFdy(mTextureCoordinates);
// Convert normal to tangent space
vec3 normal = normalize(viewNormal);
vec3 tangent = normalize(dPosX * dTexY.t - dPosY * dTexX.t);
vec3 binormal = -normalize(cross(normal, tangent));
mat3 TBN = mat3(tangent, binormal, normal);
return normalize(TBN * textureNormal);
}
And my test shader code is:
VERTEX SHADER
#version 420
layout (location = 0) in vec3 vPosition;
layout (location = 1) in vec2 vTextureCoordinates;
out vec2 mTextureCoordinates;
void main()
{
mTextureCoordinates = vTextureCoordinates; // Pass out texture coords
gl_Position = vec4(vPosition, 1.0f);
};
FRAGMENT SHADER
#version 420
in vec2 mTextureCoordinates;
out vec4 oColor;
uniform sampler2D testTexture;
void main()
{
vec3 color = texture(testTexture, mTextureCoordinates).rgb;
oColor = vec4(color, 1.0f);
}
I've made sure that glCheckFramebufferStatus is always complete and that all of my uniform variables are being passed correctly in to the shader
Turns out my code here is correct. My issue was that I was crossing the wrong vectors so my camera's view matrix was wrong.

Rendering white box textures in STB/Opengl

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;
}

Texture a tube OpenGL

I'm trying to texture a tube object in OpenGL, for a project, and a have problem texturing it. The texture is coming up nicely but there is a white line in the middle of the back of the tube that I can't get rid of. I'm using standard texture class that I build from a tutorial that I read. the mesh and the texture are upload normally- meaning nothing is unusual.
Back of the tube
Front of the tube
Texture::Texture(const std::string& fileName)
{
int width, height, numComponents;
unsigned char* data = stbi_load((fileName).c_str(), &width, &height, &numComponents, 4);
if (data == NULL)
std::cerr << "Unable to load 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);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
stbi_image_free(data);
}
Texture::~Texture()
{
glDeleteTextures(1, &m_texture);
}
void Texture::Bind()
{
glBindTexture(GL_TEXTURE_2D, m_texture);
}
#version 130--fragment shader
varying vec2 texCoord0;
varying vec3 normal0;
varying vec3 color0;
uniform sampler2D ourTexture1; // added
uniform vec3 lightDirection;
uniform vec3 MinMax;
void main()
{
//vec3 tmp = dot(-lightDirection, normal0) * color0 ;44
gl_FragColor = texture(ourTexture1, texCoord0);
if(color0.y<MinMax.x||color0.y>MinMax.y)
gl_FragColor=vec4(1.0,1.0,1.0,1.0);
}
#version 120-vertex shader
attribute vec3 position;
attribute vec2 texCoord;
attribute vec3 normal;
attribute vec3 color;
varying vec2 texCoord0;
varying vec3 normal0;
varying vec3 color0;
uniform mat4 MVP;
uniform mat4 Normal;
void main()
{
gl_Position = MVP * vec4(position, 1.0);
texCoord0 = texCoord;
texCoord0[0]=0.25+texCoord0[0];
if(texCoord0[0]>=1)
{
texCoord0[0]=texCoord0[0]-1;
}
texCoord0[1]=1-texCoord0[1];
color0 = position;
normal0 = (Normal * vec4(normal, 0.0)).xyz;
}
The problem almost certainly comes from the following part of your vertex shader:
texCoord0[0]=0.25+texCoord0[0];
if(texCoord0[0]>=1)
{
texCoord0[0]=texCoord0[0]-1;
}
I'm not entirely sure what you are trying to accomplish with this, but it will cause neighbouring vertices to have values that are very far appart, which means that almost the entire texture gets squeezed in between these two vertices.
Normally, you would want to just apply the offset, and let the rendering pipeline take care of of the modulus operation. So I would have expected to just see this:
texCoord0[0]=0.25+texCoord0[0];
N.B.
You might still see the issue if you are sharing vertices accross the the entire circumference of the tube. The point of the mesh where the texture coordinate "loops" around should have duplicated vertices with different UVs.

Shadow map stuck at 1

I am following the shadow tutorial on http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-16-shadow-mapping/ and I can view the depth value in the depth texture when rendered to a screen aligned quad. The problem is when I sample from this depth texture I get only one value.
This is how I setup the depth texture FBO; the size of the texture is set to the window size. I'm not sure if this is part of the problem, but if I half the dimensions of the depth texture and try to view that, I end up seeing a corner quarter of the view. I thought textures are always accessed from [0,1]?
glGenFramebuffers(1, &FramebufferName);
glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);
glGenTextures(1, &renderedTexture);
glBindTexture(GL_TEXTURE_2D, renderedTexture);
glTexImage2D(GL_TEXTURE_2D, 0,
GL_DEPTH_COMPONENT,
fbWidth,
fbHeight,
0,
GL_DEPTH_COMPONENT,
GL_FLOAT,
0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, renderedTexture, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
assert(false && "framebuffer NOT OK");
1st pass vertex shader
#version 150 core
in vec3 position;
uniform mat4 model;
void main(){
gl_Position = model * vec4(position,1.0);
}
1st pass fragment shader
#version 150 core
void main(){ //letting the default gl_FragDepth assignment happen
}
2nd pass vertex shader
#version 150 core
in vec3 position;
out vec4 shadowCoord;
uniform mat4 model;
uniform mat4 camera;
uniform mat4 DepthBiasMVP;
void main() {
gl_Position = camera * model * vec4(position, 1.0);
shadowCoord = DepthBiasMVP * vec4(position, 1.0);
}
2nd pass fragment shader: the stuck at 1 or 0 problems are in the comments, along with the variations I've tried
#version 150 core
in vec4 shadowCoord;
uniform mat4 model;
out vec4 outColor;
//tried both types
//uniform sampler2D shadowMap;
uniform sampler2DShadow shadowMap;
void main() {
vec3 finalColor = ...
float visibility = 1.0;
vec3 P = shadowCoord.xyz / shadowCoord.w; //doesn't work
// vec3 P =vec3(shadowCoord.x, shadowCoord.y, shadowCoord.z); //no difference
// vec3 P = vec3(shadowCoord.xy, shadowCoord.z / shadowCoord.w); //also no difference
visibility = texture( shadowMap, P); // always 1
// //when shadowMap is set to sampler2D
// vec3 textureCoord = shadowCoord.xyz/ shadowCoord.w;
// if (texture(shadowMap, shadowCoord.xy).z ==0) //always 0
// if (texture(shadowMap, shadowCoord.xy).x ==0) //always 1
// if (shadowCoord.z == 0) //always 0
// visibility = 0.06; //
finalColor *= visibility;
outColor = vec4(finalColor, 1.0);
}
This is how I call the passes, the object I am looking at is located at the origin
glm::vec3 srcPerspective(0,0,-4);
glm::mat4 depthProjectionMatrix = glm::ortho<float>(-1,1,-1,1,-10,10);
glm::mat4 depthViewMatrix = glm::lookAt(srcPerspective, glm::vec3(0,0,0), glm::vec3(0,1,0));
//pass 1
glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shadowMap.shaderProgram);
depthMVP = depthProjectionMatrix * depthViewMatrix * modelMatrix;
shadowMap.drawIndexed(world, camera, depthMVP, shapes[shipIdx].mesh.indices.data());
//pass 2
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, renderedTexture);
glm::mat4 biasMatrix(
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
);
glm::mat4 depthBiasMVP = biasMatrix * depthMVP;
glUniformMatrix4fv(loc, 1, GL_FALSE, &depthBiasMVP[0][0]);
ship.drawIndexed(world, camera, lightPos, mvp, shipColor, shapes[shipIdx].mesh.indices.data());

Shadow map in OpenGL

I've problem with shadow map in OpenGL.
Well, the shadows look like this:
http://i.stack.imgur.com/7wWm2.png
My vertex shader:
#version 330 core
layout(location = 0) in vec3 vertex;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec2 UV;
out vec2 oUV;
out vec3 oNormal;
out vec4 shadowCoord;
uniform mat4 MVP;
uniform mat4 DepthMVP;
void main(){
gl_Position = MVP * vec4(vertex, 1);
shadowCoord = DepthMVP * vec4(vertex, 1);
oUV = UV;
oNormal = normal;
}
fragment shader:
#version 330 core
in vec2 oUV;
in vec3 oNormal;
in vec4 shadowCoord;
out vec3 color;
uniform sampler2D textureSampler;
uniform sampler2DShadow shadowMap;
void main(){
float v = 1.0;
if(texture(shadowMap,
vec3(shadowCoord.xy, shadowCoord.z /
shadowCoord.w)) < shadowCoord.z )
v = 0;
color = v * texture2D(textureSampler, oUV).rgb*
vec3(1, 1, 1);
}
and here is how i create frame buffer:
glGenFramebuffers(1, &ld.fb);
glBindFramebuffer(GL_FRAMEBUFFER, ld.fb);
glGenTextures(1, &ld.dtext);
glBindTexture(GL_TEXTURE_2D, ld.dtext);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1024, 768, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, ld.dtext, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
What is the problem? Why shadows on objects look so bad?