假设我的纹理是256x256像素。它包含16个64x64像素的子纹理。子纹理将渲染为四边形。为了提高性能,我想将离散值传递给每个顶点纹理坐标编码的着色器。例如,值0,1,2,3应对应于每个顶点纹理坐标的(0,64),(64,64),(64,0),(0,0)等。
这是我到目前为止所拥有的。
我加载并绑定一个mipmap纹理:
glGenTextures(1, &texture[0]);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
gluBuild2DMipmaps(GL_TEXTURE_2D,3,TextureImage[0]->w,TextureImage[0]->h,GL_RGB,GL_UNSIGNED_BYTE,TextureImage[0]->pixels);
然后我加载我的数据:
glGenVertexArrays(1, &VecArrObj);
glBindVertexArray(VecArrObj);
glGenBuffers(1, &VertexBO);
glBindBuffer(GL_ARRAY_BUFFER, VertexBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(VertAndTex), VertAndTex, GL_STREAM_DRAW);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(0, 3, GL_SHORT, GL_FALSE, 0, 0);
glVertexAttribPointer(1, 1, GL_SHORT, GL_FALSE, 0, (void*)TexOffset);
glGenBuffers(1, &IndexBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indx), Indx, GL_STREAM_DRAW);
此处使用glBindAttribLocation将属性正确分配给myProgram。 这是我显示我的四边形的方式:
glUseProgram(myProgram);
glBindVertexArray(VecArrObj);
glDrawElements(GL_QUADS, 4, GL_UNSIGNED_SHORT, 0);
glBindVertexArray(0);
glUseProgram(0);
现在mipmap纹理经常被绑定,它应该可以从着色器访问。到目前为止,我的着色器看起来如下。
顶点着色器:
#version 130
in vec4 posit; //attr=0
in short textu; //attr=1
uniform mat4 trafoMat;
void main()
{
gl_Position = trafoMat * posit;
gl_TexCoord[0] = gl_MultiTexCoord0;
}
片段着色器:
#version 130
uniform sampler2D tex;
out vec4 outColor;
void main()
{
outColor = texture2D(tex,gl_TexCoord[0].st);
}
tex设置为零。这些着色器甚至不能获取整个纹理,只是将整个四边形设置为纹理中的一种颜色(我认为它是左上角像素)。显然我对着色器没有多少经验。基本上,我的问题是:我应该如何为开头所描述的目的修改着色器? (我能够对每个顶点纹理坐标进行数学计算 - 我主要要求的是如何在着色器中处理纹理。请注意:我的硬件不支持glGenSamplers())。
答案 0 :(得分:3)
首先,除非你使用简单的映射(即f(x) - >(u,v),其中f是一个简单的函数),你应该创建一个执行映射的间接纹理。在您的情况下,它将是一维纹理并具有16(双组件)条目。
其次,您需要将 point-sample 插入到间接纹理中,以找出从实际纹理中取样的位置。假设您的四边形具有0..1 UV坐标,则生成的着色器将如下所示:
// gl_TexCoord[0].st is 0..1, per quad
void main ()
{
gl_Position = trafoMat * posit;
// 0..1 UV coordinate
gl_TexCoord[0] = gl_MultiTexCoord0;
// Rescale into sub-tile
gl_TexCoord[0] *= (1/4.0);
// Add the offset, if your hardware does not support
// texture fetches in the vertex shader, move this into the
// fragment shader.
// gl_MultiTexCoord1 is the 1D offset into the indirection
// texture
gl_TexCoord[0] += texture2D(offsetTexture,gl_MultiTexCoord1);
}
// This is the fragment shader!
void main ()
{
outColor = texture2D(tex,gl_TexCoord[0]);
}
tex
纹理最有可能是线性过滤的,offsetTexture
需要点 - 您可以使用glTexParameter手动设置它们而不使用采样器。