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 3 of 3

Thread: glDrawArrays is not drawing triangles, why?

  1. #1
    Intern Newbie
    Join Date
    Jan 2010
    Posts
    34

    glDrawArrays is not drawing triangles, why?

    Code :
    #include<glad/glad.h>
    #include<GLFW/glfw3.h>
    #include<stdio.h>
    #include<GL/glu.h>
    #include<vector>
    using namespace std;
     
    void draw_all() {	
    	glClearColor(1.0,1.0,1.0,0.0);
    	glClear(GL_COLOR_BUFFER_BIT);
     
    	gluOrtho2D(0.0,640,0.0,480);
    	glMatrixMode(GL_PROJECTION);
     
    	glLoadIdentity();
    	glViewport(10,10,640,480);
     
    	GLuint VertexArrayID;
    	glGenVertexArrays(1, &VertexArrayID);
    	glBindVertexArray(VertexArrayID);
     
    	static const GLfloat g_vertex_buffer_data[] = {
       	-1.0f, -1.0f, 0.0f,
       	1.0f, -1.0f, 0.0f,
       	0.0f,  1.0f, 0.0f,
    	};
     
    	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);
    	// Give our vertices to OpenGL.
    	glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);	
     
    	// 1rst attribute buffer : vertices
    	glEnableVertexAttribArray(0);
    	glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    	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
    	);
    	// Draw the triangle !
    	glDrawArrays(GL_TRIANGLES, 0, 3); // Starting from vertex 0; 3 vertices total -> 1 triangle
    	glDisableVertexAttribArray(0);	
     
    	glFlush();
    }
     
    int main(void)
    {
        GLFWwindow* window;
        /* Initialize the library */
        if (!glfwInit())
            return -1;
        /* Create a windowed mode window and its OpenGL context */
        window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
        if (!window)
        {
            glfwTerminate();
            return -1;
        }
        /* Make the window's context current */
        glfwMakeContextCurrent(window);
        /* Loop until the user closes the window */
        while (!glfwWindowShouldClose(window))
        {
        	gladLoadGL();
            /* Render here */
       		draw_all();   		
            /* Swap front and back buffers */
            glfwSwapBuffers(window); 		
            /* Poll for and process events */
            glfwPollEvents();
        }
        glfwTerminate();
        return 0;
    }

    Code :
    g++ op.cpp -o op -lglfw -lGL -lGLU -Iinclude/ src/glad.c -ldl
    ./op

    It's white background. It's not drawing anything. Why?

    What should i do?
    Any answer will be highly appreciated.
    Thanks in advance.

  2. #2
    Senior Member OpenGL Pro
    Join Date
    Jan 2007
    Posts
    1,715
    Disclaimer: I haven't bothered reading all of your code.

    Your projection matrix is set to identity. GL operations happen in the same order as the function calls that invoke them, so have a look at this:
    Code :
    gluOrtho2D(0.0,640,0.0,480);
    glMatrixMode(GL_PROJECTION);
     
    glLoadIdentity();
    First of all you create an ortho matrix and multiply whatever the current matrix is () by it.

    Then you switch the matrix mode to projection.

    Then you load identity onto it.

    The correct order is:
    Code :
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0,640,0.0,480);

  3. #3
    Member Regular Contributor
    Join Date
    May 2016
    Posts
    435
    after you've created the context, you HAVE TO initialize the openGL functions, i personally to it with GLEW:
    Code :
    if (glewInit() != GLEW_OK)
    	{
    		std::cout << "ERROR: cannot initialize glew" << std::endl;
    		exit(1);
    	}

    if you're doing it with "gladLoadGL();", you should call that funcion only once, before entering the main loop

    regarding your "draw_all();"
    are you aware of the fact that you are creating every frame a new buffer and vertex array ??
    you should do this also only once

    what shader program are you using ??
    i dont know what "glFlush();" actually does, but i would recommend you create your own shader program
    Code :
    unsigned int LoadShader()
    {
    	GLuint programID = 0;
     
    	// reset error log
    	GLenum ErrorCheckValue = glGetError();
     
    	// create shaders
    	GLuint shadervertexID = glCreateShader(GL_VERTEX_SHADER);
    	GLuint shaderfragmentID = glCreateShader(GL_FRAGMENT_SHADER);
     
    	// openGL wants for every shader an array of c-strings as source code
    	const char* sourcecodearrayVS[] = { LoadTextFile("vertexshader.txt") };
    	const char* sourcecodearrayFS[] = { LoadTextFile("fragmentshader.txt") };
     
    	// set source code for shaders
    	glShaderSource(shadervertexID, 1, sourcecodearrayVS, nullptr);
    	glShaderSource(shaderfragmentID, 1, sourcecodearrayFS, nullptr);
     
    	// compile shaders
    	glCompileShader(shadervertexID);
    	glCompileShader(shaderfragmentID);
     
    	// create program
    	programID = glCreateProgram();
     
    	// attach shaders to program
    	glAttachShader(programID, shadervertexID);
    	glAttachShader(programID, shaderfragmentID);
     
    	// link program
    	glLinkProgram(programID);
     
    	// tag for deletion (takes effect when no shader program uses them anymore)
    	glDeleteShader(shadervertexID);
    	glDeleteShader(shaderfragmentID);
     
    	// check for errors ...
    	ErrorCheckValue = glGetError();
    	if (ErrorCheckValue != GL_NO_ERROR)
    	{
    		std::cout << "ERROR: cannot load shaders:   errorcode = " << ErrorCheckValue << std::endl;
    		system("PAUSE");
    		exit(-1);
    	}
     
    	return programID;
    }

    then before "glDrawArrays()", activate your program by calling
    glUseProgram(GLuint program);


    EDIT:
    i assume you're following this tutorial, right ??
    http://www.opengl-tutorial.org/begin...irst-triangle/

    then create 2 textfiles, rename them to "vertexshader.txt" and "fragmentshader.txt", and paste the source codes in them, save them

    load the shader program also only once !
    Last edited by john_connor; 05-28-2016 at 07:17 AM.

Posting Permissions

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