
Two textures
Posted Friday, 27 March, 2009 - 12:13 by Dinberg inHello!
I have been fooling around with the example for the heightmap, and decided to try to make a field of magma to surround a textured mountain. I managed to load the texture for the mountain easily, and all went well - but upon trying to add the lava texture, it seems to override the mountains.
At first I thought I was in someway saving the image over the same slot, but I compared the values of 'texture' and 'magma' (see below, these are the ids for each texture) and they displayed 1 and 2 respectively. This is my first foray into 3d, so I'm sure i've made a silly mistake. Any help is much appreciated; below is the significant code.
In the initiation of the window:
Bitmap bmp = new Bitmap("tile.bmp"); GL.Enable(EnableCap.Texture2D); GL.GenTextures(1, out texture); GL.BindTexture(TextureTarget.Texture2D, texture); BitmapData 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, data.Width, data.Height, 0, OpenTK.Graphics.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0); bmp.UnlockBits(data); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); bmp = new Bitmap("magma.bmp"); GL.GenTextures(1, out magma); Console.WriteLine("water:" + magma + ", texture:" + texture); GL.BindTexture(TextureTarget.Texture2D, magma); 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, data.Width, data.Height, 0, OpenTK.Graphics.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); bmp.UnlockBits(data);
Before rendering the landscape:
GL.Enable(EnableCap.Texture2D); GL.BindTexture(TextureTarget.Texture2D, texture);
Before rendering the magma:
GL.BindTexture(TextureTarget.Texture2D, magma);
Included is a screenie to elaborate ;)
Many thanks!


Comments
Re: Two textures
Now, this is a seminal example of a support request!
Nothing seems out of place on first look. Are "magma.bmp" and "tile.bmp" really different textures on disk? (Sounds crazy, but I've fallen for that many times). What happens if you place a call to
bmp.Dispose();just before creating the new Bitmap?Re: Two textures
The two textures are definately different - intriguingly, if i comment out the second loading, and set magma = texture, the tiling texture for the mountain comes out perfectly; but then the lava is also covered in the same texture, as would be expected ;)
I'll go test the dispose now ;)
Re: Two textures
No luck on the bmp.Dispose() I'm afraid - I even tried making a new Bitmap object, 'bmp2', in the hope that it would clear things up.
I've tried another BitmapData object aswell, thinking perhaps the information was somehow readonly on account of the locking. That too, turned up no results.
Thanks so far ;)
Re: Two textures
Add GL.Finish after the teximage call and before unlocking the bitmap to guarantee that OpenGL is done with the image. There's no harm in calling GL.Finish during initialization, just avoid calling it per frame.
If that's of no help, GL.GetError() very likely points towards a solution.
Re: Two textures
Related to Inertia's suggestion, it might be a little less efficient, but you could try declaring a second BitmapData object for the second Bitmap.LockBits() call rather than reusing the first one.
Re: Two textures
Hmm the error code at several locations through the code returns as 'NoError', and I'm afraid the GL.Finish didn't bring any fruit either.
Entropy: I did try another Bitmap object aswell, but still giving the same result.
Is there an example which uses multiple textures that you know of? I'm going to continue to crack on and see if I can fix this :D
Was I also correct in my assumption that the int returned by GL.GenTextures is a free 'memory slot' on the textures list? That's the gist I got from all the tutorials, in which case I cant see why slots 1 and 2 are loading different textures yet displaying the same one. As I say I'm new to this, so any help is appreciated =)
Many thanks!
Re: Two textures
Are you positive the problem isn't in the render function?
What happens if you swap the magma/texture handles in the render function for example?
Re: Two textures
Still causing the same issue - if I swap the order both textures are loaded however, its the tile texture that is pasted over the mountain. It's as if it will only display the last texture loaded I think, but I'm pretty stumped!
Thanks for the ideas though, I'll keep trying ;)
Re: Two textures
I tried to start it over, to see if I could get round the problem that way. Sometimes a fresh start helps :D
I made the following function to return the uint slot of a texture generated from a .bmp file path. However this too causes the same errors - I store the uints for both loaded textures in separate variables, 'magma' and 'dirt', yet the same problems occur on rendering:
Re: Two textures
Take a look at the source of OpenTK.Utilities, it contains a simple Texture2D and an RgbaTexture2D.
Add a new constructor to the RgbaTexture2D class that reads like this:
I'm using this in my project without problems.
Edit: I cannot see any problems in your code, maybe there is something amiss in the rendering side. Trying running a "Find all references" on the two texture handles and check for stray assignments or
BindTexturecalls.