1

I am new to OpenGL and i want to draw a simple triangle on screen with my shader. I set up buffers and wrote a shaders but it doesn't seem to work. It gives white screen, i tried to change glCreateBuffer with glGenBuffer and screen turned to black screen. I want to create&compile shaders in one function called createAndCompileShader(...), buffers are defined in main function.

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

static unsigned int createAndCompileShader(const char* vertexShader, const char* fragmentShader) {

    unsigned int fragmentShaderr = glCreateShader(GL_FRAGMENT_SHADER);
    unsigned int vertexShaderr = glCreateShader(GL_VERTEX_SHADER);

    glShaderSource(vertexShaderr, 1, &vertexShader, NULL);
    glShaderSource(fragmentShaderr, 1, &fragmentShader, NULL);

    glCompileShader(vertexShaderr);
    glCompileShader(fragmentShaderr);

    unsigned int program = glCreateProgram();

    glAttachShader(program, vertexShaderr);
    glAttachShader(program, fragmentShaderr);
    glLinkProgram(program);
    

    return program;
}


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);

    float vertexPositions[6] = {
             -0.5, -0.5,
             0.0, 0.5,
             0.5, -0.5
    };


    const char* vertexShader = "#version 330 core\n"
        "layout(location = 0) in vec4 position;\n"
        "void main()\n"
        "{\n"
        "gl_Position = position;\n"
        "}\n";

    const char* fragementShader = "#version 330 core\n"
        "layout(location = 0) in vec4 position;\n"
        "void main()\n"
        "{\n"
        "color = vec4(1.0, 0.0, 0.0, 1.0);\n"
        "}\n";

    unsigned int program = createAndCompileShader(vertexShader, fragementShader);

    glUseProgram(program);

    unsigned int buffer;

    glGenBuffers(1, &buffer);
    //glCreateBuffers(1, &buffer);
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), vertexPositions, GL_STATIC_DRAW);

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float)*2 , 0);

  
    //std::string vertexShader;
    //std::string fragmentShader;

    /* Loop until the user closes the window */
    while (!glfwWindowShouldClose(window))
    {
        /* Render here */
        glClear(GL_COLOR_BUFFER_BIT);


        glDrawArrays(GL_TRIANGLES, 0 ,3);

        /*glBegin(GL_TRIANGLES);
        glVertex2f(-0.5, -0.5);
        glVertex2f( 0.0, 0.5);
        glVertex2f( 0.5, -0.5);
        glEnd();*/

        /* Swap front and back buffers */
        glfwSwapBuffers(window);

        /* Poll for and process events */
        glfwPollEvents();
    }

    glDeleteProgram(program);

    glfwTerminate();
    return 0;
}


2
  • Do some error handling in your createAndCompileShader Commented Oct 24, 2020 at 14:29
  • I tried that, but i didn't see any error about syntax etc. Commented Oct 24, 2020 at 14:46

1 Answer 1

3

Fragment shader input layout locations qualifiers are not provided in GLSL 3.30. You have to switch to GLSL 4.10 or remove the layout location in the fragment shader:

layout(location = 0) in vec4 position;

in vec4 position;

Furthermore you missed the specification of the fragment shader output color.

#version 330 core
in vec4 position;
out vec4 color;
void main()
{
    color = vec4(1.0, 0.0, 0.0, 1.0);
}

I recommend to use Raw string liters:

const char* fragementShader = R"(#version 330 core
in vec4 position;
out vec4 color;
void main()
{
    color = vec4(1.0, 0.0, 0.0, 1.0);
})";

Check if the shader compilation succeeded and if the program object linked successfully.
If the compiling of a shader succeeded can be checked by glGetShaderiv and the parameter GL_COMPILE_STATUS.
If the linking of a program was successful can be checked by glGetProgramiv and the parameter GL_LINK_STATUS.
(See the answer to this question.)


If you use a core profile OpenGL Context, the the default Vertex Array Object is not valid. Create a named VAO:

unsigned int VAO;
glCreateVertexArrays(1, &VAO);
glBindVertexArray(VAO);

unsigned int buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), vertexPositions, GL_STATIC_DRAW);

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float)*2 , 0); 

GLEW has to be initialized by glewInit(). See Initializing GLEW:

glfwMakeContextCurrent(window);
glewInit(); 
Sign up to request clarification or add additional context in comments.

5 Comments

@Bcrx It works fine for me. Just copy the shader code.
It worked!, little inattention, i'll be more careful after this, thank you for your help.
@Rabbid76 I have frequently used layout location qualifiers for vertex shaders, glsl 3.30, without any problems. Only in Visual Studio using an extension for glsl support was I presented with warning, but I just ignored it and it still worked fine. You wouldn't happen to know why that could be?
@ワイきんぐ Please read the answer: Fragment shader input layout locations qualifiers [...]. Of course vertex shader input layout qualifiers are valid in GLSL 3.30
That's weird, because I always got this warning for vertex shaders. But thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.