Help with Texturing (Beginner)

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

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

You need to set the program before setting the uniforms, as glUniform calls set the uniform for the current program.

Have tried it (call glUseProgram() before setting any uniform variables) -> still didn’t work at all.

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.

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

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).

Ok it works now. I mistakenly used vs.attrib() instead of vs.uniform() because the MVP is declared as uniform variables.