在Opengl中从不同颜色的正方形中绘制矩形

Draw rectangle from squares of different colours in Opengl

本文关键字:正方形 绘制 Opengl 颜色      更新时间:2023-10-16

我有一个在CUDA上运行的波束成形程序,我必须在Opengl中显示波束的输出,我必须用Opengl绘制一个由24x12个小方块组成的矩形。我必须根据进行波束成形的CUDA程序的输出,用不同的颜色给每个正方形上色。我已经能够使用VBO绘制重新缠结,我使用以下结构将包含正方形顶点和每个顶点颜色的数组传递到VBO。我面临的问题的总体总结是,我无法正确地为每个正方形分配颜色。代码摘录:

struct attributes {
GLfloat coords[2]; //co-ordinates of the vertices
GLfloat color[3]; //color of the vertices
};
glGenBuffers(1, &vbo_romanis); // vbo_romanis is the VBO for drawing the frame
glBindBuffer(GL_ARRAY_BUFFER, vbo_romanis);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STREAM_DRAW);
glShadeModel (GL_SMOOTH);
glUseProgram(program);
glEnableVertexAttribArray(attribute_coord);
glEnableVertexAttribArray(attribute_color);
glBindBuffer(GL_ARRAY_BUFFER, vbo_romanis);
glVertexAttribPointer(
attribute_coord2d,   // attribute
2,                   // number of elements per vertex, here (x,y)
GL_FLOAT,            // the type of each element
GL_FALSE,            // take our values as-is
sizeof(struct attributes),  // next coord2 appears every 5 floats
0                    // offset of first element
);
glVertexAttribPointer(
attribute_color,      // attribute
3,                      // number of elements per vertex, here (r,g,b)
GL_FLOAT,               // the type of each element
GL_FALSE,               // take our values as-is
sizeof(struct attributes),  // stride
(GLvoid*) offsetof(struct attributes, color)  // offset
);
/* Push each element in buffer_vertices to the vertex shader */
glDrawArrays(GL_QUADS, 0, 4*NUM_SQRS);

因此,当我绘制阵列时,我面临两个问题:

  1. 颜色没有按我希望的方式显示。根据我所读到的关于Opengl的内容,顶点的颜色一旦指定就无法更改。但是,由于所有的正方形之间共享顶点,因此颜色可能会混乱。如果我为所有顶点指定相同的颜色,效果很好,但当我想绘制不同颜色的所有正方形时就不行了。所以,如果有人能指出我如何为每个正方形分配不同的颜色,那将非常有帮助。

  2. 如何更新每帧顶点的颜色,是否需要重新绘制整个帧,或者是否有只更新顶点颜色的方法。

我是OpenGL编程的新手,如果有任何帮助,我将不胜感激。

目前尚不清楚您的顶点数据实际是什么,但这是:

但是,由于所有的正方形之间共享顶点,因此颜色为可能搞砸了。

对我来说,这意味着你正试图对两个相邻的正方形(A-F是顶点)使用以下数据:

A---B---C
|   |   |
|   |   |
D---E---F

但是,在OpenGL中,顶点是所有属性的集合,而不仅仅是位置。这里得到的是,颜色将在正方形之间平滑插值。因此,从技术上讲,你需要将顶点B和E复制到B1/B2和E1/E2中,其中B1,E1是立方的颜色,B2,E2是直角的颜色,但坐标相同。

但是,对于您的问题,可能有一个快捷方式,以flat shading的形式,将您的vaertex着色器输出声明为flat。默认情况下,顶点着色器输出(变量)是在整个基本体上插值的。但是,将它们定义为flat将阻止插值。相反,仅一个顶点的值用于整个基本体。OpenGL使用引发顶点的顶点来定义基元的哪个顶点将是定义此类flat输出值的顶点。

命令glProvokingVertex()可用于指定要为其选择顶点的一般规则,您可以在第一个和最后一个之间进行选择。如果您巧妙地构建顶点数据,您可以为一个正方形的两个三角形共享一个顶点,该顶点将成为两个三角形的激发顶点,因此您可以仅用单元的一个角顶点的颜色定义每个"网格单元"的颜色,而无需复制顶点。

附带说明一下:您的代码中有commang glShadeModel(GL_SMOOTH);。正如您的评论所暗示的那样,当您使用可编程管道时,这是不推荐使用的,也是完全无用的。然而,从概念上讲,这与我在这里建议的平面着色方法完全相反。

我如何更新每帧顶点的颜色,我需要吗重新绘制整个框架,或者有没有方法只更新颜色仅顶点的。

OpenGL不是一个场景图库。它不记得您过去绘制过哪些对象,也不允许更改它们的属性。OpenGL是一个渲染API,所以如果你想在屏幕上显示不同的东西,你必须告诉它重新绘制。如果您计划在不更改正方形本身位置的情况下更新颜色,则最好使用两个非交错VBO来分割颜色和位置数据。这样,就可以在一个缓冲区中静态地放置位置,而在另一个缓冲区时只流式传输颜色更新。