c++ - OpenGL 3.3 2D 渲染 : VAO not properly configured?

标签 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 现在已经跟踪了以下内容:

  • quad buffer 'VBO[0]' 及其对应的 attribPointer 'quadAttrib' 到着色器中的“quad”
  • 颜色缓冲区'same VBO[0]'及其对应的属性指针'colorAttrib'指向着色器中的'color'
  • 着色器中的 UV 缓冲区 'VBO[1]' 及其对应的属性指针 'uvAttrib' 到 'uvCoords'
  • 当前纹理单元(0)对应于加载的纹理和片段着色器中“img1”的绑定(bind)及其参数
  • 绑定(bind)到 GL_ELEMENT_ARRAY_BUFFER 的 EBO
  • 投影矩阵及其uniform
  • 模型矩阵的处理程序
  • 绑定(bind) VAO 时正在使用的着色器程序?不确定,我还是在程序中明确使用了唯一的shader程序

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

    // 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 记住的比实际记住的多?如果不是,我做错了什么?

最佳答案

这不可能是对的:

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

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

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

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

The quad buffer 'VBO[0]' and its corresponding attribPointer 'quadAttrib' to "quad" in the shader

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

The color buffer 'same VBO[0]' and its corresponding attribPointer 'colorAttrib' to 'color' in shader

这里也一样。

The UV buffer 'VBO[1]' and its corresponding attribPointer 'uvAttrib' to 'uvCoords' in shader

还有这里。

That the current texture unit (0) corresponds to the loaded texture and the bind to "img1" in the fragment shader as well as its parameters

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

The EBO that is bounded to GL_ELEMENT_ARRAY_BUFFER

是的。

The projection matrix and its uniform

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

The handler to the model matrix

没有。

The shader program that was in use while the VAO was bound?

没有。

关于c++ - OpenGL 3.3 2D 渲染 : VAO not properly configured?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27415772/

相关文章:

c++ - 数据库表-数据结构设计c++

c# - 错误处理超过重试次数 10

javascript - 无法让 Node 调试工作

java - LWJGL 旋转 : Won't rotate

java - 创建一个 List<Point3D> ,添加点并使用 glDrawArrays 进行绘制

c++ - static_cast 转换构造函数 vs 转换运算符

c++ - 如何获得 "hardware time"

c# - 如何查看 .NET 应用程序的堆栈跟踪

java - 使用 lwjgl 调整窗口内容的大小

c++ - 与以值作为参数的普通函数相比,仿函数有何独特之处