Search code examples
copenglopengl-3

Opengl is drawing nothing but telling me there is no errors


When I run the program, the window is just black. I've been using this tutorial https://open.gl/drawing. Though I didn't copy it verbatim. glgeterror turned up 0. What's wrong with my code. I used 9 array elements instead of the 6 suggested in the tutorial but made up for it.

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

int main(){
    //window initalization
        if(!glfwInit()){
                fprintf(stderr,"failed glfw initialization");
                return -1;
        }

        GLFWwindow* window = glfwCreateWindow(800,800,"i hope this works",NULL,NULL);
        if (!window){
                fprintf(stderr,"window creation failed");
                return -1;
        }
        glfwMakeContextCurrent(window);
    //glew initialization
        glewExperimental = 1;
        if(glewInit() != GLEW_OK){
                fprintf(stderr,"glew failed to initialize");
                return -1;

    //vertex specification(vs)
    //vertex array object(vs)
    GLuint vao;
    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    //vertex buffer object(vs)
    GLuint vbo;
    glGenBuffers(1, &vbo);

    //vertex data(vs)
    const GLfloat tri_verts[] = {
        -1.0f,1.0f,0.0f,
        -1.0f,0.0f,0.0f,
         1.0f,0.0f,0.0f};
        //-west +east -south +north -farther +closer
        //{{x,y,z}{x,y,z}{x,y,z}}
        //just a nemonic to associate which direction each letter goes.

    //bind the vertices to the buffer(vs)
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER,sizeof(tri_verts),tri_verts,GL_STATIC_DRAW);

    //vertex processing(vp)
    //vertex shader(vp)
    const GLchar* Vshader_source = "\
    version 330 \
    in vec3 position; \
    void main() \
     \
    gl_Position = vec4(position,1.0); \
     \
    ";
    //fragment shader(vp)
    const GLchar* Fshader_source = "\
    #version 330\
    out vec4 outColor;\
    void main()\
    {\
        outColor = vec4(1.0, 1.0, 1.0, 1.0);\
    }";

    //shader compilation(vp)
    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1,&Vshader_source,NULL);
    glCompileShader(vertexShader);

    //vertex shader compilation status
    GLint Vstatus;      
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &Vstatus);
    char Vbuffer[512];
    glGetShaderInfoLog(vertexShader, 512, NULL, Vbuffer);
    fprintf(stderr,"%s",Vbuffer);
    fprintf(stderr,"\n\n");

    //fragment shader compilation
    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &Fshader_source, NULL);
    glCompileShader(fragmentShader);

    //Fragment shader compilation status
    GLint Fstatus;         
        glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &Fstatus);
        char Fbuffer[512];
        glGetShaderInfoLog(fragmentShader, 512, NULL, Fbuffer);
    fprintf(stderr,"%s",Fbuffer);

    //shader program creation
    GLuint shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram,vertexShader);
    glAttachShader(shaderProgram,fragmentShader);
    glBindFragDataLocation(shaderProgram,0,"outcolor");
    glLinkProgram(shaderProgram);
    glUseProgram(shaderProgram);

    //tell opengl how to interpret and format the vertices data
    GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
    glVertexAttribPointer(posAttrib,3, GL_FLOAT,GL_FALSE,0,0);
    glEnableVertexAttribArray(posAttrib );

    //vertex post-processing(fixed)
    //Primitive assembly(fixed)
    //Rasterization(fixed)
    //Fragment Processing(fixed)
    //per-sample operations(fixed)

        }
    char error_num = 0;
        while(!glfwWindowShouldClose(window)){
        glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        if (!error_num){
                fprintf(stderr,"%d",glGetError());
                error_num++;
        }
        glDrawArrays(GL_TRIANGLES,0,3);
        glfwSwapBuffers(window);
        glfwPollEvents();
        }
}

Solution

  • Looks like a matter of several typos to me. First, the big one:

    if(glewInit() != GLEW_OK){
        fprintf(stderr,"glew failed to initialize");
        return -1;
    

    There's no closing brace for this error check. So most of your program actually isn't even executing, because it's inside this block.

    Your vertex shader:

    version 330
    in vec3 position;
    void main()
      gl_Position = vec4(position,1.0);
    

    version 330 should be #version 330. main should have braces. Corrected version:

    #version 330
    in vec3 position;
    void main() {
      gl_Position = vec4(position,1.0);
    }
    

    As genpfault mentioned, you also didn't include newlines (\n). That's alright (if a bit...ugly) for most things, but not for directives like #version. You need a newline after it.

    In the future, you should really save yourself some trouble and load shaders from a file instead of embedding them as a multi-line string. Speaking of which, if you really are going to use multi-line strings like that, do it this way:

    const GLchar* Vshader_source =
        "#version 330\n"
        "in vec3 position;"
        "void main() {"
        "  gl_Position = vec4(position,1.0);"
        "}";
    

    The preprocessor automatically concatenates constant strings when they are separated by nothing but whitespace. Bit more manageable than all those backslashes!

    Next,

    glBindFragDataLocation(shaderProgram,0,"outcolor");
    

    In your frag shader you called it outColor, not outcolor. Case matters here!

    No, I'm not positive that I caught them all but...that should be a start?