簡體   English   中英

glDrawArrays意外行為

[英]glDrawArrays unexpected behavior

我花了很多時間使用openGL的固定管道,最近我開始學習可編程管道。 我知道我的畫家,着色器類不是問題,因為它們使用固定功能管道的東西。 我似乎無法讓glDrawArrays為我的生活工作。

我不確定我的錯誤是在我如何設置頂點緩沖區對象,在我的着色器或其他地方。 我也調試了我的代碼並在整個顯示函數中設置了斷點,它似乎永遠不會超過glDrawArrays(),(它在glDrawArrays上遇到一個斷點,但之后沒有命中,不知道為什么。)

輸出的只是一個白色的屏幕,沒有別的。

繼承我的代碼:

float   vertices[] = {   0.75,  0.75, 0.0, 1.0,
                         0.75, -0.75, 0.0, 1.0,
                        -0.75, -0.75, 0.0, 1.0 };

GLuint  vertexBufferObject;
GLuint  positionLocation;
GLuint  vaoObject;

void initVertexBuffer(GLuint& vertexBufferObject, float* vertexData, unsigned int size, GLenum GL_DRAW_TYPE)
{
    glGenBuffers(1, &vertexBufferObject);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
    glBufferData(GL_ARRAY_BUFFER, size, vertexData, GL_DRAW_TYPE);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

void main(int argc, char* argv[])
{

    painter.initEngine(argc, argv, 500, 500, 0, 0, "2D3D");
    painter.initGlutFuncs(display, resize, Input::MouseButtonClick,   Input::MouseDrag, keyboard);

    defaultShader.init("default.vert", "default.frag"); 
    defaultShader.link();

    initVertexBuffer(vertexBufferObject, vertices, sizeof(vertices), GL_STATIC_DRAW);
    glGenVertexArrays(1, &vaoObject);
    glBindVertexArray(vaoObject);
    positionLocation = glGetAttribLocation(defaultShader.id(), "position");

    painter.startMainLoop();
}

void display()
{
    painter.clearDisplay();

    defaultShader.bind();

    glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
    glEnableVertexAttribArray(positionLocation);
    glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, 0);
    std::cout << Framework::glErrorCheck() << std::endl;

    glDrawArrays(GL_TRIANGLES, 0, 3);

    glDisableVertexAttribArray(positionLocation);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    defaultShader.unbind();

    painter.flushAndSwapBuffers();
}

頂點着色器:

#version 140

in vec4 position; 

void main()
{   
    gl_Position = position; 
}

片段着色器:

#version 140

out vec4 outColor;

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

編輯:代碼更新了Joey Dewd,keltar和genpfault的建議。 我不再掛在glDrawArrays,即不是白色的屏幕,我得到一個黑屏。 這讓我覺得我的緩沖區仍然沒有正確設置。 或者可能,我遺漏了頂點數組緩沖區初始化所需的其他內容(vaoObject)?

void initVertexBuffer(GLuint vertexBufferObject, float* vertexData, GLenum GL_DRAW_TYPE)
{
    glGenBuffers(1, &vertexBufferObject);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_DRAW_TYPE);
                                  ^^^^^^^^^^^^^^^^^^ nnnnope
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

在這種情況下, sizeof(vertexData)並不像你希望的那樣

它可能是4或8,具體取決於您的64位編輯。 即,指向浮點的指針的sizeof 不是 sizeof(vertices)

您需要傳入一個單獨的大小參數:

void initVertexBuffer(GLuint& vertexBufferObject, float* vertexData, unsigned int size, GLenum GL_DRAW_TYPE)
{
    glGenBuffers(1, &vertexBufferObject);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
    glBufferData(GL_ARRAY_BUFFER, size, vertexData, GL_DRAW_TYPE);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

...

void main(int argc, char* argv[])
{
    ...
    initVertexBuffer(vertexBufferObject, vertices, sizeof(vertices), GL_STATIC_DRAW);
    ...    
}

或者像std::vector這樣的連續(重要!)標准容器:

template< typename Container >
void initVertexBuffer(GLuint& vertexBufferObject, const Container& vertexData, GLenum GL_DRAW_TYPE)
{
    glGenBuffers(1, &vertexBufferObject);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
    glBufferData(GL_ARRAY_BUFFER, vertexData.size() * sizeof( typename Container::value_type ), &vertexData[0], GL_DRAW_TYPE);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

完整示例:

#include <GL/glew.h>
#include <GL/freeglut.h>

#include <iostream>
#include <vector>
using namespace std;

struct Program
{
    static GLuint Load( const char* vert, const char* geom, const char* frag )
    {
        GLuint prog = glCreateProgram();
        if( vert ) AttachShader( prog, GL_VERTEX_SHADER, vert );
        if( geom ) AttachShader( prog, GL_GEOMETRY_SHADER, geom );
        if( frag ) AttachShader( prog, GL_FRAGMENT_SHADER, frag );
        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( -1 );
    }

    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


void initVertexBuffer(GLuint& vertexBufferObject, float* vertexData, unsigned int size, GLenum GL_DRAW_TYPE)
{
    glGenBuffers(1, &vertexBufferObject);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
    glBufferData(GL_ARRAY_BUFFER, size, vertexData, GL_DRAW_TYPE);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

GLuint prog;
GLuint vaoObject;
void init()
{
    const char* vert = GLSL
    (
        140,
        in vec4 position; 
        void main()
        {   
            gl_Position = position; 
        }
    );

    const char* frag = GLSL
    (
        140,
        out vec4 outColor;
        void main()
        {
            outColor = vec4(1.0, 0.0, 1.0, 1.0);
        }
    );

    prog = Program::Load( vert, NULL, frag );
    glUseProgram( prog );

    glGenVertexArrays(1, &vaoObject);
    glBindVertexArray(vaoObject);

    float vertices[] = 
    {   
        0.75,  0.75, 0.0, 1.0,
        0.75, -0.75, 0.0, 1.0,
        -0.75, -0.75, 0.0, 1.0 
    };
    GLuint vertexBufferObject;
    initVertexBuffer(vertexBufferObject, vertices, sizeof(vertices), GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);

    GLuint positionLocation = glGetAttribLocation(prog, "position");
    glEnableVertexAttribArray(positionLocation);
    glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, 0);
}

void display()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glUseProgram( prog );
    glBindVertexArray(vaoObject);
    glDrawArrays(GL_TRIANGLES, 0, 3);

    glutSwapBuffers();
}

int main(int argc, char **argv)
{
    glutInit( &argc, argv );
    glutInitContextVersion( 3, 1 );
    glutInitContextProfile( GLUT_COMPATIBILITY_PROFILE );
    glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
    glutInitWindowSize( 600, 600 );
    glutCreateWindow( "GLUT" );

    glewExperimental = GL_TRUE;
    glewInit();

    init();

    glutDisplayFunc( display );
    glutMainLoop();
    return 0;
}
glGenBuffers(1, &vertexBufferObject);

將頂點緩沖區的id保存在局部變量中。 在繪制調用不再可用,此值修改全局vertexBufferObject (但緩沖區仍然存在-你只是失去了它的ID,不能再使用它甚至不能消滅它)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM