Updating VAO using for loop

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 += "
" + Line;
		VertexShaderStream.close();
	}else{
		printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !
", 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 += "
" + Line;
		FragmentShaderStream.close();
	}

	GLint Result = GL_FALSE;
	int InfoLogLength;


	// Compile Vertex Shader
	printf("Compiling shader : %s
", 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
", &VertexShaderErrorMessage[0]);
	}



	// Compile Fragment Shader
	printf("Compiling shader : %s
", 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
", &FragmentShaderErrorMessage[0]);
	}



	// Link the program
	printf("Linking program
");
	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
", &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
" );
	    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.
" );
	    glfwTerminate();
	    return -1;
	}

	glfwMakeContextCurrent(window); 
	glewExperimental=true; 
	if (glewInit() != GLEW_OK) {
	    fprintf(stderr, "Failed to initialize GLEW
");
	    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_color_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 :
[ATTACH=CONFIG]1628[/ATTACH]

I am not getting NN squares, so I do not know why this algorithm is not working. I tried to replace ij by i+j, the program drew something that does not correspond to a square. I also tried to replace 0+ij18 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.

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 IJ18 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