OpenGL,一个非常基本的着色器无法正常工作

时间:2018-04-10 18:10:32

标签: c++ opengl shader glfw

我正在通过TheCherno Project学习OpenGL。 下面的代码来自那里,我忠实地为我的学习目的重现它。我还添加了顶点和片段着色器。

我的问题在于我的方形输出我根本看不到颜色,我猜它是使用默认着色器。

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

if (glewInit() != GLEW_OK)
    std::cout << "ERROR GLEW" << std::endl;

std::cout << glGetString(GL_VERSION) << std::endl;

float positions[] = {
        -0.5f,-0.5f,    //0
         0.5f, -0.5f,   //1
         0.5f, 0.5f,    //2
        -0.5f, 0.5f     //3
};

unsigned int indices[] = {
        0, 1, 2,
        2, 3, 0
};

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


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


unsigned int ibo;
glGenBuffers(1, &ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(unsigned int), indices, GL_STATIC_DRAW);

ShaderSourceProgram shader = ParseShader("res/shaders/Basic.shader");
//std::cout << "VERTEX" << std::endl;
//std::cout << shader.VertexShader << std::endl;
unsigned int shaderProgram = CreateShader(shader.VertexShader, shader.FragmentShader);
glUseProgram(shaderProgram);

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

    //glDrawArrays(GL_TRIANGLES, 0, 6);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);

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

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

glDeleteProgram(shaderProgram);

glfwTerminate();
return 0;
}

着色器:

#shader vertex
#version 330 core
layout(location = 0)in vec4 position;

void main()
{
    gl_Position = position;
};

#shader fragment
#version 330 core
out vec4 color;

void main()
{
    color = vec4(0.0,1.0,0.0,1.0);
};

编辑: Please click here for the entire project (github)

1 个答案:

答案 0 :(得分:0)

正如@ Ripi2指出你的glBufferData()来电,虽然并非完全错误(他们 over 请求缓冲区空​​间),但也不完全正确。由于您使用的是原始数组,因此您可以使用sizeof(<arrayname>)直接size参数:

glBufferData( GL_ARRAY_BUFFER, sizeof( positions ), positions, GL_STATIC_DRAW );
...
glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof( indices ), indices, GL_STATIC_DRAW );

我怀疑你的(未知)着色器加载器可能会因为我的个人工作正常而感到不稳定。

所有在一起:

screenshot of green square

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

#include <iostream>
#include <cstdarg>

struct Program
{
    static GLuint Load( const char* shader, ... )
    {
        GLuint prog = glCreateProgram();
        va_list args;
        va_start( args, shader );
        while( shader )
        {
            const GLenum type = va_arg( args, GLenum );
            AttachShader( prog, type, shader );
            shader = va_arg( args, const char* );
        }
        va_end( args );
        glLinkProgram( prog );
        CheckStatus( prog );
        return prog;
    }

private:
    static void CheckStatus( GLuint obj )
    {
        GLint status = GL_FALSE;
        if( glIsShader(obj) ) glGetShaderiv( obj, GL_COMPILE_STATUS, &status );
        if( glIsProgram(obj) ) glGetProgramiv( obj, GL_LINK_STATUS, &status );
        if( status == GL_TRUE ) return;
        GLchar log[ 1 << 15 ] = { 0 };
        if( glIsShader(obj) ) glGetShaderInfoLog( obj, sizeof(log), NULL, log );
        if( glIsProgram(obj) ) glGetProgramInfoLog( obj, sizeof(log), NULL, log );
        std::cerr << log << std::endl;
        exit( EXIT_FAILURE );
    }

    static void AttachShader( GLuint program, GLenum type, const char* src )
    {
        GLuint shader = glCreateShader( type );
        glShaderSource( shader, 1, &src, NULL );
        glCompileShader( shader );
        CheckStatus( shader );
        glAttachShader( program, shader );
        glDeleteShader( shader );
    }
};

#define GLSL(version, shader) "#version " #version "\n" #shader

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

    if( glewInit() != GLEW_OK )
        std::cout << "ERROR GLEW" << std::endl;

    std::cout << glGetString( GL_VERSION ) << std::endl;

    float positions[] = {
        -0.5f,-0.5f,    //0
        0.5f, -0.5f,   //1
        0.5f, 0.5f,    //2
        -0.5f, 0.5f     //3
    };

    unsigned int indices[] = {
        0, 1, 2,
        2, 3, 0
    };

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

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

    unsigned int ibo;
    glGenBuffers( 1, &ibo );
    glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, ibo );
    glBufferData( GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof( unsigned int ), indices, GL_STATIC_DRAW );

    const char* vert = GLSL
    (
        330 core,
        layout(location = 0)in vec4 position;

        void main()
        {
            gl_Position = position;
        };
    );

    const char* frag = GLSL
    (
        330 core,
        out vec4 color;

        void main()
        {
            color = vec4(0.0,1.0,0.0,1.0);
        };
    );

    unsigned int shaderProgram = Program::Load
        (
        vert, GL_VERTEX_SHADER,
        frag, GL_FRAGMENT_SHADER,
        NULL
        );
    glUseProgram( shaderProgram );

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

        //glDrawArrays(GL_TRIANGLES, 0, 6);
        glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr );

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

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

    glDeleteProgram( shaderProgram );

    glfwTerminate();
    return 0;
}