PDA

View Full Version : More opengl and a sample :)



jdarling
11-08-2010, 03:58 PM
I've made even more progress on my OpenGL learnings and now have something (well sort of) to show for it. I have random height mapping in place, texturing, and other fun things and started on lighting (headache of headaches). I'm hoping that someone can take a run through and look at what I've done and help point out my mistakes (I know there are several) as I'm getting to the point of just beating my head against the wall.

1st thing to notice when running is that only 1 side of the spinning star is lighted (I'm guessing normals here)
2nd thing is that the ground doesn't look right. Even though it has height it looks smooth. If you scale the size down or move to the edges you can see the height changers.
3rd thing is the speed... I'm using display lists and everything I thought was the right way of doing things, but still, at only 100x100 land size I only get ~150 fps on a system that should do much better.

This all tells me, I'm doing it wrong, but hey, I'm having fun learning :)



ESC - Exit
Left Arrow - Turn Left
Right Arrow - Turn Right
Up Arrow - Move Forward
Down Arrow - Move Backward
A - Strafe Left
D - Strafe Right
Q - Float Up
Z - Sink Down
R - Reset Camera Position
H - Toggle HUD
F11 - Toggle Full Screen
? - Display Help to console window


Download at: http://www.eonclash.com/PGD/RenderingEngine.zip

Thanks,
- Jeremy

Traveler
11-08-2010, 08:35 PM
Hi Jeremy,

I've tried the demo but it didn't work for me. It shuts down right on startup. I assume there aren't any dll's involved since its opengl, but still is there something missing from the package?

jdarling
11-08-2010, 09:49 PM
Shouldn't be anything missing... The sources are all there to build the app from scratch if you have Lazarus installed. I'd be interested to know what your running so I know where to start looking :)

Traveler
12-08-2010, 08:00 AM
Ah, tbh it was already getting late so I only tried the executable and didn't look at the source. Plus, I'm not that familiar with opengl so I probably couldn't tell what to improve anyway. I only use Delphi btw, no lazarus.

User137
12-08-2010, 12:02 PM
The executable doesn't work for some reason. It normally flashes and closes, but running from console i captured the message:

An unhandled exception occurred at $004028D4 :
EAccessViolation : Access violation
$004028D4 BUILDHUDBACKGROUND, line 255 of EngineTest.lpr
$00417A31 TGLHUD__REINIT, line 165 of D:/netti/RenderingEngine/RenderingEngi
ne/lib/uGLHUD.pas
$00410DBB TGLENGINE__RUN, line 488 of D:/netti/RenderingEngine/RenderingEngi
ne/lib/uGLEngine.pas
$00402E10 main, line 343 of EngineTest.lpr

Weirdly when i first run it from Lazarus it worked. Cubes rotating and in HUD aswell. But then i modified code to force recompile, debugger stopped with SIGSEGV at:

procedure BuildHUDBackground(const sender : TGLHUD);
begin
GLHUD.DrawRect(...

jdarling
12-08-2010, 12:53 PM
Talk about a DUHH moment, I had one! Apparently while testing my ability to load images I took out the default value for the image wrapper used by the HUD. Quick fix, put it back in. Of course, no one saw this when running in the IDE as it was passing the image name (test2.png) as a parameter and loading it properly (oops).

Fixed now, download location is the same. Should be able to extract and re-run with no problems. Really need to get that logging stuff put back into place :)

- Jeremy

PS: Does anyone know a way to make a class method that still has class visibility? IE:


type
TMyClass=Class
class function test : TObject;
end;

class function TMyClass.test : TObject;
begin
if(assigned(self))then
result := self
else
result := TMyClass.Create;
end;

And no, that's not what I'm trying to do, but singleton's make for a good example :)

VilleK
12-08-2010, 01:38 PM
You need a static member field in your class. This works at least in Delphi 2010.

TTest = class
private
class var Instance : TTest;
public
end;

Brainer
13-08-2010, 11:49 AM
Looks solid. :) The only thing I can complain about is that the terrain (I suppose it's a terrain) doesn't have either normals calculated or the texture is of a poor quality. Other than that, everything seems to be working fine. I didn't have a look at the code, tho', but looking at the framerate I can assume your code is optimal.

Keep up the great work. :)

jdarling
13-08-2010, 01:06 PM
Looks solid. :) The only thing I can complain about is that the terrain (I suppose it's a terrain) doesn't have either normals calculated or the texture is of a poor quality. Other than that, everything seems to be working fine. I didn't have a look at the code, tho', but looking at the framerate I can assume your code is optimal.

Keep up the great work. :)


The "Terrain" is simply random numbers stuck together into an array of points. So, um... yeah, it doesn't look good. The texture isn't exactly high quality either, it was just the first thing I found :)

My problem really lies in when I start taking the land mass up to large (say 1000x1000) quads, then the performance drops off like a rock. Since I'm using Display Lists I didn't think this would happen, but I'm obviously wrong. So, back to the drawing board as I guess I'm going to have to tell OpenGL here is a sub block of land, render it.

Seen lots of posts about VBO's but have yet to find easy to understand code about how to set this up AND use it in the end.

- Jeremy

grudzio
13-08-2010, 07:16 PM
You can speed up terrain rendering by using triangle strips instead of quads. It is a bit tricky because you have to draw odd rows of terrain in one direction and event in opposite one. Here is sample code. (This code is from some old project of mine and it should work).


procedure TTerrainRenderer.Render;
var
x,z,w,h : integer;
grid : single;
switchSides : boolean;
begin
if not Assigned(fTerrainData) then exit;

w := fTerrainData.Width;
h := fTerrainData.Height;
grid := fTerrainData.GridSize;
switchSides := false;
fTerrainData.Texture.Apply;

glBegin(GL_TRIANGLE_STRIP);
for x := 0 to w-2 do begin

if switchSides then begin
for z := h-1 downto 0 do begin
glTexCoord2f(x/w,z/h);
glVertex3f(x*grid,fTerrainData.Heights[x,z],z*grid);
glTexCoord2f((x+1)/w,z/h);
glvertex3f((x+1)*grid,fTerrainData.Heights[x+1,z],z*grid);
end;
end else begin
for z := 0 to h-1 do begin
glTexCoord2f((x+1)/w,z/h);
glvertex3f((x+1)*grid,fTerrainData.Heights[x+1,z],z*grid);
glTexCoord2f(x/W,z/H);
glVertex3f(x*grid,fTerrainData.Heights[x,z],z*grid);
end;
end;
switchSides := not SwitchSides;
end;
glEnd;
end;

Triangle strips nay help but for large terrains you should use frustum culling.

I also noticed that you put calls to glEnable/Disable into display lists. I do not think is a good idea since state changes in OpenGL are quite expensive. It may not matter in this demo, but if you had many small objects rendered with display lists, it might hurt performance.

Always try to organise your rendering code so there is as little as possible state changes.

Brainer
13-08-2010, 08:25 PM
Seen lots of posts about VBO's but have yet to find easy to understand code about how to set this up AND use it in the end.

Hope this (http://www.google.pl/url?sa=t&source=web&cd=1&ved=0CBUQFjAA&url=http%3A%2F%2Fwww.ozone3d.net%2Ftutorials%2Fope ngl_vbo.php&rct=j&q=opengl%20vbo%20tutorial&ei=26llTLiqINrGOP3QzfoM&usg=AFQjCNFxmNMDkdDsBQpkO-jaoGBgTOOGtQ&sig2=EIpsXPNHxXRCD-JzOynj2w&cad=rja) will make the subject clean. :)

phibermon
10-10-2010, 10:26 AM
Yes, excellent tutorial. I also used this while learning about vertex shaders, moving towards Bone Animation on the GPU (Hardware Skinning). Reccomend!

chronozphere
10-10-2010, 03:36 PM
Your demo works here too.

I don't have the time to dive into the source. Nevertheless, I have a tip for you. Your terrain seems very pixelated. This is caused by the high-contrast of the texture and maybe by the fact that you didn't turn mipmapping on. You could have a look at that and improve the quality of your terrain.

Good luck!