不正确的插值,opengl索引的vbo,顶点结构和glsl

时间:2013-11-15 23:20:34

标签: c++ opengl glsl

已修改:已添加到问题的底部,即_vertices_indices成员的创建。 (并在渲染功能中添加了对glEnableVertexAttribArray的遗失调用)。

我有一个问题,可能会归结为我误解了一些概念,所以写在这里希望能够理顺这一点。

我遇到的问题似乎是一个相当简单的着色器,或者我猜测问题在于传输到着色器的数据。

基本上我是尝试使用一个三角形来完成这项工作,而且我得到的结果对我来说似乎很意外。

我有opengl-code并将它与着色器源一起带到这里,希望有人可以指出我正确的方向。

首先,让我们从着色器开始,因为它们非常简单。

顶点着色器:

#version 330
in vec2 vertex_position;
in vec4 color;

smooth out vec4 vertex_color;

void main () {
    gl_Position = vec4(vertex_position, 0.0, 1.0);
    vertex_color = color;
}

片段着色器:     #version 330     在vec4 vertex_color中平滑;     out vec4 fragment_color;

void main () {
    fragment_color = vertex_color;
}

预期结果:

我的期望是,如果我发送一个顶点颜色为[1,0,0], [0,1,0], [0,0,1]的三角形,它会给我一个三角形,从红色到蓝色插补,从红色到绿色(如果有意义的话,这是很常见的例如我相信人们知道会发生什么?)

我所得到的似乎是一个带有纯色的填充三角形,在一些倾向于淡绿色的值之间进行插值。

Triangle rendered with this shader 所以有了这些信息,我相信我们可以非常肯定问题不是着色器,而是我们放在那里的数据,对吗?

所以转向数据..

顶点结构

typedef struct _gui_vertex {
    union {
        struct {float x, y;};
        float position[2];
    };
    union {
        struct {float r, g, b, a;};
        float color[4];
    };
};

我有点像这样的布局,如果我没有遗漏一些基本的东西,它应该是严格的,我使用union基本上作为一种语法糖,所以我可以以不同的方式访问数据,但是{{1}应该在内存方面与float x, y相同,所以我认为数据类型不应该受到责备。离开我实际上认为应该责怪的opengl位。

我有一个名为position[2]的类(或者实际上是gui :: element,但我会将命名空间排除在外,因为我觉得它更容易阅读和理解)。

类的声明看起来像这样:

gui_element.h

GUI_Element

对于实现,我将首先查看class GUI_Element { public: void render(); private: void create_buffers(); gui_vertex _vertices[4]; GLuint _indices[4]; GLuint _vertex_buffer; GLuint _index_buffer; }; 函数,然后是create_buffers();函数。假设数据已分配给render_vertices数组,我已在各个执行点检查它们,并且它们在契约中包含具有红色,蓝色和绿色顶点的三角形的正确数据,以及正确的指数。

实施create_buffers()

_indices

在渲染函数上,我会在这里引用它时尽量保持尽可能接近我的实现,但我已经“简化了它”,因为它包含了对包装器的依赖性以处理属性和喜欢( shader-communication)我非常肯定包装器“有效”,但我可能会发现有问题,如果我发布的代码看起来是正确的,我可以深入了解该实现,但我相信如果我更好看的话将代码保持在最低限度。

实施渲染()

glGenBuffers (1, &_vertex_buffer);
glBindBuffer (GL_ARRAY_BUFFER, _vertex_buffer);
    glBufferData(
        GL_ARRAY_BUFFER,
        sizeof(tehengine::gui_vertex)*4,
        _vertices,
        GL_STATIC_DRAW
    );

glGenBuffers (1, &_index_buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _index_buffer);
glBufferData(
    GL_ELEMENT_ARRAY_BUFFER,
    sizeof(GLuint)*4,
    _indices,
    GL_STATIC_DRAW
);

所以就是这样,在实现中,GLShaderProgram *program; // my shader-wrapper, basically keep track of attribs, and the program along with loading, compiling and linking shaders. program->use(); glBindBuffer (GL_ARRAY_BUFFER, _vertex_buffer); glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, _index_buffer); glVertexAttribPointer ( program->attribute_index("vertex_position"), 2, GL_FLOAT, GL_FALSE, sizeof(gui_vertex), (const GLvoid *) offsetof(gui_vertex, position) ); glVertexAttribPointer ( program->attribute_index("color"), 4, GL_FLOAT, GL_FALSE, sizeof(gui_vertex), (const GLvoid *) offsetof(gui_vertex, color) ); glEnableVertexAttribArray (program->attribute_index("vertex_position")); glEnableVertexAttribArray (program->attribute_index("color")); glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, (void *)0); // disable stuff, left out for readability. 函数使用program->attribute_index将索引映射到属性,使用哈希表来跟踪它们,没有什么真正的魔力。渲染的“设置”非常简单,我正在做一个没有深度缓冲的正交,并且对此没什么好说的。

可能错误位于glGetAttribLocation函数和render函数中的某个位置?似乎最有可能,也许我正在考虑抵消,并采取错误的方式?

无论如何,我很感谢您花时间看这个,我可能会补充一点,我希望它能与glsl 3.30一起使用,因为它是我的显卡可以集合的(或至少它是受支持的版本)报告)。

创建_vertices和_indices 在构造函数中,我这样做是为了填写glVertexAttribPointer_vertices

的数据
_indices

我确实知道我早先做了一点谎言,_vertices[0] = { {{-50.0f, -50.0f}}, {{1.0f, 0.0f, 0.0f, 1.0f}} }; _vertices[1] = { {{ 50.0f, -50.0f}}, {{0.0f, 1.0f, 0.0f, 1.0f}} }; _vertices[2] = { {{ 50.0f, 50.0f}}, {{0.0f, 0.0f, 1.0f, 1.0f}} }; _indices[0] = 0; _indices[1] = 1; _indices[2] = 2; 实际设置为不同的顶点。为什么它看起来像绿色等等。当我纠正它时(根据上面的布局我得到一个紫色的三角形(在另一个角落,因为错误的顶点实际上是构成四边形的第四个顶点,它有颜色1,1,1,1(白色) )。

1 个答案:

答案 0 :(得分:1)

事实证明......

我只是“愚蠢”..一切都工作得很好,我确实看到一个内插的图像,这一切都是正确的,但我没有看到太多 - -

只是一点点,因为对于两个轴,ortho的坐标系似乎是[-1,1]。我画了我的三角形,认为它是[-50,50](在两个轴上),所以我看到了一个大小超过五十个插值三角形的部分。

很抱歉浪费你的时间给任何人阅读,并感谢你们试图帮助那些做过的人!

(即如果我绘制一个适合视口内部的三角形,它确实有效)