好的,所以我需要创建我自己的纹理/图像数据,然后在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不能处理我使用的普通int,但它可以很好地与uint8_t一起工作。我假设这是因为我上传到GPU时使用的GL_RGB以及GL_UNSIGNED_BYTE(只有8位,普通int不是8位)标志。
默认情况下,纹理的每一行应对齐到4字节。该纹理是一种RGB纹理,每个纹理需要24位或3字节,并且纹理被紧密压缩,尤其是纹理的行。这意味着将忽略纹理行开头的4字节对齐(除了纹理宽度的3倍可被4整除,不留剩余部分)。
为了解决这个问题,路线必须改为1。这意味着在将紧密堆积的纹理加载到GPU(glTexImage2D
)之前,必须设置GL_UNPACK_ALIGNMENT
参数:
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
否则,在纹理查找时,每行获得0-3个字节的偏移量。这会导致纹理连续扭曲或倾斜。
由于在GL_UNSIGNED_BYTE
中使用soure格式GL_RGB
,每个像素由3个颜色通道(红色、绿色和蓝色)组成,每个颜色通道存储在[0255]范围内的一个字节中。
如果您想将(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;
但是我如何创建自己的“自制图像”,即每个像素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]
);
我试图用lwjgl创建一个简单的OpenGL程序,但目前我还停留在创建纹理渲染上。 我得到的错误是一个分段错误: 机器信息: 有问题的JVM线程堆栈: 最后是我处理纹理创建的代码: 我创建的图像类工作得很好,我使用的示例图像是2 x 2像素,并且具有12字节长度的内部缓冲区,因此segvault不应该由太短的缓冲区引起。
最近我发现了一个OpenGL示例,它应用纹理而没有指定纹理图像单元并且没有将相应的单元整数均匀发送到着色器中,是否可以在不使用纹理单元的情况下应用纹理??或者它只是为活动纹理单元及其着色器采样器值使用默认值。 我的代码块(纹理相关): 我的片段着色器:
我有一个用于OpenGL中模型渲染的纹理数组。此数组包含漫反射和镜面纹理。由于某些网格没有镜面纹理,因此我在每次渲染后简单地将NULL纹理绑定到我的镜面采样器,并且只有当网格具有镜面纹理时,我才绑定一个。但是,我仍然在没有镜面纹理的网格上看到镜面纹理。 这是我的渲染代码 材质索引保存数组中纹理的索引,如果网格没有镜面纹理 索引为-1 纹理单元0用于漫反射 纹理单元2用于镜面
所以最近我开始阅读OpenGL维基文章。这就是我在这里描述OpenGL纹理的方式。不过,有几点尚不清楚。 以下陈述是真的、假的还是视情况而定? 将两个纹理绑定到同一个纹理单元是不可能的。 将两个采样器绑定到同一个纹理单元是不可能的。 将一个纹理绑定到两个不同的纹理单元是不可能的。 将一个采样器绑定到两个不同的纹理单元是不可能的。 应用程序有责任明确将什么采样器类型传递给什么统一变量。 着色器程序有
“我在我的申请中发现了一个奇怪的行为,希望你能解释给我听。”。你看,我有两个3D纹理,它们被发送到片段着色器,渲染得非常好。但有一个问题,当我创建另一个纹理(它是1D纹理)时,一个黑屏正在被渲染,而不是正确的前一个结果。 关于这个1D纹理,我甚至没有将其发送到片段着色器。当我调用glTexImage1D(…)时,黑屏就出现了。我评论这句话,它就消失了!!这两种纹理被渲染。 我觉得纹理单位肯定有问题
在andrid上的opengl es中,当我将两个纹理相邻放置时,会有一个轻微的接缝,可以看到它们后面绘制的对象。基本上看起来是一个小差距。我把范围缩小到了地图上 glTexParameteri(GL_纹理_2D、GL_纹理_最小过滤器、GL_线性_MIPMAP_线性);glTexParameteri(GL_纹理_2D、GL_纹理_MAG_过滤器、GL_线性); 如果我将它们都设置为距接缝最近的G