1. ホーム
  2. c++

[解決済み] glGetTexImage()で画素アクセス?

2022-02-16 14:15:57

質問

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 です。

問題は、配列のサイズがピクセル数の4倍で、これより小さいサイズを使用するたびに Visual Studio がエラーを出すため、Pixel p(x,y) を正しく扱う方法が全く分からないということです。

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

また、それらのデータを2次元配列で取得することは可能でしょうか?

どのように解決するのですか?

配列のサイズ(バイト)は1048576バイト( 256 * 256 * 4 * sizeof(GLuint) ). これは、1つのピクセルの各色チャンネルが、それぞれ別の GLuint で4バイトのサイズ( sizeof(GLuint) == 4 ). つまり、1画素あたり4色チャンネルなので、1画素のサイズは16バイトとなり 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 のように、1つの画素の色にアクセスすることができます。

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);

もう一つの一般的な方式は、以下の通りです。 ルーマ :

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

カラーRGBチャンネルをグレースケールで置き換える。

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