如何在现代 opengl 中制作样本一维纹理?
How to make a sample 1D textures in modern opengl?
我创建了这个简单的程序。它创建两个纹理,一个 2D 和一个 1D 纹理绑定它们,等等。
我可以在我的着色器程序中从 2D 纹理采样和绘制,没有任何问题。尝试从 1D 纹理采样和绘制,四边形变成黑色。
如果我不在下面的 if..else.. 语句中的片段着色器中使用 1D 纹理样本,则所有内容都呈现为黑白。尝试使用示例,它只呈现黑屏。
如果我像这样进行黑客攻击:
if (i == maxIterations)
{
tcolor = vec4(0.0f, 0.0f, 0.0f, 1.0f);
}
else if(i <= 10)
{
tcolor = vec4(1.0f, 0.0f, 0.0f, 0.0f);
} else if ( i >= 11)
{
tcolor = vec4(1.0f, 1.0f, 0.0f, 0.0f);
}
它也可以.....我如何采样一维纹理?
源代码如下
glGenTextures(1, &colorTextureID);
glBindTexture(GL_TEXTURE_2D, colorTextureID);
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_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, Mode, colorSurface->w, colorSurface->h, 0, Mode, GL_UNSIGNED_BYTE, colorSurface->pixels);
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
free(colorSurface);
//mandi 1d texture
glGenTextures(1, &mandiTextureID);
glBindTexture(GL_TEXTURE_1D, mandiTextureID);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage1D(GL_TEXTURE_1D, 0, Mode1, mandiSurface->w, 0, Mode1, GL_UNSIGNED_BYTE, mandiSurface->pixels);
glBindTexture(GL_TEXTURE_1D, 0);
free(mandiSurface);
//render
void render()
{
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glUseProgram(sp);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, colorTextureID);//ourTexture
ourTexture = getUniformLocation(sp, "ourTexture");
glUniform1i(ourTexture, 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_1D, mandiTextureID);//mandiTexture
mandiTexture = getUniformLocation(sp, "mandiTexture");
glUniform1i(mandiTexture, 1);
glBindVertexArray(verticesBuffer);
viewMat = getUniformLocation(sp, "viewMat");
modelMat = getUniformLocation(sp, "modelMat");
projMat = getUniformLocation(sp, "projMat");
maxIterLoc = getUniformLocation(sp, "maxIterations");
centerLoc = getUniformLocation(sp, "center");
scaleLoc = getUniformLocation(sp, "scale");
glUniformMatrix4fv(viewMat, 1, GL_FALSE, vm.m);
glUniformMatrix4fv(projMat, 1, GL_FALSE, opm.m);
glUniformMatrix4fv(modelMat, 1, GL_FALSE, tm.m);
glUniform1i(maxIterLoc, 20);
glUniform1f(scaleLoc, scale);
glUniform2f(centerLoc, cx, cy);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
}
顶点着色器
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 icolor;
layout (location = 2) in vec2 vTexCoord;
uniform mat4 modelMat;
uniform mat4 viewMat;
uniform mat4 projMat;
out vec4 fcolor;
out vec2 fTexCoord;
out vec2 fCoord;
void main()
{
gl_Position = projMat * viewMat * modelMat * vec4(position, 1.0);
fCoord = vec2(position);
fTexCoord = vTexCoord;
fcolor = vec4(icolor, 1.0f);
}
片段着色器
#version 330 core
in vec4 fcolor;
in vec2 fTexCoord;
in vec2 fCoord;
uniform int maxIterations;
uniform vec2 center;
uniform float scale;
uniform sampler2D ourTexture;
uniform sampler1D mandiTexture;
out vec4 color;
void main()
{
vec2 c, z;
c.x = 1.3333 * (fCoord.x - 0.5) - center.x;
c.y = (fCoord.y - 0.5) - center.y;
int i;
z = c;
for(i=0; i<maxIterations; i++) {
float x = (z.x * z.x - z.y * z.y) + c.x;
float y = (z.y * z.x + z.x * z.y) + c.y;
if((x * x + y * y) > 4.0) break;
z.x = x;
z.y = y;
}
vec4 tcolor;
if (i == maxIterations)
{
tcolor = vec4(0.0f, 0.0f, 0.0f, 1.0f);
}
else
{
/* tcolor = vec4(1.0f, 1.0f, 1.0f, 1.0f); this works but only renders black and white */
tcolor = texture(mandiTexture, float(i)).rgba; /* only renders black screen */
}
/* color = texture(ourTexture, fTexCoord) * fcolor; //this also works */
color = tcolor;
}
目前,您正在使用 0 到 maxIterations
(i
的可能值)范围内的纹理坐标来查找 1D 纹理中的值。正如dari在评论中提到的,纹理坐标在0-1的范围内,忽略了wrapping和clamping。
因此,将 i
除以 maxIterations
得到 0-1 范围内的坐标:
tcolor = texture(mandiTexture, float(i) / float(maxIterations)).rgba;
我创建了这个简单的程序。它创建两个纹理,一个 2D 和一个 1D 纹理绑定它们,等等。
我可以在我的着色器程序中从 2D 纹理采样和绘制,没有任何问题。尝试从 1D 纹理采样和绘制,四边形变成黑色。
如果我不在下面的 if..else.. 语句中的片段着色器中使用 1D 纹理样本,则所有内容都呈现为黑白。尝试使用示例,它只呈现黑屏。
如果我像这样进行黑客攻击:
if (i == maxIterations)
{
tcolor = vec4(0.0f, 0.0f, 0.0f, 1.0f);
}
else if(i <= 10)
{
tcolor = vec4(1.0f, 0.0f, 0.0f, 0.0f);
} else if ( i >= 11)
{
tcolor = vec4(1.0f, 1.0f, 0.0f, 0.0f);
}
它也可以.....我如何采样一维纹理?
源代码如下
glGenTextures(1, &colorTextureID);
glBindTexture(GL_TEXTURE_2D, colorTextureID);
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_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, Mode, colorSurface->w, colorSurface->h, 0, Mode, GL_UNSIGNED_BYTE, colorSurface->pixels);
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
free(colorSurface);
//mandi 1d texture
glGenTextures(1, &mandiTextureID);
glBindTexture(GL_TEXTURE_1D, mandiTextureID);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage1D(GL_TEXTURE_1D, 0, Mode1, mandiSurface->w, 0, Mode1, GL_UNSIGNED_BYTE, mandiSurface->pixels);
glBindTexture(GL_TEXTURE_1D, 0);
free(mandiSurface);
//render
void render()
{
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glUseProgram(sp);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, colorTextureID);//ourTexture
ourTexture = getUniformLocation(sp, "ourTexture");
glUniform1i(ourTexture, 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_1D, mandiTextureID);//mandiTexture
mandiTexture = getUniformLocation(sp, "mandiTexture");
glUniform1i(mandiTexture, 1);
glBindVertexArray(verticesBuffer);
viewMat = getUniformLocation(sp, "viewMat");
modelMat = getUniformLocation(sp, "modelMat");
projMat = getUniformLocation(sp, "projMat");
maxIterLoc = getUniformLocation(sp, "maxIterations");
centerLoc = getUniformLocation(sp, "center");
scaleLoc = getUniformLocation(sp, "scale");
glUniformMatrix4fv(viewMat, 1, GL_FALSE, vm.m);
glUniformMatrix4fv(projMat, 1, GL_FALSE, opm.m);
glUniformMatrix4fv(modelMat, 1, GL_FALSE, tm.m);
glUniform1i(maxIterLoc, 20);
glUniform1f(scaleLoc, scale);
glUniform2f(centerLoc, cx, cy);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
}
顶点着色器
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 icolor;
layout (location = 2) in vec2 vTexCoord;
uniform mat4 modelMat;
uniform mat4 viewMat;
uniform mat4 projMat;
out vec4 fcolor;
out vec2 fTexCoord;
out vec2 fCoord;
void main()
{
gl_Position = projMat * viewMat * modelMat * vec4(position, 1.0);
fCoord = vec2(position);
fTexCoord = vTexCoord;
fcolor = vec4(icolor, 1.0f);
}
片段着色器
#version 330 core
in vec4 fcolor;
in vec2 fTexCoord;
in vec2 fCoord;
uniform int maxIterations;
uniform vec2 center;
uniform float scale;
uniform sampler2D ourTexture;
uniform sampler1D mandiTexture;
out vec4 color;
void main()
{
vec2 c, z;
c.x = 1.3333 * (fCoord.x - 0.5) - center.x;
c.y = (fCoord.y - 0.5) - center.y;
int i;
z = c;
for(i=0; i<maxIterations; i++) {
float x = (z.x * z.x - z.y * z.y) + c.x;
float y = (z.y * z.x + z.x * z.y) + c.y;
if((x * x + y * y) > 4.0) break;
z.x = x;
z.y = y;
}
vec4 tcolor;
if (i == maxIterations)
{
tcolor = vec4(0.0f, 0.0f, 0.0f, 1.0f);
}
else
{
/* tcolor = vec4(1.0f, 1.0f, 1.0f, 1.0f); this works but only renders black and white */
tcolor = texture(mandiTexture, float(i)).rgba; /* only renders black screen */
}
/* color = texture(ourTexture, fTexCoord) * fcolor; //this also works */
color = tcolor;
}
目前,您正在使用 0 到 maxIterations
(i
的可能值)范围内的纹理坐标来查找 1D 纹理中的值。正如dari在评论中提到的,纹理坐标在0-1的范围内,忽略了wrapping和clamping。
因此,将 i
除以 maxIterations
得到 0-1 范围内的坐标:
tcolor = texture(mandiTexture, float(i) / float(maxIterations)).rgba;