Difference between revisions of "OpenGL/zh CN"

From Lazarus wiki
Jump to navigationJump to search
(New page: {{OpenGL}} OpenGL ('''Open''' '''G'''raphics '''L'''ibrary) is a cross-platform API for producing 3D computer graphics. Most modern video cards provide hardware accelerated OpenGL support...)
 
m (Fixed syntax highlighting)
 
(14 intermediate revisions by 3 users not shown)
Line 1: Line 1:
 
{{OpenGL}}
 
{{OpenGL}}
  
OpenGL ('''Open''' '''G'''raphics '''L'''ibrary) is a cross-platform API for producing 3D computer graphics. Most modern video cards provide hardware accelerated OpenGL support, wich makes OpenGL a good solution for writing advanced graphics software.
+
OpenGL ('''Open''' '''G'''raphics '''L'''ibrary) 是一个跨平台的3D图像API.市面上流行的显卡都支持OpenGL硬件加速, 它是解决高级图形软件开发的一个好的方案。
  
==OpenGL units in Free Pascal==
+
==Free Pascal的OpenGL单元 ==
  
The FreePascal OpenGL interface consists of the following units:
+
FreePascal OpenGL 接口由下列单元构成:
* '''gl''': This unit contains the main functionality such as drawing polygons, applying transformations, setting colors and materials,... Procedures always start with the preposition "gl".
+
* '''gl''': 单元的主要功能包括绘置多边形, applying transformations, setting colors and materials,... Procedures always start with the preposition "gl".
 
* '''glu''': This unit contains OpenGL utils. Although it has some useful functions, this unit is not necessary as you can implement all glu Procedures with the functionality of the gl unit. Procedures always start with the preposition "glu".
 
* '''glu''': This unit contains OpenGL utils. Although it has some useful functions, this unit is not necessary as you can implement all glu Procedures with the functionality of the gl unit. Procedures always start with the preposition "glu".
 
* '''glext''': Vendors can provide additional functionality through extensions. Use this unit to use these extensions. <p>The functionality specific to higher OpenGL versions (1.2 and later) is available in this unit as well. Initializing this functionality is similar to initializing normal OpenGL extensions: just call Load_GL_version_X_Y function. If your OpenGL library version is older than X.Y, Load_GL_version_X_Y will return false.</p>
 
* '''glext''': Vendors can provide additional functionality through extensions. Use this unit to use these extensions. <p>The functionality specific to higher OpenGL versions (1.2 and later) is available in this unit as well. Initializing this functionality is similar to initializing normal OpenGL extensions: just call Load_GL_version_X_Y function. If your OpenGL library version is older than X.Y, Load_GL_version_X_Y will return false.</p>
* '''glut''': This unit provides functionality for creating an OpenGL window. Although this is a cross-platform unit, most Windows operating systems don't have a glut dll by default.
+
* '''glut''': 该单元提供建立OpenGL窗口的功能。 尽管这是一个跨平台的单元, 基本上所有Windows操作系统都没有默认的glut dll.
 
* '''glx''': glx provides functionality to set up an OpenGL window in an x window system. Procedures always start with the preposition "glx". Obviously, you cannot use this unit on non-x window systems such as Windows.
 
* '''glx''': glx provides functionality to set up an OpenGL window in an x window system. Procedures always start with the preposition "glx". Obviously, you cannot use this unit on non-x window systems such as Windows.
  
==OpenGL units in Lazarus==
+
==Lazarus 内的 OpenGL 单元 ==
  
Lazarus includes a TOpenGLControl - a LCL control with an OpenGL context. The lazarus package LazOpenGLContext can be found lazarus/components/opengl/lazopenglcontext.lpk. An example can be found in lazarus/examples/openglcontrol/openglcontrol_demo.lpi.
+
Lazarus 包含 TOpenGLControl - LCL 控件 提供 OpenGL 环境. 可以找到这个包 lazarus/components/opengl/lazopenglcontext.lpk. 还有一个例子: lazarus/examples/openglcontrol/openglcontrol_demo.lpi. 
 +
(注:我在ubuntu 9.04 64bit里没有编译成功,郁闷。提示lGL没有发现,我在/usr/lib/发现libgl-2.0.so)
  
==Third party OpenGL units==
+
==第三方 OpenGL 单元==
  
 
*[[GLScene]] is a Lazarus package with lots of extra features for OpenGL applications.
 
*[[GLScene]] is a Lazarus package with lots of extra features for OpenGL applications.
*[[Kambi VRML game engine]] allows you to navigate and render 3D worlds (in VRML, X3D and other 3D formats).
+
*[[Castle Game Engine]] allows you to navigate and render 3D worlds (in VRML, X3D and other 3D formats).
  
==Tutorial==
+
(注:不知道SDL算不算!)
  
[[OpenGL Tutorial]]
+
==教程==
 +
 
 +
[[OpenGL Tutorial]] OpenGL 教程
  
 
==Q/A using OpenGL binding==
 
==Q/A using OpenGL binding==
Line 45: Line 48:
 
initialized separately. In particular cases, you can make tricks like
 
initialized separately. In particular cases, you can make tricks like
  
<delphi>if glIsBufferARB = nil then glIsBufferARB := @glIsBuffer;</delphi>
+
<syntaxhighlight lang=pascal>if glIsBufferARB = nil then glIsBufferARB := @glIsBuffer;</syntaxhighlight>
  
 
but this should be left to the final programmer that knows that
 
but this should be left to the final programmer that knows that
Line 57: Line 60:
 
'''glu''' unit:
 
'''glu''' unit:
  
<delphi>{$IFDEF Windows}
+
<syntaxhighlight lang=pascal>{$IFDEF Windows}
 
   {$DEFINE extdecl := stdcall}
 
   {$DEFINE extdecl := stdcall}
 
{$ELSE}
 
{$ELSE}
Line 63: Line 66:
 
{$ENDIF}
 
{$ENDIF}
  
gluTessCallback: procedure(tess: PGLUtesselator; which: GLenum; fn: TCallBack); extdecl;</delphi>
+
gluTessCallback: procedure(tess: PGLUtesselator; which: GLenum; fn: TCallBack); extdecl;</syntaxhighlight>
  
 
<b>Windows note:</b>A common problem is that the calling convention of the glu functions seems to vary in several different GLUT DLLs builds for windows.
 
<b>Windows note:</b>A common problem is that the calling convention of the glu functions seems to vary in several different GLUT DLLs builds for windows.
Line 70: Line 73:
 
You should define your callback functions like so:
 
You should define your callback functions like so:
  
<delphi>procedure MyTessBegin(which: GLEnum);  
+
<syntaxhighlight lang=pascal>procedure MyTessBegin(which: GLEnum);  
 
{$IFDEF Windows} stdcall; {$else} cdecl; {$endif}
 
{$IFDEF Windows} stdcall; {$else} cdecl; {$endif}
 
begin
 
begin
Line 86: Line 89:
 
begin
 
begin
 
   glVertex3dv(PGLDouble(data));
 
   glVertex3dv(PGLDouble(data));
end;</delphi>
+
end;</syntaxhighlight>
  
 
Note the cdecl/stdcall modifiers; they are required. You then call gluTessCallback in  
 
Note the cdecl/stdcall modifiers; they are required. You then call gluTessCallback in  
 
the following manner:
 
the following manner:
  
<delphi>gluTessCallback(tess, GLU_TESS_BEGIN, TCallBack(@MyTessBegin));
+
<syntaxhighlight lang=pascal>gluTessCallback(tess, GLU_TESS_BEGIN, TCallBack(@MyTessBegin));
 
gluTessCallback(tess, GLU_TESS_END, TCallBack(@MyTessEnd));
 
gluTessCallback(tess, GLU_TESS_END, TCallBack(@MyTessEnd));
gluTessCallback(tess, GLU_TESS_VERTEX, TCallBack(@MyTessVertex));</delphi>
+
gluTessCallback(tess, GLU_TESS_VERTEX, TCallBack(@MyTessVertex));</syntaxhighlight>
  
 
Make sure you cast the pointer to your callback function to the TCallBack type,  
 
Make sure you cast the pointer to your callback function to the TCallBack type,  
Line 101: Line 104:
 
following calling convention:
 
following calling convention:
  
<delphi>gluTessCallback(tess, GLU_TESS_BEGIN, TCallBack(glBegin));
+
<syntaxhighlight lang=pascal>gluTessCallback(tess, GLU_TESS_BEGIN, TCallBack(glBegin));
 
gluTessCallback(tess, GLU_TESS_END, TCallBack(glEnd));
 
gluTessCallback(tess, GLU_TESS_END, TCallBack(glEnd));
gluTessCallback(tess, GLU_TESS_VERTEX, TCallBack(glVertex3dv));</delphi>
+
gluTessCallback(tess, GLU_TESS_VERTEX, TCallBack(glVertex3dv));</syntaxhighlight>
  
 
Finally, [http://www.ludicity.org/files/tess_demo.pp here] is source code
 
Finally, [http://www.ludicity.org/files/tess_demo.pp here] is source code

Latest revision as of 05:56, 23 February 2020

Deutsch (de) English (en) français (fr) 日本語 (ja) português (pt) русский (ru) Tiếng Việt (vi) 中文(中国大陆)‎ (zh_CN)

OpenGL (Open Graphics Library) 是一个跨平台的3D图像API.市面上流行的显卡都支持OpenGL硬件加速, 它是解决高级图形软件开发的一个好的方案。

Free Pascal的OpenGL单元

FreePascal OpenGL 接口由下列单元构成:

  • gl: 单元的主要功能包括绘置多边形, applying transformations, setting colors and materials,... Procedures always start with the preposition "gl".
  • glu: This unit contains OpenGL utils. Although it has some useful functions, this unit is not necessary as you can implement all glu Procedures with the functionality of the gl unit. Procedures always start with the preposition "glu".
  • glext: Vendors can provide additional functionality through extensions. Use this unit to use these extensions.

    The functionality specific to higher OpenGL versions (1.2 and later) is available in this unit as well. Initializing this functionality is similar to initializing normal OpenGL extensions: just call Load_GL_version_X_Y function. If your OpenGL library version is older than X.Y, Load_GL_version_X_Y will return false.

  • glut: 该单元提供建立OpenGL窗口的功能。 尽管这是一个跨平台的单元, 基本上所有Windows操作系统都没有默认的glut dll.
  • glx: glx provides functionality to set up an OpenGL window in an x window system. Procedures always start with the preposition "glx". Obviously, you cannot use this unit on non-x window systems such as Windows.

Lazarus 内的 OpenGL 单元

Lazarus 包含 TOpenGLControl - LCL 控件 提供 OpenGL 环境. 可以找到这个包 lazarus/components/opengl/lazopenglcontext.lpk. 还有一个例子: lazarus/examples/openglcontrol/openglcontrol_demo.lpi.  (注:我在ubuntu 9.04 64bit里没有编译成功,郁闷。提示lGL没有发现,我在/usr/lib/发现libgl-2.0.so)

第三方 OpenGL 单元

  • GLScene is a Lazarus package with lots of extra features for OpenGL applications.
  • Castle Game Engine allows you to navigate and render 3D worlds (in VRML, X3D and other 3D formats).

(注:不知道SDL算不算!)

教程

OpenGL Tutorial OpenGL 教程

Q/A using OpenGL binding

Q: I don't understand why the ARB version does not work. AFAIK it has the same entry points as the core functionality and OpenGL versions are required to support the ARB version of functions even if the non ARB version is in the core now.

A: No. OpenGL doesn't have to support the extension entry points, even when it supports the same functionality in core already. Vendor is free to remove the extensions, and support only the "core" functions.

Also, sometimes when functionality is promoted from ARB extension into core it's slightly changed (although in 99% cases it stays the same). Example is the GLSL shaders, that expose (very slightly) different API through ARB extensions and through core 2.0 specification.

Basically, what is exposed through extensions is completely orthogonal to what is exposed through core functionality, so they should be initialized separately. In particular cases, you can make tricks like

if glIsBufferARB = nil then glIsBufferARB := @glIsBuffer;

but this should be left to the final programmer that knows that "ARB_vertex_buffer_object" behavior is identical to how it works in core.

Q: When I try to use the gluTessCallback function from the glu unit, either the compiler complains or I get a segmentation fault when I try to run my program. How can I get it to work properly?

A: The gluTessCallback function is defined in the following way in the glu unit:

{$IFDEF Windows}
  {$DEFINE extdecl := stdcall}
{$ELSE}
  {$DEFINE extdecl := cdecl}
{$ENDIF}

gluTessCallback: procedure(tess: PGLUtesselator; which: GLenum; fn: TCallBack); extdecl;

Windows note:A common problem is that the calling convention of the glu functions seems to vary in several different GLUT DLLs builds for windows. In some it is stdcall, in some cdecl. The most used one seems to be stdcall.

You should define your callback functions like so:

procedure MyTessBegin(which: GLEnum); 
{$IFDEF Windows} stdcall; {$else} cdecl; {$endif}
begin
  glBegin(which);
end;

procedure MyTessEnd; 
{$IFDEF Windows} stdcall; {$else} cdecl; {$endif}
begin
  glEnd();   // The () is required
end;

procedure MyTessVertex(data: Pointer);
{$IFDEF Windows} stdcall; {$else} cdecl; {$endif}
begin
  glVertex3dv(PGLDouble(data));
end;

Note the cdecl/stdcall modifiers; they are required. You then call gluTessCallback in the following manner:

gluTessCallback(tess, GLU_TESS_BEGIN, TCallBack(@MyTessBegin));
gluTessCallback(tess, GLU_TESS_END, TCallBack(@MyTessEnd));
gluTessCallback(tess, GLU_TESS_VERTEX, TCallBack(@MyTessVertex));

Make sure you cast the pointer to your callback function to the TCallBack type, as shown above.

Alternatively, if you want to refer to the OpenGL functions directly, use the following calling convention:

gluTessCallback(tess, GLU_TESS_BEGIN, TCallBack(glBegin));
gluTessCallback(tess, GLU_TESS_END, TCallBack(glEnd));
gluTessCallback(tess, GLU_TESS_VERTEX, TCallBack(glVertex3dv));

Finally, here is source code for a simple tessellation demo (uses glut).

Go to back Packages List