减少缓冲区对象大小

时间:2012-08-13 18:18:34

标签: opengl opengl-3

我现在拥有什么

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

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

但为什么我们需要将GL_float用于-1.0,1.0? 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:我是否需要将标准化设置为GL_TRUE?
问题2: GLclampf和GLfloat都有4个字符浮点数,但颜色值从0.0到1.0,所以如果我也把它们放在GLbyte中(val / 256,那么255代表1.0,128代表0.5,0代表0)我是否需要GL_TRUE在glVertexAttribPointer中进行标准化?
问题3:我真的需要在顶点数据/其他数据中填充吗?添加虚构的pos_data.g,仅适用于sizeof(pos_data)= 16 ==适合gpu?

2 个答案:

答案 0 :(得分:2)

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

您的实现看起来会导致一些绘制调用开销。规范化(动态!)将导致额外的开销。为了绘制这个常数四边形的多个实例,我推荐以下内容来加快速度:

  • 几何着色器的实现;让它为你生成,转换和发射四边形的4个顶点。
  • 实例化绘图,使用包含每个quad实例的变换矩阵的纹理缓冲区对象(TBO)的变换缓冲区(将使用内置函数访问每个矩阵列统一'gl_InstanceID')。
    OR:
    通过顶点属性数组提供矩阵(可能更快)。 这两种方法可以在相同的缓冲区数据布局(只是一个矩阵数组)上实现

答案 1 :(得分:1)

  

但为什么我们需要将GL_float用于-1.0,1.0? GL_Byte就足够了。

请注意,一般情况下并非如此,在大多数情况下,您需要一个精确的浮点数。如果你只有这么少的值和如此简单的几何,那么几率很高,甚至根本没有理由将它优化到glByte。你可能根本没有顶点,所以为什么要在它们上面存储?这听起来像是过早优化的一个很好的例子(我知道,这是一个过度使用的术语)。

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

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