PDA

View Full Version : Updating VAO using for loop



hiroki
12-05-2017, 07:10 AM
Hello,

I want to draw N*N squares. In order to do so, I draw 2 triangles by using 2 for loops which update coordinates following i and j. here is the whole code :
Note 1 : Those points are using 3D coordinates, because I will need to use 3D coordinate later.
Note 2 : I will also need a second VAO, that is why g_vertex_buffer_data_1 is being initialized but is not used.


#include <stdio.h>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <unistd.h>
using namespace std;

#include <stdlib.h>
#include <string.h>

#include <GL/glew.h>
#include <GLFW/glfw3.h>

#ifdef __APPLE__
#include <OpenGL/gl.h>
#else
#include <GL/gl.h>
#endif

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

using namespace glm;

#define GLM_FORCE_RADIANS

const int N = 10;
GLint uniform_proj, uniform_view, uniform_model;

GLuint LoadShaders(const char * vertex_file_path,const char * fragment_file_path){

// Create the shaders
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);

// Read the Vertex Shader code from the file
std::string VertexShaderCode;
std::ifstream VertexShaderStream(vertex_file_path, std::ios::in);
if(VertexShaderStream.is_open()){
std::string Line = "";
while(getline(VertexShaderStream, Line))
VertexShaderCode += "\n" + Line;
VertexShaderStream.close();
}else{
printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !\n", vertex_file_path);
getchar();
return 0;
}

// Read the Fragment Shader code from the file
std::string FragmentShaderCode;
std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
if(FragmentShaderStream.is_open()){
std::string Line = "";
while(getline(FragmentShaderStream, Line))
FragmentShaderCode += "\n" + Line;
FragmentShaderStream.close();
}

GLint Result = GL_FALSE;
int InfoLogLength;


// Compile Vertex Shader
printf("Compiling shader : %s\n", vertex_file_path);
char const * VertexSourcePointer = VertexShaderCode.c_str();
glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
glCompileShader(VertexShaderID);

// Check Vertex Shader
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if ( InfoLogLength > 0 ){
std::vector<char> VertexShaderErrorMessage(InfoLogLength+1);
glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
printf("%s\n", &VertexShaderErrorMessage[0]);
}



// Compile Fragment Shader
printf("Compiling shader : %s\n", fragment_file_path);
char const * FragmentSourcePointer = FragmentShaderCode.c_str();
glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
glCompileShader(FragmentShaderID);

// Check Fragment Shader
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if ( InfoLogLength > 0 ){
std::vector<char> FragmentShaderErrorMessage(InfoLogLength+1);
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
printf("%s\n", &FragmentShaderErrorMessage[0]);
}



// Link the program
printf("Linking program\n");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);

uniform_proj = glGetUniformLocation(ProgramID, "projectionMatrix");
uniform_view = glGetUniformLocation(ProgramID, "viewMatrix");
uniform_model = glGetUniformLocation(ProgramID, "modelMatrix");

// Check the program
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if ( InfoLogLength > 0 ){
std::vector<char> ProgramErrorMessage(InfoLogLength+1);
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
printf("%s\n", &ProgramErrorMessage[0]);
}


glDetachShader(ProgramID, VertexShaderID);
glDetachShader(ProgramID, FragmentShaderID);

glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);

return ProgramID;
}

int main(){
// Initialises GLFW
if( !glfwInit() ) {
fprintf( stderr, "Failed to initialize GLFW\n" );
return -1;
}

GLfloat g_vertex_buffer_data[N*N*18];
GLfloat g_vertex_color_data[N*N*18];

GLfloat g_vertex_buffer_data_1[9*5*N];
GLfloat g_vertex_color_data_1[9*5*N];

for (int j=0; j<N; j++){
for(int i=0; i<N; i++){

//Triangle1
g_vertex_buffer_data[ 0+i*j*18] = i;
g_vertex_buffer_data[ 1+i*j*18] = j;
g_vertex_buffer_data[ 2+i*j*18] = 0.0f;

g_vertex_buffer_data[ 3+i*j*18] = i;
g_vertex_buffer_data[ 4+i*j*18] = j+1;
g_vertex_buffer_data[ 5+i*j*18] = 0.0f;

g_vertex_buffer_data[ 6+i*j*18] = i+1;
g_vertex_buffer_data[ 7+i*j*18] = j;
g_vertex_buffer_data[ 8+i*j*18] = 0.0f;

//Triangle2
g_vertex_buffer_data[ 9+i*j*18] = i;
g_vertex_buffer_data[10+i*j*18] = j+1;
g_vertex_buffer_data[11+i*j*18] = 0.0;

g_vertex_buffer_data[12+i*j*18] = i+1;
g_vertex_buffer_data[13+i*j*18] = j;
g_vertex_buffer_data[14+i*j*18] = 0.0f;

g_vertex_buffer_data[15+i*j*18] = i+1;
g_vertex_buffer_data[16+i*j*18] = j+1;
g_vertex_buffer_data[17+i*j*18] = 0.0f;

//colors

g_vertex_color_data[ 0+i*j*18] = 0.0;
g_vertex_color_data[ 1+i*j*18] = 0.0;
g_vertex_color_data[ 2+i*j*18] = 1.0;

g_vertex_color_data[ 3+i*j*18] = 0.0;
g_vertex_color_data[ 4+i*j*18] = 1.0;
g_vertex_color_data[ 5+i*j*18] = 0.0;

g_vertex_color_data[ 6+i*j*18] = 1.0;
g_vertex_color_data[ 7+i*j*18] = 0.0;
g_vertex_color_data[ 8+i*j*18] = 0.0;


g_vertex_color_data[ 9+i*j*18] = 0.0;
g_vertex_color_data[10+i*j*18] = 0.0;
g_vertex_color_data[11+i*j*18] = 1.0;

g_vertex_color_data[12+i*j*18] = 0.0;
g_vertex_color_data[13+i*j*18] = 1.0;
g_vertex_color_data[14+i*j*18] = 0.0;

g_vertex_color_data[15+i*j*18] = 1.0;
g_vertex_color_data[16+i*j*18] = 0.0;
g_vertex_color_data[17+i*j*18] = 0.0;


}
}

glfwWindowHint(GLFW_SAMPLES, 4); // 4x antialiasing
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // On veut OpenGL 3.3
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_DEPTH_BITS, 24);


GLFWwindow* window;
window = glfwCreateWindow( 1024, 768, "Tutorial 01", NULL, NULL);
if( window == NULL ){
fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n" );
glfwTerminate();
return -1;
}

glfwMakeContextCurrent(window);
glewExperimental=true;
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
return -1;
}

// Enable depth test
glEnable(GL_DEPTH_TEST);
// Accept fragment if it closer to the camera than the former one
glDepthFunc(GL_LESS);
glDepthRange(-1, 1);

// modern OpenGL do not have a default VAO anymore. Even if we don't want to use it
// we have a create and bind one before playing with buffers !
GLuint VertexArrayID;

glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);

// This will identify our vertex buffer
GLuint vertexbuffer;

// Generate 1 buffer, put the resulting identifier in vertexbuffer
glGenBuffers(1, &vertexbuffer);

//The following commands will talk about our 'vertexbuffer' buffer
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);

// Only allocqte memory. Do not send yet our vertices to OpenGL.
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data)+sizeof(g_vertex_color _data), 0, GL_STATIC_DRAW);

// send vertices in the first part of the buffer
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(g_vertex_buffer_data), g_vertex_buffer_data);

// send vertices in the second part of the buffer
glBufferSubData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), sizeof(g_vertex_color_data), g_vertex_color_data);

// ici les commandes stockees "une fois pour toute" dans le VAO
glVertexAttribPointer(
0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
glEnableVertexAttribArray(0);

glVertexAttribPointer( // same thing for the colors
1,
3,
GL_FLOAT,
GL_FALSE,
0,
(void*)sizeof(g_vertex_buffer_data));
glEnableVertexAttribArray(1);


glBindBuffer(GL_ARRAY_BUFFER, 0);

// on desactive le VAO a la fin de l'initialisation
glBindVertexArray (0);

GLuint VertexArrayID_1;

glGenVertexArrays(1, &VertexArrayID_1);
glBindVertexArray(VertexArrayID_1);

// This will identify our vertex buffer
GLuint vertexbuffer_1;

// Generate 1 buffer, put the resulting identifier in vertexbuffer
glGenBuffers(1, &vertexbuffer_1);

//The following commands will talk about our 'vertexbuffer' buffer
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer_1);

// Only allocate memory. Do not send yet our vertices to OpenGL.
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data_1)+sizeof(g_vertex_col or_data_1), 0, GL_STATIC_DRAW);

// send vertices in the first part of the buffer
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(g_vertex_buffer_data_1), g_vertex_buffer_data_1);

// send vertices in the second part of the buffer
glBufferSubData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data_1), sizeof(g_vertex_color_data_1), g_vertex_color_data_1);

glVertexAttribPointer(
0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
glEnableVertexAttribArray(0);

glVertexAttribPointer( // same thing for the colors
1,
3,
GL_FLOAT,
GL_FALSE,
0,
(void*)sizeof(g_vertex_buffer_data));
glEnableVertexAttribArray(1);


glBindBuffer(GL_ARRAY_BUFFER, 0);

glBindVertexArray (0);


glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);

GLuint programID = LoadShaders( "SimpleVertexShader5.vertexshader", "SimpleFragmentShader5.fragmentshader" );

float angle = 0.0f;

do{
angle = (angle+M_PI/200);

// clear before every draw 1
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// Use our shader
glUseProgram(programID);

// onchange de matrice de projection : la projection orthogonale est plus propice a la visualization !
//glm::mat4 projectionMatrix = glm::perspective(45.0f, 1024.0f / 768.0f, 0.0f, 200.0f);
glm::mat4 projectionMatrix = glm::ortho( -60.0f, 40.0f, -20.0f, 20.0f, -200.f, 20.f );
glm::mat4 viewMatrix = glm::lookAt(
vec3(1.5*cos(1.5*M_PI), 1.5*sin(1.5*M_PI), -0.5), // where is the camera
vec3(0,0,0.5), //where it looks
vec3(0,0, 1) // head is up
);
mat4 modelMatrix = glm::mat4(1.0);
mat4 modelMatrix_1 = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 0.5f));

glUniformMatrix4fv(uniform_proj, 1, GL_FALSE, glm::value_ptr(projectionMatrix));
glUniformMatrix4fv(uniform_view, 1, GL_FALSE, glm::value_ptr(viewMatrix));
glUniformMatrix4fv(uniform_model, 1, GL_FALSE, glm::value_ptr(modelMatrix));


glBindVertexArray(VertexArrayID);


// Draw the triangle(s) !
glDrawArrays(GL_TRIANGLES, 0, sizeof(g_vertex_buffer_data)/(3*sizeof(float))); // Starting from vertex 0; 6 vertices total -> 2 triangles

glBindVertexArray (0);

glBindVertexArray(VertexArrayID_1);
//glUniformMatrix4fv(uniform_model, 1, GL_FALSE, glm::value_ptr(modelMatrix_1));
glDrawArrays(GL_TRIANGLES, 0, sizeof(g_vertex_buffer_data_1)/(3*sizeof(float))); // Starting from vertex 0; 6 vertices total -> 2 triangles
glBindVertexArray (0);


glUseProgram(0);

// Swap buffers
glfwSwapBuffers(window);
glfwPollEvents();

}while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
glfwWindowShouldClose(window) == 0 );
}



}
}
Where j represents the number of columns and i represents the number of rows. I expect this program to draw N squares, but it only draws a some of them. In fact, the amount of columns and rows are respected but there are also a lot of black space between some squares. Here is what I get for N = 10 :
2566

I am not getting N*N squares, so I do not know why this algorithm is not working. I tried to replace i*j by i+j, the program drew something that does not correspond to a square. I also tried to replace 0+i*j*18 with i+j*18, but in this case, I only get a black screen. So I do not know where are the issues.

Thanks for reading.

OceanJeff40
12-10-2017, 09:22 PM
Greetings,

I just looked at your code, and it appears that your loop to initialize the data, just take for instance the first loop through J=0..... all the I*J*18 will be zero, for each of the 10 iterations of I, so it's just setting one set of variables ten times.

Start by fixing that main loop, and you're on your way.

Regards,

Jeff
(below is a link to my youtube video series of tutorials, as I work through the world of opengl, and figure things out! hope it helps, and keep up your coding, looks great!)
https://www.youtube.com/channel/UCzx8alrxVELz5h1dfCdkdfg?view_as=subscriber