0

我现在拥有的

#define QUAD_VERT_COUNT 4

#define QUAD_POS_COMP 3

typedef struct quad_pos
{
 GLfloat x, y, z;
}quad_pos;

#define SIZE_QUAD_POS = sizeof(quad_pos) * QUAD_VERT_COUNT

static QUAD_BUFFER = 0;

void init_quad_buffer()
{
 quad_pos* pos_data = malloc(SIZE_QUAD_POS);

 pos_data[0].x = -1.0f;
 pos_data[0].y = -1.0f;
 pos_data[0].z = 0.0f;

 pos_data[1].x = 1.0f;
 pos_data[1].y = -1.0f;
 pos_data[1].z = 0.0f;

 pos_data[2].x = -1.0f;
 pos_data[2].y = 1.0f;
 pos_data[2].z = 0.0f;

 pos_data[3].x = 1.0f;
 pos_data[3].y = 1.0f;
 pos_data[3].z = 0.0f;

 QUAD_BUFFER = create_buffer(GL_ARRAY_BUFFER, GL_STATIC_DRAW, pos_data, SIZE_QUAD_POS);
 free(pos_data);
}

void get_quad_buffer
{
  return QUAD_BUFFER;
}

和绘图(部分)

glBindBuffer(GL_ARRAY_BUFFER, get_quad_buffer());
glEnableVertexAttribArray(ss->attrib[0]);//attrib[o] is vertex pos
glVertexAttribPointer(ss->attrib[0], QUAD_POS_COMP, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, QUAD_VERT_COUNT);

使用矩阵和着色器实现缩放、平移和旋转,所以是的,这个缓冲区永远不会因每个精灵而改变。

但是为什么我们只需要为 -1.0、1.0 使用 GL_float 呢?GL_Byte 就足够了。

 typedef struct quad_pos
 {
 GLbyte x, y, z;
 }quad_pos;

void init_quad_buffer()
{
 quad_pos* pos_data = malloc(SIZE_QUAD_POS);

 pos_data[0].x = -1;
 pos_data[0].y = -1;
 pos_data[0].z = 0;
 ....
}

绘图

  ...
  glVertexAttribPointer(ss->attrib[0], QUAD_POS_COMP, GL_BYTE, GL_FALSE, 0, 0);
  glDrawArrays(GL_TRIANGLE_STRIP, 0, QUAD_VERT_COUNT);

问题 1:我需要将 normalize 设置为 GL_TRUE 吗?
问题 2: GLclampf 和 GLfloat 都是 4 字节浮点数,但是颜色值是从 0.0 到 1.0,所以如果我也将它们放入 GLbyte(val/256,所以 1.0 为 255,0.5 为 128,0 为 0)我需要 GL_TRUE在 glVertexAttribPointer 中标准化?
问题 3:我真的需要在顶点数据/其他数据中进行填充吗?添加虚构的 pos_data.g,只是为了 sizeof(pos_data) = 16 == 对 gpu 好?

4

2 回答 2

2

通常,您始终可以使用半浮点(16 位浮点)扩展来节省内存。

您的实现看起来会导致一些绘制调用开销。规范化(即时!)将导致额外的开销。为了绘制这个常量四边形的多个实例,我建议使用以下方法来加快速度:

  • 几何着色器的实现;让它为你生成、变换和发射四边形的 4 个顶点。
  • 使用包含每个四边形实例的变换矩阵的纹理缓冲区对象(TBO)使用变换缓冲区进行实例化绘图(将使用内置的统一“gl_InstanceID”访问每个矩阵列)。
    或:
    通过顶点属性数组提供矩阵(可能更快)。这两种方法可以在相同的缓冲区数据布局上实现(只是一个矩阵数组)
于 2012-08-13T23:25:29.600 回答
1

但是为什么我们只需要为 -1.0、1.0 使用 GL_float 呢?GL_Byte 就足够了。

请注意,这通常不是真的,在大多数情况下,您需要一个浮点数来精确。如果你只有这么少的值和这么简单的几何图形,那么可能性非常高,甚至根本没有理由首先对其进行优化glByte。您可能根本没有顶点,那么为什么要在它们上节省存储空间呢?这听起来像是过早优化的一个很好的例子(我知道,这是一个过度使用的术语)。

现在,对于您的实际问题:

  1. 不,如果您想要相同的功能,则不是,如果 normalize 为假,-1则将转换为-1.0f,如果为真,它将更像-0.0078125f(或-1/128.0f)。所以如果你想保持相同的比例,你不希望它标准化。
  2. 您从哪里得到 GLclampf 和 GLfloat 是 8 字节浮点数的想法?它们通常是 4 字节浮点数。如果您想通过顶点属性传递 RGB 颜色,是的,您应该将它们归一化,因为 OpenGL 期望颜色分量在 range 范围内[0.0f,1.0f]。但是再说一遍:为什么不简单地将它们作为浮点数传递呢?你觉得有什么收获?在简单的游戏中,您可能没有足够的颜色来注意到差异,而在非简单的游戏中,您更有可能使用纹理。
  3. 对此我不确定。我知道旧 GPU 确实如此(我的意思是差不多 10 年前),但我不知道最近有任何声称这实际上会改善某些东西。在任何情况下,最著名的对齐方式是将一个顶点的所有顶点属性一起支撑为 32 字节(的倍数),这适用于 ATI 卡。对于一些更棘手的事情/扩展,字节对齐可能是必要的,但我认为你现在不需要担心它。
于 2012-08-13T22:02:05.507 回答