【发布时间】:2011-11-20 20:35:51
【问题描述】:
我想在 OpenGL ES 中逐个像素地渲染图像。我想这样做是因为我计划随着时间的推移移动这些像素以创建各种效果。
出于性能和设计原因,我决定仅在两个方向上使用每隔一个像素(从而将它们的数量减少到四分之一)
我对opengl只有非常基本的了解,所以我可能缺少一些关键知识来实现这一点。
实现这一目标的最佳方法是什么?我真的必须逐个像素地渲染它吗?或者我可以以某种方式从像素数组中创建纹理吗?
我希望在尽可能多的设备上进行这项工作(因此首选 OpenGL ES 1.1 解决方案,但如果无法实现或者确实不方便或速度很慢,则可以使用 2.0)
我尝试使用 VBO 执行此操作,但结果好坏参半。我不确定我是否做得正确,因为存在一些问题(而且速度很慢)。这是我的代码:
初始化:
glGenBuffers(1, &pointsVBO);
glBindBuffer(GL_ARRAY_BUFFER, pointsVBO);
glBufferData(GL_ARRAY_BUFFER, 160*240*sizeof(Vertex), 0, GL_DYNAMIC_DRAW);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
渲染:
- (void)renderPoints:(ImagePixel**)imagePixels {
int count = 160 * 240;
for(int i = 0; i < count; ++i) {
vertices[i].v[0] = imagePixels[i]->positionX;
vertices[i].v[1] = imagePixels[i]->positionY;
vertices[i].color[0] = imagePixels[i]->red;
vertices[i].color[1] = imagePixels[i]->green;
vertices[i].color[2] = imagePixels[i]->blue;
vertices[i].color[3] = 1;
}
glVertexPointer(2, GL_FLOAT, sizeof(Vertex), vertices[0].v);
glColorPointer(4, GL_FLOAT, sizeof(Vertex), vertices[0].color);
// update vbo
GLvoid *vbo_buffer = glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES);
memcpy(vbo_buffer, vertices, count * sizeof(Vertex));
glUnmapBufferOES(GL_ARRAY_BUFFER);
// draw contents of vbo
glDrawArrays(GL_POINTS, 0, count);
}
顶点结构:
typedef struct Vertex
{
float v[2];
float color[4];
} Vertex;
imagePixels 数组填充了来自图像的数据。
当我这样做时,我得到了大部分图像,但我缺少最后几行,我可以在屏幕周围看到一些随机像素。是否有可能我在仅使用部分数据的 drawArrays 中遇到了一些限制?
第二个问题是,后半列中的点没有正确对齐。我猜这是由于在渲染本身期间计算位置时浮点数学中的舍入误差引起的(提供的坐标都是 2 的倍数)。有什么办法可以防止这种情况发生吗?我需要在正确的网格中对齐所有点。
我一拿回我的手机就会给你截图
【问题讨论】:
-
你考虑过像素缓冲对象吗? (公益组织)
-
我以前没有听说过它们 :) 我也会调查一下,谢谢