PDA

View Full Version : Drawing with OpenGL



IlovePascal
03-02-2007, 10:39 PM
Hello, I have recently learned how to use the basic functions of OpenGL and I would like to know a few more things.

1. I know how to draw triangles, quads, lines and polygons; is there a routine to draw circles, cylindres, spheres, cones, spirals ??

2. What is the command to set the alpha value (I use glColor3f(...) for colour, is there may be one that lets you set the alpha as well?) ?

3. I have learnt about Lists. What are their advantages and disadvantages?

Thanks for the help ;)

Robert Kosek
03-02-2007, 11:29 PM
1. I know how to draw triangles, quads, lines and polygons; is there a routine to draw circles, cylindres, spheres, cones, spirals ??Yes, look up GLUT in google, specifically for delphi. Else you can check out the red book (http://fly.cc.fer.hr/~unreal/theredbook/).


2. What is the command to set the alpha value (I use glColor3f(...) for colour, is there may be one that lets you set the alpha as well?) ?Yes, glColor4f(); will handle colors for you with alpha transparency. The Redbook is a great tool for learning about openGL.


3. I have learnt about Lists. What are their advantages and disadvantages? Sorry, but I'm not well versed in vertex buffers, render lists and such. If you mean a TList to contain objects, then that's different; you should be more specific in this case.

grudzio
03-02-2007, 11:49 PM
3. I have learnt about Lists. What are their advantages and disadvantages?

Display lists are designed to increase performance. They allow to store a set of openGL commands in a memory in a 'compiled' form and call it when needed. To give an analogy, the drawing commands between glBegin...glEnd are like a source code. Display list is like an executable.
Each time you draw something with glBegin...glEnd OpenGL needs to 'compile' it and then execute, while display list when called is executed straight away. A big speed gain. (It is like compiling program each time you want to use it versus compiling it once and runnig it without any recompilation). But it means that display lists are good for static geometry. You can't change part of it without recompiling whole list. So if your geometry changes a lot display lists are not effecitve. Lastly not all openGL commands can be put into display list.

To get more information check the redbook like Robert suggests.

IlovePascal
04-02-2007, 03:42 AM
Cool, thank you guys! I have just spend a whole afternoon reading some parts of the 'Red book'... my eyes are sore! lol

But real interesting!

One more question at the moment:

- Is there a way of knowing where a point in the 3D matrix is on the screen? For example, I draw a triangle with many rotations and translations, then I work out where its centre of mass is and I draw a point there. How can I find out where in the screen that point will be displayed?
Would I really have to do all the complex calculations, or is there an easier way, like reading from the buffer or something?
Also, can I check the colour of a particular pixel on the screen or on the buffer ?

Cheers ;)

grudzio
04-02-2007, 11:32 AM
I think gluProject (http://developer.apple.com/documentation/Darwin/Reference/ManPages/man3/gluProject.3.html) is the anwser to your first question.

To check color of the pixel on the screen use glReadPixels (http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/readpixels.html) function.

IlovePascal
07-02-2007, 10:51 PM
:wink: ur the man :thumbup::thumbup::thumbup:

IlovePascal
07-02-2007, 10:55 PM
Can you destroy/erase a List?

Like if I want to make an object move around for a few seconds, is it worth making a list to draw it, use the list for a while then destroy the list when the animation ends?

grudzio
08-02-2007, 09:50 AM
Can you destroy/erase a List?
Yes. The lists are created and destroyed with calls to glGenLists and glDeleteLists. The contents of the list are specified by putting the drawing commands between glNewList..glEndList pair (glGenLists creates empty list). If the glNewList is called for a list which is not empty, its old contents are replaced with new one.


Like if I want to make an object move around for a few seconds, is it worth making a list to draw it, use the list for a while then destroy the list when the animation ends?i
Why would you want to destroy the list? You can use it to draw object, no matter if it moves or not.

IlovePascal
13-02-2007, 12:48 AM
Hey, I read a whole bunch about the procedures/functions you mentioned, but when I tried using them, it didn't work!

I have a few questions tht might help...

-Why does this not work:

Procedure Matrix_to_Win;
var model, proj, Winx,Winy,Winz : PGLdouble;
Matrixx,Matrixy,Matrixz : real;
view : PGLint;
begin
{view := 0;
model := GL_MODELVIEW;
proj := GL_PROJECTION;}
Winx := 0; Winy := 0; Winz := 0;
Matrixx := 0; Matrixy := 0; Matrixz := 0;

glGetDoublev(GL_MODELVIEW_MATRIX, model);
glGetDoublev(GL_PROJECTION_MATRIX, proj);

glGetIntegerv(GL_VIEWPORT, view);


gluProject(Matrixx, Matrixy, Matrixz,
model, proj, view,
Winx, Winy, Winz);
end;
I found that in an example they had on the internet, but it doesn't seem to work. Any clues?
I tried commenting out all the gl lines but one to see where the problem was but they all bugged! lol

-The gluProject 'returns' WinX, WinY and WinZ, right? bt those are the coordinates of the screen, right? then why a Z coordinate? :scratch:

-Does it return coordinates outside the screen too?

-If I want to use the Win coordinates, i'd like to make them integers, how do I do that?
How to convert PGLdouble to LongInt?
Double to longint?

Cheers :wink:

grudzio
13-02-2007, 11:10 AM
This procedure does not work because OpenGL functions do not allocate memory to store results. Although the specs says that glGetDoublev expects PGLDouble as a parameter (PGDouble - pointer to a double type) but actually it expects an array of doubles big enough to store the result of the query.

Pascal versions of glu(Un)Projects expects specific data types which are defined in glu.pas.

Here is a corrected version of your Matrix_to_win procedure


// objx,objy,objz - 3D location of a point
// screenX, screenY - will hold screen coordinates of (objx,objy,objz)
procedure Matrix_To_Win(objx,objy,objz : gldouble; var screenX : integer, var screenY : integer);
var
model, proj : T16dArray; //type defined in glu.pas
view : TViewportArray; //also defined in glu.pas
winx,winy,winz : glDouble;
begin
glGetDoublev(GL_PROJECTION, @proj);
glGetDoublev(GL_MODELVIEW, @model);
glGetIntegerv(GL_VIEWPORT,@view);

gluProject(objx,objy,objz, proj, model, view, @winx, @winy, @winz);
screenX := Round(winx);
//since OpenGL treats lower left corner as a (0,0) winy must be
//transformed to normal window coordinates with (0,0) at upper left
//corner
screenY := ScreenHeight - Round(winy);
end;

The z coordinate is a depth value. It is put into depth buffer and is used for depth sorting.

I think that gluProject may return coordinates that are outside the screen.

P. S. If you use FPC and gluProject crashes your application, look at this thread http://www.pascalgamedevelopment.com/viewtopic.php?t=3636

IlovePascal
14-02-2007, 12:04 AM
Kool! Thanks! I can't try it out now, but I sure will soon!

Btw, that thing with the GL and GLU units in FPC is quite interesting! Now I'm warned! lol

Also, when reading that other thread, I learned about GluUnProject, which is the opposite of what I asked, right?
I hadn't even asked cos I thought it was not possible to do that, since a point in the screen is an infinite line in a 3D matrix...

But obviously (and fortunately!) ppl are a lot smarter, and they found a way! I saw it requires to input the window coordinates plus a Z coordinate.
So that Z coordinate, is it the depth out of the screen (so negative for into the screen) regardless of the transformations you have made to your matrix; is it like the depth buffer you talked about, in which case I guess it would be positive into the screen, right?; or is it the z coordinate of your matrix?
If it's the latter, then what if you rotate the matrix so that the z axis is 'parallel' to the screen, wouldn't that make it undefined?

thanks for this extended help! :wink:

grudzio
14-02-2007, 11:25 AM
The winZ coordinate that must be passed to gluUnProject is a depth buffer value. You can get it by using glRedPixels with GL_DEPTH_COMPONENT parameter:


glReadPixels(screenX,screenY,1,1,GL_DEPTH_COMPONEN T,GL_FLOAT,@wz);


Another possibility that can be used for picking objects, is to call gluUnproject with minimal and maximal values of depth buffer which are zero and one. As a result you get two points from which you construct a ray and see if it intersects any objects.

aalina
18-10-2011, 07:33 AM
The right one is this dear
Procedure Matrix_to_Win; var model, proj, Winx,Winy,Winz : PGLdouble; Matrixx,Matrixy,Matrixz : real; view : PGLint; begin {view := 0; model := GL_MODELVIEW; proj := GL_PROJECTION;} Winx := 0; Winy := 0; Winz := 0; Matrixx := 0; Matrixy := 0; Matrixz := 0; glGetDoublev(GL_MODELVIEW_MATRIX, model); glGetDoublev(GL_PROJECTION_MATRIX, proj); glGetIntegerv(GL_VIEWPORT, view); gluProject(Matrixx, Matrixy, Matrixz, model, proj, view, Winx, Winy, Winz); end;