首页 文章

OpenGL纹理格式,为OpenGL创建图像/纹理数据

提问于
浏览
2

好的,我需要创建自己的纹理/图像数据,然后将其显示在OpenGL中的四边形上 . 我有四边形工作,我可以用我自己的纹理加载器在它上面显示一个TGA文件,它完美地映射到四边形 .

但是如何为每个像素创建自己的“自制图像”,即1000x1000和3个通道(RGB值)?纹理数组的格式是什么,例如如何将像素(100,100)设置为黑色?

这就是我想象的完全白色图像/纹理:

#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工作正常 . 我假设这是因为GL_RGB和我上传到GPU时使用的GL_UNSIGNED_BYTE(只有8位且普通int不是8位)标志 .

2 回答

  • 3

    但是如何为每个像素创建自己的“自制图像”,即1000x1000和3个通道(RGB值)?

    std::vector< unsigned char > image( 1000 * 1000 * 3 /* bytes per pixel */ );
    

    纹理数组的格式是什么

    红色字节,然后是绿色字节,然后是蓝色字节 . 重复 .

    我如何将像素(100,100)设置为黑色?

    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]
        );
    
  • 2

    默认情况下,纹理的每一行应对齐到4个字节 . 纹理是RGB纹理,每个纹素需要24位或3个字节,纹理紧密包装,尤其是纹理行 . 这意味着忽略了纹理线开始的4个字节的对齐(除了纹理宽度的3倍可被4整除而没有剩余) .

    要解决这个问题,必须将对齐方式更改为1.这意味着在将紧密压缩的纹理加载到GPU(glTexImage2D)之前必须设置GL_UNPACK_ALIGNMENT参数:

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    

    否则,在纹理查找时获得每行0-3字节的偏移 . 这会导致连续扭曲或倾斜的纹理 .

    由于您在 GL_UNSIGNED_BYTE 中使用了源格式 GL_RGB ,因此每个像素由3个颜色通道(红色,绿色和蓝色)组成,每个颜色通道存储在范围[0,255]中的一个字节中 .

    如果要将( xy )处的像素设置为 RGB 颜色,则执行以下操作:

    texdata[(y*WIDTH+x)*3+0] = R;
    texdata[(y*WIDTH+x)*3+1] = G;
    texdata[(y*WIDTH+x)*3+2] = B;
    

相关问题