for Delphi and CBuilder

project source available

Copyright (c) 2001 by Charlie Calvert

Index

Charlie's Source

Delphi OpenGL ProgramsdelphiOpenGLSrc.zip
ScreenshotsopenGLScreenShots.html
C++Builder OpenGL ProgramscppOpenGLSrc.zip

Charlie's notes on installing the Linux version of OpenGL, called Mesa

DefaultScreen and RootWIndow can be XDefaultScreen and XRootWindow

Naming Conventions

All the commands used in OpenGL begin with letters gl. For instance, the following functions are all commonly used in OpenGL programs: glBegin, glEnd, glOrtho and glViewport. 

Some names end with something that looks at bit like Hungarian notation: glVertex3f or glVertex2i. The information appended on to the end of these names designates the parameters that are passed to the function. For instance, the glVertex3f takes three floats as parameters, and glVertex2i takes two Integers are parameters. With functions like this, you are usually free to decide how want to call them. Just choose the form that suits you needs. For instance, if you can define a vertex with two Integers designating the x and y coordinates, then go ahead and use that form. The third coordinate, the z dimension, will be set to zero automatically. If you need three floating point numbers to define you point in space, then use the glVertex3f version of the function. (I will, of course, explain these functions in more depth at the appropriate place in this paper.

Function of this type have a lot of variety:

procedure glVertex2d;
procedure glVertex2dv;
procedure glVertex2f;
procedure glVertex2fv;
procedure glVertex2i;
procedure glVertex2iv;
procedure glVertex2s;
procedure glVertex2sv;
procedure glVertex3d;
procedure glVertex3dv;
procedure glVertex3f;
procedure glVertex3fv;
procedure glVertex3i;
procedure glVertex3iv;
procedure glVertex3s;
procedure glVertex3sv;
procedure glVertex4d;
procedure glVertex4dv;
procedure glVertex4f;
procedure glVertex4fv;
procedure glVertex4i;
procedure glVertex4iv;
procedure glVertex4s;
procedure glVertex4sv;

GL Command Reference

http://www.cevis.uni-bremen.de/~uwe/opengl/opengl.html

Basic Types

Here you can find references to basic types used in OpenGL to support cross platform development. There types are very simple, usually just references to basic types such as integers or floats. However, using them makes it easy for you to write one set of code that will run anywhere.

Clearing the Background

Consider this method:

void Display(void)
{
   glBegin(GL_TRIANGLES);
     glColor3f(1.0,0.0,0.0);
     glVertex3f(-1.0,0.0,0.0);
     glColor3f(0.0,1.0,0.0);
     glVertex3f(0.0,1.0,0.0);
     glColor3f(0.0,0.0,1.0);
     glVertex3f(1.0,0.0,0.0);
   glEnd();
   glFlush ();
}

Here is what it produces:

Let's remove the first two calls:

 
  glClearColor(0.8,0.8,0.9,1.0);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

Now we get this:

As you can see, the background was not cleared properly, and portions of C++Builder are clearly visible in the window. You are not actually seeing through the window, you are just seeing what happen to be behind the window when it was created. In other words, this is not a cool transparent window, its just a window with a messed up background.

GlBegin and GLEnd

There are only certain calls you can make in here. The most important are the glColor* and glVertex* calls

However, my favorite mistake, in C++Builder, is to write

glEnd

What I mean to write is:

glEnd()

If you don't include glEnd when its needed, or if you leave off the () in C++, then your screen may appear blank, or may be incorrectly drawn.

Ortho and Viewport

glOrtho and glViewport help you to set up the screen corrently so that the shapes you create appear in the location you expect to be in.

glViewport defines the area of the window you are using into which you want to draw. Here is how to tell OpenGL that you want to use your entire window to draw in:

glViewport(0, 0, ClientWidth, ClientHeight); 

A call like will this will take up the entire width and height of the window, or whatever portion of the window that you asked the shape to fill:

If you wanted to only use the 25 pixels at the bottom left of the window to work in, then you would call the function like this:

glViewport(0, 0, 25, 25);

If you specify negative values for the first two parameters, then you start to move things down and to the left, and potentially all the way off the screen:

void glViewport(GLint x, GLint y, GLsizei width, GLsizei height);
procedure glViewport(x,y: GLint; width, height: GLsizei); stdcall;
x, ySpecify the lower left corner of the viewport rectangle, in pixels. The default is (0, 0).
width, heightSpecify the width and height, respectively, of the viewport. When a GL context is first attached to a window, width and height are set to the dimensions of that window.

glOrtho

void glOrtho(GLdouble left,
             GLdouble right,
             GLdouble bottom,
             GLdouble top,
             GLdouble near,
             GLdouble far)

procedure glOrtho (left, right, bottom, top, zNear, zFar: GLdouble); stdcall;

left, rightSpecify the coordinates for the left and right vertical clipping planes.
bottom, topSpecify the coordinates for the bottom and top horizontal clipping planes.
near, farSpecify the distances to the nearer and farther depth clipping planes. These distances are negative if the plane is to be behind the viewer.

glOrtho is related to glViewport, but it does something quite different. In OpenGL, you are free to completely ignore coordinates the native Windows or Xlib dimensions of your window. Instead, you can think in terms of your own logical coordinates.

The window you are working with may be 640X480 pixels. However, you can ask OpenGL to think of the window has having a logical dimension of 1 X 1. This would mean that placing an item at 0.5, 0.5, would put it at the real coordinates of 320 X 240.

glOrtho is the call you make to specify the logical coordinates that you want to use. Consider the following example:

glOrtho(-1, 1, -1, 1, -1, 1)

This code says that you want the x coordinate to run from -1 to 1, the y coordinate from -1 to 1, and the depth to run from -1 to 1. In such a system, placing an object at a depth of -2 would put it out of the clipping plane, and therefore make it invisible to the user. This is a source of great confusion to beginners, who are often trying to display objects at locations not visible to themselves or the user.

Consider this Glut method:

procedure ReShape(Width: Integer; Height: Integer); cdecl;
begin
  glViewport(0, 0, Width div 2, Height div 2);
  glOrtho(-50, 50, -50, 50, -1, 1);
end;

This code specifies that you want to use the bottom left quadrant of the window you are inside. Furthermore, you want the logical coordinates of that area to be 50 X 50, and to have a depth of 2. The best way to see how that works is to sit down a computer and try some experiments.

Consider what would happen if a programmer drew the following triangle in the window we have just defined:

procedure Display; cdecl;
begin
  glClearColor(0.0,0.0,0.0,1.0);
  glClear(GL_COLOR_BUFFER_BIT);
  glBegin(GL_TRIANGLES);
    glColor3f(1.0,0.0,0.0); glVertex3f(-1.0,-1.0,0.0);
    glColor3f(0.0,1.0,0.0); glVertex3f(0.0,1.0,0.0);
    glColor3f(0.0,0.0,1.0); glVertex3f(1.0,-1.0,0.0);
  glEnd();
  glFlush ();
end;

The triangle would appear as little more than a dot, down at the center of the bottom left quadrant of the window.

Suppose you changed the code to look like this:

procedure Display; cdecl;
begin
  glClearColor(0.0,0.0,0.0,1.0);
  glClear(GL_COLOR_BUFFER_BIT);
  glBegin(GL_TRIANGLES);
    glColor3f(1.0,0.0,0.0); glVertex3f(-50.0,-50.0,0.0);
    glColor3f(0.0,1.0,0.0); glVertex3f(0.0,50.0,0.0);
    glColor3f(0.0,0.0,1.0); glVertex3f(50.0,-50.0,0.0);
  glEnd();
  glFlush ();
end;

Now your code would take up the entire bottom left quadrant:

glOrtho and glScale

Consider these two methods:

void reshape(int w, int h)
{
  glViewport(0, 0, w, h);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(-1, 1, -1, 1, -10, 10);
  glScalef(1, 1, 0);
  glTranslatef(0, 0, 0);
}

void display(void)
{
  glClearColor(0.8,0.8,0.9,1.0);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glBegin(GL_TRIANGLES);
     ErrorCheck("Display middle");
     glColor3f(1.0,0.0,0.0);  glVertex3f(1.0, 0.0, 0.0);
     glColor3f(0.0,1.0,0.0);  glVertex3f(0.0, 1.0, 0.0);
     glColor3f(0.0,0.0,1.0);  glVertex3f(-1.0, 0.0, 0.0);
  glEnd();
  glFlush();
  ErrorCheck("Display End");
}

Here is what it looks like:

Let's change the values in glOrtho:

  glOrtho(-2, 2, -2, 2, -10, 10);

Here is what it looks like now:

Now let's scale the image up:

glScalef(2, 2, 0);

Here is what it looks like now:

As you can see, we have really returned back to where we started. In short, there is a relationship between glOrtho and glScalef such that giving them the same values is equivalent to setting the values in each call to one. That is, these two sets of calls yield the same results:

  glOrtho(-1, 1, -1, 1, -10, 10);
  glScalef(1, -1, 0);
	
  glOrtho(-2, 2, -2, 2, -10, 10);
  glScalef(2, -2, 0);

Now let's reverse the image by setting the middle parameter to glScalef to a negative value:

  glScalef(2, -2, 0);

Here is what it looks like now:

Working with Textures

Follow this link.

Creating and Compiling Packages: OpenGL12 and Geometry

Much of the code that I have included with the materials for this talk uses units that are part of GLScene, an Open Source project you can download for free from the web.

Two units that come with GLScene, one called OpenGL12.pas and another called Geometry.pas, are generally useful. OpenGL12.pas is similar to the OpenGL unit that ships with Delphi, but it is clearly superior. If you create any opengl components, you will almost certainly want to put OpenGL12 and Geometry in that package. A problem arises because it is also used by GLScene, which is another package you will almost certainly want to use. As a result, under some circumstances, you may find it best to put Geometry.pas and OpenGL12.pas in their own Core package, and then have both the GLScene and your own package depend on that Core package.

One other note, you need to call the InitOpenGL call, that is in OpenGL12, if you want to use OpenGL12 in your programs.

glScene

Charlie's first tutorial on GLScene.

From their page:

GLScene is an OpenGL based 3D library for Delphi. It provides visual components and objects allowing description and rendering of 3D scenes in an easy, no-hassle, yet powerfull manner.

GLScene is not just an OpenGL wrapper or utility library, it has grown to become a set of founding classes for a generic 3D engine with Rapid Application Development in mind. GLScene allows you to quickly design and render 3D scenes without having to learn the intricacies of OpenGL, if you know how to design a TForm, you'll easily master the basic operations of TGLScene. The library comes with a set of demos showcasing the ease of use, and demonstrating RAD wasn't done at the expense of CPU horsepower.


http://www.glscene.org/

Glut

Read Charlie's explanation and tutorials on Glut.

xgl

A link showing the XGL format for storing and reading OPENGL data:

http://www.xglspec.org/

3D File Formats

A link to a page showing how to learn about 3D file formats and openGL:

http://www.opengl.org/developers/faqs/technical/miscellaneous.htm#misc0040

Delphi 3DS Renderer

A link to a Delphi renderer for openGL using the 3DS file format:

http://www.lischke-online.de/3DS.html

OpenFX

OpenFX is an Open-Source 3D modeling, animation and rendering suite created by Dr. Stuart Ferguson. He made the decision to release the source code to the public in the middle of 1999, and the product formerly named SoftF/X was renamed to OpenFX. It has now been released under the terms of the GNU General Public Licence

http://www.openfx.org/news/index.php

GLaux

The 'glAux' unit can be found at

http://www.delphi-jedi.org/DelphiGraphics/jedi-index.htm
    The glaux translation was done by Manuel Parma and is hosted at the
    Delphi-Jedi Project web site in the graphics section. You may also
    be interested in the OpenGL headers available there, since they are
    more complete than the version that shipped with Delphi 4 and 5.
    The OpenGL headers there support the full 1.1 spec and supports dynamic
    linking to the opengl32.dll so you can detect whether or not it's
    available in the first place. If you DO use that version of the OpenGL
    header, you can remove the two texture procedures declared below since
    they are present in that translation.

    Please note: the glAux unit will REQUIRE the glaux.dll library to be
    present when you run this program. You can install it from the GLAux.zip
    mentioned above into your Windows SYSTEM directory (SYSTEM32 for you
    NT users). Or, simply keep a copy of it in the same directory as your
    application.

    If any of this is confusing or you need help, feel free to e-mail me
    at marca@stack.nl. Do NOT e-mail Jeff regarding Delphi translation
    issues since he is not responsible for the translation I've done here.}
		

3D Shapes

http://www.datavis.com.au/

Notes from the author:

The "3DShapes"  OpenGL engine differs from the GLScene engine in that it
provides a fully user interactive OpenGL scene environment, starts at a more
basic primitive (namely a point),  includes a more complete scene graph
management structure, has an integrated dynamic physics system and has a number
of performance optimisations including some specifically for the nVidea range of
graphics chips.  The vision for the future also includes collision detection and
advanced force feedback (haptic) interface into the scene.

Currently the engine supports D5 and D6.  We are assessing the opportunities for
a Kylix versiuon as well.

"3DShapes" is the foundation for an ambitious application being currently
developed for the mining industry.  We have made this basic engine available to
assist the Delphi community in developing 3D based applications.

Some OpenGL Links

http://nehe.gamedev.net/
http://arrowsoft.ifrance.com/arrowsoft/gllinks.html http://crystal.linuxgames.com/ http://www.lischke-online.de/

Is it broken:

http://www.signsoft.com/e_opengl.htm http://www.digitalprojects.com/way-x/ewx.htm http://www.scitechsoft.com/dp_mgl.html

Here are glut 3.7 dlls that I have not tested:

http://www.xmission.com/~nate/glut.html

C++Builder Links

http://www.hellix.com/Products/TOpenGL.asp
http://www.signsoft.com/international/visit/main/index.phtm
http://www.wischik.com/lu/programmer/index.html
http://www.foxholly.demon.co.uk/Programming.html
http://www.cobweb.net/~dplakosh/

Read 3DS Stuff

http://wcc.ruca.ua.ac.be/~saenen/releases.html

Get Meshes

http://www.3dcafe.com/asp/meshes.asp

Headers with no extensions

using namespace std;

Books

A well written and easy to understand guide to OpenGL programming. John knows the subject matter fairly well, has a light touch, an enjoyable style, and best of all, he knows how to teach.
This is the "classic" book on the subject. For beginners, I would rate it only so-so. If you already understand the basics, this book can be a big help. It is, however, heavy going throughout. There is no talent here for taking a difficult subject and making it easy to understand. It is grunt work plowing through it, but you will be rewarded for your efforts. Lot's of good information.
I own the first edition of this book. Good information in here, but not an inspired presentation. It does the job, but nothing special.