Sign in to follow this  
jett

Drawing terrain as triangles (from heightmap)

Recommended Posts

I've been experimenting with terrain rendering for my game, but it always turns out wrong. Any help?. I've seen nehes tutorials. But they use quads, which aren't good for terrain. Thanks.

Share this post


Link to post
Share on other sites
Well, it just doesnt draw anything, and when it does, it looks wacky.

And, Quads are harder for the videocard to do textures with.
Its easier to do two triangles.

I'm using .RAW files made with Gimp.


void LoadRawFile(char filename[], int nSize, BYTE *hm)
{

FILE *f = NULL;
f = fopen(filename, "rb");

if(f == NULL)
{
char tmperr[40];
sprintf(tmperr, "Error: Cannot load raw file '%s'.", filename);
l.LogMessage(tmperr);
return;
}

// Read the bytes from the file. 1 byte at a time
// and send them to the pointer to the byte-array.
fread(hm, 1, nSize, f);

if(ferror(f))
{
char tmperr[40];
sprintf(tmperr, "Error: Failed to read raw '%s'.", filename);
l.LogMessage(tmperr);
fclose(f);
return;
}

if(!hm)
{
char tmperr[40];
sprintf(tmperr, "Error: Heightmap '%s', is invalid.", filename);
l.LogMessage(tmperr);
fclose(f);
return;
}

char tmpstr[40];
sprintf(tmpstr, "Heightmap '%s', loaded at (0x%X).", filename, &hm);
l.LogMessage(tmpstr);

fclose(f);

return;
}

But how to draw? I know im not doing it right, cuase its not there.

Im a super beginner at opengl.

Share this post


Link to post
Share on other sites
Quote:
Original post by Arex
Try this tutorial :
http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=34


Read post #1,

Quote:
Original post by Jett
I've seen nehes tutorials. But they use quad



Quote:
Original post by Jett
2 Triangles are easier than a quad for the videocard.



Share this post


Link to post
Share on other sites
Quote:
Original post by jett
I need code for Triangles.


Quads are triangles.

But I digress. I used triangle strips in my terrain engine way back in the day. The algorithm is something like this:


1 2 3 4 5
*-----*-----*-----*-----*
|\ |\ |\ |\ |
| \ | \ | \ | \ |
| \ | \ | \ | \ |
| \ | \ | \ | \ |
| \| \| \| \|
*-----*-----*-----*-----*
6 7 8 9 10
*-----*-----*-----*-----*
|\ |\ |\ |\ |
| \ | \ | \ | \ |
| \ | \ | \ | \ |
| \ | \ | \ | \ |
| \| \| \| \|
*-----*-----*-----*-----*
11 12 13 14 15


You draw this first strip from left to right (you can look up the syntax for triangle strips). But the index ordering is something like:
1, 2, 7, 1, 7, 6, 2, 3, 8, 2, 8, 7, etc

The next strip you draw from right to left (again you can look up the syntax). But the ordering is something like:
9, 10, 15, 9, 15, 14, 8, 9, 14, 8, 14, 13

I don't remember openGL winding or if that's nessarily the correct index ordering but hopefully you get the idea.

-me

Share this post


Link to post
Share on other sites
Use the same code, it is using triangles, but that is an easier way to do quads in opengl, already indexed. You just need to create 2 more vertices which are those vertices that overlap with the other triangle vertices. So basically the quad system is faster, because if you want to draw triangles without indexing then you will have 2 extra vertices. :)

So, duplicate the bottom right and top left vertices for example. And then set it to render triangles.

Share this post


Link to post
Share on other sites
in reply to post #7.

OK, I have an 512X512 heightmap, i try to draw it like,

GLBegin(GL_TRIANGLES);
glVertex3f(x, heightmap[x + (y * 512)], y);
glVertex3f(x+1, heightmap[x + (y * 512)], y);
glVertex3f(x, heightmap[x + (y * 512)], y+1);
glVertex3f(x+1, heightmap[x + (y * 512)], y+1);

dont remember the rest
GLEnd();


i have


BYTE heightmap[512*512];


and,

you saw my loading code.

So, if someone could put what you said in code?

in reply to post #8

Triangles are eaiser for the video card to wrap textures onto.
But with triangles, not trianglestrips.
That would be great.

Share this post


Link to post
Share on other sites
start again from scratch. With what you've learned so far you'll get farther than you will tinkering with existing faulty code, and you'll learn even more in the process.

You want to work with quads, which are each comprised of two triangles. For every pixel (x, y) in the heightmap you want to draw a quad with corners (x, y), (x+1, y), (x, y+1), (x+1, y+1). Because of this fact, you loop through every pixel except for the right/bottom edge ones. This is because you can't access x+1 of the rightmost pixel, as it is off themap. So you end up with a loop structure like this:


for(j=0; j<mapheight-1; j++)
{
for(i=0; i<mapwidth-1; i++)
{
(create a quad by sampling the heightmap at
(i, j), (i+1, j), (i, j+1), (i+1, j+1)
...


Hope that helps!

Share this post


Link to post
Share on other sites
i tried with lines:

X = x;
Y = hmap[(y*512) + x];
Z = y;

glVertex3f(X, Y, Z);

X = x;
Y = hmap[(y*512)+1 + x];
Z = y+1;

glVertex3f(X, Y, Z);

X = x+1;
Y = hmap[(y*512)+1 + x+1];
Z = y+1;

glVertex3f(X, Y, Z);

X = x+1;
Y = hmap[(y*512)+1 + x];
Z = y;

glVertex3f(X, Y, Z);

It showed nothing....

:(

Thanks.

Share this post


Link to post
Share on other sites
My game is at an impasse, because of this.

I have no idea what im doing....

:(

(Im checking this topic every Minute).

If someone posted while i posted this, Thanks.

Share this post


Link to post
Share on other sites
k heres how you do it. Since a quad is two triangles you need to put in six vertices. (Two are the same) So here is the basic idea:


glVertex3f( x, map[ (x * xsize ) + y ], y );
glVertex3f( x, map[ (x * xsize) + y + 1 ], y + 1.0f );
glVertex3f( x + 1.0f, map[ ((x + 1) * xsize) + y ], y );
glVertex3f( x, map[ ( x * xsize) + y + 1 ], y + 1.0f );
glVertex3f( x + 1.0f, map[ ( (x + 1) * xsize) + y ], y );
glVertex3f( x + 1.0f, map[ ( (x + 1) * xsize) + y + 1 ], y + 1.0f );


You probably have to tweak the array reading part.

Share this post


Link to post
Share on other sites
I tweaked it and ran it, still nothing. :(

I know the functions being called. And the commands are sending, But its just not drawing anything.... Cause it worked before. Until i made a new loading function. I did it like nehe but with lines, it didnt work though.

:(

Thanks, In-advance.
-Its so wierd.

Share this post


Link to post
Share on other sites
for starters, you are indexing into your array incorrectly:

Y = hmap[(y*512)+1 + x+1];

should be:

Y = hmap[( (y+1) *512 ) + x+1 ];

what you wrote originally is exactly the same as this:
Y = hmap[(y*512) + x+2];

[EDIT: If you're making mistakes like that I'm also going to suggest that you are way over your head in terms of programming knowledge at this point. You should only try Graphics and OpenGL _after_ you understand the majority of C/C++ (whichever you are using). Graphics is considered advanced programming for good reason. Don't take offense to this, we were all beginners. But you really should start simple and work your way to graphics. Generally graphics is for 3rd year programming students (i.e. they have 2 full years of programming experience before they start with graphics)]

-me

Share this post


Link to post
Share on other sites
Quote:
Original post by Palidine
for starters, you are indexing into your array incorrectly:

Y = hmap[(y*512)+1 + x+1];

should be:

Y = hmap[( (y+1) *512 ) + x+1 ];

what you wrote originally is exactly the same as this:
Y = hmap[(y*512) + x+2];

-me


But i also tried slymr's way.

Nothing :(

Share this post


Link to post
Share on other sites
are you sure you have the winding correct? I believe OpenGL wants the triangles to be of clockwise winding by default. You can check this easily by just moving the camera underneath the terrain.

Otherwise, are you sure you have your camera set up correctly? Are the rendered triangles within the view frustum? You can debug this by just hardcoding a couple triangles that have the coordinates of the triangles you are trying to draw from the array.

-me

Share this post


Link to post
Share on other sites
Quote:
Original post by Palidine
for starters, you are indexing into your array incorrectly:

Y = hmap[(y*512)+1 + x+1];

should be:

Y = hmap[( (y+1) *512 ) + x+1 ];

what you wrote originally is exactly the same as this:
Y = hmap[(y*512) + x+2];

[EDIT: If you're making mistakes like that I'm also going to suggest that you are way over your head in terms of programming knowledge at this point. You should only try Graphics and OpenGL _after_ you understand the majority of C/C++ (whichever you are using). Graphics is considered advanced programming for good reason. Don't take offense to this, we were all beginners. But you really should start simple and work your way to graphics. Generally graphics is for 3rd year programming students (i.e. they have 2 full years of programming experience before they start with graphics)]


-me


I just forgot about the parameter scope.

Anyway, The camera (to my knowledge) is pointing the right way.

And i moved the camera, still squat.

And, Nehes tutorial runs at like 40fps, and there HMAP, is 1024*1024,
Mine runs at 4fps. Im using OGLFT to render fonts, but i dont think it could push it down that much.

Thanks.

Share this post


Link to post
Share on other sites
Quote:
Original post by jett
Mine runs at 4fps. Im using OGLFT to render fonts, but i dont think it could push it down that much.


What makes you think the difference in framerate has anything to do with quads v. triangles? Did you run a profiler on your code and find that the rendering of the quads was what was slowing you down? If you really want to speed up your rendering you want to use triangle strips and vertex arrays instead of glVertex3f(...)

Anyway, did you put in some hardcoded triangles? Do they draw?

-me

Share this post


Link to post
Share on other sites
Yes, hard-coded works, i had to move the camera but it works.

I repeated the process, with the camera moved.

Nothing

Share this post


Link to post
Share on other sites
you are declaring your vertices in a clockwise order?

Are you sure that your hmap array is being loaded correctly? I would try some basic debugging to see what each variable is at each point in the program's execution, and what functions are called when.

Share this post


Link to post
Share on other sites
Im loading it like this:

function Pull(BYTE *hmap, int nsize, filename)

open filename, fread hmap 1 nsize file

close filename

exact code in post #3(i think)

Share this post


Link to post
Share on other sites
Try debug strings. At key points throughout the code do a dump where you printf or cout or whatever the contents of your variables. This way you can be sure that stuff is allocated correctly and that calculations have been done properly

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this