在 openGL 纹理中加载图像(使用它们的 RGB(A) 像素数据)

Posted

技术标签:

【中文标题】在 openGL 纹理中加载图像(使用它们的 RGB(A) 像素数据)【英文标题】:Loading Images (using their RGB(A) pixel data) in openGL textures 【发布时间】:2013-05-27 12:12:35 【问题描述】:

在主函数中:

    img = cvLoadImage("test.JPG");

//openCV functions to load and create matrix
    CvMat *mat = cvCreateMat(img->height,img->width,CV_8SC3 );
    cvGetMat( img, mat,0,1);
//creating the 3-dimensional array during runtime
data = new float**[img->height];
       for(int i=0;i<img->height;i++)
       data[i] = new float*[img->width];
       

       for(int i=0;i<img->height;i++)
         for(int j=0;j<img->width;j++)
            data[i][j] = new float[3];
    
//setting RGB values
for(int i=0;i<img->height;i++)
    
        for(int j=0;j<img->width;j++)
        
            CvScalar scal = cvGet2D( mat,i,j);
                    data[i][j][0] = scal.val[0];
            data[i][j][1] = scal.val[1];
            data[i][j][2] = scal.val[2];
        
        

我正在使用openCV获取图像像素数据,将其存储在动态创建的矩阵“数据”中。现在生成纹理并绑定它们:

glGenTextures(1,&texName);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
glTexImage2D(GL_TEXTURE_2D, 0 ,GL_RGB, img->width,img->height,0,GL_RGB,GL_FLOAT,data);
glBindTexture(GL_TEXTURE_2D, texName);

glBegin(GL_QUADS);
glTexCoord2f(0,0); 
glVertex3f(-1,-1,0);
glTexCoord2f(0,1); 
glVertex3f(-1,1,0);
glTexCoord2f(1,1); 
glVertex3f(1,1,0);
glTexCoord2f(1,0); 
glVertex3f(1,-1,0);
glEnd();

没有编译错误,但在运行时,窗口显示我制作的正方形,而不是我尝试转换为纹理的图像。

如何使用我使用 openCV 提取的像素数据将任何图像加载到纹理中。我已经打印了 RGB 值,它们看起来足够合法,打印的三元组数量也符合预期。

【问题讨论】:

【参考方案1】:

glBindTexture 应该在 glTexParemeteri...glTexImage2D 调用之前调用,因此 openGL 知道您正在设置哪个纹理。

glEnable(GL_TEXTURE_2D);
glGenTextures(1,&texName);
glBindTexture(GL_TEXTURE_2D, texName);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
glTexImage2D(GL_TEXTURE_2D, 0 ,GL_RGB, img->width,img->height,0,GL_RGB,GL_FLOAT,data);

更重要的是,您没有正确设置 data 变量:

float* data = new float[img->height * img->width * 3];
for (int i = 0; i < img->height; i++)

    for (int j = 0; j < img->width; j++)
    
        CvScalar scal = cvGet2D(mat, i, j);
        data[(i * img->width + j) + 0] = scal.val[0];
        data[(i * img->width + j) + 1] = scal.val[1];
        data[(i * img->width + j) + 2] = scal.val[2];
    

另外,您可能需要交换颜色分量的顺序和/或将它们转换为 0..1 范围,我不知道 openCV 如何加载图像。

【讨论】:

我试过这个。当我用 glBegin()..glEnd() 序列绘制时,它给了我一个白色的四边形。 “数据”变量是一个浮点数,有任何问题(尽管 glTexImage2D 有一个有效的枚举作为 GL_FLOAT) 哦,我刚刚注意到,您的 data 变量不正确。它应该是一个线性阵列,而不是一个阵列阵列。你很幸运它没有崩溃。

以上是关于在 openGL 纹理中加载图像(使用它们的 RGB(A) 像素数据)的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL-在一个函数中加载多重纹理

使用 FBO 和着色器 OpenGL 渲染到纹理

使用 DevIL 在 C++ OpenGL 中加载纹理

如何使用 FBX SDK 在 fbx 文件中加载嵌入的纹理? [关闭]

在OpenGL中加载图像以用于GIS应用程序

使用 Boost.GIL 加载 opengl 纹理