protongun's picture

Textures Displaying with Texture Unit 0 but not Unit 1 (using Fixed Function Pipeline)

I've constructed a basic example to show the issue:

class TextureUnits
    {
        public static GameWindow game = new GameWindow();
 
 
        public static void Main()
        {
            using (game)
            {
                game.Load += game_Load;
                game.RenderFrame += game_RenderFrame;
                game.UpdateFrame += game_UpdateFrame;
 
                game.Run(10.0, 10.0);
            }
        }
        static void game_Load(object sender, EventArgs e)
        {
 
            /*
            **** Change to TextureUnit.Texture1 ******
             */
            GL.ActiveTexture(TextureUnit.Texture0);
            GL.Enable(EnableCap.Texture2D);
 
            int texId = GL.GenTexture();
            GL.BindTexture(TextureTarget.Texture2D, texId);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
            UploadImageFileAsTexture("img.jpg");
 
 
        }
 
        static void UploadImageFileAsTexture(string filename)
        {
            Bitmap bmp = new Bitmap(filename);
            BitmapData bmp_data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
 
            GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, bmp_data.Width, bmp_data.Height, 0,
                OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, bmp_data.Scan0);
 
            bmp.UnlockBits(bmp_data);
        }
 
        static void game_UpdateFrame(object sender, FrameEventArgs e)
        {
 
        }
 
        static void game_RenderFrame(object sender, FrameEventArgs e)
        {
            GL.Begin(PrimitiveType.Quads);
                GL.TexCoord2(0, 0);
                GL.Vertex2(-1, -1);
 
                GL.TexCoord2(1, 0);
                GL.Vertex2(1, -1);
 
                GL.TexCoord2(1, 1);
                GL.Vertex2(1, 1);
 
                GL.TexCoord2(0, 1);
                GL.Vertex2(-1, 1);
            GL.End();
            game.SwapBuffers();
 
        }
    }

If I change GL.ActiveTexture(TextureUnit.Texture0) to GL.ActiveTexture(TextureUnit.Texture1), then I see a single colour for the whole texture. There is clearly something wrong with the sampling / texture coords, as the colour at tex coord (0,0) is being applied to the whole texture.

Strangely, if I apply:

GL.Enable(EnableCap.TextureGenS);
            GL.Enable(EnableCap.TextureGenT);

when TextureUnit1 is used, then the texture image displays but because my vertex coords range from -1 to 1, then the texture coords range from 0 to 2, so I get four images, due to wrapping mode set to repeat.

While I can certainly work around that by using vertex coords in the interval [0,1], I don't see why texture coordinate generation is necessary. Shouldn't the texture mapping work without it, just like it does with texture unit 0?

I know shaders are the way forward, and I've successfully been able to use multiple textures units with shaders. However, I'd still like to know why the fixed function approach won't work.


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
winterhell's picture

Edit: never mind, wrong answer

Frassle's picture

The TexCoord function only affects the first texture unit (TextureUnit.Texture0), to use other texture units you need to use the MultiTexCoord functions (glMultiTexCoord).

        GL.Begin(PrimitiveType.Quads);
        GL.MultiTexCoord2(TextureUnit.Texture1, 0, 0);
        GL.Vertex2(-1, -1);
 
        GL.MultiTexCoord2(TextureUnit.Texture1, 1, 0);
        GL.Vertex2(1, -1);
 
        GL.MultiTexCoord2(TextureUnit.Texture1, 1, 1);
        GL.Vertex2(1, 1);
 
        GL.MultiTexCoord2(TextureUnit.Texture1, 0, 1);
        GL.Vertex2(-1, 1);
        GL.End();
        game.SwapBuffers();
protongun's picture

Wow, did not know about glMultiTexCoord at all. Seems all the texture mapping resources I've read leave it out... and glTexCoord only applying to Tex Unit 0, rather than the current active tex unit, seems like an inconsistency in the OpenGL spec to begin with.

Thanks for your help.