• 全部
  • 问答

请教各位一个GPGPU(使用OpenGL)的精度问题

wwybj 2010-05-18 06:06:56
各位好~
需求是这样,我需要将一些32位整数(比较大)存储在纹理中,

我在为纹理开辟显存空间时,使用以下函数:
glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA32I, texSize,texSize,0,GL_RGBA,GL_INT,0);

再使用glDrawPixels(texSize,texSize,GL_RGBA,GL_INT,data);将int类型的数组data中的数据传入纹理中

但是当我使用:
glReadPixels(0, 0, texSize, texSize,GL_RGBA,GL_INT,result);
来将纹理中数据读回int类型的result数组并输出后,发现是一堆无规律的整数。

如果在glTexImage2D()中将 GL_RGBA32I 改成 GL_RGBA32F 的话,就能得到正确的结果了,却又产生了另外一个问题,由于是32F即浮点类型,因此实际上能正确操作的最大整数是9999999(七位),而非32位整数的最高值。

请教大家如果我想在纹理中某个通道存入完整的32位整数该怎么办?这个问题研究了好几天了,未果……

完整代码在下面贴出。很简单,初始化FBO后,从数组data1中读取数据存入纹理,再从纹理中读取数据存入数组result。只是为了实验一下怎么向纹理中存入32位整数值。

非常感谢!


#include <GL/glew.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#include <windows.h>
#include <GL/glut.h>

#include <textfile.h>

int main(int argc, char **argv) {
// 这里声明纹理的大小为:teSize;而数组的大小就必须是texSize*texSize*4
int texSize = 2;

int i;

GLhandleARB programObject;
GLhandleARB shaderObject;
GLint yParam, xParam, alphaParam;

// 生成测试数组的数据
int* data = (int*)malloc(4*texSize*texSize*sizeof(int));
int* result = (int*)malloc(4*texSize*texSize*sizeof(int));
for (i=0; i<4*texSize*texSize; i++)
data[i] = 1;

// 初始化OpenGL的环境
glutInit (&argc, argv);
glutCreateWindow("TEST1");
glewInit();
// 视口的比例是 1:1 pixel=texel=data 使得三者一一对应
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,texSize,0.0,texSize);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0,0,texSize,texSize);

glEnable(GL_TEXTURE_2D);


// 生成并绑定一个FBO,也就是生成一个离屏渲染对像
GLuint fb;
glGenFramebuffersEXT(1,&fb);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,fb);
// 生成两个纹理,一个是用来保存数据的纹理,一个是用作渲染对像的纹理

GLuint tex,fboTex;
glGenTextures (1, &tex);
glGenTextures (1, &fboTex);

glBindTexture(GL_TEXTURE_RECTANGLE_ARB,fboTex);
// 设定纹理参数
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,
GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,
GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,
GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,
GL_TEXTURE_WRAP_T, GL_CLAMP);

// 这里在显卡上分配FBO纹理的贮存空间,每个元素的初始值是0;
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB,0,GL_RGBA32F,
texSize,texSize,0,GL_RGBA,GL_INT,0);


//把当前的FBO对像,与FBO纹理绑定在一起
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_RECTANGLE_ARB,fboTex,0);



//////////////////////////////////OPTION TWO/////////////////////////////////////////////////////
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
glRasterPos2i(0,0);
glDrawPixels(texSize,texSize,GL_RGBA,GL_INT,data);
//////////////////////////////////////////////////////////////////////////////////////////////////

// 从帧缓冲中读取数据,并把数据保存到result数组中。
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
glReadPixels(0, 0, texSize, texSize,GL_RGBA,GL_INT,result);


// 显示最终的结果
printf("Data before roundtrip:\n");

for (i=0; i<4*texSize*texSize; i++)
printf("%d\n",data[i]);
printf("Data after roundtrip:\n");
for (i=0; i<4*texSize*texSize; i++)
printf("%d\n",result[i]);
// 释放本地内存
free(data);
free(result);

// 释放显卡内存
glDeleteFramebuffersEXT (1,&fb);
glDeleteTextures (1,&tex);
glDeleteTextures(1,&fboTex);

return 0;
}

...全文
142 点赞 收藏 6
写回复
6 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
wwybj 2010-05-24
1.%d改成%u是没有用的。
2.glFlush()也是没有用的。

在gpgpu论坛上问了,问题已经解决了,结论就是:
使用glColor()或者glClear()这类的函数,会自动将颜色值在【0,1】的浮点中“规范化”,所以目前没有可能将颜色值写入一个32位整数类型的纹理像素中。
唯一的解决办法是使用shader传入数据,而不通过glColor()传入数据。

希望今后的OpenGL版本能够增加这个功能~~
回复
zenny_chen 2010-05-19
忘了,你在调用完glDrawPixels(texSize,texSize,GL_RGBA,GL_INT,data);之后
再调用一下glFlush()试试。
因为你调了glDrawPixels以后,像素不一定马上写到GDDR,呵呵。需要冲刷一下。
回复
zenny_chen 2010-05-19
呵呵,你把%d改成%u输出试试。
回复
向立天 2010-05-19
是不是有符号的问题
回复
dongnanfanlin 2010-05-19
我也不会,帮顶
回复
十八道胡同 2010-05-18
不会,帮顶!
回复
相关推荐
发帖
C++ 语言
创建于2007-09-28

5.9w+

社区成员

C++ 语言相关问题讨论,技术干货分享,前沿动态等
申请成为版主
帖子事件
创建了帖子
2010-05-18 06:06
社区公告
暂无公告