OpenGL heightmap terrain render does not draw - c++

I have a bitmap map that created from a dted file. I want to use that bitmap and create a 3d terrain render. I am trying to do it with vertex vectors but I couldn't reach my goal at all. Here is my paintGL code:
void render::paintGL(){
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glTranslatef(0,0,-100);
for(int z=0;z<dted.width()-1;z++){
glBegin(GL_TRIANGLE_STRIP);
for(int x = 0; x<dted.height()-1; x++){
glColor3f(matrix[x][z], matrix[x][z], matrix[x][z]);
glVertex3f(x, matrix[x][z], -z);
//vertex0 ends here
glColor3f(matrix[x+1][z], matrix[x+1][z], matrix[x+1][z]);
glVertex3f(x+1, matrix[x+1][z], -z);
//vertex1 ends here
glColor3f(matrix[x][z+1], matrix[x][z+1], matrix[x][z+1]);
glVertex3f(x, matrix[x][z+1], -z-1);
//vertex2 ends here
glColor3f(matrix[x+1][z+1], matrix[x+1][z+1], matrix[x+1][z+1]);
glVertex3f(x+1, matrix[x+1][z+1], -z-1);
//vertex3 ends here
}
glEnd();
}}
I had to write the code instead of copy-paste because of internet issues. So there may be things that I forgot but I did my best. Let me explain the variables and other things above:
dted is the dted image I created and I set boundaries from that images width and height values. matrix is a 2d matrix that holds the elevation values I get from the pre-created dted image pixels.
After all the code above I couldn't manage to render the terrain. I don't know if it renders the terrain but it just doesn't show me or it's not rendering at all. If you explain where is my mistake and suggest a solution for it, it would be great.
Sorry for the grammar mistakes if I did any, and I hope I did explain my problem well. If the code I provided is not sufficient, feel free to mention that and I can write the other parts down too.
Have a nice day.
Edit: Ok I got a fresh news over here. I have managed to draw a plain after getting over some control with mouse issues. However, when I try to get amplitude, it shows nothing. That because of the too much amplitude I guess, but when I divide it by a constant like 15 the same plain shows up again. Is this because of I used GL_TRIANGLE_STRIP ?

Your rendering code seems strange: You build your tri strip with degenerated triangles and might access data which isn't there. I guessed the rest of your approach and tried to fix your method. Try this:
void render::paintGL(){
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glTranslatef(0,0,-100);
for(int z = 0; z < dted.width() - 2; z++) {
glBegin(GL_TRIANGLE_STRIP);
for(int x = 0; x < dted.height() - 1; x++){
glColor3f(matrix[x][z], matrix[x][z], matrix[x][z]);
glVertex3f(x, matrix[x][z], -z);
//vertex0 ends here
glColor3f(matrix[x][z + 1], matrix[x][z + 1], matrix[x][z + 1]);
glVertex3f(x, matrix[x][z + 1], -z - 1);
//vertex1 ends here
}
glEnd();
}}
Other than this, triangle strips are fine. If you still don't see anything, follow the suggestion by Sga and use GL_POINTS. Then fix you camera/other rendering code until you see them.

For the other guys who are looking for solution at this: Make sure that your glFrustum's zNear parameter is far enough to see things. Mine were to close and when I increased it, the problem was solved.

Related

2D Coordinate Confusion

Alright, so I have never created a game before, and I am trying to make a 2d tile based game.
So I am really confused about something that should be pretty simple, coordinates.
I have tile coordinates, like
{0,0,0,0,0,1}
{0,0,1,0,0,1}
{0,0,0,0,0,1}
{0,0,1,1,1,1}
{0,0,0,0,0,1}
lets say this is my world and i am trying to render it, well i cant render it, each tile needs a width,
this is where i get confused, so you can do, im not new to coding
twidth = 100, theight = 100;
for(y = each row) {
for(x = each tile in each row) {
draw rect (
X1 = x*twidth,
Y1 = y*theight,
X2 = x*twidth+twidth,
X2 = y*theight+theight
)
}
}
I might be wrong about this, but: now literally everything else needs to multiplied by the twidth/height, it will be even harder if you want different sized tiles, at least its confusing to me, how do other games handle things like this? im not sure if i explained very well what my problem is, any help would be appreciated
im using opengl[legacy] and i think the solution might be a function to setup screenspace differently, so rendering
glVertex2d(0,1) is actually 100px, this would make collisions, and such, much easier
im using opengl[legacy] and i think the solution might be a function to setup screenspace differently, so rendering glVertex2d(0,1) is actually 100px, this would make collisions, and such, much easier
You can achieve that in legacy OpenGL by setting up the projection matrix properly:
glMatrixMode(GL_PROJECTION);
glOrtho(0, 16, 0, 9, -1, 1);
This will set it up so that glVertex2d(0, 0) maps to the bottom left corner and glVertex2d(16, 9) will map to the top right corner, giving you 16x9 tiles in the viewport. To fix the size of the tile in pixels we calculate the fractional number of tiles instead:
glOrtho(0, (double)viewportWidth / twidth, 0, (double)viewportHeight / theight, -1, 1);
After that you can 'scroll' the world by translating it through the GL_MODELVIEW matrix.

OpenGL glRasterPos doesn't properly accept my Values

I've been trying to add some basic HUD-like Text to my OpenGL/C++ project.
Therefore i decided
glutBitmapCharacter( type, character)
to be my weapon of choice.
I realized that, for the easiest use, i should append a 2D Matrix to my previous Rendering area.
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0, 10, 0, 10);
This should give me a sweet 10*10 2D cube to play around in.
Now a problem arised when glutBitmapCharacter remembers his last character position to append the next one. Pretty smart while it's writing a string, it obviously remembers this position and makes my Text fly all the way across screen once :) Naughty.
glRasterPos2f(x,y);
should be - as i heard - the normal thing to reset this thingy - (altough i don't perfectly understand why a gl function controls a glu Function, but thats just a sidenote).
Now the weird thing that happens, is once i run the code:
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0, 10, 0, 10);
string message ="mmh... Pie...";
float poss[3];
glRasterPos3f(0.0, 0.0, 0.0);
glGetFloatv(GL_CURRENT_RASTER_POSITION, poss);
std::cout<< "X" <<(GLfloat) poss[0] << " Y"<<poss[1] << " Z"<<poss[2] << std::endl;
for( size_t i = 0; i < message.size(); ++i ) {
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, message[i]);
}
glPopMatrix();
My Text doesnt get shown. In fact the resulting X, Y and Z
(not even sure Z is necessary.. should be 0 anyway) are all inf (infinite).
If i don't set my own glRasterPos, things just work out fine, apart from leaving the screen. My returning positions are an upcounting X and 0 , 0 - as expected.
So whats the deal on this, what exactly am i doing wrong?
you produced a grand Segmentation Error: glGetFloatv(GL_CURRENT_RASTER_POSITION, poss) returns 4 values, so you must use:
float poss[4];
Apart from this, your code runs fine on my machine and returns:
X0 Y0 Z0.5
So the fault seems not to be in the code you posted here. You should try&copy it to a basic "HelloWorld"-GL program and see if it works there. Be careful that some OpenGL commands only work after a valid drawing surface is initialized - I guess you did that?

opengl glutWireTorus artifact

I am working on a small animation of a sinewave being generated by a moving circle similar to this gif.
However I'm having a weird issue with using glutWireTorus for the circle. Even when I comment out all the other drawing code and leave the torus moving along the z axis alone, I get flashing lines on the inside of it:
This is the display function where everything is drawn. I use the display function as my idle function, also, I checked if that was the issue by creating an idle function and putting my update code there but it still persisted.
void display(void)
{
glClearColor(0.f,0.f,0.f,0.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the color buffer
and the depth buffer
glLoadIdentity();
glTranslatef(0.0f,0.0f,-5.0f); //Push everything back 5 units into the scene,
otherwise we won't see the primitive
camera();
//yPrev = myCircle.y;
glPushMatrix();
glTranslatef(0.0f,0.0f,t);
glutWireTorus(0.02,1,100,100);
glPopMatrix();
DrawAxes();
glutSwapBuffers(); //swap the buffers
glFlush();//Flush the OpenGL buffers to the window
t-=0.002;
if (t < -T)
{
t = 0;
}
}
Uh, interesting, I run into the same problem.
Here is the picture using parameter
glutWireTorus(/*innerRadius*/0.3, /*outerRadius*/0.5, /*nsides*/32, /*rings*/32);
another picture using parameter
glutWireTorus(/*innerRadius*/0.3, /*outerRadius*/0.5, /*nsides*/64, /*rings*/128);
We don't know why without glutWireTorus function implementation, but we can implements our own torus, or maybe someone can explain it?

Add sin wave to triangle mesh

can someone help me addd a sin wave onto my triangle mesh to help me get a wave effect.
for(int i = 0; i<150; i++){
for(int j = 0; j<150; j++){
grid[i][j] = 0;
glBegin(GL_LINE_LOOP);
glVertex3f(i*3,grid[i][j],j*3);
glVertex3f(i*3,grid[i][j],j*3+3);
glVertex3f(i*3+3,grid[i][j],j*3);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex3f(i*3,grid[i][j],j*3+3);
glVertex3f(i*3+3,grid[i][j],j*3+3);
glVertex3f(i*3+3,grid[i][j],j*3);
glEnd();
}
}
If i've got it right, all i should need to do is add a sin value to grid[i][j], am i right?
Are all the y values to be set to the same grid[i][j]?
It really depends on what you are trying to accomplish.
Are you trying to set up a surface that when looked on edge it looks like a sine wave?
If that is the case then assuming that you are modulating the y-axis and the z-axis plays no effect then you need to determine the frequency you want to use.
i.e y = A * sine (w * x + p) where A is amplitude, w is angular frequency, and p is phase.
You will also have to take into account the number of sample points on the x-axis so that it doesn't look to aliased. Sine is a continuous function but you are take only 150 samples.
Also you may want to reconsider how to calculate and draw your final triangle mesh. Your current code is not the most efficient because you are recalculating your mesh every frame.
You may want to consider initializing grid and then drawing triangle strips, etc. There is a lot online that discusses that.

Flag effect in opengl

I'm trying to follow this online tutorial to create some waves
http://nehe.gamedev.net/tutorial/flag_effect_(waving_texture)/16002/.
I want to make the wave much bigger, but I'm not sure if I'm going about it the right way, the current mesh of quads is sized 45 in the tutorial, so i have increased to 450, however the size doesn't seem to increase that much.
Can someone point me in the right direction as to what needs to be modified to make the quads bigger.
If you just want to make the quads bigger, then you need to modify the vertex position code. In the NeHe tutorial you posted change this part:
// Loop Through The X Plane
for(int x=0; x<45; x++)
{
// Loop Through The Y Plane
for(int y=0; y<45; y++)
{
// Apply The Wave To Our Mesh
points[x][y][0]=float((x/5.0f)-4.5f);
points[x][y][1]=float((y/5.0f)-4.5f);
points[x][y][2]=float(sin((((x/5.0f)*40.0f)/360.0f)*3.141592654*2.0f));
}
}
To this:
// Loop Through The X Plane
float spacing = 0.5f;
float spacingInv = 1.0f/spacing;
float offset = (45 / spacingInv) / 2.0f; // The 45 comes from the number of points (if you change this, change the for loop and the variable creation)
for(int x=0; x<45; x++)
{
// Loop Through The Y Plane
for(int y=0; y<45; y++)
{
// Apply The Wave To Our Mesh
// We change the x/5.0f-4.5f to change the size of the quads
// See text after for more details
points[x][y][0]=float((x/spacingInv)-offset);
points[x][y][1]=float((y/spacingInv)-offset);
points[x][y][2]=float(sin((((x/spacingInv)*40.0f)/360.0f)*3.141592654*2.0f));
}
}
Explanation:
x/5.0f gives you values 0, 0.2, 0.4, 0.6, 0.8, 1.0, ......, 9.0.
If you were to take just those values, you would now have an off center grid of quads. Now taking x/5.0f - 4.5f gives you values -4.5 -4.3, -4.1, ...... 4.1, 4.3, 4.5
If you wanted to make the quads bigger, you need to increase the spacing between the points (i.e. change the x/5.0f to something like x/2.0f (which is what happens in the example I gave)). And then you want to recenter (i.e. change the -4.5f).