After binding the normal buffer OpenGL does not draw anymore.

Hello,

I am trying to learn lights in Opengl. It seems that i have a problem when i and the third buffer for normals to VAO. When i enable the normal buffer (glBindBuffer(GL_ARRAY_BUFFER, normals_buffer):wink: I dont get anything in rendered even if leave the code as it is.

I have checked the number of vertexes and normals. they are the same. i did export other obj files from blender with normals I still get the same problem.

The good thing is that im learning even thought it can be frustrating sometimes :smiley:

Binding data code


size_t normals_buffer_size = 0;
	size_t vertex_buffer_size = 0;
	size_t index_buffer_size = 0;

	for (size_t i = 0; i < shapes.size(); i++) {
		vertex_buffer_size += sizeof(float)* shapes[i].mesh.positions.size();
		normals_buffer_size += sizeof(float)* shapes[i].mesh.normals.size();
		index_buffer_size += sizeof(unsigned int)* shapes[i].mesh.indices.size();
	}

	glGenBuffers(1, &vertex_buffer);
	glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
	glBufferData(GL_ARRAY_BUFFER, vertex_buffer_size, NULL, GL_STATIC_DRAW);
	vertex_buffer_size = 0;
	for (size_t i = 0; i < shapes.size(); i++) {
		glBufferSubData(GL_ARRAY_BUFFER, vertex_buffer_size, sizeof(float)* shapes[i].mesh.positions.size(), &shapes[i].mesh.positions[0]);
		vertex_buffer_size += sizeof(float)* shapes[i].mesh.positions.size();
	}
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	
	// Index
	/*size_t index_buffer_size = 0;
	for (size_t i = 0; i < shapes.size(); i++) {
		index_buffer_size += sizeof(unsigned int)* shapes[i].mesh.indices.size();
	}*/
	glGenBuffers(1, &index_buffer);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_buffer_size, NULL, GL_STATIC_DRAW);
	index_buffer_size = 0;
	for (size_t i = 0; i < shapes.size(); i++) {
		glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, index_buffer_size, sizeof(unsigned int)* shapes[i].mesh.indices.size(), &shapes[i].mesh.indices[0]);
		index_buffer_size += sizeof(unsigned int)* shapes[i].mesh.indices.size();
	}
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

	// Normals
	glGenBuffers(1, &normals_buffer);
	glBindBuffer(GL_ARRAY_BUFFER, normals_buffer);
	glBufferData(GL_ARRAY_BUFFER, normals_buffer_size, NULL, GL_STATIC_DRAW);
	normals_buffer_size = 0;
	for (size_t i = 0; i < shapes.size(); i++) {
		glBufferSubData(GL_ARRAY_BUFFER, normals_buffer_size, sizeof(float)* shapes[i].mesh.normals.size(), &shapes[i].mesh.normals[0]);
		normals_buffer_size += sizeof(float)* shapes[i].mesh.normals.size();
	}
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	//fprintf(stderr, "normals_buffer_size %d  vertex_buffer_size %d   index_buffer_size %d 
", normals_buffer_size, vertex_buffer_size, index_buffer_size);
	// draw multiple objects with one draw call
	glGenVertexArrays(1, &vertex_array_object);
	glBindVertexArray(vertex_array_object);
	glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
	//glBindBuffer(GL_ARRAY_BUFFER, normals_buffer); <===== if I un-comment this i wont get anything rendered
	//glBindBuffer(GL_ARRAY_BUFFER, 0);
	//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
	glBindVertexArray(0);
        
        //MVP matrix
	uniform_mvp = glGetUniformLocation(shader_program, "MVP");
        //light position 
	uniform_lightPosition = glGetUniformLocation(shader_program, "lightPosition");
	
	errorCode = glGetError();
	if (errorCode != 0)
	{
		fprintf(stderr, "Error data: %s, code %d
", glewGetErrorString(errorCode), errorCode);
	}

the draw function



void display(){

	GLenum errorCode = 0;
	// Clear the screen to black
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	glClearDepth(1.0f);

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Use our shader
	glUseProgram(shader_program);

	// Send our transformation to the currently bound shader, in the "MVP" uniform 
	glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, glm::value_ptr(cam.calculateMVP()));
	glUniform3fv(uniform_lightPosition, 3, glm::value_ptr(glm::vec4(cam.calculateMVP() * glm::vec4(cam.cameraPosition,1.0f))) );
		
	glBindVertexArray(vertex_array_object);
	glEnableVertexAttribArray(0);
	glEnableVertexAttribArray(1);

	size_t vertex_buffer_size = 0;
	size_t index_buffer_size = 0;
	size_t normals_buffer_size = 0;

	for (size_t i = 0; i < shapes.size(); i++) {

		glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)vertex_buffer_size);
		glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)normals_buffer_size);
		glDrawElements(GL_TRIANGLES, shapes[i].mesh.indices.size(), GL_UNSIGNED_INT, (void*)index_buffer_size);
		
		vertex_buffer_size += sizeof(float) * shapes[i].mesh.positions.size();
		index_buffer_size += sizeof(unsigned int) *shapes[i].mesh.indices.size();
		normals_buffer_size += sizeof(float) * shapes[i].mesh.normals.size();

		if (errorCode != 0)
		{
			fprintf(stderr, "Error rendering shape[%d].name = %s. Error name: %s. Error code code %d
", i, shapes[i].name.c_str(), glewGetErrorString(errorCode), errorCode);
		}
	}

	glDisableVertexAttribArray(0);
	glDisableVertexAttribArray(1);
	glBindVertexArray(0);

	glUseProgram(0);

	// Swap buffers
	SDL_GL_SwapWindow(window);
}

Vertex shader code. I deleted few comments and few lines oc code that i am usign jsut to make something render so i might have few errors in this code. Sorry

#version 330

uniform mat4 MVP;
uniform vec3 lightPosition;

layout(location = 0) in vec3 position;
layout(location = 1) in vec3 normals;

vec3 lightIntensity = vec3(1.0f, 1.0f, 1.0f); // for now this value for testing 
vec3 diffuseColor = vec3(0.0f, 0.9f, 0.9f); // for now this value for testing 

vec3 direction;

out vec3 Color;

void main() {

	gl_Position = MVP * vec4(position, 1.0);
	vec3 normalsMVP =  vec3(MVP * vec4(normals,1.0f));
	
	float cosAngIncidence = dot(normalsMVP,  lightPos);
	//cosAngIncidence = clamp(cosAngIncidence, 0, 1);
	cosAngIncidence = clamp(cosAngIncidence, 0.1, 1);

	Color = vec3(1.0f, 1.0f, 1.0f) *lightIntensity * diffuseColor * cosAngIncidence;
	//Color = lightIntensity * diffuseColor * cosAngIncidence;
	//Color = vec3(1.0f, 1.0f, 1.0f) * cosAngIncidence; 
	//Color = vec3(1.0f, 1.0f, 1.0f);
}

Edit:: I did change the vertex shared a bit and i am getting these results. I am not sure why the walls are transparent before going black. Thanks.
New shader code


#version 330

uniform mat4 MVP;

uniform vec3 lightPosition;
vec3 lightIntensity = vec3(1.0f, 1.0f, 1.0f);

vec3 lightPos = vec3(10.0f, 120.0f, 100.0f);

vec3 diffuseColor = vec3(0.0f, 0.9f, 0.9f);
layout(location = 0) in vec3 position;
layout(location = 1) in vec3 normals;

vec3 direction;

out vec3 Color;

void main() {

	gl_Position = MVP * vec4(position, 1.0);
	vec4 normals =  MVP * vec4(lightPos, 1.0);
	direction =  vec3(gl_Position - normals);

	float cosAngIncidence = dot(direction,  lightPos);
	cosAngIncidence = clamp(cosAngIncidence, 0, 1);

	//Color = vec3(1.0f, 1.0f, 1.0f) * lightIntensity * diffuseColor;
	Color = vec3(1.0f, 1.0f, 1.0f) *lightIntensity * diffuseColor * cosAngIncidence;
	//Color = lightIntensity * diffuseColor * cosAngIncidence;
	//Color = vec3(1.0f, 1.0f, 1.0f) * cosAngIncidence;
}

Fixed the issue with rendering. I had culling enabled the wrong way.
[ATTACH=CONFIG]751[/ATTACH]
No im have to fix this problem with binding normals and i believe I am set for light tutorials and experiments :smiley:

OK so what i am doing is the following.

I am copying the normals but I an not enabling them when I bind the buffers to VAO.


void initData(){
	GLenum errorCode = 0;

	// Copy data to GPU
	// Vertex
	size_t normals_buffer_size = 0;
	size_t vertex_buffer_size = 0;
	size_t index_buffer_size = 0;

	for (size_t i = 0; i < shapes.size(); i++) {
		vertex_buffer_size += sizeof(float)* shapes[i].mesh.positions.size();
		normals_buffer_size += sizeof(float)* shapes[i].mesh.normals.size();
		index_buffer_size += sizeof(unsigned int)* shapes[i].mesh.indices.size();
	}

	glGenBuffers(1, &vertex_buffer);
	glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
	glBufferData(GL_ARRAY_BUFFER, vertex_buffer_size, NULL, GL_STATIC_DRAW);
	vertex_buffer_size = 0;
	for (size_t i = 0; i < shapes.size(); i++) {
		glBufferSubData(GL_ARRAY_BUFFER, vertex_buffer_size, sizeof(float)* shapes[i].mesh.positions.size(), &shapes[i].mesh.positions[0]);
		vertex_buffer_size += sizeof(float)* shapes[i].mesh.positions.size();
	}
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	
	// Index
	/*size_t index_buffer_size = 0;
	for (size_t i = 0; i < shapes.size(); i++) {
		index_buffer_size += sizeof(unsigned int)* shapes[i].mesh.indices.size();
	}*/
	glGenBuffers(1, &index_buffer);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_buffer_size, NULL, GL_STATIC_DRAW);
	index_buffer_size = 0;
	for (size_t i = 0; i < shapes.size(); i++) {
		glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, index_buffer_size, sizeof(unsigned int)* shapes[i].mesh.indices.size(), &shapes[i].mesh.indices[0]);
		index_buffer_size += sizeof(unsigned int)* shapes[i].mesh.indices.size();
	}
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

	// Normals
	glGenBuffers(1, &normals_buffer);
	glBindBuffer(GL_ARRAY_BUFFER, normals_buffer);
	glBufferData(GL_ARRAY_BUFFER, normals_buffer_size, NULL, GL_STATIC_DRAW);
	normals_buffer_size = 0;
	for (size_t i = 0; i < shapes.size(); i++) {
		glBufferSubData(GL_ARRAY_BUFFER, normals_buffer_size, sizeof(float)* shapes[i].mesh.normals.size(), &shapes[i].mesh.normals[0]);
		normals_buffer_size += sizeof(float)* shapes[i].mesh.normals.size();
	}
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	//fprintf(stderr, "normals_buffer_size %d  vertex_buffer_size %d   index_buffer_size %d 
", normals_buffer_size, vertex_buffer_size, index_buffer_size);
	// draw multiple objects with one draw call
	glGenVertexArrays(1, &vertex_array_object);
	glBindVertexArray(vertex_array_object);
	glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
	//glBindBuffer(GL_ARRAY_BUFFER, normals_buffer); <====== this is where the normal buffer is commented
	//glBindBuffer(GL_ARRAY_BUFFER, 0);
	//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
	glBindVertexArray(0);

	uniform_mvp = glGetUniformLocation(shader_program, "MVP");
	uniform_lightPosition = glGetUniformLocation(shader_program, "lightPosition");
	
	errorCode = glGetError();
	if (errorCode != 0)
	{
		fprintf(stderr, "Error data: %s, code %d
", glewGetErrorString(errorCode), errorCode);
	}
}

Then when i draw i just enable the attribute and. I guess this is very wrong since im not binding the normals.


void display(){

	GLenum errorCode = 0;
	// Clear the screen to black
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	glClearDepth(1.0f);

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Use our shader
	glUseProgram(shader_program);

	// Send our transformation to the currently bound shader, in the "MVP" uniform 
	glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, glm::value_ptr(cam.calculateMVP()));
	glUniform3fv(uniform_lightPosition, 1, glm::value_ptr(glm::vec4(100.0f, 10.0f, 0.0f, 0.0f) * cam.calculateMVP()));
	//glUniform3fv(uniform_lightPosition, 1, glm::value_ptr((glm::vec4(cam.cameraPosition, 0.0f) - glm::vec4(cam.cameraPosition, 0.0f)) * cam.calculateMVP()));

	glBindVertexArray(vertex_array_object);
	glEnableVertexAttribArray(0);
	glEnableVertexAttribArray(1);

	size_t vertex_buffer_size = 0;
	size_t index_buffer_size = 0;
	size_t normals_buffer_size = 0;

	for (size_t i = 0; i < shapes.size(); i++) {

		glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)vertex_buffer_size);
		glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)normals_buffer_size);
		glDrawElements(GL_TRIANGLES, shapes[i].mesh.indices.size(), GL_UNSIGNED_INT, (void*)index_buffer_size);
		
		vertex_buffer_size += sizeof(float) * shapes[i].mesh.positions.size();
		index_buffer_size += sizeof(unsigned int) *shapes[i].mesh.indices.size();
		normals_buffer_size += sizeof(float) * shapes[i].mesh.normals.size();

		if (errorCode != 0)
		{
			fprintf(stderr, "Error rendering shape[%d].name = %s. Error name: %s. Error code code %d
", i, shapes[i].name.c_str(), glewGetErrorString(errorCode), errorCode);
		}
	}

	glDisableVertexAttribArray(0);
	glDisableVertexAttribArray(1);
	glBindVertexArray(0);

	glUseProgram(0);

	// Swap buffers
	SDL_GL_SwapWindow(window);
}

The vertex shader looks like this. This is also wrong because when i turn the camera other sides of the object get illuminated (pics below).


#version 330

uniform mat4 MVP;
uniform vec3 lightPosition;

vec3 lightIntensity = vec3(1.0f, 1.0f, 1.0f);
vec3 diffuseColor = vec3(1.0f, 1.0f, 1.0f);

layout(location = 0) in vec3 position;
layout(location = 1) in vec3 normals;

smooth out vec3 Color;

void main() {
	
	gl_Position = MVP * vec4(position, 1.0);
	// wrong i guess
	float cosAngIncidence = dot(normals,  lightPosition);
	cosAngIncidence = clamp(cosAngIncidence, 0, 1);

	Color = lightIntensity * diffuseColor * cosAngIncidence;
}

[ATTACH=CONFIG]752[/ATTACH][ATTACH=CONFIG]753[/ATTACH]

It never makes sense to have a sequence of glBindBuffer(GL_ARRAY_BUFFER, …) calls without anything between them. There is only a single GL_ARRAY_BUFFER bind point, so only the last buffer bound there is relevant. It is of course still possible to have positions taken from a different buffer object than normals; that works because glVertexAttribPointer() remembers which buffer object is bound to the GL_ARRAY_BUFFER bind point at the time of the call.
Perhaps as a first step ignore vertex array objects, just create and bind one at the beginning of your program, then never touch it again. In that case your first code block becomes:


        // positions/index buffer unchanged

	// Normals
	glGenBuffers(1, &normals_buffer);
	glBindBuffer(GL_ARRAY_BUFFER, normals_buffer);
	glBufferData(GL_ARRAY_BUFFER, normals_buffer_size, NULL, GL_STATIC_DRAW);
	normals_buffer_size = 0;
	for (size_t i = 0; i < shapes.size(); i++) {
		glBufferSubData(GL_ARRAY_BUFFER, normals_buffer_size, sizeof(float)* shapes[i].mesh.normals.size(), &shapes[i].mesh.normals[0]);
		normals_buffer_size += sizeof(float)* shapes[i].mesh.normals.size();
	}
	glBindBuffer(GL_ARRAY_BUFFER, 0);

        // create a VAO, bind it, and forget about it
	glGenVertexArrays(1, &vertex_array_object);
	glBindVertexArray(vertex_array_object);
 
        //MVP matrix
	uniform_mvp = glGetUniformLocation(shader_program, "MVP");
        //light position 
	uniform_lightPosition = glGetUniformLocation(shader_program, "lightPosition");
 
	errorCode = glGetError();
	if (errorCode != 0)
	{
		fprintf(stderr, "Error data: %s, code %d
", glewGetErrorString(errorCode), errorCode);
	}

and the core of your draw function becomes:


       	glEnableVertexAttribArray(0);
	glEnableVertexAttribArray(1);
 
        // bind index buffer
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);

	size_t vertex_buffer_size = 0;
	size_t index_buffer_size = 0;
	size_t normals_buffer_size = 0;
 
	for (size_t i = 0; i < shapes.size(); i++)
        {
                glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
		glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)vertex_buffer_size);

                glBindBuffer(GL_ARRAY_BUFFER, normal_buffer);
		glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)normals_buffer_size);

		glDrawElements(GL_TRIANGLES, shapes[i].mesh.indices.size(), GL_UNSIGNED_INT, (void*)index_buffer_size);
 
		vertex_buffer_size += sizeof(float) * shapes[i].mesh.positions.size();
		index_buffer_size += sizeof(unsigned int) *shapes[i].mesh.indices.size();
		normals_buffer_size += sizeof(float) * shapes[i].mesh.normals.size();
 
		if (errorCode != 0)
		{
			fprintf(stderr, "Error rendering shape[%d].name = %s. Error name: %s. Error code code %d
", i, shapes[i].name.c_str(), glewGetErrorString(errorCode), errorCode);
		}
	}
 
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        glBindBuffer(GL_ARRAY_BUFFER, 0);

	glDisableVertexAttribArray(0);
	glDisableVertexAttribArray(1);

Since glVertexAttribPointer always ‘refers’ to the buffer bound to GL_ARRAY_BUFFER you need to keep switching between your position and your normal buffers. There are a number of ways around that, you can interleave your vertex attributes into a single buffer, i.e. store [p0, n0, p1, n1, … , pN, nN] where pX is a position and nX is a normal. Or you make a vertex array object per shape, because then you only need to call glVertexAttribPointer once when setting up the VAO for the shape and at draw time simply bind the VAO for each shape; roughly like this:


// fill buffers with data like you do now

for (size_t i = 0; i < shapes.size(); ++i)
{
    glGenVertexArrays(1, &shape_vao[i]);
    glBindVertexArray(shape_vao[i]);

    glEnableVertexAttribute(0);
    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)vertex_buffer_size);

    glEnableVertexAttribute(1);
    glBindBuffer(GL_ARRAY_BUFFER, normal_buffer);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)normals_buffer_size);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);

    // increment vertex_buffer_size, normals_buffer_size
}

glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);   // this must happen after glBindVertexArray(0)!

and to draw:


for (size_t i = 0; i < shapes.size(); ++i)
{
    glBindVertexArray(shape_vao[i]);

    glDrawElements(GL_TRIANGLES, shapes[i].mesh.indices.size(), GL_UNSIGNED_INT, (void*)index_buffer_size);

    // increment index_buffer_size
}

Ok, for now i will use only 1 VAO until i get a bit more used to this whole OpenGL thing. I have an idea how to make the mesh call render calls and how to make multiple objects, identify camera in obj file but i just don’t want to spend time on them now. I want to focus on OpenGl and possibly later make my tiny small render engine if not small and simple game engine.

There is a lot of things ahead of me. More C++ and more OpenGL but it looks fun so far besides being stuck many times.

I fixed the normal buffer issue. Thanks carsten again for help.

This is the my point light diffuse shader (mix between my code. OpenGl superbible 5ed, and http://www.arcsynthesis.org/gltut/)

#version 330

uniform mat4 MVP;
uniform mat4 MV;
uniform mat3 normalMatrix;
uniform vec3 lightPosition;

layout(location = 0) in vec3 position;
layout(location = 1) in vec3 normals;

smooth out vec3 Color;

vec3 diffuseColor = vec3(1.0f, 1.0f, 1.0f);

void main() {

	// FIXED :: do normalMatric on CPU with GLM
	//mat4 normalMatrix = transpose(inverse(MV));
	//vec3 eyeNormal = normalize(vec3(normalMatrix * vec4(normals, 1.0)));
	vec3 eyeNormal = normalize(normalMatrix * normals);

	// vertex positionm in eye coordinates
	vec4 vPosition4 = MV * vec4(position, 1.0);
	vec3 vPosition3 = vPosition4.xyz/ vPosition4.w;
	
	// Light Direction
	vec3 dirToLight = normalize(lightPosition - vPosition3);
	
	// Diffuse intensity
	float diff = max(0.0, dot(eyeNormal,  dirToLight));
	Color = diffuseColor * diff;

	gl_Position = MVP * vec4(position, 1.0);
}

and the result :surprise: [ATTACH=CONFIG]754[/ATTACH]

Last question. Can i try and use GL_NORMAL_ARRAY and then use to bind. I Just found that enum and I am asking because i cant find much material to read about it now.

:smiley:

Valid buffer bind points are listed on the man page, GL_NORMAL_ARRAY is not one of them, so no that won’t work :wink: Off hand I don’t remember where that enum value is used.

OK so i had some fun today trying out and fixing small things.

I wanted to try and change the code so that i will put vertex and normals in one buffer. put vertexes then normals afterwards. I just wanted to reduce number of loops that i had to one loop.I ended up having a weird result in very few triangles when render with diffuse light. If i remove that and i have a solid color i can see that everything looks fine lol.

Here is the code for buffers


void initData(){
	GLenum errorCode = 0;

	// Copy data to GPU
	size_t normals_buffer_size =0;
	size_t vertex_buffer_size = 0;
	size_t index_buffer_size = 0;

	for (size_t i = 0; i < shapes.size(); i++) {
		vertex_buffer_size += sizeof(float)* shapes[i].mesh.positions.size();
		normals_buffer_size += sizeof(float)* shapes[i].mesh.normals.size();
		index_buffer_size += sizeof(unsigned int)* shapes[i].mesh.indices.size();
	}

	glGenBuffers(1, &vertex_buffer);
		glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
	        glBufferData(GL_ARRAY_BUFFER, vertex_buffer_size + normals_buffer_size, NULL, GL_STATIC_DRAW);
	glGenBuffers(1, &index_buffer);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
	        glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_buffer_size, NULL, GL_STATIC_DRAW);

	vertex_buffer_size = 0;
	normals_buffer_size = 0;
	index_buffer_size = 0;

	for (size_t i = 0; i < shapes.size(); i++) {
		glBufferSubData(GL_ARRAY_BUFFER, vertex_buffer_size, sizeof(float)* shapes[i].mesh.positions.size(), &shapes[i].mesh.positions[0]);
			vertex_buffer_size += sizeof(float)* shapes[i].mesh.positions.size();
		glBufferSubData(GL_ARRAY_BUFFER, vertex_buffer_size + normals_buffer_size, sizeof(float)* shapes[i].mesh.normals.size(), &shapes[i].mesh.normals[0]);
			normals_buffer_size += sizeof(float)* shapes[i].mesh.normals.size();
		glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, index_buffer_size, sizeof(unsigned int)* shapes[i].mesh.indices.size(), &shapes[i].mesh.indices[0]);
			index_buffer_size += sizeof(unsigned int)* shapes[i].mesh.indices.size();
	}
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

	glGenVertexArrays(1, &vertex_array_object);
	glBindVertexArray(vertex_array_object);
		glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
	glBindVertexArray(0);

	uniform_mvp = glGetUniformLocation(shader_program, "MVP");
	uniform_mv = glGetUniformLocation(shader_program, "MV");
	uniform_lightPosition = glGetUniformLocation(shader_program, "lightPosition");
	uniform_normalMatrix = glGetUniformLocation(shader_program, "normalMatrix");

	errorCode = glGetError();
	if (errorCode != 0)
	{
		fprintf(stderr, "Error data: %s, code %d
", glewGetErrorString(errorCode), errorCode);
	}
}

and the draw call code


void display(){

	GLenum errorCode = 0;
	// Clear the screen to black
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	glClearDepth(1.0f);

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Use our shader
	glUseProgram(shader_program);

	// Send our transformation to the currently bound shader, in the "MVP" uniform 
	glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, glm::value_ptr(cam.calculateMVP()));
	glUniformMatrix4fv(uniform_mv, 1, GL_FALSE, glm::value_ptr(cam.calculateMV()));
	glUniformMatrix3fv(uniform_normalMatrix, 1, GL_FALSE, glm::value_ptr(cam.calculateEyeNormal()));
	//glUniform3fv(uniform_lightPosition, 1, glm::value_ptr(glm::vec3(glm::vec4(cam.cameraPosition, 1.0f) * cam.calculateMVP())));
	glUniform3fv(uniform_lightPosition, 1, glm::value_ptr(lightPosition));
	//glUniform3fv(uniform_lightPosition, 1, glm::value_ptr(cam.cameraPosition));

	glBindVertexArray(vertex_array_object);
	glEnableVertexAttribArray(0);
	glEnableVertexAttribArray(1);

	size_t vertex_buffer_size = 0;
	size_t index_buffer_size = 0;
	size_t normals_buffer_size = 0;

	for (size_t i = 0; i < shapes.size(); i++) {
		glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)vertex_buffer_size); // vertexes
			vertex_buffer_size +=  sizeof(float) * shapes[i].mesh.positions.size(); // increase the counter for the next vertex
		glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)(vertex_buffer_size + normals_buffer_size)); // normals <=== i suspect that i have an error here or there is a problem when i exported the files from blender
			normals_buffer_size += sizeof(float) * shapes[i].mesh.normals.size();// increase the counter for the next normal
		glDrawElements(GL_TRIANGLES, shapes[i].mesh.indices.size(), GL_UNSIGNED_INT, (void*)index_buffer_size);
			index_buffer_size += sizeof(unsigned int) *shapes[i].mesh.indices.size();

			if (errorCode != 0)
		{
			fprintf(stderr, "Error rendering shape[%d].name = %s. Error name: %s. Error code code %d
", i, shapes[i].name.c_str(), glewGetErrorString(errorCode), errorCode);
		}
	}

	glDisableVertexAttribArray(0);
	glDisableVertexAttribArray(1);
	glBindVertexArray(0);

	glUseProgram(0);

	// Swap buffers
	SDL_GL_SwapWindow(window);
}

and the shader code (since i import the object and im not scaling i dont need to transform the models to view space and use normal matrix:) ); fragment is just an output color shared for now. this weekend i will play more with lights and probably more questions.


#version 330

uniform mat4 MVP;
uniform mat4 MV;
uniform mat3 normalMatrix;
uniform vec3 lightPosition;

layout(location = 0) in vec3 position;
layout(location = 1) in vec3 normals;

out vec3 positionOut;
out vec3 normalsOut;

smooth out vec3 Color;

vec3 diffuseColor = vec3(1.0f, 1.0f, 1.0f);

void main() {

	// Everything is at the MV space because of OBJ imoprt not programatically generated bojects (I GUESS)	
	vec3 dirToLight = normalize(lightPosition - position);
	//float diff = max(0.0, dot(normals,  dirToLight));
	float diff = clamp( dot(normals,  dirToLight),0.0, 1.0);

	Color = diffuseColor * diff;
	//Color = diffuseColor;
	gl_Position = MVP * vec4(position, 1.0);
}

[ATTACH=CONFIG]755[/ATTACH] [ATTACH=CONFIG]756[/ATTACH] [ATTACH=CONFIG]757[/ATTACH]

Hmm, don’t take this the wrong way, but I think this is a good opportunity to practice debugging code, because it will be much more satisfying (and faster) if you can diagnose problems like this yourself :wink: Run your code in a debugger, set a breakpoint at the beginning of the block of code below and single step through the loop, keeping an eye on where in the buffer you are writing data:


        vertex_buffer_size = 0;
	normals_buffer_size = 0;
	index_buffer_size = 0;
 
	for (size_t i = 0; i < shapes.size(); i++) {
		glBufferSubData(GL_ARRAY_BUFFER, vertex_buffer_size, sizeof(float)* shapes[i].mesh.positions.size(), &shapes[i].mesh.positions[0]);
			vertex_buffer_size += sizeof(float)* shapes[i].mesh.positions.size();
		glBufferSubData(GL_ARRAY_BUFFER, vertex_buffer_size + normals_buffer_size, sizeof(float)* shapes[i].mesh.normals.size(), &shapes[i].mesh.normals[0]);
			normals_buffer_size += sizeof(float)* shapes[i].mesh.normals.size();
		glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, index_buffer_size, sizeof(unsigned int)* shapes[i].mesh.indices.size(), &shapes[i].mesh.indices[0]);
			index_buffer_size += sizeof(unsigned int)* shapes[i].mesh.indices.size();
	}

Nahh its ok. I just have to get used to C++ debugger and reading it better. I programmed with Java, and Prolog at university and at work C#. I will check it and i will post the result :smiley:

BTW only the sphere and the cube does not render properly the rest are look OK.

Also i guess i will give a shot to glslDevil this weekend for the first time. Maybe i will see something there

Fixed, I had 2 identical squares in the obj file. :stuck_out_tongue:
Weird i didn’t have any z fight.

next thing make pixel based light, log and i want to see if how can i make dynamic shader loading. If i find that the shader time-stamp is older compile the new program link it and if everything is ok destroy the old program an use the new one. :smiley: