OpenGL 3.3 2D渲染:VAO配置不正确?

时间:2014-12-11 05:12:27

标签: c++ debugging opengl 2d shader

在添加VAO后,我似乎无法让这个OpenGL程序渲染四边形。

假设程序正确初始化且没有错误,以下是填充VAO的代码。

float quad[] = 
    {
        //verts        colors
        32.0f,  0.0f, 1.0f, 0.0f, 0.0f, // Top-left
        32.0f,  32.0f, 0.0f, 1.0f, 0.0f, // Top-right
        0.0f, 32.0f, 0.0f, 0.0f, 1.0f, // Bottom-right
        0.0f, 0.0f, 1.0f, 1.0f, 1.0f  // Bottom-left
    };

float textureCoords[] = 
    {
        0.0f, 0.0f, //x
        0.5f, 0.0f, //w
        0.5f, 0.5f, //y
        0.0f, 0.5f  //h
    };

float elements[] =
    {
        0,1,2,
        2,3,0
    };

//loadShaders compiles and links both shaders
GLuint shaders = loadShaders("vertexShader.c", "fragmentShader.c");
GLuint VAO, VBO[2], EBO;


glGenVertexArrays(1, &VAO);

glGenBuffers(2, VBO);
glGenBuffers(1, &EBO);

//bind VAO
glBindVertexArray(VAO);

glUseProgram(shaders);

//quad and color data
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(quad), quad, GL_STATIC_DRAW);
GLint quadAttrib = glGetAttribLocation(shaders, "quad");
glEnableVertexAttribArray(quadAttrib);//target 'quad' in shader
glVertexAttribPointer(quadAttrib, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), 0);
//color data
GLint colorAttrib = glGetAttribLocation(shaders, "color");
glEnableVertexAttribArray(colorAttrib);//target 'color' in shader
glVertexAttribPointer(colorAttrib, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat)));

//UV data
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(textureCoords), textureCoords, GL_STATIC_DRAW);
GLint uvAttrib = glGetAttribLocation(shaders, "uvCoords");//target 'uvCoords' in shaders 
glEnableVertexAttribArray(uvAttrib);
glVertexAttribPointer(uvAttrib, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), 0);


//TEXTURES
//laod and use textures
GLuint textures[2];
glGenTextures(2, textures);


int texWidth, texHeigth;
unsigned char *image;

//activate texture 0
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textures[0]);
image = SOIL_load_image("atlas.png", &texWidth, &texHeigth, 0, SOIL_LOAD_RGB);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texWidth, texHeigth, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
SOIL_free_image_data(image);
glUniform1i(glGetUniformLocation(shaders, "img1"), 0);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);


//element buffer data
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);

//UNIFORMS

//projection matrix
GLint projectionUniform = glGetUniformLocation(shaders, "projection");
glm::mat4 orthoProjection = glm::ortho( 0.0f, static_cast<float>(480), 0.0f, static_cast<float>(272));
glUniformMatrix4fv(projectionUniform, 1, GL_FALSE, glm::value_ptr(orthoProjection));
//model view projection
GLint modelViewUniform = glGetUniformLocation(shaders, "modelView");


//unbind VAO and current shader, the VAO remembers the bound shader
glBindVertexArray(0);
glUseProgram(0);

我假设VAO现在已经跟踪了以下内容:

  • 四元缓冲区'VBO [0]'及其对应的attribPointer'quadAttrib'到着色器中的“quad”
  • 颜色缓冲区'相同的VBO [0]'及其对应的attribPointer'colorAttrib'到着色器中的'color'
  • UV缓冲区'VBO [1]'及其对应的attribPointer'uvAttrib'到'uvCoords'的着色器
  • 当前纹理单元(0)对应于加载的纹理,并且片段着色器中的“img1”绑定及其参数
  • 与GL_ELEMENT_ARRAY_BUFFER
  • 绑定的EBO
  • 投影矩阵及其均匀
  • 模型矩阵的处理程序
  • VAO绑定时使用的着色器程序?不确定,我仍然明确使用程序中唯一的着色器程序

稍后在主循环中,如果我尝试以下操作,则不会绘制任何内容:

    // Clear the screen to black
    glClearColor(0.2f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    //draw the quad within this VAO
    glBindVertexArray(VAO);
glUseProgram(shaders);

    glm::mat4 model;

    model = glm::translate(glm::mat4(1.0f), glm::vec3(newTransX, newTransY, newTransZ));
    model = glm::scale(model, glm::vec3(newScale));

    model = glm::rotate(
        model,
        (GLfloat)clock()  / (GLfloat)CLOCKS_PER_SEC * 10000.0f,
        glm::vec3(0.0f, 0.0f, 1.0f)
    );      

// upload the uniform matrix, modelViewUniform should be already linked to the shader uniform through the VAO

    glUniformMatrix4fv(modelViewUniform, 1, GL_FALSE, glm::value_ptr(model)); 


    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

    glBindVertexArray(0);

    SDL_GL_SwapWindow(window);

顶点着色器:

    #version 330

in vec2 quad;
in vec3 color;
in vec2 uvCoords;

out vec3 Color;
out vec2 UVCoords;


uniform mat4 modelView;
uniform mat4 projection;

void main()
{
    Color = color;
    UVCoords = uvCoords;

    gl_Position = projection * modelView * vec4(quad, 0.0f, 1.0f);
}

片段着色器:

    #version 330

in vec3 Color;//not in use, simple pipeline test
in vec2 UVCoords;

out vec4 outColor;

uniform sampler2D img1;


void main()
{
    vec4 finalTexture = texture(img1, UVCoords);
    outColor = finalTexture;
} 

我做错了什么?我知道modelView和投影矩阵中的值是正确的,因为程序有效如果我从不使用VAO。

我是否认为VAO记得比实际更多?如果没有,我做错了什么?

1 个答案:

答案 0 :(得分:1)

这不可能是正确的:

float elements[] =
{
    0,1,2,
    2,3,0
};

您不能将浮点数用于顶点索引。根据您传递给glDrawElements()的类型,这应该是:

GLuint elements[] =
{
    0,1,2,
    2,3,0
};

至于VAO中跟踪的状态:不,它不会保持所有状态。它只跟踪顶点属性设置状态。从您的列表中:

  

四元缓冲区'VBO [0]'及其对应的attribPointer'quadAttrib'到着色器中的“quad”

是。更确切地说,VBO /指针与位置quadAttrib相关联,并且在VAO中跟踪该关联。您从着色器查询quadAttrib,但VAO状态不包含与着色器的任何直接关联。

  

颜色缓冲区'相同的VBO [0]'及其对应的attribPointer'colorAttrib'到着色器中的'color'

同样在这里。

  

UV着色器'VBO [1]'及其相应的attribPointer'uvAttrib'到着色器中的'uvCoords'

在这里。

  

当前纹理单元(0)对应于加载的纹理以及片段着色器中与“img1”的绑定及其参数

没有。这与顶点属性状态无关。

  

与GL_ELEMENT_ARRAY_BUFFER

绑定的EBO

  

投影矩阵及其均匀

没有。统一值是程序状态的一部分。

  

模型矩阵的处理程序

没有

  

VAO绑定时使用的着色器程序?

没有