PDA

View Full Version : After binding the normal buffer OpenGL does not draw anymore.



lummxx
09-25-2014, 05:25 AM
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);) 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 :D

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 \n", 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\n", 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\n", 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.
1445
No im have to fix this problem with binding normals and i believe I am set for light tutorials and experiments :D

lummxx
09-25-2014, 08:25 AM
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 \n", 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\n", 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\n", 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;
}


14461447

carsten neumann
09-25-2014, 08:44 AM
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\n", 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\n", 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
}

lummxx
09-25-2014, 11:59 AM
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: 1448

lummxx
09-25-2014, 02:11 PM
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.

:D

carsten neumann
09-25-2014, 02:29 PM
Valid buffer bind points are listed on the man page (http://www.opengl.org/sdk/docs/man/html/glBindBuffer.xhtml), GL_NORMAL_ARRAY is not one of them, so no that won't work ;) Off hand I don't remember where that enum value is used.

lummxx
09-26-2014, 08:26 AM
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\n", 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.cameraPosit ion, 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\n", 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);
}

1449 1450 1451

carsten neumann
09-26-2014, 08:41 AM
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 ;) 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();
}

lummxx
09-26-2014, 08:56 AM
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 :D

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

lummxx
09-27-2014, 09:12 AM
Fixed, I had 2 identical squares in the obj file. :P
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. :D