c++ - 使用 glGetTexImage() 访问像素?

标签 c++ opengl textures sdl-2

我对 OpenGL 和 glGetTexImage() 有疑问。

我想获取我之前创建的纹理的像素 代码如下:

glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D,
    0, 
    GL_RGBA, 
    width,
    height,
    0, 
    GL_RGB, 
    GL_UNSIGNED_BYTE, 
    someRandomPixels);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

我正在使用 SDL2。

加载该纹理后,我尝试获取该纹理的像素 在我声明如下的 GLuint* 像素指针中:

GLuint* pixels = new GLuint[256*256*4];

这张图片的大小是 256x256 像素。

我通过使用得到了像素数据

GLuint* Textur::getPixelsOfTextur(GLuint textur, int width, int height, int numChannels)
{
    GLuint* pixels=new GLuint[width*height*numChannels];
    glBindTexture(GL_TEXTURE_2D, textur);
    glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_INT, pixels);
     return pixels;
}

其中“numChannels”对于 RGBA 为 4,对于 RGB 为 3

现在我的问题是,我真的不知道如何正确处理像素 p(x,y),因为我的数组大小是像素数的 4 倍,每次我使用较小尺寸的 Visual Studio 都会抛出一个错误:

Exception thrown at 0x5ED71FCE (opengl32.dll) in sdl_opengl_Frameworktest.exe: 0xC0000005: Access violation writing location 0x09C33000.

另外,是否可以将这些数据放在二维数组中?

最佳答案

以字节为单位的数组大小为 1048576 字节 (256 * 256 * 4 * sizeof(GLuint))。这是因为单个像素的每个颜色 channel 都存储在一个单独的 GLuint 中,大小为 4 个字节 (sizeof(GLuint) == 4)。所以每个像素的大小是 16 字节,因为每个像素有 4 个颜色 channel ,并且每个颜色 channel 都有 sizeof(GLuint)

可能将每种颜色存储在 GLubyte 中就足够了。那么数组的大小将为 262144 字节 (256 * 256 * 4 * sizeof(GLubyte))

GLubyte* pixels = new GLubyte[256*256*4];

glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);

无论你使用GLuint还是GLubyte,单个像素的颜色都可以像这样访问:

GLuint r, g, b, a; // or GLubyte r, g, b, a;

size_t x, y; // line and column of the pixel

size_t elmes_per_line = 256 * 4; // elements per line = 256 * "RGBA"

size_t row = y * elmes_per_line;
size_t col = x * 4;

r = pixels[row + col]; 
g = pixels[row + col + 1]; 
b = pixels[row + col + 2]; 
a = pixels[row + col + 3]; 


如果你想从 r, g , b 值计算一个灰度值,可以这样做:

GLubyte gray = (GLubyte)((r + g + b) / 3.0);

另一个流行的公式可以在 Luma 找到:

GLubyte gray = (GLubyte)(r*0.2126 + g*0.7152 + b*0.0722);

用灰度替换颜色 RGB channel :

pixels[row + col]     = gray; 
pixels[row + col + 1] = gray; 
pixels[row + col + 2] = gray; 

关于c++ - 使用 glGetTexImage() 访问像素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48938930/

相关文章:

c++ - 来自片段着色器中 GL_TEXTURE_1D 的样本

c++ - 突然一个 : syntax error: identifier

c++ - 取消/清除 boost::tuple of pointers

c++ - glGetUniformLocation OpenGL ES 2.0 (ipad 3 iOS 7.0.3 返回结果错误)

c++ - 64 位系统上的 OS X Carbon 框架

c++ - 当窗口不是焦点 OpenGL - C++ 时,一种将控制权返回给 Windows 的方法

c++ - C 预处理器字符串化中的额外间接性有所不同

java - LWJGL:无法在 opengl 中渲染多个形状

c# - 什么决定了最大纹理尺寸?

c++ - 我正在尝试为正方形设置棋盘纹理