这可能又是一个愚蠢的问题,也许这是我所遗漏的一些非常明显的东西,但我无法让glMultiDrawArrays在OpenGL4中工作。
我找到了很多这样的解释:
for (int i = 0; i < numarrays; i++)
glDrawArrays (GL_TRIANGLE_FAN, arrayfirsts[i], arraycounts[i]);
类似于:
glMultiDrawArrays (GL_TRIANGLE_FAN, arrayfirsts, arraycounts, numarrays);
我对这个解释完全没问题。但是,到目前为止我无法找到的是 - 当我想使用glMultiDrawArrays时,如何进行缓冲?
目前我的代码是这样的:
UINT vertssize = FloatsPerVertex * 4;
UINT texsize = TexCoords2D * 4;
VertsBuf[0] = RFX2*Z*(X - FX2);
VertsBuf[1] = RFY2*Z*(Y - FY2);
VertsBuf[2] = Z;
VertsBuf[3] = (U)*TexInfo[0].UMult;
VertsBuf[4] = (V)*TexInfo[0].VMult;
VertsBuf[5] = RFX2*Z*(X + XL - FX2);
VertsBuf[6] = RFY2*Z*(Y - FY2);
VertsBuf[7] = Z;
VertsBuf[8] = (U + UL)*TexInfo[0].UMult;
VertsBuf[9] = (V)*TexInfo[0].VMult;
VertsBuf[10] = RFX2*Z*(X + XL - FX2);
VertsBuf[11] = RFY2*Z*(Y + YL - FY2);
VertsBuf[12] = Z;
VertsBuf[13] = (U + UL)*TexInfo[0].UMult;
VertsBuf[14] = (V + VL)*TexInfo[0].VMult;
VertsBuf[15] = RFX2*Z*(X - FX2);
VertsBuf[16] = RFY2*Z*(Y + YL - FY2);
VertsBuf[17] = Z;
VertsBuf[18] = (U)*TexInfo[0].UMult;
VertsBuf[19] = (V + VL)*TexInfo[0].VMult;
DrawVerts(DrawVertsBuf, vertssize, texsize, Color);
使用DrawVerts:
void DrawVerts(FLOAT* verts, UINT vertsize, UINT texsize, vec4f DrawColor)
{
UINT TotalSize = vertsize + texsize;
UINT stride = (sizeof(float) * FloatsPerVertex) + (sizeof(float) * TexCoords2D);
UINT vertoffset = (sizeof(float) * FloatsPerVertex);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * TotalSize, verts, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(VERTEX_COORD_ATTRIB);
glEnableVertexAttribArray(TEXTURE_COORD_ATTRIB);
glVertexAttribPointer(VERTEX_COORD_ATTRIB, 3, GL_FLOAT, GL_FALSE, stride, 0);
glVertexAttribPointer(TEXTURE_COORD_ATTRIB, 2, GL_FLOAT, GL_FALSE, stride, (void*)vertoffset);
glUniform4f(DrawTileDrawColor, DrawColor.X, DrawColor.Y, DrawColor.Z, DrawColor.W);
// Draw
glDrawArrays(GL_TRIANGLE_FAN, 0, vertsize / FloatsPerVertex);
// Clean up
glDisableVertexAttribArray(VERTEX_COORD_ATTRIB);
glDisableVertexAttribArray(TEXTURE_COORD_ATTRIB);
}
为了成功调用glMultiDrawArrays,我如何更改它?当然我必须添加一个计数器,这是显而易见的。我也尝试了一些,但到目前为止只是崩溃或没有绘图。教程和示例我找到了备用缓冲部分或者它们用于OpenGL1.x,我理解转移到OpenGL4。 目前它被调用了1000次,我想尝试用它来优化我的代码。
答案 0 :(得分:2)
以下是绘制两个四边形的示例:
#include <stdio.h>
#include <string.h>
#include <GL/glew.h>
#include <GL/glut.h>
typedef struct {
int elements_count;
float *array;
} fan_s;
GLuint vbo_id;
#define VBO_SIZE 4096
static void setup_vbo(void) {
glGenBuffers(1, &vbo_id);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
glBufferData(GL_ARRAY_BUFFER, VBO_SIZE, NULL, GL_DYNAMIC_DRAW);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, 0);
}
static void draw_fans(const fan_s *fans, int num_fans) {
#define MAX_FANS 1024
GLint fans_starts[MAX_FANS];
GLsizei fans_sizes[MAX_FANS];
float *mapping = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
int i;
int num_elements_total = 0;
for(i = 0; i != num_fans; ++i) {
memcpy(mapping, fans[i].array, fans[i].elements_count * 3 * sizeof(float));
mapping += fans[i].elements_count * 3;
fans_starts[i] = num_elements_total;
fans_sizes[i] = fans[i].elements_count;
num_elements_total += fans[i].elements_count;
}
glUnmapBuffer(GL_ARRAY_BUFFER);
glMultiDrawArrays(GL_TRIANGLE_FAN, fans_starts, fans_sizes, num_fans);
}
static void display(void) {
glClear(GL_COLOR_BUFFER_BIT);
float fan0_data[] = {
0.0, 0.0, 0.0,
0.0, 100.0, 0.0,
100.0, 100.0, 0.0,
100.0, 0.0, 0.0
};
float fan1_data[] = {
200.0, 0.0, 0.0,
200.0, 100.0, 0.0,
300.0, 100.0, 0.0,
300.0, 0.0, 0.0
};
fan_s fans[] = {
4, fan0_data,
4, fan1_data
};
draw_fans(fans, 2);
glutSwapBuffers();
}
static void reshape(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, w, h, 0);
glMatrixMode(GL_MODELVIEW);
}
static void keyboard(unsigned char key, int x, int y) {
if(key == 27) {
exit(0);
}
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500, 150);
glutCreateWindow("");
glClearColor(0.0, 0.0, 0.0, 1.0);
glColor4f(1.0, 1.0, 1.0, 1.0);
glewInit();
setup_vbo();
glutDisplayFunc(display);
glutIdleFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
为简单起见,我没有检查任何错误,包括溢出(请参阅VBO_SIZE
和MAX_FANS
)。