【问题标题】:openGL texture/shader bindingopenGL 纹理/着色器绑定
【发布时间】:2013-08-01 07:03:30
【问题描述】:

我是 OpenGL 的新手,无法理清将纹理和着色器绑定到 VBO 的工作原理。

我正在使用 Cinder 的纹理和着色器类。这是我绘制方法的一部分:

mShader.bind();

myImage.bind();
glPushMatrix();
glTranslated( scaledX, scaledY, scaledZ);
gl::draw(sphere.getVBO());
glPopMatrix();

glPushMatrix();
glTranslated( 0, 0, zshift - 200);
mDisc.draw();
glPopMatrix();

在上面的代码中,如果我注释掉对 mShader.bind() 的调用,我的球体 VBO 将显示纹理 (myImage)。我的着色器适用于普通(无纹理)形状,但是当我在绘制任何带有包裹纹理的形状之前绑定着色器时,它会阻止纹理显示。

这是我正在使用的着色器的问题,还是我不理解的其他问题? (……还有很多不明白的地方)

谢谢

编辑:

这是我正在使用的着色器:

(片段):

uniform sampler2DShadow     depthTexture;

varying vec3                N, V, L;
varying vec4                q;

void main(void)
{
    vec3 normal = normalize( N );
    vec3 R = -normalize( reflect( L, normal ) );

vec4 ambient = gl_FrontLightProduct[0].ambient;
vec4 diffuse = gl_FrontLightProduct[0].diffuse * max(dot( normal, L), 0.0);
vec4 specular = gl_FrontLightProduct[0].specular * pow(max(dot(R, V), 0.0), gl_FrontMaterial.shininess);

vec3 coord = 0.5 * (q.xyz / q.w + 1.0);
float shadow = shadow2D( depthTexture, coord ).r;
gl_FragColor = ((ambient + (0.2 + 0.8 * shadow) * diffuse) + specular * shadow);

}

(垂直):

varying vec3        N, V, L;
varying vec4        q;
uniform mat4        shadowTransMatrix;

void main(void)
{
    vec4 eyeCoord = gl_ModelViewMatrix * gl_Vertex;

V = normalize( -eyeCoord.xyz );
L = normalize( gl_LightSource[0].position.xyz - eyeCoord.xyz );
N = gl_NormalMatrix * gl_Normal;

q = shadowTransMatrix * eyeCoord;

gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

}

【问题讨论】:

  • 显示你的着色器代码。大多数情况下,您将需要不同的着色器来进行纹理处理。此代码还将 VBO 和着色器与不推荐使用的功能混合在一起。
  • "我正在使用 Cinder 的纹理和着色器类。" 如果你想了解 OpenGL 的工作原理,你需要让自己接触 OpenGL ,而不是隐藏 OpenGL的类。
  • 我已经添加了着色器。我正在为一个心理课程做一个项目,而且时间非常有限。我很快就会正确地学习 OpenGL,但现在我只是想理解足够多的东西来拼凑一些像样的东西。

标签: opengl shader textures


【解决方案1】:

您必须自己在着色器中实现纹理采样。我看到着色器已经使用了阴影纹理采样器,这是​​您要使用的纹理吗?如果是这样,你必须这样做:

  1. 设置活动纹理单元:glActiveTexture(GL_TEXTURE0);
  2. 激活纹理:可能是myImage.bind();
  3. 获取统一变量“depthTexture”的位置:GLint loc = glGetUniformLocation(program, "depthTexture");
  4. 将纹理绑定到着色器中的纹理采样器:glUniform1i(loc, 0);

注意:在第 3 步中,您必须将着色器程序 ID 作为第一个参数传递给 glGetUniformLocation。我不知道Cinder 的纹理和着色器类,但我想有一种方法可以直接查询它们以获得统一的变量位置(甚至直接设置变量值),或者至少它们应该允许您获取程序 ID。在第 4 步中,您告诉 OpenGL 将 depthTexture 采样器设置为第一个纹理单元的纹理(索引为 0);您需要这样做,因为您之前使用 glActiveTexture(GL_TEXTURE0); 选择了此纹理单元。

有关在着色器中使用纹理的更深入示例,另请参阅 this

【讨论】:

  • 有了着色器,您不再需要glEnable(GL_TEXTURE_…); 过去由 glEnable 状态控制的大部分内容现在都根据着色器执行来定义。
  • 好吧嗯,是的,我显然在这里遗漏了一些核心信息。当我使用显示列表绘制几何形状时,着色器中的阴影纹理按我想要的方式工作,每个列表都设置了材料(煤渣类)。当我想在我制作的 VBO 上使用该阴影着色器时会出现问题(通过导入我在 photoshop 中制作的 .obj 文件);具体来说,当我在 VBO 周围包裹纹理时,我似乎无法让当前着色器与 VBO 一起工作(这只是一朵花的 .png)
  • 所以你想在你的 VBO 中额外应用纹理到对象的面?
  • 是的。我可以让纹理在没有着色器的情况下工作,而着色器在没有纹理的情况下工作,但不能同时进行。问题似乎是我对着色器如何工作的理解为零。我希望我错过了一些简单的东西,但可能不是!
  • 您是否查看了我在答案中链接的教程?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-07
  • 2012-12-27
  • 1970-01-01
  • 1970-01-01
  • 2016-01-10
  • 1970-01-01
  • 2013-06-13
相关资源
最近更新 更多