【问题标题】:incorrect interpolation, opengl indexed vbo, vertex struct and glsl不正确的插值、opengl 索引 vbo、顶点结构和 glsl
【发布时间】:2013-11-16 08:58:01
【问题描述】:

已编辑:添加到问题底部,创建_vertices_indices 成员。 (并在渲染函数中添加了对glEnableVertexAttribArray 的缺失调用)。

我有一个问题可能归结为我误解了一些概念,所以写在这里希望能纠正它。

我在使用看似相当简单的着色器时遇到了问题,或者我猜问题出在传输到着色器的数据上。

基本上我只需要尝试一个三角形来完成这项工作,但我仍然得到了一个对我来说似乎很意外的结果。

我有 opengl 代码并将其与着色器源一起带到这里,希望有人能指出我正确的方向。

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

顶点着色器:

#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;
}

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

void main () {
    fragment_color = vertex_color;
}

预期结果:

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

我得到的似乎是一个带有纯色的实心三角形,它插值在一些倾向于淡绿色的值之间。

因此,有了这些信息,我相信我们可以非常确定问题不在于着色器,而在于我们放入其中的数据,对吧?

所以转到数据..

顶点结构

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

我有点喜欢这样的布局,如果我没有遗漏一些基本的东西,它应该是刚性的,我基本上使用联合作为一种语法糖,所以我可以以不同的方式访问数据,但 float x, y 应该在内存方面与position[2] 相同,所以我不认为数据类型是罪魁祸首。留下我认为应该归咎的opengl位。

我有一个名为 GUI_Element 的类(或者实际上是 gui::element,但我将不使用命名空间,因为我认为它更易于阅读和理解)。

类的声明如下所示:

gui_element.h

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_indices 数组,我已经在不同的执行点检查了它们,它们确实包含具有红色、蓝色和绿色顶点的三角形的正确数据,以及正确的索引。

实现 create_buffers()

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 函数的某个地方,也许是glVertexAttribPointer 的东西?似乎最有可能,也许我正在考虑偏移量,并以错误的方式填充?

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

创建 _vertices 和 _indices 在构造函数中,我这样做是为了填写 _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;

但我确实意识到我确实早点撒谎了,_indices[2] 实际上被设置为不同的顶点。为什么它看起来是绿色的等等。当我纠正它时(根据上面的布局,我得到一个紫色的三角形(在另一个角落,由于错误的顶点实际上是构成四边形的第四个顶点,它的颜色为 1,1,1,1(白色) )。

【问题讨论】:

  • 我知道您检查过是否使用正确的数据填充(本地)数组;但请仍然向我们展示创建它的代码(或调试打印)。它仍然可能是错误的。
  • 我绝对会用信息更新原始问题。
  • 啊,我没有看到任何glEnableVertexAttribArray。不确定这是否需要,因为我总是对不同的 GL 版本以及如何为 GL 提供足够的属性数据信息感到困惑(有一些不同的方法可以做到)。但是尝试为这两个属性添加glEnableVertexAttribArray(program->attribute_index("..."))...
  • 另外,颜色好像是(0.5, 1.0, 0.5, 1.0)。这些数字有告诉你什么吗?也许它们是缓冲区中其他一些数据的一部分(所以指向它们时可能存在一些偏移错误)?
  • @leemes 会让你知道结果如何......也许这可能是课程......会立即尝试:)

标签: c++ opengl glsl


【解决方案1】:

事实证明...

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

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

很抱歉将您的时间浪费在阅读的任何人身上,感谢您尝试帮助那些阅读的人!

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    • 2021-03-05
    • 1970-01-01
    • 2010-11-02
    • 2013-09-14
    • 2012-05-27
    • 1970-01-01
    相关资源
    最近更新 更多