PDA

View Full Version : Help with Texturing (Beginner)



charisma_tubagus
10-15-2013, 04:05 AM
I just started to learn OpenGL version 4 and GLSL version 3.3. I want to create a simple quad using texture. However, my window just doesn't show anything(blank screen).

My main.cpp

void LoadQuad(){
//Load the Texture
Texture = ReadBMP("NeHe.bmp");

//make and bind VAO
glGenBuffers(1, &gVAO);
glBindVertexArray(gVAO);

//create vertex data
GLfloat vertex_data[] = {
-0.5f, 0.5f, 0.0f,
0.5f, 0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f
};
//Make and bind VBO
glGenBuffers(1, &gVBO);
glBindBuffer(GL_ARRAY_BUFFER, gVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW);
glEnableVertexAttribArray( vs.attrib("vert"));
glVertexAttribPointer( vs.attrib("vert"), 3, GL_FLOAT, GL_FALSE, 0, NULL);


GLfloat uv_data[] = {
0.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f,
1.0f, 1.0f
};

//Make and bind UV buffer
glGenBuffers(1, &gUV);
glBindBuffer(GL_ARRAY_BUFFER, gUV);
glBufferData(GL_ARRAY_BUFFER, sizeof(uv_data), uv_data, GL_STATIC_DRAW);
glEnableVertexAttribArray(vs.attrib("inUV"));
glVertexAttribPointer(vs.attrib("inUV"), 2, GL_FLOAT, GL_FALSE, 0, NULL);

}

void Render(){
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

//Use the Shader program
glUseProgram(program);

//Set the MVP matrix
GLint MVPID = vs.attrib("MVP");
glUniformMatrix4fv( MVPID, 1, GL_FALSE, &MVP[0][0]);

//Set the texture
glActiveTexture(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, Texture);
//Get a handle of "textureSampler" in fragment shader code
GLuint TextureID = fs.attrib("textureSampler");
glUniform1i(TextureID, 0);

//Draw the scene
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

//Unuse the shader program
glUseProgram(0);

}


And then for the VS program:

#version 330 core
//vertex shader

//Input vertex data, changes frequently
in vec3 vert;
in vec2 inUV;

out vec2 outUV;

//uniform variables - stay constant for the whole mesh
uniform mat4 MVP;

void main(){
gl_Position = MVP * vec4(vert,1);

outUV = inUV;
}

FS program:

#version 330 core
//fragment shaders
in vec2 outUV;

out vec3 finalColor;

uniform sampler2D textureSampler;

void main(){
finalColor = texture2D(textureSampler, outUV).rgb;
}

charisma_tubagus
10-15-2013, 05:58 AM
So I changed the source code and it gives an error about access reading violation in glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

The Program:




GLuint gVBO = 0;
GLuint gVAO = 0;
GLuint gUV = 0;
GLuint Texture = 0;

void LoadQuad(){

//Load the Texture
//Texture = ReadBMP("NeHe.bmp");
Texture = loadBMP_custom("NeHe.bmp");

//make and bind VAO
glGenBuffers(1, &gVAO);
glBindVertexArray(gVAO);

//Make and bind VBO
glGenBuffers(1, &gVBO);
glBindBuffer(GL_ARRAY_BUFFER, gVBO);

//create vertex data
GLfloat vertex_data[] = {
-0.5f, 0.5f, 0.0f,
0.5f, 0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
};

glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), vertex_data, GL_STATIC_DRAW);
glEnableVertexAttribArray( vs.attrib("vert"));
glVertexAttribPointer( vs.attrib("vert"), 3, GL_FLOAT, GL_FALSE, 0, nullptr);

//Make and bind UV buffer
glGenBuffers(1, &gUV);
glBindBuffer(GL_ARRAY_BUFFER, gUV);

//Create UV data
GLfloat uv_data[] = {
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
};

glBufferData(GL_ARRAY_BUFFER, sizeof(uv_data), uv_data, GL_STATIC_DRAW);
glEnableVertexAttribArray(vs.attrib("inUV"));
glVertexAttribPointer(vs.attrib("inUV"), 2, GL_FLOAT, GL_FALSE, 0, nullptr);

//unbind VBO and VAO
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);

}

void Render(){
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

//enable depth testing
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);

glBindVertexArray( gVAO);

//Set the MVP matrix
GLint MVPID = vs.attrib("MVP");
glUniformMatrix4fv( MVPID, 1, GL_FALSE, &MVP[0][0]);

//Set the texture
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, Texture);
//Get a handle of "textureSampler" in fragment shader code
GLint TextureID = fs.attrib("textureSampler");
glUniform1i(TextureID, 0); //why 0 because Active Texture is GL_TEXTURE0

//Use the Shader program
glUseProgram(program);

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

//Unuse the shader program
glUseProgram(0);

}




The VS:


#version 330 core
//vertex shader

//Input vertex data, changes frequently
in vec3 vert;
in vec2 inUV;

//Output vertex data to be sent to fragment shaders
out vec2 outUV;

//uniform variables - stay constant for the whole mesh
uniform mat4 MVP;

void main(){
gl_Position = MVP * vec4(vert,1);

outUV = inUV;
}


The FS:



#version 330 core
//fragment shaders

in vec2 outUV;

out vec4 finalColor;

uniform sampler2D textureSampler;

void main(){
finalColor = texture2D(textureSampler, outUV);
}

Dan Bartlett
10-15-2013, 07:20 AM
You need to set the program before setting the uniforms, as glUniform calls set the uniform for the current program.

charisma_tubagus
10-15-2013, 10:27 AM
Have tried it (call glUseProgram() before setting any uniform variables) -> still didn't work at all.

Dan Bartlett
10-15-2013, 10:45 AM
A couple of other possible problems:

You use

glGenBuffers(1, &gVAO);
which should be:

glGenVertexArrays(1, &gVAO);

You use vs.attrib(...) to retrieve both attribute + uniform locations, but I guess you probably need separate methods for these, using glGetAttribLocation and glGetUniformLocation.

charisma_tubagus
10-15-2013, 10:16 PM
Ok thanks for the reminder of using glGenVertexArrays() instead of glGenBuffers. It was my mistake (forgot it). :tired:

But I still have dark screen. Which means my texture and (or) my VBO is not drawn correctly. For the vs.attrib() and vs.uniform() I use glGetAttribLocation() and glGetUniformLocation() inside those methods. I think it shouldn't be a problem. Here is my code for shader helper:




GLint Shader::attrib(const char *attributeName){
assert( attributeName != NULL);

GLint attrib = glGetAttribLocation( getProgram(), attributeName);
if( attrib == -1){
string err(attributeName);
err += "cannot be found in shader code";
runtime_error(err.c_str());
}

return attrib;
}

GLint Shader::uniform(const char *uniformName){
assert( uniformName != NULL);

GLint uniform = glGetUniformLocation( getProgram(), uniformName);

if( uniform == -1){
string err(uniformName);
err += "cannot be found in shader code";
runtime_error(err.c_str());
}

return uniform;
}

charisma_tubagus
10-17-2013, 01:05 AM
Now it works, the reason is why MVP matrix does not work properly which I don't know the reason why.



#version 330 core
//vertex shader

//Input vertex data, changes frequently
in vec3 vert;
in vec2 inUV;

//Output vertex data to be sent to fragment shaders
out vec2 outUV;

//uniform variables - stay constant for the whole mesh
uniform mat4 MVP;

void main(){
//gl_Position = MVP * vec4(vert,1);
gl_Position = vec4(vert, 1.0);

outUV = inUV;
}


Can somebody tell me why my MVP matrix doesn't work? Previously, It worked with other tutorial(practice).

charisma_tubagus
10-17-2013, 04:23 AM
Ok it works now. I mistakenly used vs.attrib() instead of vs.uniform() because the MVP is declared as uniform variables.