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

标签 c++ opengl glsl

编辑:添加到问题的底部,创建了_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;
}

片段着色器:
#version 330
在vec4 vertex_color中平滑;
vec4fragment_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,但是我将 namespace 排除在外了,因为我认为它更易于阅读和理解)。

类的声明如下所示:

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
);

在render函数上,在这里引用它时,我将尝试使其与实现尽可能接近,但由于它包含用于处理属性等的包装器(着色器通信),因此我对其进行了“简化”。 )我可以肯定包装器是“有效的”,但是对于那里出现问题的可能性是开放的,如果我发布的代码似乎正确,我可以更深入地实现该实现,但是我相信如果保留代码,阅读起来会更好最小。

实现render()
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(白色) )。

最佳答案

事实证明...

我只是个“愚蠢”。.一直都很好,我确实看到了一张插值图像,这一切都是正确的,但是我没看到太多-_-

正交的坐标系似乎对于两个轴都是[-1,1],只是一点点。我画了三角形,以为它是[-50,50](在两个轴上),所以我看到了一个内插三角形的部分尺寸超过五十。

对不起,浪费您的时间给任何阅读者,并感谢您尝试帮助所做的人!

(即,如果我绘制一个适合视口内部的三角形,它将起作用)

关于c++ - 不正确的插值,opengl索引的vbo,顶点结构和glsl,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20012360/

相关文章:

c++ - InternetReadFile 填充缓冲区,但返回读取的零字节

c++ - 需要帮助构建正则表达式模式

c++ - Mac 上的 OpenGL GLSL 着色器无法编译

java - 3D模型无法翻译

c++ - 全向阴影贴图

algorithm - GLSL 快速屏幕模式

c++ - 用于 *NIX C++ 的 SQL API

c++ - OpenCV drawCircle 并在圆线上绘制矩形

c++ - 在 wxGLCanvas 上调整大小之前无法初始化着色器

GLSL:确定向量是否不为零