Binding 2 textures, only see 1
Asked Answered
R

1

6

i'm trying to bind 2 textures for my shader. But for some reason it always seems to take the last image that i defined. Am i doing something wrong?

GLuint textures[2];

glEnable(GL_TEXTURE_2D);

glGenTextures(2, textures);
glBindTexture(GL_TEXTURE_2D, textures[0]);
glfwLoadTexture2D("C:\\front.tga", GLFW_BUILD_MIPMAPS_BIT);

glBindTexture(GL_TEXTURE_2D, textures[1]);
glfwLoadTexture2D("C:\\reflect.tga", GLFW_BUILD_MIPMAPS_BIT);

In this case i see 'reflect.tga' for both the reflection and refraction in my shader...

const vec3 Xunitvec = vec3 (1.0, 0.0, 0.0);
const vec3 Yunitvec = vec3 (0.0, 1.0, 0.0);

uniform vec3  BaseColor;
uniform float Depth;
uniform float MixRatio;

// need to scale our framebuffer - it has a fixed width/height of 2048
uniform float FrameWidth;
uniform float FrameHeight;

uniform sampler2D EnvMap;
uniform sampler2D RefractionMap;

varying vec3  Normal;
varying vec3  EyeDir;
varying vec4  EyePos;
varying float LightIntensity;

void main (void)
{
    // Compute reflection vector
    vec3 reflectDir = reflect(EyeDir, Normal);

    // Compute altitude and azimuth angles

    vec2 index;

    index.y = dot(normalize(reflectDir), Yunitvec);
    reflectDir.y = 0.0;
    index.x = dot(normalize(reflectDir), Xunitvec) * 0.5;

    // Translate index values into proper range

    if (reflectDir.z >= 0.0)
        index = (index + 1.0) * 0.5;
    else
    {
        index.t = (index.t + 1.0) * 0.5;
        index.s = (-index.s) * 0.5 + 1.0;
    }

    // if reflectDir.z >= 0.0, s will go from 0.25 to 0.75
    // if reflectDir.z <  0.0, s will go from 0.75 to 1.25, and
    // that's OK, because we've set the texture to wrap.

    // Do a lookup into the environment map.

    vec3 envColor = vec3 (texture2D(EnvMap, index));

    // calc fresnels term.  This allows a view dependant blend of reflection/refraction
    float fresnel = abs(dot(normalize(EyeDir), Normal));
    fresnel *= MixRatio;
    fresnel = clamp(fresnel, 0.1, 0.9);

   // calc refraction
   vec3 refractionDir = normalize(EyeDir) - normalize(Normal);

   // Scale the refraction so the z element is equal to depth
   float depthVal = Depth / -refractionDir.z;

   // perform the div by w
   float recipW = 1.0 / EyePos.w;
   vec2 eye = EyePos.xy * vec2(recipW);

   // calc the refraction lookup
   index.s = (eye.x + refractionDir.x * depthVal);
   index.t = (eye.y + refractionDir.y * depthVal);

   // scale and shift so we're in the range 0-1
   index.s = index.s / 2.0 + 0.5;
   index.t = index.t / 2.0 + 0.5;

   // as we're looking at the framebuffer, we want it clamping at the edge of the rendered scene, not the edge of the texture,
   // so we clamp before scaling to fit
   float recip1k = 1.0 / 2048.0;
   index.s = clamp(index.s, 0.0, 1.0 - recip1k);
   index.t = clamp(index.t, 0.0, 1.0 - recip1k);

   // scale the texture so we just see the rendered framebuffer
   index.s = index.s * FrameWidth * recip1k;
   index.t = index.t * FrameHeight * recip1k;

    vec3 RefractionColor = vec3 (texture2D(RefractionMap, index));

    // Add lighting to base color and mix
    vec3 base = LightIntensity * BaseColor;
    envColor = mix(envColor, RefractionColor, fresnel);
    envColor = mix(envColor, base, 0.2);

    gl_FragColor = vec4 (envColor, 1.0);
}
Resistless answered 28/1, 2012 at 15:3 Comment(4)
What does your shader look like?Verdure
@Verdure Added the code of my fragment shader.Resistless
I'm not seeing any of the obvious things wrong with it. How are you setting the uniform locations of sampler variables? (For example, what's your call to glUniform1i (envMapLoc, 0); look like?)Verdure
@Verdure Well, actually i didn't get the uniform locations for the samplers, because i thought i didn't need to for textures. I just tried to implement it with glUniformli. But its still showing 1 texture instead of two. So i guess i'm still doing it wrong. I've pasted the part of my code where i set all the uniforms and the textures: pastebin.com/0S2iYBB2 --- Any idea what i'm doing wrong there..??Resistless
B
9

A sampler uniform does not bind a texture object but a texture unit. And texture objects are bound to texture units. So the sequence for binding a texture to a shader is

glActiveTexture(GL_TEXTURE0 + texture_unit1);
glBindTexture(GL_TEXTURE_..., texture_object1);

glActiveTexture(GL_TEXTURE0 + texture_unit2);
glBindTexture(GL_TEXTURE_..., texture_object2);


glUniform1i(sampler1_location, texture_unit1);
glUniform1i(sampler2_location, texture_unit2);

Texture Units are in the range 0...GL_MAX_TEXTURE_UNITS.

Brasier answered 28/1, 2012 at 16:27 Comment(2)
Great, thanks alot. Its working good now :) Can't vote up though because of my rep :-(Resistless
Note: You can't pass glUniform1i the same value you use for glActiveTexture. glActiveTexture takes an enum, while glUniform1i takes a texture unit index. So generally, this looks like glActiveTexture(GL_TEXTURE0 + texture_unit1); ... glUniform1i(sampler1_location, texture_unit1);Fidelfidela

© 2022 - 2024 — McMap. All rights reserved.