Creation of a rectangle with texture fails - opengl

I want to draw a simple rectangle in OpenGL 3.0 with a texture on it. As starting point I use the example from https://learnopengl.com/code_viewer_gh.php?code=src/1.getting_started/4.2.textures_combined/textures_combined.cpp but with some modifications:
all done for GLSL 1.3
no colours in vertex-array
only one texture instead of two overlapping ones
So I modified this code as follows. The vertex shader:
#version 130
in vec3 aPos;
in vec2 aTexCoord;
out vec2 TexCoord;
uniform mat4 inputTransform;
void main()
{
TexCoord=vec2(aTexCoord.x, aTexCoord.y);
gl_Position = inputTransform * vec4(aPos.x, aPos.y, aPos.z, 1.0);
}
The fragment shader:
#version 130
out vec4 FragColor;
in vec2 TexCoord;
uniform sampler2D texture1;
void main()
{
FragColor=texture(texture1, TexCoord);
}
-> both of them compile without errors
My vertex coordinates are arranged in one array making use of x,y,z,u,v:
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
The GL_TRIANGLE_STRIP-based rectangle (without UV-coordinates and without the texture-stuff) works well and has the correct size but as soon as I apply the texture coordinates and function calls to it, nothing more than a very tiny triangle is drawn.
So I'd guess something goes wrong with the coordinates in my vertex array. But...what exactly could be wrong here?
Update: my VBO/VAO setup (simplified, so error handling code is not shown):
gl3Element->shaderProgram=glCreateProgram();
glAttachShader(gl3Element->shaderProgram, m_gl3TexVertexShader);
glAttachShader(gl3Element->shaderProgram,m_gl3TexFragmentShader);
glLinkProgram(gl3Element->shaderProgram);
glDeleteShader(m_gl3TexFragmentShader);
glDeleteShader(m_gl3DynColourFragmentShader);
glUseProgram(gl3Element->shaderProgram);
glGenVertexArrays(1, &gl3Element->VAO);
glGenBuffers(1, &gl3Element->VBO);
...and the texture-specific stuff to sue them:
glGenTextures(1, &imgEntity->m_glTexture);
glBindTexture(GL_TEXTURE_2D, imgEntity->m_glTexture);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,transImage->GetWidth(),transImage->GetHeight(),0,GL_RGB,GL_UNSIGNED_BYTE,transImage->GetData());
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
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_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenerateMipmap(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, imgEntity->m_glTexture);

Related

OpenGL 3.3 - I can only bind to GL_TEXTURE0

I've been trying to follow an OpenGL-3.3 tutorial for some time but it appears that I can only bind a texture to GL_TEXTURE0 otherwise I get a black square.
Example:
This works
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glActiveTexture(GL_TEXTURE0 + 0);
glBindTexture(GL_TEXTURE_2D, texture1);
glUniform1i(glGetUniformLocation(shader.program, "our_texture1"), 0);
shader.bind();
glBindVertexArray(vertex_array);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
This doesn't
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glActiveTexture(GL_TEXTURE0 + 1);
glBindTexture(GL_TEXTURE_2D, texture1);
glUniform1i(glGetUniformLocation(shader.program, "our_texture1"), 1);
shader.bind();
glBindVertexArray(vertex_array);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
Details:
shader.bind simply calls glUseProgram
Vertex Shader:
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 color;
layout (location = 2) in vec2 tex_coords;
out vec4 our_color;
out vec2 our_tex_coords;
void main()
{
gl_Position = vec4(position, 1.0f);
our_color = vec4(color, 1.0f);
our_tex_coords = tex_coords;
}
Fragment Shader:
#version 330 core
out vec4 color;
in vec4 our_color;
in vec2 our_tex_coords;
uniform sampler2D our_texture1;
void main()
{
color = texture(our_texture1, our_tex_coords);
}
Texture Creation:
GLuint texture1;
glGenTextures(1, &texture1);
glBindTexture(GL_TEXTURE_2D, texture1);
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);
sf::Image image1;
if (!image1.loadFromFile("../Assets/container.jpg"))
{
error();
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image1.getSize().x, image1.getSize().y, 0, GL_RGBA, GL_UNSIGNED_BYTE, image1.getPixelsPtr());
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
From what I can inspect the file is loaded correctly. Any idea on what may be wrong?
The earlier answer tells you how to change the code to make it work, but gives the wrong explanation. In this sequence:
glActiveTexture(GL_TEXTURE0 + 1);
glBindTexture(GL_TEXTURE_2D, texture1);
glUniform1i(glGetUniformLocation(shader.program, "our_texture1"), 1);
shader.bind();
with shader.bind() calling glUseProgram(), there is indeed a problem with the sequence. But it has nothing to do with glActiveTexture(), which is completely unrelated to the currently bound program.
The glUniform1i() call sets a uniform value on the currently bound program. So the key is that you call glUseProgram() before glUniform*(). For example, the following sequence will work:
glActiveTexture(GL_TEXTURE0 + 1);
glBindTexture(GL_TEXTURE_2D, texture1);
shader.bind();
glUniform1i(glGetUniformLocation(shader.program, "our_texture1"), 1);
Your code looks good.
But I think shader.bind() should be called before glActiveTexture in general.
Further hint: If you want your texture to be antialiased when minification is used, take GL_LINEAR_MIPMAP_LINEAR instead of GL_LINEAR. This should work out of the box since you already generated MIPMaps.
Best regards,
Chris

glGetTexImage don't work with unsigned integer texture

I'm using integer texture and bind it to framebuffer to get render data.
I'v bind it to quad to display it on the screen and I'm sure the content of the texture is right.
But when I use glGetTexImage to get the content of the texture, I get random numbers.
here is the code to create the framebuffer:
glEnable(GL_TEXTURE_2D);
glGenFramebuffers(1, &param.fbo);
glGenTextures(1,&param.triTex);
glBindTexture(GL_TEXTURE_2D, param.triTex);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
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_GENERATE_MIPMAP, GL_FALSE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, param.fboSize, param.fboSize, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, 0);
glBindFramebuffer(GL_FRAMEBUFFER, param.fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, param.triTex, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
The texture and framebuffer renders without problem.
here is the code of getting the content:
glBindTexture(GL_TEXTURE_2D, param.triTex);
glPixelStorei(GL_PACK_ALIGNMENT, 1);
triTexData = (unsigned int *)malloc(param.fboSize * param.fboSize * sizeof(unsigned int));
memset(triTexData, 0, sizeof(unsigned int) * param.fboSize * param.fboSize);
glGetTexImage(GL_TEXTURE_2D, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, triTexData);
glBindTexture(GL_TEXTURE_2D,0);
Fragment shader and geometry shader
#version 330
flat in int color;
out vec4 fragColor;
void main(void)
{
fragColor = vec4(color,0.0,0.0,0.0);
}
#version 330
layout (triangles) in;
layout (triangle_strip, max_vertices = 3) out;
flat out int color;
void main(void)
{
gl_Position = gl_in[0].gl_Position;
color = gl_PrimitiveIDIn;
EmitVertex();
gl_Position = gl_in[1].gl_Position;
color = gl_PrimitiveIDIn;
EmitVertex();
gl_Position = gl_in[2].gl_Position;
color = gl_PrimitiveIDIn;
EmitVertex();
EndPrimitive();
};
Your fragment shader should actually be written this way to output to a GL_R32UI image:
#version 330
flat in int color;
out uint fragColor;
void main (void) {
fragColor = color;
}
At present, you are not reading back "random" numbers, you are just seeing what happens when you interpret floating-point data as integers without the proper conversion. Not pleasant, is it?

OpenGL GLSL texture(...) function always returning v4(0,0,0,1)

I have the following setup for basic texture mapping
void init(void) {
glGenVertexArrays(NumVAOs, VAOs);
glBindVertexArray(VAOs[Triangles]);
GLfloat vertices[6][2] = {
{ -0.90, -0.90 }, // Triangle 1
{ 0.85, -0.90 },
{ -0.90, 0.85 },
{ 0.1, 0.1 }, // UVs
{ 0.9, 0.1 },
{ 0.1, 0.9 }
};
glGenBuffers(NumBuffers, Buffers);
glBindBuffer(GL_ARRAY_BUFFER, Buffers[ArrayBuffer]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
GLuint program = LoadShaders( "triangles.vert", "triangles.frag" );
glUseProgram(program);
glVertexAttribPointer(vPosition, 2, GL_FLOAT,
GL_FALSE, 0, BUFFER_OFFSET(0));
glEnableVertexAttribArray(vPosition);
glVertexAttribPointer(1, 2, GL_FLOAT,
GL_FALSE, 0, BUFFER_OFFSET(2*3*sizeof(GLfloat)));
glEnableVertexAttribArray(1);
GLuint sloc = glGetUniformLocation(program, "mySampler");
glUniform1i(sloc, 0);
int x,y,n;
unsigned char *data = stbi_load("bricks.jpg", &x, &y, &n, 4);
glGenTextures(1, &m_textureId);
glBindTexture(GL_TEXTURE_2D, m_textureId);
glTexParameterf(m_textureId, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(m_textureId, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
stbi_image_free(data);
}
void display(void) {
glClear(GL_COLOR_BUFFER_BIT);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_textureId);
glBindVertexArray(VAOs[Triangles]);
glDrawArrays(GL_TRIANGLES, 0, NumVertices);
glFlush();
}
Vertex Shader:
#version 330 core
layout(location = 0) in vec4 vPosition;
layout(location = 1) in vec2 uv;
out vec2 texCoord;
void
main() {
gl_Position = vPosition;
texCoord = uv;
}
Fragment Shader:
#version 330 core
in vec2 texCoord;
out vec4 fColor;
uniform sampler2D mySampler;
void
main() {
fColor = texture(mySampler, texCoord);
}
However, nothing is displayed on the screen. If I swap out my frag shader with one that just sets a static color, I see the triangle. I have confirmed that I am getting data from the image and printed out a sample set of RGBA data that looks correct (rgb vary, but alpha is constant 0xFF). I've read at least 5 tutorials but can't seem to get it right.
I've also confirmed that if I do:
fColor = vec4(texCoord.x, texCoord.y, 0.0, 1.0);
I get a gradient of colors which I believe tells me I'm getting correctly interpolated values of my UVs coming through.
Apparently these texparams are required for some implementations
glTexParameter( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameter( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameter( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameter( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );

Pointlight Shadow Cube Mapping

So i managed to create shadow maps for a directional light (extended at infinity). Now i am trying to create point light shadow cube map, so the shadows spread in the direction of the light->fragment. I created a new FBO like so:
//gen new fbo
glGenFramebuffers(1, &framebuffer_object);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_object);
//gen color texture
glGenTextures(1, &texture_color);
glBindTexture(GL_TEXTURE_2D, texture_color);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
//gen cubemap
glGenTextures(1, &shadow_cubemap);
glBindTexture(GL_TEXTURE_2D_ARRAY, shadow_cubemap);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
//bind color texture
unsigned int attachment_index_color_texture = 0;
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+attachment_index_color_texture, texture_color,0);
//add attachments
std::vector<GLenum> drawbuffers;
drawbuffers.push_back(GL_COLOR_ATTACHMENT0+attachment_index_color_texture);
glDrawBuffers(drawbuffers.size(),&drawbuffers[0]);
//check the fbo state
if(glCheckFramebufferStatus(GL_FRAMEBUFFER)!=GL_FRAMEBUFFER_COMPLETE){
std::cout<<"Error.FBO not integral."<<std::endl;
std::cin.get();
std::terminate();
}
//Unbind
glBindFramebuffer(GL_FRAMEBUFFER,0);
This function is called upon reshaping(so you could say at init time) reshape is called once at program start.
Next i create my light_view matrixes , each view for a different cube face, and my projection matrix like so :
//view matrix for +x
lightView_matrix[0]=glm::lookAt(light_position,light_position+glm::vec3(1,0,0),glm::vec3(0,1,0));
//view_matrix for -x
lightView_matrix[1]=glm::lookAt(light_position,light_position+glm::vec3(-1,0,0),glm::vec3(0,1,0));
//view_matrix for +z
lightView_matrix[2]=glm::lookAt(light_position,light_position+glm::vec3(0,0,1),glm::vec3(0,1,0));
//view_matrix for -z
lightView_matrix[3]=glm::lookAt(light_position,light_position+glm::vec3(0,0,-1),glm::vec3(0,1,0));
//view_matrix for +y
lightView_matrix[4]=glm::lookAt(light_position,light_position+glm::vec3(0,1,0),glm::vec3(0,0,-1));
//view_matrix for -y
lightView_matrix[5]=glm::lookAt(light_position,light_position+glm::vec3(0,-1,0),glm::vec3(0,0,1));
lightProjection_matrix = glm::perspective(90.0f, 1.0f, 0.5f, 140.0f);
Is the projection matrix ok? Should it be perspective when doing a cubemap instead of ortographic like i did for a directional light? I don't know if the values are ok : here is what i have, the width and height of the texture is 1366 x 768 which is my window size, my entire scene is from -70 to 70 on the z axis so 140 total,i chose a fov of pi/4 .
Moving on, to the first pass - hopefully generating the 6 faces of the cubemap:
cube_fbo.bind();
{
for(int i=0;i<6;i++){
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, cube_fbo.shadow_cubemap, 0);
//clear screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//use shader
glUseProgram(program_shader);
//send uniform values
glUniformMatrix4fv(glGetUniformLocation(program_shader,"light_view_matrix"),1,false,glm::value_ptr(lightView_matrix[i]));
glUniformMatrix4fv(glGetUniformLocation(program_shader,"light_projection_matrix"),1,false,glm::value_ptr(lightProjection_matrix));
//draw my objects with textures,i also have an alpha texture hence the has_alpha in the shaders (will post below )
}
}
//unbind fbo
cube_fbo.unbind();
Now the second pass which should draw the shadows based on the fragment position(should i do this in the drawing function or in the shader? )
{
//clear screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(program_shadow);
//send uniform values
glUniformMatrix4fv(glGetUniformLocation(program_shadow,"view_matrix"),1,false,glm::value_ptr(view_matrix));
glUniformMatrix4fv(glGetUniformLocation(program_shadow,"projection_matrix"),1,false,glm::value_ptr(projection_matrix));
glUniformMatrix4fv(glGetUniformLocation(program_shadow,"light_view_matrix"),1,false,glm::value_ptr(light_view_matrix));
glUniformMatrix4fv(glGetUniformLocation(program_shadow,"light_projection_matrix"),1,false,glm::value_ptr(light_projection_matrix));
glUniformMatrix4fv(glGetUniformLocation(program_shadow,"BiasMatrix"),1,false,glm::value_ptr(BiasMatrix));
glUniform3f(glGetUniformLocation(program_shadow,"light_position"),light_position.x,light_position.y,light_position.z);
//sphere at light position for reference------------------------
glUniformMatrix4fv(glGetUniformLocation(program_shadow,"model_matrix"),1,false,glm::value_ptr(light_model_matrix));
lab::drawSolidSphere(2,6,6);
//glEnable(GL_CULL_FACE);
//glCullFace(GL_BACK);
//ground----------------------------
glUniformMatrix4fv(glGetUniformLocation(program_shadow,"model_matrix"),1,false,glm::value_ptr(ground_model_matrix));
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, ground_texture);
glUniform1i( glGetUniformLocation(program_shadow, "textura1"), 1 );
glUniform1i( glGetUniformLocation(program_shadow, "has_alpha"), 0);
//glDisable(GL_CULL_FACE);
//send cubemap texture(GLuint bound in the first part (shadow_cubemap))
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_CUBE_MAP, cube_fbo[0].getCubeMapTexture());
glUniform1i(glGetUniformLocation(program_shadow, "textura_depth"), 2);
glBindVertexArray(ground_vao);
glDrawElements(GL_TRIANGLES, ground_num_indices, GL_UNSIGNED_INT, 0);
//bamboo(s)----------------------------
glActiveTexture(GL_TEXTURE0+1);
glBindTexture(GL_TEXTURE_2D, bamboo_texture_color);
glActiveTexture(GL_TEXTURE0+2);
glBindTexture(GL_TEXTURE_2D, bamboo_texture_alpha);
glUniform1i( glGetUniformLocation(program_shadow, "textura1"), 1 );
glUniform1i( glGetUniformLocation(program_shadow, "textura2"), 2 );
glUniform1i( glGetUniformLocation(program_shadow, "has_alpha"), 1);
//send cubemap texture
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, cube_fbo[0].getCubeMapTexture());
glUniform1i(glGetUniformLocation(program_shadow, "textura_depth"), 3);
glBindVertexArray(bamboo_vao);
for(int i=0;i<10;i++) for(int j=0;j<10;j++) {
if(j==5){
glUniformMatrix4fv(glGetUniformLocation(program_shadow,"model_matrix"),1,false,glm::value_ptr(bamboo_model_matrix[i*10+j]));
glDrawElements(GL_TRIANGLES, bamboo_num_indices, GL_UNSIGNED_INT, 0);
}
}
}
As you can see in this last part i draw from the camera position and pass to the shader the cubemap generate from the first pass. I have a few misunderstandings and probably some mistakes untill this point.
What do i return from the first pass (from the shader), when i did shadow mapping for a directional light i returned the depth (glFragcoord.z) but now i have to return a vec3 direction ? How do i compute that.Do i need something else to pass to the shader?
Is the second part ok ? Do i just draw the objects and pass the cube map to the shader and let him calculate which fragment is where in relation to the light ? If so , how do i compute this ?
Here is my shader for the first pass(so generate the cubemap from the 6 light views):
#version 330 /*VERTEX SHADER*\
layout(location = 0) in vec3 in_position;
layout(location = 2) in vec2 in_texcoord;
uniform mat4 model_matrix;
uniform mat4 light_view_matrix,light_projection_matrix;
out vec2 texcoord;
out vec4 v_position;
void main(){
texcoord = in_texcoord;
gl_Position = light_projection_matrix*light_view_matrix*model_matrix*vec4(in_position,1);
}
#version 330 /*FRAGMENT SHADER*\
layout(location = 0) out vec4 out_color;
//layout(location = 1) out float depth;
uniform sampler2D textura1;
uniform sampler2D textura2;
uniform int has_alpha;
in vec2 texcoord;
in vec4 v_position;
void main(){
vec3 tex1 = texture(textura1, texcoord).xyz;
vec3 tex2 = texture(textura2, texcoord).xyz;
if(has_alpha>0.5) if((tex2.r<0.1) && (tex2.g<0.1) && (tex2.b<0.1)) discard;
out_color = vec4(tex1, 1);
}
And the shader for the second pass (tried to calculate shadow by getting the vec3 from pixel position in world space - light position in world space)
#version 330 core /*VERTEX SHADER*\
layout(location = 0) in vec3 in_position;
layout(location = 1) in vec3 in_normal;
layout(location = 2) in vec2 in_texcoord;
out vec3 lightPosw;
out vec3 pixelPosw;
out vec2 texcoord;
uniform mat4 model_matrix,view_matrix,projection_matrix;
uniform vec3 light_position;
void main(){
texcoord=in_texcoord;
gl_Position = projection_matrix*view_matrix*model_matrix*vec4(in_position,1);
lightPosw= (model_matrix * vec4(light_position,1)).xyz;
pixelPosw = (model_matrix * vec4(in_position, 1)).xyz;
}
#version 330 core /*FRAGMENT SHADER*\
in vec3 lightPosw;
in vec3 pixelPosw;
in vec2 texcoord;
out vec4 out_color;
uniform samplerCube textura_depth;
uniform sampler2D textura1,textura2;
uniform mat4 view_matrix,model_matrix;
uniform int has_alpha;
void main(){
vec3 lightToPixel=pixelPosw-lightPosw;
vec3 tex1 = texture(textura1, texcoord).xyz;
vec3 tex2 = texture(textura2, texcoord).xyz;
if(has_alpha>0.5) if((tex2.r<0.1) && (tex2.g<0.1) && (tex2.b<0.1)) discard;
float shadowDepth = texture(textura_depth, normalize(lightToPixel));
float shadowFactor=1.0;
if(length(lightToPixel) < shadowDepth)
shadowFactor=0.5;
out_color = vec4(tex1*shadowFactor,1);
}
Sorry for the wall of code, i wanted to post all the relevant stuff so i can get better help. My problem is , everything renders semi-black, because i set the output color in the fragment shader to 0.5, if I wouldn't , then it all renders black.

Sampling from a texture in OpenGL is black

I'm trying out my hand at graphics, following a tutorial at http://en.wikibooks.org/wiki/OpenGL_Programming/Modern_OpenGL_Tutorial_06
Problem: When I try to texture my cube, my sample is black.
Screenshot: http://puu.sh/2JP1H.jpg (note: I set blue = uv.x to test my UVs)
I looked at the threads OpenGL textures appear just black, and
Texture is all black, but it seemed they had different problems.
First I load my texture using SOIL image loading library:
int w, h;
unsigned char* img = SOIL_load_image("resources/images/4x4window.jpg",&w,&h,0,0);
ErrorIf(!img, "%s", SOIL_last_result());
glGenTextures(1, &texture_id);
glBindTexture(GL_TEXTURE, texture_id);
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_RGB,w,h,0,GL_RGB,GL_UNSIGNED_BYTE,img);
My render function where I pass my texture to the shader program:
void onDisplay()
{
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(program);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture_id);
glUniform1i(uniform_myTexture, /*GL_TEXTURE*/0);
glEnableVertexAttribArray(attribute_coord3d); // open shader var
glBindBuffer(GL_ARRAY_BUFFER, vbo_cube_verts); // put stuff in buffer
glVertexAttribPointer(attribute_coord3d, 3, GL_FLOAT, GL_FALSE, 0, 0); //send
glEnableVertexAttribArray(attribute_texcoord);
glBindBuffer(GL_ARRAY_BUFFER, vbo_cube_texcoords);
glVertexAttribPointer(attribute_texcoord, 2, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_cube_elements);
int size;
glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
glDrawElements(GL_TRIANGLES, size / sizeof(GLushort), GL_UNSIGNED_SHORT, 0);
glDisableVertexAttribArray(attribute_coord3d);
glDisableVertexAttribArray(attribute_texcoord);
glutSwapBuffers();
}
Vertex Shader:
attribute vec3 coord3d;
attribute vec2 texcoord;
varying vec2 f_texcoord;
uniform mat4 mvp;
void main(void)
{
gl_Position = mvp * vec4(coord3d, 1.0);
f_texcoord = texcoord;
}
Fragment Shader:
varying vec2 f_texcoord;
uniform sampler2D mytexture;
void main(void)
{
vec4 result = texture2D(mytexture, f_texcoord);
result.z = f_texcoord.x;
result.w = 1;
gl_FragColor = result;
}
The line where the the texture is bound is:
glBindTexture(GL_TEXTURE, texture_id);
that should be:
glBindTexture(GL_TEXTURE_2D, texture_id);