PDA

View Full Version : Texture height map



Adrian Hooper
03-17-2009, 06:18 AM
I'm trying to load a texture over a height map and struggling. I've got my texture stored as a jpg and have loaded it. This is working as I've applied the texture to something else as a test, however I can't get it to work properly on my height map

public void renderHeightMap(GL gl, byte[] pheightMap) {
gl.glBindTexture(GL.GL_TEXTURE_2D, land[0]);
gl.glBegin(renderType);
for(int X = 0; X < (MAP_SIZE - STEP_SIZE); X += STEP_SIZE) {
for(int Y = 0; Y < (MAP_SIZE - STEP_SIZE); Y += STEP_SIZE) {
int x = X;
int y = height(pheightMap, X, Y);
int z = Y;

// setVertexColor(gl, pheightMap, x, z);
gl.glTexCoord2i(0,0);
gl.glVertex3i(x, y, z);

x = X;
y = height(pheightMap, X, Y + STEP_SIZE);
z = Y + STEP_SIZE;

// setVertexColor(gl, pheightMap, x, z);
gl.glTexCoord2i(1,0);
gl.glVertex3i(x, y, z);

x = X + STEP_SIZE;
y = height(pheightMap, X + STEP_SIZE, Y + STEP_SIZE);
z = Y + STEP_SIZE;

// setVertexColor(gl, pheightMap, x, z);
gl.glTexCoord2i(1,1);
gl.glVertex3i(x, y, z);

x = X + STEP_SIZE;
y = height(pheightMap, X + STEP_SIZE, Y);
z = Y;

// setVertexColor(gl, pheightMap, x, z);
gl.glTexCoord2i(0,1);
gl.glVertex3i(x, y, z);
}
}
gl.glEnd();
gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
}

That is the code used for rendering my height map. I've added the TexCoord commands and the texture is being applied but for every single square being drawn. I want to stretch the texture over the entire map.

How?
Thanks

BionicBytes
03-17-2009, 06:49 AM
The problem is the drawing loop is setting the same texture coordinates for each of the 4 corners of the square, on each iteration of the loop. Therefore each square is sending 0,1 as texture coords each time.
You need to send in a fraction of the texture width/height on each iteration, for each square.

Notice the use of floats for the texture coords:


public void renderHeightMap(GL gl, byte[] pheightMap) {
gl.glBindTexture(GL.GL_TEXTURE_2D, land[0]);
gl.glBegin(renderType);
for(int X = 0; X < (MAP_SIZE - STEP_SIZE); X += STEP_SIZE) {
for(int Y = 0; Y < (MAP_SIZE - STEP_SIZE); Y += STEP_SIZE) {
int x = X;
int y = height(pheightMap, X, Y);
int z = Y;

// setVertexColor(gl, pheightMap, x, z);
gl.glTexCoord2f(x/MAP_SIZE, z/MAP_SIZE);
gl.glVertex3i(x, y, z);

x = X;
y = height(pheightMap, X, Y + STEP_SIZE);
z = Y + STEP_SIZE;

// setVertexColor(gl, pheightMap, x, z);
gl.glTexCoord2f(x/MAP_SIZE, z/MAP_SIZE);
gl.glVertex3i(x, y, z);

x = X + STEP_SIZE;
y = height(pheightMap, X + STEP_SIZE, Y + STEP_SIZE);
z = Y + STEP_SIZE;

// setVertexColor(gl, pheightMap, x, z);
gl.glTexCoord2f(x/MAP_SIZE, z/MAP_SIZE);
gl.glVertex3i(x, y, z);

x = X + STEP_SIZE;
y = height(pheightMap, X + STEP_SIZE, Y);
z = Y;

// setVertexColor(gl, pheightMap, x, z);
gl.glTexCoord2f(x/MAP_SIZE, z/MAP_SIZE);
gl.glVertex3i(x, y, z);
}
}
gl.glEnd();
gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
}

Adrian Hooper
03-17-2009, 06:55 AM
Cheers. Now however it's not rendering any texture? The map just comes out a slightly greyish colour?

BionicBytes
03-17-2009, 08:03 AM
It may be the winding order of the polygons. Try disabling cullface or change the winding order to test this.

gldisable (GL_CULL_FACE)

If this is the case, you'll need to reorder the texture coordinates to match the winding order.

Adrian Hooper
03-17-2009, 08:41 AM
Still nothing. Just a blank height map :(

BionicBytes
03-17-2009, 08:51 AM
Have you changed any GL state since the change to the texture coordinates?
eg Disabled GL_TEXTURE_2D, or enabled GL_TEXTURE_3D
(You could always put back the original code and check).

What's your graphic h/w ?
What colour are you expecting for the texture? Don't forget that the texture will appear very S T R E A T C H E D !!

Adrian Hooper
03-17-2009, 08:59 AM
I've enabled texture in the init method so that should be fine. I've got a skybox around everything and the textures are loading into that without any issue.

The graphics chip is the NVidia 8600M GT so should be more than capable of handling it.

I made the height map in Terragen and created a texture on there which I've taken and am trying to overlay, so it should be a birds eye view image. I've tested it by loading it to the roof the the skybox which works fine but then this won't load. It simply changes the colour of the height map but not an image

BionicBytes
03-17-2009, 09:04 AM
I've tested it by loading it to the roof the the skybox which works fine but then this won't load. It simply changes the colour of the height map but not an image
I don't understand what you're saying here.
What happens if you put back your 0 1 texture coords ?
All I have done is replace integer tex coords for float coords in the range 0..1. Your GeForce is way more than capable...

Adrian Hooper
03-17-2009, 09:10 AM
That's why I'm confused. When I had the 0 and 1 coords, every little rectangle being produced had the entire texture in rather than stretching over the entire thing. When the coords were changed to the float values it seems to do nothing.

The skybox is made up of 6 textures. If I replace one of these textures for the one I'm trying to use for the height map, it loads and can be seen. But if I try it on this height map it doesn't work.

BionicBytes
03-17-2009, 09:22 AM
Ok so we have established there is no probs displaying the texture...so it has to be the generated texture coordinates for each square.

Change each of the vertex from
gl.glVertex3i(x, y, z);

to

gl.glVertex3f(x, y, z);

and see what happens.

Adrian Hooper
03-17-2009, 09:24 AM
nope exactly the same issue

BionicBytes
03-17-2009, 10:00 AM
x = X + STEP_SIZE;
y = height(pheightMap, X + STEP_SIZE, Y);
z = Y;

// setVertexColor(gl, pheightMap, x, z);
gl.glTexCoord2i(0,1);
gl.glVertex3i(x, y, z);

If you look at the original code you posted, and work your way through the texture coordinates being generated for each square, you'll notice you have transposed the X and Y when generating the UV texture coordinates. For example, look at the code quoted above: you have x = X + step_size and yet the text-coord is set to 0.
A re-write of the function is required to get the correct texture coordinates to align with each vertex.

BionicBytes
03-17-2009, 10:09 AM
Your original code set the vertex winding order in a clock-wise fashion. Try the following to do it counter-clock wise.

public void renderHeightMap(GL gl, byte[] pheightMap) {
gl.glBindTexture(GL.GL_TEXTURE_2D, land[0]);
gl.glBegin(renderType);
for(int X = 0; X < (MAP_SIZE - STEP_SIZE); X += STEP_SIZE) {
for(int Y = 0; Y < (MAP_SIZE - STEP_SIZE); Y += STEP_SIZE) {


int x = X;
int z = Y;
int y = height(pheightMap, x,z);

gl.glTexCoord2f(x/MAP_SIZE, z/MAP_SIZE);
gl.glVertex3f(x, y, z);

x = X + STEP_SIZE;
z = Y;
y = height(pheightMap, x, z);

gl.glTexCoord2f(x/MAP_SIZE, z/MAP_SIZE);
gl.glVertex3f(x, y, z);

x = X + STEP_SIZE;
z = Y + STEP_SIZE;
y = height(pheightMap, x, z);


gl.glTexCoord2f(x/MAP_SIZE, z/MAP_SIZE);
gl.glVertex3f(x, y, z);

x = X;
z = Y + STEP_SIZE;;
y = height(pheightMap, x,z);

gl.glTexCoord2f(x/MAP_SIZE, z/MAP_SIZE);
gl.glVertex3f(x, y, z);
}
}
gl.glEnd();
gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
}

Dj3hut1
03-17-2009, 12:32 PM
Hello,

if f.e. x and MAP_SIZE are integers, x/MAP_SIZE is also of type integer and is rounded down to zero ( that is a popular mistake ).

Try f.e. x * 1.0f / MAP_SIZE


dj3hut1

BionicBytes
03-17-2009, 02:38 PM
yep, good spot. All that has to happen is declare x and z as glfloat.

Adrian Hooper
03-18-2009, 02:15 PM
awesome!!! Thanks! Was the float part. Only thing now is that it seems to have an unusual blueish colour under it. Is there a way to get rid of this? Also the texture seems to be back to front. ie there is water on the peaks and snow where there should be water. Is there a way of flipping this?

BionicBytes
03-19-2009, 04:58 AM
Try flipping the texture coordinate generation if the texture is being displayed upside down or left to right.
Not sure what you mean by blueish colour - have you enabled blending?

Adrian Hooper
03-19-2009, 11:13 AM
ahhh brill got it working! Thanks for your help guys. Really appreciate it :D