繁体   English   中英

glMultiDrawArrays缓冲

[英]glMultiDrawArrays buffering

这可能又是一个愚蠢的问题,也许这确实是我所缺少的明显问题,但是我无法让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次,我想尝试使用它来优化我的代码。

这是绘制两个四边形的示例:

#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_SIZEMAX_FANS )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM