OpenGL 纹理格式,为 OpenGL 创建 image/texture 数据
OpenGL texture format, create image/texture data for OpenGL
好的,所以我需要创建自己的 texture/image 数据,然后在 OpenGL 中将其显示到四边形上。我有四边形工作,我可以用我自己的纹理加载器在上面显示一个 TGA 文件,它完美地映射到四边形。
但是如何创建自己的 "homemade image",即每个像素 1000x1000 和 3 个通道(RGB 值)?纹理数组的格式是什么,例如如何将像素 (100,100) 设置为黑色?
这就是我对全白的想象 image/texture:
#DEFINE SCREEN_WIDTH 1000
#DEFINE SCREEN_HEIGHT 1000
unsigned int* texdata = new unsigned int[SCREEN_HEIGHT * SCREEN_WIDTH * 3];
for(int i=0; i<SCREEN_HEIGHT * SCREEN_WIDTH * 3; i++)
texdata[i] = 255;
GLuint t = 0;
glEnable(GL_TEXTURE_2D);
glGenTextures( 1, &t );
glBindTexture(GL_TEXTURE_2D, t);
// Set parameters to determine how the texture is resized
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR_MIPMAP_LINEAR );
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR );
// Set parameters to determine how the texture wraps at edges
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_S , GL_REPEAT );
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_T , GL_REPEAT );
// Read the texture data from file and upload it to the GPU
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, SCREEN_WIDTH, SCREEN_HEIGHT, 0,
GL_RGB, GL_UNSIGNED_BYTE, texdata);
glGenerateMipmap(GL_TEXTURE_2D);
编辑:下面的答案是正确的,但我还发现 OpenGL 不处理我使用的普通整数,但它与 uint8_t 一起工作正常。我认为这是因为我在上传到 GPU 时使用了 GL_RGB 和 GL_UNSIGNED_BYTE(只有 8 位,普通的 int 不是 8 位)标志。
But how do I create my own "homemade image", that is 1000x1000 and 3 channels (RGB values) for each pixel?
std::vector< unsigned char > image( 1000 * 1000 * 3 /* bytes per pixel */ );
What is the format of the texture array
红色字节,然后是绿色字节,然后是蓝色字节。重复。
how do I for example set pixel (100,100) to black?
unsigned int width = 1000;
unsigned int x = 100;
unsigned int y = 100;
unsigned int location = ( x + ( y * width ) ) * 3;
image[ location + 0 ] = 0; // R
image[ location + 1 ] = 0; // G
image[ location + 2 ] = 0; // B
上传方式:
// the rows in the image array don't have any padding
// so set GL_UNPACK_ALIGNMENT to 1 (instead of the default of 4)
// https://www.khronos.org/opengl/wiki/Pixel_Transfer#Pixel_layout
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
glTexImage2D
(
GL_TEXTURE_2D, 0,
GL_RGB, 1000, 1000, 0,
GL_RGB, GL_UNSIGNED_BYTE, &image[0]
);
默认情况下,纹理的每一行应对齐到 4 个字节。
纹理是一个 RGB 纹理,每个纹素需要 24 位或 3 个字节,并且纹理被紧密压缩,尤其是纹理的行。
这意味着忽略纹理一行开始的 4 个字节的对齐(除了纹理宽度的 3 倍可以被 4 整除而没有剩余)。
为了解决这个问题,必须将对齐方式更改为 1。
这意味着 GL_UNPACK_ALIGNMENT
paramter has to be set before loading a tightly packed texture to the GPU (glTexImage2D
):
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
否则,在纹理查找时,每行将获得 0-3 个字节的偏移量。这会导致连续扭曲或倾斜的纹理。
由于您在 GL_UNSIGNED_BYTE
中使用了源格式 GL_RGB
,每个像素由 3 个颜色通道(红色、绿色和蓝色)组成,每个颜色通道存储在范围 [0] 中的一个字节中, 255].
如果要将 (x
、y
) 处的像素设置为颜色 R
、G
和 B
,这是这样做:
texdata[(y*WIDTH+x)*3+0] = R;
texdata[(y*WIDTH+x)*3+1] = G;
texdata[(y*WIDTH+x)*3+2] = B;
好的,所以我需要创建自己的 texture/image 数据,然后在 OpenGL 中将其显示到四边形上。我有四边形工作,我可以用我自己的纹理加载器在上面显示一个 TGA 文件,它完美地映射到四边形。
但是如何创建自己的 "homemade image",即每个像素 1000x1000 和 3 个通道(RGB 值)?纹理数组的格式是什么,例如如何将像素 (100,100) 设置为黑色?
这就是我对全白的想象 image/texture:
#DEFINE SCREEN_WIDTH 1000
#DEFINE SCREEN_HEIGHT 1000
unsigned int* texdata = new unsigned int[SCREEN_HEIGHT * SCREEN_WIDTH * 3];
for(int i=0; i<SCREEN_HEIGHT * SCREEN_WIDTH * 3; i++)
texdata[i] = 255;
GLuint t = 0;
glEnable(GL_TEXTURE_2D);
glGenTextures( 1, &t );
glBindTexture(GL_TEXTURE_2D, t);
// Set parameters to determine how the texture is resized
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR_MIPMAP_LINEAR );
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR );
// Set parameters to determine how the texture wraps at edges
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_S , GL_REPEAT );
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_T , GL_REPEAT );
// Read the texture data from file and upload it to the GPU
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, SCREEN_WIDTH, SCREEN_HEIGHT, 0,
GL_RGB, GL_UNSIGNED_BYTE, texdata);
glGenerateMipmap(GL_TEXTURE_2D);
编辑:下面的答案是正确的,但我还发现 OpenGL 不处理我使用的普通整数,但它与 uint8_t 一起工作正常。我认为这是因为我在上传到 GPU 时使用了 GL_RGB 和 GL_UNSIGNED_BYTE(只有 8 位,普通的 int 不是 8 位)标志。
But how do I create my own "homemade image", that is 1000x1000 and 3 channels (RGB values) for each pixel?
std::vector< unsigned char > image( 1000 * 1000 * 3 /* bytes per pixel */ );
What is the format of the texture array
红色字节,然后是绿色字节,然后是蓝色字节。重复。
how do I for example set pixel (100,100) to black?
unsigned int width = 1000;
unsigned int x = 100;
unsigned int y = 100;
unsigned int location = ( x + ( y * width ) ) * 3;
image[ location + 0 ] = 0; // R
image[ location + 1 ] = 0; // G
image[ location + 2 ] = 0; // B
上传方式:
// the rows in the image array don't have any padding
// so set GL_UNPACK_ALIGNMENT to 1 (instead of the default of 4)
// https://www.khronos.org/opengl/wiki/Pixel_Transfer#Pixel_layout
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
glTexImage2D
(
GL_TEXTURE_2D, 0,
GL_RGB, 1000, 1000, 0,
GL_RGB, GL_UNSIGNED_BYTE, &image[0]
);
默认情况下,纹理的每一行应对齐到 4 个字节。 纹理是一个 RGB 纹理,每个纹素需要 24 位或 3 个字节,并且纹理被紧密压缩,尤其是纹理的行。 这意味着忽略纹理一行开始的 4 个字节的对齐(除了纹理宽度的 3 倍可以被 4 整除而没有剩余)。
为了解决这个问题,必须将对齐方式更改为 1。
这意味着 GL_UNPACK_ALIGNMENT
paramter has to be set before loading a tightly packed texture to the GPU (glTexImage2D
):
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
否则,在纹理查找时,每行将获得 0-3 个字节的偏移量。这会导致连续扭曲或倾斜的纹理。
由于您在 GL_UNSIGNED_BYTE
中使用了源格式 GL_RGB
,每个像素由 3 个颜色通道(红色、绿色和蓝色)组成,每个颜色通道存储在范围 [0] 中的一个字节中, 255].
如果要将 (x
、y
) 处的像素设置为颜色 R
、G
和 B
,这是这样做:
texdata[(y*WIDTH+x)*3+0] = R;
texdata[(y*WIDTH+x)*3+1] = G;
texdata[(y*WIDTH+x)*3+2] = B;