OpenGL Texture - texture render twice - c++

I have a problem that a texture covers only part of an object in height dimensions and start over again rendering a smaller texture in the bottom as shown in the pic.
I'm posting my Texture and Shader code as well. note that I'm using glTexSubImage2D for the background of the object. the same problem occurred when I didn't use the glTexSubImage2D and just glTexImage2D.
texture code
try {
data = stbi_load((fileName).c_str(), &width, &height, &numComponents, 4);
if (data == NULL)
std::cerr << "Unable to load texture: " << fileName << std::endl;
else
std::cerr << "texture loaded " << fileName << std::endl;
std::string fileName2 = t ? filePathe + "//images//" + mediaColor + ".bmp" : "./res/textures/plane1.bmp";
int width2, height2, numComponents2;
unsigned char* data2 = stbi_load((fileName2).c_str(), &width2, &height2, &numComponents2, 4);
if (data2 == NULL)
std::cerr << "Unable to load texture: " << fileName2 << std::endl;
else
std::cerr << "texture loaded " << fileName2 << 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, width2, height2, 0, GL_RGBA, GL_UNSIGNED_BYTE, data2);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height , GL_RGBA, GL_UNSIGNED_BYTE, data);
stbi_image_free(data);
stbi_image_free(data2);
}
catch (std::invalid_argument &e)
{
vertex shader
#version 120
attribute vec3 position;
attribute vec2 texCoord;
attribute vec3 normal;
attribute vec3 color;
varying vec2 texCoord0;
varying vec3 normal0;
varying vec3 color0;
varying float index0;
uniform mat4 MVP;
uniform mat4 Normal;
uniform float index;
void main()
{
gl_Position = MVP * vec4(position, 1.0);
texCoord0 = texCoord;
if (index == 0.0) {
//texCoord0[0]=0.25+texCoord0[0];
texCoord0[1]=1-texCoord0[1];
}
}
fragment shader
#version 130
varying vec2 texCoord0;
varying vec3 normal0;
varying vec3 color0;
varying float index0;
uniform sampler2D ourTexture1; // added
uniform vec3 lightDirection;
uniform vec3 capOffSet;
uniform vec3 mediaColor;
uniform vec3 capColor;
void main()
{
gl_FragColor = texture(ourTexture1, texCoord0);
}

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.

I am facing a glTextureStorage2D error. Opengl

Here is an image of the issue I am facing in opengl:
In the image I tagged my texture also displays weirdly.
Can someone help me figure out why the texture on the ground is incomplete and placed odd?
This is my code:
Ground.LoadModel("O_Ground.obj");
Fence.LoadModel("O_Fence.obj");
string names[] = { "Green.jpg","wood.jpg" };
glGenTextures(2, texture);
for( string name :names)
{
stbi_set_flip_vertically_on_load(true);
int iWidth, iHeight, iChannels;
unsigned char* iData = stbi_load(name.c_str(), &iWidth, &iHeight, &iChannels, 0);
for (int i=0;i<2;i++)
{
glBindTexture(GL_TEXTURE_2D, texture[i]);
glTextureStorage2D(texture[i], 1, GL_RGB8, iWidth, iHeight);
glTextureSubImage2D(texture[i], 0, 0, 0, iWidth, iHeight, GL_RGB, GL_UNSIGNED_BYTE, iData);
cout << texture[i];
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_MIN_FILTER, GL_LINEAR);
glGenerateMipmap(GL_TEXTURE_2D);
}
}
This is my render function
for (int i = 0;i < 2; i++)
{
glActiveTexture(GL_TEXTURE0 + i);
glBindTexture(GL_TEXTURE_2D, texture[i]);
GLint tex_location = glGetUniformLocation(program, "texture[i]");
glUniform1i(tex_location, i);
}
Ground.Draw();
Fence.Draw();
And my vertex and fragment shaders
vsmodel1
layout (location = 0) in vec3 position;
layout (location = 1) in vec2 tc;
layout (location = 2) in vec3 normals;
out VS_OUT
{
vec2 tc;
vec3 normals;
} vs_out;
uniform mat4 model_matrix;
uniform mat4 view_matrix;
uniform mat4 proj_matrix;
void main(void)
{
gl_Position = proj_matrix * view_matrix * model_matrix * vec4(position, 1.0);
vs_out.tc = tc;
vs_out.normals = normals;
}
fsmodel1
out vec4 color;
in VS_OUT
{
vec2 tc;
vec3 normals;
}
fs_in;
layout(binding=0)uniform sampler2D tex;
void main(void)
{
color= texture(tex, fs_in.tc);
}
The functions glTextureStorage2D and glTextureSubImage2D are not part of OpenGL 4.3 which you are using here.
These functions were introduced with direct state access in OpenGL 4.5. You'll have to use the non-DSA functions glTexStorage2D and glTexSubImage2D instead, with the other semantics of course.
This part of the code is also not going to work:
for (int i = 0;i < 2; i++)
{
glActiveTexture(GL_TEXTURE0 + i);
glBindTexture(GL_TEXTURE_2D, texture[i]);
GLint tex_location = glGetUniformLocation(program, "texture[i]");
glUniform1i(tex_location, i);
}
There is no uniform called texture in your shader program. And even if it were, and it were an array, texture[i] would still not work, as the i is just part of the string literal, and not the value of the variable i you declared in your code.
Since the above glGetUniformLocation() calls a guaranteed to return -1, thew glUniform call following it will have no effect.
Your shader:
// [...]
layout(binding=0)uniform sampler2D tex;
void main(void)
{
color= texture(tex, fs_in.tc);
}
is only using a tex uniform, and it is using only one texture unit at all. The tex uniform will point to unit 0. It is totally unclear why you even bind 2 different textures at once to units 0 and 1, if your shader can ever only deal with one.

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.

Deferred Shading OpenGL implementation

I'm currently trying to implement deferred shading in OpenGL 3.2 and have a problem that I just can't seem to solve no matter what I try.
I implemented it in two steps(geometry pass and lighting pass) like one would expect. After compiling and running it the screen shows the scene I prepared almost like one would expect it to look like. The colors of the objects are correct and they are also positioned where and how I wanted them to be.
The thing is, that the light calculations seem to have no influence on the color, what so ever. After a lot of hours I found out, that the textures for the positions and normals seem to contain the same content like the color texture.
If one changes the last line in the lighting fragment shader from fragColor = lightIntensity * color; to fragColor = lightIntensity * norm; or fragColor = lightIntensity * pos; it has absolutely no impact on how the screen is rendered.
I have tried a lot to figure out what is going wrong but honestly have no idea what it could be.
It would be awesome if someone could help me.
My render method looks like this:
void render()
{
//geometry pass
gBuffer->bindForWriting();
geometryShader->use(true);
calculateGBuffer();
//lighting pass
gBuffer->bindForReading(lightShader->programID());
lightShader->use(true);
drawOnScreen();
}
The initialization of the gBuffer object is like this:
void GBuffer::initializeFBO(int viewWidth, int viewHeight)
{
//initialize fbo and corresponding textures;
glGenFramebuffers(1, &fbo_ID);
glBindFramebuffer(GL_FRAMEBUFFER, fbo_ID);
glGenTextures(1, &colorTexture_ID);
glBindTexture(GL_TEXTURE_2D, colorTexture_ID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, viewWidth, viewHeight, 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_ATTACHMENT0, GL_TEXTURE_2D, colorTexture_ID, 0);
glGenTextures(1, &posTexture_ID);
glBindTexture(GL_TEXTURE_2D, posTexture_ID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, viewWidth, viewHeight, 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_ATTACHMENT1, GL_TEXTURE_2D, posTexture_ID, 0);
glGenTextures(1, &normTexture_ID);
glBindTexture(GL_TEXTURE_2D, normTexture_ID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, viewWidth, viewHeight, 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_ATTACHMENT2, GL_TEXTURE_2D, normTexture_ID, 0);
GLuint attachments[3] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 };
glDrawBuffers(3, attachments);
glGenRenderbuffers(1, &depthBuffer_ID);
glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer_ID);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, viewWidth, viewHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer_ID);
//Check Status
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
qDebug() << "error while initializing framebuffer" << glCheckFramebufferStatus(GL_FRAMEBUFFER);
else{
qDebug() << "framebuffer successfully created";
initialized = true;
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
The methods bindForReading and bindForWriting:
void GBuffer::bindForWriting()
{
glBindFramebuffer(GL_FRAMEBUFFER, fbo_ID);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
void GBuffer::bindForReading(GLuint programID)
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, colorTexture_ID);
GLuint samplerTexture_ID = glGetUniformLocation(programID, "colorTexture");
glUniform1i(samplerTexture_ID, 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, posTexture_ID);
samplerTexture_ID = glGetUniformLocation(programID, "positionTexture");
glUniform1i(samplerTexture_ID, 1);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, normTexture_ID);
samplerTexture_ID = glGetUniformLocation(programID, "normTexture");
glUniform1i(samplerTexture_ID, 2);
}
And at last the 4 Shaders:
Geometry Vertex Shader:
#version 150
#extension GL_ARB_separate_shader_objects : enable
uniform mat4 MVPMatrix;
uniform mat4 modelMatrix;
in vec4 in_position;
in vec4 in_color;
in vec2 in_texcoord;
in vec3 in_norm;
out vec4 color_varying;
out vec3 frag_position;
out vec3 norm_vec;
out vec2 texcoord_varying;
void main()
{
gl_Position = MVPMatrix * in_position;
vec4 worldPosition = (modelMatrix * in_position);
frag_position = worldPosition.xyz;
norm_vec = in_norm;
color_varying = in_color;
texcoord_varying = in_texcoord;
}
Geometry Fragment Shader:
#version 150
#extension GL_ARB_explicit_attrib_location : enable
in vec4 color_varying;
in vec3 frag_position;
in vec3 norm_vec;
in vec2 texcoord_varying;
layout (location = 0) out vec4 fragColor;
layout (location = 1) out vec3 fragPosition;
layout (location = 2) out vec3 frag_norm_vec;
uniform sampler2D myTexture;
void main()
{
vec4 texel = texture(myTexture, texcoord_varying);
fragColor = texel * color_varying;
fragPosition = frag_position;
frag_norm_vec = normalize(norm_vec);
}
Lighting VertexShader:
#version 150
#extension GL_ARB_explicit_attrib_location : enable
layout (location = 0) in vec2 in_position;
out vec2 texCoord;
void main()
{
gl_Position = vec4(in_position, 0, 1.0f);
texCoord = in_position;
if(texCoord.x == -1.0f)
texCoord.x = 0.0f;
if(texCoord.y == -1.0f)
texCoord.y = 0.0f;
}
Lighting Fragment Shader(without lighting calculation to make it shorter)
#version 150
#extension GL_ARB_separate_shader_objects : enable
out vec4 fragColor;
in vec2 texCoord;
uniform sampler2D colorTexture;
uniform sampler2D positionTexture;
uniform sampler2D normTexture;
void main()
{
//extract fragment data from fbo
vec3 pos = texture(positionTexture, texCoord).rgb;
vec3 norm = texture(normTexture, texCoord).rgb;
vec4 color = texture(colorTexture, texCoord);
fragColor = lightIntensity * color;
}
Sry for the code spamming but I can't narrow down the error.
The problem is most likely in your order of operations here:
gBuffer->bindForReading(lightShader->programID());
lightShader->use(true);
where, in bindForReading(), you have calls like this one:
samplerTexture_ID = glGetUniformLocation(programID, "positionTexture");
glUniform1i(samplerTexture_ID, 1);
The glUniform*() calls set uniform values on the currently active program. Since you make the lightShader active after you make these calls, the uniform values will be set on the previously active program, which probably doesn't even have these uniforms.
Simply changing the order of these calls might already fix this:
lightShader->use(true);
gBuffer->bindForReading(lightShader->programID());
Also, you're using GL_RGB16F as the format of two of your buffers. The OpenGL implementation you use may support this, but this is not a format that is required to be color-renderable in the spec. If you want your code to work across platforms, you should use GL_RGBA16F, which is guaranteed to be color-renderable.

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?