我正在尝试在OpenGL中创建浮点纹理。 我有4个顶点(2个多边形)形成正方形:
-------
|\ |
| \ |
| \|
-------
现在我想创建具有浮点值的纹理,每个纹理值代表每个像素的基本颜色强度。
我想在片段着色器中计算像素颜色,如下所示:
color = texture2D(texture, coordinates).r * vec4(0.4, 1.0, 0.8, 1.0);
vec4(0.4,1.0,0.8,1.0)只是我使用的基本颜色
当我准备这样的数据时:
int width, height;
width = 16;
height = 16;
float data[16][16];
for(int i = 0; i < width; i++){
for(int j = 0; j < height; j++){
data[i][j] = 0.5f;
}
}
GLuint n_tex_surface;
glGenTextures(1, &n_tex_surface);
glBindTexture(GL_TEXTURE_2D, n_tex_surface);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, data);
glGenerateMipmap(GL_TEXTURE_2D);
编辑:
INIT
vertices[] = {
0, 1, -1, -1, 1, /**/1, 1, 1, -1, 1,/**/ 1, 0, 1, 1, 1,/**/ 0, 0, -1, 1, 1};
indices[] = {
0, 1, 2, 0, 2, 3};
glGenBuffers(1, &n_vertex_buffer_object);
glBindBuffer(GL_ARRAY_BUFFER, n_vertex_buffer_object);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glGenBuffers(1, &n_index_buffer_object);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, n_index_buffer_object);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glGenVertexArrays(1, &n_vertex_array_object);
glBindVertexArray(n_vertex_array_object);
{
glBindBuffer(GL_ARRAY_BUFFER, n_vertex_buffer_object);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), p_OffsetInVBO(0));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), p_OffsetInVBO(2 * sizeof(float)));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, n_index_buffer_object);
}
glBindVertexArray(0);
DRAW
glBindVertexArray(n_vertex_array_object);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, p_OffsetInVBO(0));
glBindVertexArray(0);
我的结果如下:
而不是只有一种颜色强度的方形我得到了这个烂摊子。看起来质地太小而且不适合方形。应该是什么尺寸的质地?我怎么知道的? 我是否以正确的方式创建纹理?
尺寸为128x128:
64x64我得到了这个专栏,这就是我想要的,但为什么不覆盖整个广场呢?
这是在我的计算机上的OpenGL 3.3中。
你能帮帮我吗?
编辑:
当我用Addison Wesley OpenGL编程指南中的示例替换我的纹理创建代码时,它的效果很好,为什么我的代码没有呢?
GLuint n_tex_surface;
GLubyte checkImage[dataheight][datawidth][4];
int i, j, c;
for (i = 0; i < dataheight; i++) {
for (j = 0; j < datawidth; j++) {
c = (((i&0x8)==0)^((j&0x8))==0)*255;
checkImage[i][j][0] = (GLubyte) c;
checkImage[i][j][1] = (GLubyte) c;
checkImage[i][j][2] = (GLubyte) c;
checkImage[i][j][3] = (GLubyte) 255;
}
}
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, &n_tex_surface);
glBindTexture(GL_TEXTURE_2D, n_tex_surface);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, datawidth,
dataheight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
checkImage);
编辑: 顶点着色器
#version 330
in vec2 v_tex;
in vec3 v_pos;
uniform mat4 t_modelview_projection_matrix;
out vec2 v_texcoord;
void main()
{
gl_Position = t_modelview_projection_matrix * vec4(v_pos, 1.0);
v_texcoord = v_tex;
}
片段着色器
#version 330
in vec2 v_texcoord;
out vec4 color;
uniform sampler2D n_box_tex;
void main()
{
frag_color = texture2D(n_box_tex, v_texcoord).r * vec4(0.4, 1.0, 0.8, 1.0);
}
答案 0 :(得分:6)
您只为纹理的 1 / 4 分配足够的存储空间。
您需要使用float data[16][16][4]
,然后为纹理的每个组件指定0.5f
的值:
int width, height;
width = 16;
height = 16;
float data[16][16][4];
for(int i = 0; i < width; i++){
for(int j = 0; j < height; j++){
data[i][j][0] = 0.5f;
data[i][j][1] = 0.5f;
data[i][j][2] = 0.5f;
data[i][j][3] = 0.5f;
}
}
你真的很幸运,做你最初尝试过的事情并没有让你的软件崩溃。在读取纹理图像数据时,您正在强制GL超出分配的存储空间。
答案 1 :(得分:-1)
谢谢大家,问题在于GL_常数! 这按预期工作:
GLuint n_tex_surface;
GLfloat checkImage[dataheight][datawidth];
for (int i = 0; i < dataheight; i++) {
for (int j = 0; j < datawidth; j++) {
float r = static_cast <float> (rand()) / static_cast <float> (RAND_MAX); = r + 0.01f;
checkImage[i][j] = (GLfloat) r;
}
}
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, &n_tex_surface);
glBindTexture(GL_TEXTURE_2D, n_tex_surface);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
这里我们有GL_RED(一个通道纹理),它是GL_FLOAT:
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, datawidth, dataheight, 0, GL_RED, GL_FLOAT, checkImage);
其余的代码和着色器保持不变。