Optimize a program

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?

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

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.

no wonder it is slow then :slight_smile:
You should use vbo instead of immediate mode.

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