Norris's picture

Textures binding problem. Only the last created is shown

Hi.
I have a big problem in my application. I draw some meshes, and each one have a different texture and a different vbo. All is good, except that my application always bind the last created texture. So all the meshes are drawn with the same texture.
My code is nested in many classes, and I can't put all this here. So , this is how I proceed.

When I load my meshes from a custom Wavefront loader, I create a texture from a bitmap and store the id. I use a custom "Texture" class to store the bitmap and the Id.

Private Sub CreateTextureFromBitmap(ByVal bitmap As Bitmap)
            Dim data As SystemImaging.BitmapData = bitmap.LockBits(New Rectangle(0, 0, bitmap.Width, bitmap.Height), _
                                                               SystemImaging.ImageLockMode.ReadOnly, SystemImaging.PixelFormat.Format32bppArgb)
            GL.BindBuffer(BufferTarget.ArrayBuffer, _TextureId)
            GL.BindTexture(TextureTarget.Texture2D, _TextureId)
            GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, data.Width, data.Height, 0, _
                            OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0)
            bitmap.UnlockBits(data)
            'set params
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, CInt(TextureMinFilter.Linear))
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, CInt(TextureMagFilter.Linear))
    End Sub

Now, when I draw a mesh, just before, I bind to his texture with the Id like this.

Private Sub DrawMesh(ByVal meshObj As Mesh)
        GL.Translate(meshObj.WorldPosition)
        GL.Rotate(meshObj.WorldRotation.Y, Vector3.UnitY)
        GL.Rotate(meshObj.WorldRotation.Z, Vector3.UnitZ)
        GL.Rotate(meshObj.WorldRotation.X, Vector3.UnitX)
 
        GL.Enable(EnableCap.Texture2D)
 
        If Not String.IsNullOrEmpty(meshObj.MaterialName) Then
            If _MaterialsDico.ContainsKey(meshObj.MaterialName) Then
                Console.WriteLine("le matériau existe bien")
                Dim meshMat As Material = _MaterialsDico.Item(meshObj.MaterialName)
                GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, meshMat.DiffuseMapEnvironnementMode)
                If meshMat.DiffuseTexture IsNot Nothing Then
                    'Bind to the texture
                    GL.BindTexture(TextureTarget.ProxyTexture2D, meshMat.DiffuseTexture.TextureId)
                End If
            End If
        End If
 
 
        'now draw the mesh with vbo/ibo
        GL.BindBuffer(BufferTarget.ArrayBuffer, meshObj.VertexBufferId)
        GL.BindBuffer(BufferTarget.ElementArrayBuffer, meshObj.IndicesBufferId)
 
        GL.VertexPointer(3, VertexPointerType.Float, Vertex3PNT.Stride, 0)
        GL.NormalPointer(NormalPointerType.Float, Vertex3PNT.Stride, New IntPtr(Vector3.SizeInBytes))
        GL.TexCoordPointer(2, TexCoordPointerType.Float, Vertex3PNT.Stride, New IntPtr(2 * Vector3.SizeInBytes))
        GL.IndexPointer(IndexPointerType.Int, Marshal.SizeOf(GetType(Integer)), 0)
 
 
        GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill)
        GL.DrawElements(BeginMode.Triangles, CInt(meshObj.Indices.Count), DrawElementsType.UnsignedInt, 0)
 
        GL.BindBuffer(BufferTarget.ArrayBuffer, 0)
        GL.BindTexture(TextureTarget.ProxyTexture2D, 0)
        GL.Disable(EnableCap.Texture2D)
    End Sub

I really don't know what is wrong ! I can easily draw a mesh with his texture with this code, but if I draw more than one mesh, all are binded to the same texture, even if I use the right Id. After a check, Ids are good and I think textures are not overridden when they are created.

I have this problem, even If I recreated base projects from scratch. Since one week, I search, but don't find the answer.
Thanks in advance for your help.


Comments

Comment viewing options

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

Your second and third BindTexture calls use ProxyTexture2d as target, which is probably not what you wanted. Try changing those to TextureTarget.Texture2d.

Norris's picture

Hi the Fiddler !
Thanks very much for this very rapid answer !!
that works. I too much rely on VB Intellisense. I don't know exactly what "ProxyTexture2D" is, but I know what I want is "Texture2D".
Shame on me, and thanks again to take time to help for problems so stupid as this one.