Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 2 of 2

Thread: Updating VAO using for loop

  1. #1
    Newbie Newbie
    Join Date
    Dec 2017
    Posts
    1

    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.
    Code :
    #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_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 :
    Click image for larger version. 

Name:	Capture du 2017-12-05 15-01-05.jpg 
Views:	10 
Size:	3.3 KB 
ID:	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.

  2. #2
    Intern Contributor
    Join Date
    Dec 2016
    Location
    Ocean Shores, WA USA
    Posts
    72
    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/UCzx..._as=subscriber

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •