PDA

View Full Version : Anti-lag



IlovePascal
04-12-2006, 02:15 AM
Hey there! I have recently witnessed the wonders that some people can do with graphics (plant engines, 3D environments, etc), so I decided to start with learning about particle systems.

I would like to ask you pros to help me with my most hated difficulty : lag.
I know it's a lot easier to give advice on something concrete, so I pasted here a simple program of mine which simply applies the physics principles of wave interference.

After I made the basic structure of this program, I thought about adding different display effects from the same particle system. So, when the program's running, you can press 'd', enter a value between 1 and 4 to change the display method, and press <Enter>. When you input 4, it simply draws a line from each particle to the point (0,0), but it lags like crazy!

The idea is to get as many ppl to give their opinions on how it could be improved to maximum, so that we can all learn frm one another about anti-lag measures.
I would really like to know why something so simple lags so much more than an entire 3dimensional plant engine! lol

Jst copy the following and paste into a new file ( it was made with Dev-Pascal, so maybe if you use another compiler, it might need a few adaptations ). Btw, I only use Dev-Pascal, so please don't jst tell me to get something else!



Program Waves;
&#123;By CDB; to learn about particle systems&#125;
uses crt, dos, graph;
type Timerecord = record
Hours,Minutes,Seconds,S100 &#58; word;
Tothundreds,Lasthundreds, Timepassed&#58;integer;
end;
Waver = record
Timepassed, Disturb, StringLevel, Detail,
Howmany,NumOfDist, Colour, Speed, Starter,StartinHeight &#58; integer;
Disturbance &#58; array&#91;1..100&#93; of record
Alive &#58; boolean;
Start &#58; integer;
Heights &#58; array&#91;1..2000&#93; of real;
end;
end;
Waveparticles = record
x,y, vx,vy, oldx,oldy &#58; real;
end;
var Wave &#58; Waver;
WaveP &#58; array&#91;1..1100&#93; of waveparticles;
Timer &#58; timerecord;
FPS &#58; integer;
Procedure Initialize; forward;
Procedure CheckForInstruction; forward;
Procedure FrameIt; forward;
Procedure WaveIt; forward;
Procedure MakeAMove; forward;
Procedure MakeAStand; forward;
Procedure MoveNDraw; forward;

Procedure Initialize;
var Gd, Gm &#58; Smallint;
c &#58; integer;
begin // the next 3 lines initialise the graph window
Gd&#58;=Detect;
InitGraph&#40;Gd,Gm,''&#41;;
If GraphResult<>0 then Halt;
Randomize;
Timer.Timepassed &#58;= 0;
FPS &#58;= 0; c&#58;=0;
With Wave do
begin
Timepassed &#58;= 0;
Disturb &#58;= 1; // how often to create a wave &#40;in sec/100&#41;
StringLevel &#58;= 300; // = 'ground' level
Howmany &#58;= 550; // how many particles
NumOfDist &#58;= 100; // max number of waves at same time
Detail &#58;= 1;
colour&#58;= 4;
Speed&#58;=4;
Starter &#58;=1000; // coded&#58; if <0>1020 then starts at middle
StartinHeight &#58;= 80; // coded&#58; if <0>1000 then default =80;

//-------Disturbance
for c&#58;=1 to NumOfDist do
With Disturbance&#91;c&#93; do
begin
Alive&#58;=false;
Start&#58;=510;
end; &#123;with Disturbance&#125;
//-------Particles
for c&#58;=1 to Howmany do
With WaveP&#91;c&#93; do
begin
x&#58;= c-&#40;Howmany-1020&#41;div 2; // to centre it
y&#58;=StringLevel;
oldx&#58;=0;
oldy&#58;=y;
end; &#123;WaterMol&#125;
end; &#123;With Water&#125;
end; &#123;initialize&#125;

Procedure CheckForInstruction; //to change variables or exit
var k &#58; char; // press the correspondent letter, enter the value, press <Enter>
s &#58; string; // Note&#58; there are no validity checks so take care with what you input!
c &#58; integer;
begin
if keypressed then
begin
k&#58;=readkey;
readln&#40;s&#41;;
With Wave do
case k of
'f'&#58; begin //flaten, reset
for c&#58;= 1 to NumofDist do Disturbance&#91;c&#93;.Alive&#58;=false;
for c&#58;= 1 to Howmany do WaveP&#91;c&#93;.y&#58;=StringLevel;
//and velocities if desired
end;
'h'&#58; begin Val&#40;s,Howmany&#41;; cleardevice; end; // changes the num of particles
't'&#58; Val&#40;s,StartinHeight&#41;; // changes how high each wave is
's'&#58; Val&#40;s,Starter&#41;; // changes where the wave originates from
'l'&#58; Val&#40;s,StringLevel&#41;; // changes average level
'c'&#58; Val&#40;s,Colour&#41;; // changes colour
'v'&#58; Val&#40;s,Speed&#41;; // changes how fast each particle gets to its destination
'd'&#58; begin Val&#40;s,Detail&#41;; cleardevice; end; // changes display
'w'&#58; Val&#40;s,Disturb&#41;; // changes how often to create a wave
'x'&#58; Halt; // exits
end; &#123;case&#125;
end; &#123;if&#125;
end; &#123;CheckForInstruction&#125;

Procedure FrameIt; //not exactly FPS but jst to give an idea of performance
var s&#58;string;
begin
Str&#40;FPS,s&#41;;
setcolor&#40;0&#41;; outtextxy&#40;10,680,s&#41;; //erase what's there
if Timer.Timepassed=0 then FPS&#58;=100 else FPS &#58;= round&#40;100/Timer.Timepassed&#41;;
Str&#40;FPS,s&#41;;
setcolor&#40;15&#41;; outtextxy&#40;10,680,s&#41;; //write
end; &#123;FPS&#125;

//------------------------Wave procedures
Procedure WaveIt;
begin
MakeAStand; //creates a new wave
MakeAMove; //moves every wave
MoveNDraw; //moves and draws particles
end; &#123;WaveIt&#125;

Procedure MakeAStand;
var r &#58; integer;
begin
With Wave do
begin
Wave.Timepassed += Timer.Timepassed;
if Timepassed<0>Disturb then
begin
r&#58;=1;
while &#40;r<=&#40;NumOfDist+1&#41;&#41;and&#40;Disturbance&#91;r&#93;.Alive&#41; do r+=1; //find a wave in the array that is not 'Alive'
if r<=NumOfDist then
With Disturbance&#91;r&#93; do // and make it alive
begin
Alive&#58;=true;
writeln&#40;'Creatin wave ',r&#41;; //jst a check, can be commented out
for r&#58;= 1 to 2000 do Heights&#91;r&#93;&#58;=0; //makes sure it's all flat
Case Starter of //Starter can be set in real time. <0>1025 will make it centered
-100..-1 &#58; start &#58;= random&#40;Howmany-5&#41;+3;
0..1024 &#58; start &#58;= Starter;
1025..10000 &#58; start &#58;= Howmany div 2;
end; &#123;case&#125;
Case StartinHeight of //can be set in real time. <0>1000 will make it default
-100..-1 &#58; Heights&#91;start&#93; &#58;= random&#40;-StartinHeight&#41;;
0..1000 &#58; Heights&#91;start&#93; &#58;= StartinHeight;
1001..10000 &#58; Heights&#91;start&#93; &#58;= 80;
end; &#123;case&#125;
end; &#123;if&#125;
Timepassed&#58;=0;
end; &#123;if&#125;
end; &#123;with&#125;
end; &#123;MakeAStand&#125;

Procedure MakeAMove; //Moves each wave sideways
var b,c &#58; integer;
begin
With Wave do
for c&#58;=1 to NumOfDist do
With Disturbance&#91;c&#93; do //goes through the Disturbance array, and if alive, moves it
if Alive then
begin
Alive&#58;=false; //if the wave is still moving through the array, it will become true again
for b &#58;= 2 to &#40;Start-1&#41; do //Start is where the disturbance started
begin
if Heights&#91;b&#93; <> Heights&#91;b+1&#93; then Alive&#58;=true; //if the wave is still moving, it has to stay alive
Heights&#91;b&#93; &#58;= Heights&#91;b+1&#93;; //Moves half of the wave to the left
end; &#123;for&#125;
for b &#58;= &#40;Howmany-1&#41;downto&#40;Start+1&#41; do
begin
if Heights&#91;b&#93; <> Heights&#91;b-1&#93; then Alive&#58;=true;
Heights&#91;b&#93; &#58;= Heights&#91;b-1&#93;; //Moves half of the wave to the right
end; &#123;for&#125;
Heights&#91;start&#93; *= 4/5; if Heights&#91;start&#93;<5>4 then r&#58;=4; r/=500; // serious doubts about this...
// The idea was to make the wave move depending on how long the previous round took
// so tht it wouldn't slow down, bt it doesnt seem good.
r &#58;= 1/50000;
With Wave do
for c&#58;= 2 to &#40;Howmany-1&#41; do // The first and last have to be constant to set the average level
With WaveP&#91;c&#93; do
begin
d&#58;=0;
for b&#58;=1 to NumOfDist do
if Disturbance&#91;b&#93;.Alive then d += Disturbance&#91;b&#93;.Heights&#91;c&#93;; //adds all heights of waves at that point
d+= StringLevel; // adds the total to SeaLevel
vx += 0;
vy += &#40;d-y&#41;; //vy is how far up or down the particle has to go &#40;smthg like velocity&#41;
x += vx*r*speed;
y += vy*r*speed; //the particle moves depending on its velocity, how long since last round, and speed
if y<10>800 then y&#58;=800;
if &#40;y<>oldy&#41;or&#40;x<oldx>2 then line&#40;round&#40;x&#41;,round&#40;y&#41;,round&#40;WaveP&#91;c-1&#93;.x&#41;,round&#40;WaveP&#91;c-1&#93;.y&#41;&#41;;
end;
3&#58; begin //line to bottom of screen &#40;sea effect&#41;
setcolor&#40;0&#41;; line&#40;round&#40;oldx&#41;,round&#40;oldy&#41;,round&#40;oldx&#41;,1020&#41;;
setcolor&#40;Colour&#41;; line&#40;round&#40;x&#41;,round&#40;y&#41;,round&#40;x&#41;,1020&#41;;
oldx&#58;=x;
oldy&#58;=y;
end;
4&#58; // line to pt &#40;0,0&#41;
// This is where my problem is.
// I simply wanted to draw a line between every particle and the origin
// so as to create the effect of a horizontal plane being distorted in 3D.
// But, for some reason, unknown to me, it lags like crazy!
// so I tried to draw the lines only with every 5th point, but it still lags
// way too much.
// Please tell me how I could improve this!
if c mod 5=0 then begin
setcolor&#40;0&#41;; line&#40;round&#40;oldx&#41;,round&#40;oldy&#41;,0,0&#41;;
setcolor&#40;Colour&#41;; line&#40;round&#40;x&#41;,round&#40;y&#41;,0,0&#41;;
oldx&#58;=x;
oldy&#58;=y;
end;
else Detail&#58;=1;
end; &#123;case&#125;
end; &#123;if&#125;
end; &#123;for, with&#125;

if Wave.Detail=2 then //has to be put separately because needs to be done all at once
for c&#58;= 2 to Wave.Howmany do
With WaveP&#91;c&#93; do
begin
oldx&#58;=x;
oldy&#58;=y;
end;
end; &#123;MoveNDraw&#125;
//-------------------------------------
begin
Initialize;
Repeat
With Timer do
begin
Gettime&#40;hours,minutes,seconds,s100&#41;;
Tothundreds&#58;=&#40;s100&#41;+&#40;seconds*100&#41;+&#40;minutes*6000&#41;+&#40; hours*360000&#41;;
Timepassed &#58;= Tothundreds-Lasthundreds; //time passed since last time round
Lasthundreds &#58;= Tothundreds;
if Timepassed<0 then Timepassed&#58;=0;
end;
FrameIt;
CheckForInstruction;
WaveIt;
Until false;
end.

This is when you give all the advice you can to improve it!!! Thank you!

NB: I deleted lots of spaces to make it shorter; and some lines might have been split into 2

JernejL
04-12-2006, 11:16 AM
we've moved beyond raw graphics with lines and software rasterization, 99.9% of use opengl or directx to render stuff, and it is 2000% faster than anything you do in software.

K4Z
04-12-2006, 12:08 PM
I didn't go through all the code, only the first few lines...but the reason it's going slow is that everything is running off the CPU (Software rendering), instead of the GPU.

As Delfi is saying, you might wanna look into DirectX or OpenGL for rendering.

dmantione
04-12-2006, 01:08 PM
In addition to the comments the others have made (so consider using hardware rendering): Graph hasn't been designed for speed. If want to make your software rendering faster, switch to PTCPas.

jdarling
04-12-2006, 02:08 PM
Well, for starters your source wouldn't compile if it had to. I tried fixing your errors, but they are far and many due to the changing of the lines. Try uploading a zip file with the source in it (this is always your best solution anyways). As has already been said, move away from graph, and if you are wanting to use fast graphics then make sure and use the right library.

SDL is a good cross platform cross rendering engine library, it requires some setup, and can be slower then raw DirectX or OpenGL depending on how you set it up and use it.

DirectX is Windows only, if you don't mind developing for Windows only then its a good choice. Read up on it either way.

OpenGL is the powerhouse of cross platform development with graphics (2D and 3D). Lots of tutorials out there and ALOT of information. Read up even if your not going to use it. You will find eventually that what is true for one lib is true for most all of them.

There are some fast graphic libraries for FPC that don't require 3rd party API's. Take a look at the lazarus CCR, sure some of it requires Lazarus, but most can be done in pure FPC if you have some patience. Of course, Lazarus is a good choice and gives you a Delphiesk IDE.

If you can upload a copy of your source (don't copy/paste again please), I'm sure you will find more help available, as a compileable version always makes life easier.

IlovePascal
07-12-2006, 03:31 AM
Hey, thanks heaps for the advice!

Summing it up, Step 1 to improving graphics is to get DirectX or OpenGL! Im really quite excited, because 2000% faster seems like quite a solution! lol :D

As you all seem to agree, I won't copy and paste anymore :? lol, but then how do I upload something? I can see the option Add image to post, or Add Poll when starting a new topic, but Im nt sure how to upload a file...

I read a whole bunch about DirectX and OpenGL. What I gather is that they are both graphic libraries with improved functions to create and display 2D/3D graphics, but the first one is by Microsoft and the second is open source, is tht right?

Im really excited about all the stuff I read about both, but because I dnt like Microsoft, Ill make sure I get OpenGL!
Iv been looking for a download site for OpenGL, but there seems to be way too many different ones. I dnt know what to get, can you please give me a link? :o

dmantione, what do you mean by PTCPas?

Cheers ;)

jdarling
07-12-2006, 01:01 PM
As you all seem to agree, I won't copy and paste anymore :? lol, but then how do I upload something? I can see the option Add image to post, or Add Poll when starting a new topic, but Im nt sure how to upload a file...
Well, now that is the $20,000 question. The answer is, you can't. Instead you have to upload your file to your own server or another file hosting spot on the web, then place a link to it using the url tags.

If you don't have any personal web-space just sign up for some on any of the free hosting sites. There are many to choose from, careful though, as some don't allow for direct file linking.

IlovePascal
09-12-2006, 03:10 AM
Come on guys, any links?

IlovePascal
09-12-2006, 09:01 AM
Damn! Is it jst me or does Silicon not want ppl to download OpenGL ? Iv been googling for a while and I can't find a single place where they offer a download as a Pascal library!

On here http://www.thefreecountry.com/sourcecode/graphics.shtml, they seem to have 100 graphics libraries, but not OpenGL; in this link http://www.trolltech.com/campaign/google/qt-opengl?gclid=CN7x9NP-hIkCFSLQYAodeB6VPA they talk about it, but it's for C++ (is it the same for both?). The most convincing I found was on http://www.simulation.com/products/glstudio/glstudio.html?gclid=CKSE-N3-hIkCFQLYYgodamDLDQ, but OpenGL Studio doesn't seem to be right, is it?
I couldn't believe that on http://www.sgi.com or even on http://www.opengl.org, they don't have it!

Btw, am I looking for OpenGL Multipipe, Vizserver, Volumizer or Performer? there are so many!
http://search.sgi.com/search?q=download+OpenGL&restrict=&client=sgi&proxystylesheet=http%3A%2F%2Fwww.sgi.com%2Fstyles% 2Fnew%2Fsgi_xslt.html&output=xml_no_dtd&site=sgi

Help! Please!

dmantione
09-12-2006, 09:34 AM
You don't need to download OpenGL. It is already on your system.

Just a "uses opengl;" in your program should be enough to use OpenGL.

dmantione
09-12-2006, 09:36 AM
PTCPas is a lowlevel 2D graphics toolkit by Nikolay Nikolov that provides you with a frame buffer; it allows you to write portable software for go32, Windows and Unix: http://sourceforge.net/projects/ptcpas

It is shipped with FPC.

grudzio
09-12-2006, 09:47 AM
All you need is Pascal OpenGL headers and latest drivers for your graphics card. If you use FPC, the headers are already included wit the compiler. Another set comes with JEDI_SDL (http://sourceforge.net/projects/jedi-sdl/). And yet another headers can be found at http://www.delphigl.com/.

IlovePascal
09-12-2006, 10:25 PM
You don't need to download OpenGL. It is already on your system.
Just a "uses opengl;" in your program should be enough to use OpenGL

:D Isn't that great! Well, I jst downloaded the JEDI_SDL thing from the link grudzio gave me because I heard it was very useful.

If I get it, I should use this instead of the Graph header files that I used to use and will improve the performance of my programs immensly because it uses the graphics card which Graph didnt use, is that right?

Im sorry if Im annoying with all those questions, but it's very hard to learn something like that from scratch, you know. And you guys who are very good at it can't be bothered with such basic questions... :cry:

I'd like to ask jst 2 more questions on this thread, please answer me.

I read somewhere that the C++ version and the Pascal version of OpenGL are very similar. Does that mean if I find a tutorial for openGL in C++, I can use the same in my pascal projects?
For example, I found this very nice site http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=01, but I don't know if it's worth going through.

The other question, which is similar, is : Do you know of a great tutorial to learn about OpenGL? What about one that has a list of all its functions and procedures, with what they do and stuff (that would be very useful)? :?

dmantione
09-12-2006, 10:50 PM
If I get it, I should use this instead of the Graph header files that I used to use and will improve the performance of my programs immensly because it uses the graphics card which Graph didnt use, is that right?


Correct.



Im sorry if Im annoying with all those questions, but it's very hard to learn something like that from scratch, you know. And you guys who are very good at it can't be bothered with such basic questions... :cry:


Yes, but don't worry, you will learn, OpenGL isn't that difficult.



I read somewhere that the C++ version and the Pascal version of OpenGL are very similar. Does that mean if I find a tutorial for openGL in C++, I can use the same in my pascal projects?
For example, I found this very nice site http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=01, but I don't know if it's worth going through.


Yes, this tutorial looks pretty usable. They code in C, not C++ though. Using OpenGL from Pascal is indeed very similar to using it from C.



The other question, which is similar, is : Do you know of a great tutorial to learn about OpenGL? What about one that has a list of all its functions and procedures, with what they do and stuff (that would be very useful)? :?

I just know there are many on the internet, but can't recommend one. Check out The Sheep Killer, great example to write a game in FPC, and it uses OpenGL (http://thesheepkiller.sourceforge.net/).

dmantione
09-12-2006, 11:00 PM
The other question, which is similar, is : Do you know of a great tutorial to learn about OpenGL? What about one that has a list of all its functions and procedures, with what they do and stuff (that would be very useful)? :?

I just know there are many on the internet, but can't recommend one. Check out The Sheep Killer, great example to write a game in FPC, and it uses OpenGL (http://thesheepkiller.sourceforge.net/).

What nonsense am I talking now?! There is a good opengl tutorial specifically for FPC: http://www.friends-of-fpc.org/tutorials/graphics/dlx_ogl/german/

grudzio
09-12-2006, 11:09 PM
Another good sites are www.delphi3D.net and www.codesampler.com.

If you want OpenGL API reference, then search for the 'bluebook'.

IlovePascal
10-12-2006, 05:05 AM
The english version of dmantione's link
http://www.friends-of-fpc.org/tutorials/graphics/dlx_ogl/german/
is exactly what I was looking for!

As for grudzio, I will use your advice later on cos it seems a little more advanced.

THANK YOU BOTH SOOOO MUCH! :) :D :P