OpenGL,一个不起作用的非常基本的着色器

bbuxkriu  于 2022-09-26  发布在  其他
关注(0)|答案(2)|浏览(169)

我正在通过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)

4nkexdtk

4nkexdtk1#

正如@Ripi2指出的,您的glBufferData()调用虽然不完全错误(它们超过请求缓冲区空间),但也不完全正确。由于您使用的是原始数组,因此可以使用直接的sizeof(<arrayname>)作为size参数:

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

我怀疑你的(未知的)着色器加载程序可能不可靠,因为我的个人着色器工作得很好。

总而言之:


# 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;
}
scyqe7ek

scyqe7ek2#

需要在编译和链接着色器之后调用glUseProgram()。以下是一段示例代码:

int main()
{
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);

    GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL", NULL, NULL);
    if (window == NULL)
    {
        cout << "Failed to create GLFW window" << endl;
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);

    // Initialize GLAD
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        cout << "Failed to initialize GLAD" << endl;
        return -1;
    }
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glViewport(0, 0, 800, 600);

    float TriangleVertices[] = {
        -0.3f, -0.3f, 0.0f,
         0.0f,  0.3f, 0.0f,
         0.3f,  -0.3f, 0.0f
    };

    unsigned int VBO, VAO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    //BindVertexArray for modifying it
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(TriangleVertices), TriangleVertices, GL_STATIC_DRAW);
    glBindVertexArray(VAO);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    const char* vertexShaderSource = "n"
        "layout (location = 0) in vec3 aPos;n"
            "void main()n"
            "{n"
            "   gl_Position = vec4(aPos, 1.0);n"
            "}0";

    unsigned int vertexShader;
    vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vertexShader);

    const char* fragmentShaderSource = "n"
        "out vec4 FragColor; n"
        "void main()n"
        "{n"
        "FragColor = vec4(1.0f, 0.7f, 0.5f, 1.0f); n"
        "} n";

    unsigned int fragmentShader;
    fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fragmentShader);

    unsigned int shaderProgram;
    shaderProgram = glCreateProgram();

    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);
    glUseProgram(shaderProgram);
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);

    while (!glfwWindowShouldClose(window))
    {

        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        //// draw triangle using the data from the VAO

        //glUseProgram(shaderProgram);
        glBindVertexArray(VAO);

        glDrawArrays(GL_TRIANGLES, 0, 3);

        // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
        // -------------------------------------------------------------------------------
        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);
    glDeleteProgram(shaderProgram);
    glfwTerminate();
    return 0;

}

相关问题