I have a problem with OpenGL and glGetTexImage()
.
I want to get the pixels of a texture that I've created before with code like this:
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);
I'm using SDL2.
After I loaded that texture I tried to get the pixels of this texture in a GLuint* pixels pointer which I declared as follows:
GLuint* pixels = new GLuint[256*256*4];
the size of this image was 256x256 pixels.
I got the pixel data by using
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;
}
Where "numChannels" is 4 for RGBA and 3 for RGB
Now my problem is that I really have no clue how to address Pixel p(x,y) correctly since the size of my array is 4 times bigger than the pixel count and every time I use a smaller size visual studios throws an error:
Exception thrown at 0x5ED71FCE (opengl32.dll) in sdl_opengl_Frameworktest.exe: 0xC0000005: Access violation writing location 0x09C33000.
Also, is it possible to get those data in a 2D array?
The size of the array in bytes is 1048576 bytes (256 * 256 * 4 * sizeof(GLuint)
). This is, because every color channel of a single pixel is stored in a separate GLuint
with a size of 4 bytes (sizeof(GLuint) == 4
). So the size of each pixel is 16 bytes because of 4 color channels per pixel and sizeof(GLuint)
for each color channel.
Probably it will be sufficient to store every color in an GLubyte
. Then the size of the array will be 262144 bytes (256 * 256 * 4 * sizeof(GLubyte)
)
GLubyte* pixels = new GLubyte[256*256*4];
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
Regardless if you use GLuint
or GLubyte
, the colors of a single pixel can be accessed like this:
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];
If you want to calculate a gray scale value from the r
, g
, b
values, the this can be don like this:
GLubyte gray = (GLubyte)((r + g + b) / 3.0);
Another popular formula can be found at Luma:
GLubyte gray = (GLubyte)(r*0.2126 + g*0.7152 + b*0.0722);
Replace the color RGB channels by the grayscale:
pixels[row + col] = gray;
pixels[row + col + 1] = gray;
pixels[row + col + 2] = gray;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With