Open GL ES 2.0为什么我的VBO不起作用?

时间:2019-03-03 18:04:28

标签: c++ opengl-es drawing opengl-es-2.0 vbo

嘿,我正在尝试通过vbo在OpenGL中绘制带有2个三角形的简单四边形。 但是,我已经多次查看了我的代码,但看不到缺少的内容。 我不是Open GL专家,代码在没有任何缓冲区的情况下工作正常,但是当我切换到VBO时,我什么也看不到。 OpenGL也没有提供任何有用的错误。

Image::Image(Graphics * GFX)
{

    glm::vec2 corners[2];
    corners[0] = glm::vec2(0, 0);
    corners[1] = glm::vec2(1, 1);

    vertices = new GLfloat[30]
    {
        //Vertices XYZ                      TexCoord X,Y
        corners[0].x, corners[0].y, 0.0f,   0,0,
        corners[0].x, corners[1].y, 0.0f,   0,1,
        corners[1].x, corners[0].y, 0.0f,   1,0,

        corners[1].x,corners[1].y,0.0f,     1,1,
        corners[0].x, corners[1].y,0.0f,    0,1,
        corners[1].x, corners[0].y, 0.0f,   1,0
    };

    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    //Setting up some stuff
    const char *vertexShaderSource =
        "attribute vec4 vPosition; \n"
        "attribute vec2 vTexCoord; \n"
        "void main() \n"
        "{ \n"
        " gl_Position = vPosition; \n"
        "} \n";
    const char *fragmentShaderSource =
        "precision mediump float; \n"
        "void main() \n"
        "{ \n"
        " gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); \n"
        "} \n";


    // Load and compile the vertex/fragment shaders
    vertexShader = GFX->LoadShader(GL_VERTEX_SHADER, (const char*)vertexShaderSource);
    fragmentShader = GFX->LoadShader(GL_FRAGMENT_SHADER, (const char*)fragmentShaderSource);

    // Create the program object    
    programObject = glCreateProgram();


    // now we have the V and F shaders  attach them to the progam object
    glAttachShader(programObject, vertexShader);
    glAttachShader(programObject, fragmentShader);

    // Link the program
    glLinkProgram(programObject);
    // Check the link status

    // Link the program
    GLint AreTheylinked;
    glGetProgramiv(programObject, GL_LINK_STATUS, &AreTheylinked);
    if (!AreTheylinked)
    {
        GLint RetinfoLen = 0;
        // check and report any errors
        glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &RetinfoLen);
        if (RetinfoLen > 1)
        {
            GLchar* infoLog = (GLchar*)malloc(sizeof(char) * RetinfoLen);
            glGetProgramInfoLog(programObject, RetinfoLen, NULL, infoLog);
            fprintf(stderr, "Error linking program:\n%s\n", infoLog);
            free(infoLog);
        }
        glDeleteProgram(programObject);
    }

    positionLocation = glGetAttribLocation(programObject, "vPosition");
    textureCoordLocation = glGetAttribLocation(programObject, "vTexCoord");

    if (glGetError() == GL_NO_ERROR) {}
    else
        printf("Init failed!\n");
    //End setting up

}

Image::~Image()
{
}

void Image::Draw()
{
    std::cout << "Calling Draw on Image" << std::endl;
    glUseProgram(programObject);
    glEnable(GL_DEPTH_TEST);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);

    GLsizei stride = (5) * sizeof(GLfloat);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, stride, 0);
    glEnableVertexAttribArray(0);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    if (glGetError() != GL_NO_ERROR)
    {
        printf("UI Draw error\n");
    }
    glDisableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

}

以及如何加载着色器:

GLuint Graphics::LoadShader(GLenum type, const char *shaderSrc)
{
    // 1st create the shader object
    GLuint TheShader = glCreateShader(type);

    if (TheShader == 0) return FALSE; // can't allocate so stop.

// pass the shader source then compile it
    glShaderSource(TheShader, 1, &shaderSrc, NULL);
    glCompileShader(TheShader);

    GLint  IsItCompiled;

    // After the compile we need to check the status and report any errors
    glGetShaderiv(TheShader, GL_COMPILE_STATUS, &IsItCompiled);
    if (!IsItCompiled)
    {
        GLint RetinfoLen = 0;
        glGetShaderiv(TheShader, GL_INFO_LOG_LENGTH, &RetinfoLen);
        if (RetinfoLen > 1)
        { // standard output for errors
            char* infoLog = (char*)malloc(sizeof(char) * RetinfoLen);
            glGetShaderInfoLog(TheShader, RetinfoLen, NULL, infoLog);
            fprintf(stderr, "Error compiling this shader:\n%s\n", infoLog);
            free(infoLog);
        }
        glDeleteShader(TheShader);
        return FALSE;
    }
    return TheShader;
}

它在没有缓冲区的情况下可以正常工作,并使用以下命令看到了白色正方形:

glVertexAttribPointer(0, 6, GL_FLOAT, GL_FALSE, 0, vertices);

但是现在我想通过VBO向我的四边形添加纹理坐标,但是什么也没显示。

Smoothy101

1 个答案:

答案 0 :(得分:0)

您的缓冲区创建看起来很好-问题是您的属性指针设置。您已经添加了纹理坐标,该纹理坐标已更改了每个顶点的数据布局,但尚未在代码中进行处理。

您需要这样的东西:

glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, stride, 0);
glVertexAttribPointer(textureCoordLocation, 2, GL_FLOAT, GL_FALSE, stride, 8);

...不是这个

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, stride, 0);