PDA

View Full Version : Optimize a program



Fraktalius
08-26-2008, 01:30 AM
I have this problem with OpenGL in C++ Builder. In a panel on the form drawing a (2D) plot, that user can translating. This is a code of translating:


glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glPushMatrix();
...
glTranslatef(<some parameters>);

DrawGraphic(LastGraphic);
Setka();
glPopMatrix();
DrawAxes();
SwapBuffers(hdc);

But drawing a plot in a function DrawGraphic() is very unpractical process, reqired a big calculating. So, every time, when user translates a graphic, the program is delaying, because every time program draws a new graphic. Is it obligatory to draw a graphic every translate, or I can use glTranslatef() without re-draw a picture?

ZbuffeR
08-26-2008, 01:50 AM
Unless you draw millions of triangles, it should be fast.
How is implemented your DrawGraphic(LastGraphic) ?
You do not recalculate the values each time, right ?
You do not use glBegin/glEnd, right ?
You do use VBO, or at least use pre-compiled displaylists ?

You can also glCopyTexSubImage the part to translate to a texture, and simply move a textured quad during realtime operation. When the user is done, do a full refresh.

http://www.opengl.org/wiki/index.php/Performance

Fraktalius
08-26-2008, 02:31 AM
How is implemented your DrawGraphic(LastGraphic) ?


A complete implementation of DrawGraphic takes many lines, because it calling a functions, that converts a formula, that user typed, to Reverse Polish notation... But, this is the part of code.


//---------------------------------------------------------------------------
void __fastcall TForm4::DrawGraphic(AnsiString str)
{
LastGraphic = str;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_LINE_SMOOTH);
glDisable(GL_LINE_STIPPLE);
glColor3f(0,0,0);
DrawAxes();
Setka();
glEnable(GL_POINT_SMOOTH);
GLfloat px = -2500;
int temp = 1;
glPointSize(3);
while (px<2500)
{X = px/250;
Y = Decode(IN_OPN(str),X,A,LogBase,sqrb);

if (X>max || X<min)
temp = 0;
else
{
glBegin(GL_POINTS);
glColor3f(0,0,1);
glVertex2f(X*5,Y*5);
glEnd();}
px++;
}
SwapBuffers(hdc);
}
//--------------------------------------------------

px variable means a current X coordinate of current point.
Setka() draws a grid.
IN_OPN(str) converts a string str to Reverse Polish notation.
Decode(...) calculates a value, using a string, that returns IN_OPN function.
And this function (DrawGraphic) calls every time, when user translates a graphic. So, for each time values recalculates and it strongly delays a program work.


You do not recalculate the values each time, right ?
For translating, a have some variables, that are changing for each time.

ZbuffeR
08-26-2008, 03:15 AM
no wonder it is slow then :)
You should use vbo instead of immediate mode.

glPetr
08-26-2008, 03:55 AM
Hi,

your code is a bit tricky. I commented the "suspicious" parts here:


glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glPushMatrix();
...
glTranslatef(<some parameters>);

// You call SwapBuffers in DrawGraphic,
// You do it on the end of this frame anyway --->
DrawGraphic(LastGraphic);
Setka();
glPopMatrix();

DrawAxes();

SwapBuffers(hdc); // <-- Enough here


The second problem is that calling glBegin/glEnd for each point is extreme. In case you, for compatibility reason, cannot use Vertex Arrays or Vertex Buffer Object, try to use following:


//---------------------------------------------------------------------------
void __fastcall TForm4::DrawGraphic(AnsiString str)
{
LastGraphic = str;

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_LINE_SMOOTH);
glDisable(GL_LINE_STIPPLE);
glColor3f(0,0,0);
DrawAxes();
Setka();
glEnable(GL_POINT_SMOOTH);
GLfloat px = -2500;
int temp = 1;
glPointSize(3);
// You draw points of same color only, so enough to begin here, setting the color just once
glBegin(GL_POINTS);
glColor3f(0,0,1);

while (px<2500)
{
X = px/250;
Y = Decode(IN_OPN(str),X,A,LogBase,sqrb);

if (X>max || X<min)
{
temp = 0;
}
else
{
// Here it is enough to supply just vertex
glVertex2f(X*5,Y*5);
}
px++;
}
// End point set after all points are passed
glEnd();
// SwapBuffers removed
}
//--------------------------------------------------


Hope this helps.


Petr