例子2-7.和OpenGL在一起預置SDL
//關於目前影像設置的資訊. const info : PSDL_VideoInfo = nil; //我們視窗戶的尺度. var width : integer := 0; height : integer := 0; //在窗戶的彩色的深度. bpp : integer := 0; //我們將變為SDL_SetVideoMode通過的旗幟. flags : integer := 0; begin //首先預置SDL的影像子系統. if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) then begin //未能,出去. MessageBox(0, PChar(Format('Video initialization failed : %s', [SDL_GetError])), 'Error', MB_OK or MB_ICONHAND); quit_tutorial( 1 ); end; //讓我們得到一些影像資訊. info := SDL_GetVideoInfo; if( info = nil ) then begin //這個大概不應該發生. MessageBox(0, PChar(Format('Video query failed : %s', [SDL_GetError])), 'Error', MB_OK or MB_ICONHAND); quit_tutorial( 1 ); end; {*落下我們寬度高度向640/480你是會 *當然讓用戶在一正常標準中決定這個 *app).我們得到bpp我們需求會從 *展示.在X11上,VidMode不能改變 *分解所以這個正大概過分是 *保險箱.在Win32,ChangeDisplaySettings下面 *能改變bpp. *} width := 640; height := 480; bpp := info.vfmt.BitsPerPixel; {* *現在,我們想要向組織我們需求 為我們OpenGL窗戶*窗戶屬性. *我們想要紅色,綠色的*atleast* 5小塊 *和藍色.我們也想要至少一16位 *深度緩衝記憶體. * *我們做的最後一件事是需求一兩倍 *當窗戶緩衝.在上'1'傾向增加一倍 *當緩衝'0'關上它. * 我們不在中使用SDL_DOUBLEBUF的*筆記 *向SDL_SetVideoMode旗幟.那個做 *不僅影響GL屬性狀態 *標準2D blitting組織. *} SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 ); SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 ); SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 ); SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 ); SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); {* *我們想要請求SDL提供我們 有一扇在一fullscreen中OpenGL窗戶的* *影像方式. * *練習: 開始一選擇餘地有窗的*製造和 *柄恰當調整事件的大小和在一起 *glViewport. *} flags := SDL_OPENGL or SDL_FULLSCREEN; {* *設定影像方式 *} if ( SDL_SetVideoMode( width, height, bpp, flags ) = 0 ) then begin {* *這個能為各種各樣的理由發生 不要是設定*包括展示明確地講 *不要是可用分解,等等 *}
MessageBox(0, PChar(Format('Video mode set failed : %s', [SDL_GetError])), 'Error', MB_OK or MB_ICONHAND);quit_tutorial( 1 );
現在一完整例子代碼列表下面被提出.
例子2-8.SDL和OpenGL
{* *SDL OpenGL個別輔導. *(c)7Michael Vance,2000 *briareos@lokigames.com * *在LGPL的條款下分發. *} uses SDL, OpenGL; var should_rotate : TGLboolean := GL_TRUE; procedure quit_tutorial( code : integer ); begin {* *離開SDL,所以我們能釋放fullscreen *方式和交還前一影像設置 *等等 *} halt( code ); end; procedure handle_key_down( keysym : PSDL_keysym ); begin {* *如果'Esc',我們是僅僅有興趣 *被敦促. * *練習: *處理箭關鍵和有那改變 *觀看位置/角. *} case keysym.sym of SDLK_ESCAPE: quit_tutorial( 0 ); SDLK_SPACE: should_rotate := not should_rotate; else break; end; end; procedure process_events; var
//我們SDL事件佔位符號. event : TSDL_Event;begin
//抓起所有的離開行列事件.
while( SDL_PollEvent( @event ) ) do
begin
case event.type_ of
SDL_KEYDOWN:
/*柄重要壓.*/
handle_key_down((&event.key.keysym);
SDL_QUIT:
/*柄離開(像Ctrl c)需求.*/
quit_tutorial((0);
end;
end;
end;
procedure draw_screen;
var
angle : single;
v0, v1, v2, v3, v4, v5, v6, v7 : array[0..2] of TGLFloat;
red, green, blue, white, yellow, black, orange, purple : TGLuByte;
begin
//我們轉動的角.
angle := 0.0;
{*
*練習:
*用頂點代替這可怕混亂
*陣列和一向glDrawElements呼叫.
*
*練習:
在完整上面的以後*,改變
*向使用它匯編頂點陣列.
*
*練習:
*查證我的繞這裡是恰當;)
*}
v0[ ] := { -1.0f, -1.0f, 1.0f };
v1[ ] := { 1.0f, -1.0f, 1.0f };
v2[ ] := { 1.0f, 1.0f, 1.0f };
v3[ ] := { -1.0f, 1.0f, 1.0f };
v4[ ] := { -1.0f, -1.0f, -1.0f };
v5[ ] := { 1.0f, -1.0f, -1.0f };
v6[ ] := { 1.0f, 1.0f, -1.0f };
v7[ ] := { -1.0f, 1.0f, -1.0f };
red[ ] := { 255, 0, 0, 255 };
green[ ] := { 0, 255, 0, 255 };
blue[ ] := { 0, 0, 255, 255 };
white[ ] := { 255, 255, 255, 255 };
yellow[ ] := { 0, 255, 255, 255 };
black[ ] := { 0, 0, 0, 255 };
orange[ ] := { 255, 255, 0, 255 };
purple[ ] := { 255, 0, 255, 0 };
//清理顏色和深度緩衝記憶體.
glClear( GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT );
//我們不想要修改投影矩陣.
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
//順Z軸而下移動.
glTranslatef((0.0,0.0,-5.0);
//旋轉.
glRotatef((角,0.0,1.0,0.0);
if ( should_rotate ) then
begin
inc( angle, 1 );
if ( angle > 360.0 ) then
begin
angle := 0.0;
end;
end;
//把我們三角形資料寄給管道.
glBegin((GL_TRIANGLES);
glColor4ubv( red );
glVertex3fv( v0 );
glColor4ubv( green );
glVertex3fv( v1 );
glColor4ubv( blue );
glVertex3fv( v2 );
glColor4ubv( red );
glVertex3fv( v0 );
glColor4ubv( blue );
glVertex3fv( v2 );
glColor4ubv( white );
glVertex3fv( v3 );
glColor4ubv( green );
glVertex3fv( v1 );
glColor4ubv( black );
glVertex3fv( v5 );
glColor4ubv( orange );
glVertex3fv( v6 );
glColor4ubv( green );
glVertex3fv( v1 );
glColor4ubv( orange );
glVertex3fv( v6 );
glColor4ubv( blue );
glVertex3fv( v2 );
glColor4ubv( black );
glVertex3fv( v5 );
glColor4ubv( yellow );
glVertex3fv( v4 );
glColor4ubv( purple );
glVertex3fv( v7 );
glColor4ubv( black );
glVertex3fv( v5 );
glColor4ubv( purple );
glVertex3fv( v7 );
glColor4ubv( orange );
glVertex3fv( v6 );
glColor4ubv( yellow );
glVertex3fv( v4 );
glColor4ubv( red );
glVertex3fv( v0 );
glColor4ubv( white );
glVertex3fv( v3 );
glColor4ubv( yellow );
glVertex3fv( v4 );
glColor4ubv( white );
glVertex3fv( v3 );
glColor4ubv( purple );
glVertex3fv( v7 );
glColor4ubv( white );
glVertex3fv( v3 );
glColor4ubv( blue );
glVertex3fv( v2 );
glColor4ubv( orange );
glVertex3fv( v6 );
glColor4ubv( white );
glVertex3fv( v3 );
glColor4ubv( orange );
glVertex3fv( v6 );
glColor4ubv( purple );
glVertex3fv( v7 );
glColor4ubv( green );
glVertex3fv( v1 );
glColor4ubv( red );
glVertex3fv( v0 );
glColor4ubv( yellow );
glVertex3fv( v4 );
glColor4ubv( green );
glVertex3fv( v1 );
glColor4ubv( yellow );
glVertex3fv( v4 );
glColor4ubv( black );
glVertex3fv( v5 );
glEnd;
{*
*練習:
告訴用戶那'Spc'*拔取文本
轉動和'Esc'離開的*停頓.
*做它使用vetors和使方形天線具有特定結構.
*
*
*交換緩衝記憶體.這個這個告訴司機向
*放棄從目錄下一個結構的
*後面緩衝記憶體和設定所有的放棄運算
在什麼是前部緩衝記憶體上發生*.
*
*兩倍緩衝記憶體防止骯髒畫面流淚
從區域鼓勵應用*的
的同時被更新*銀幕.
*}
SDL_GL_SwapBuffers;
end;
procedure setup_opengl( width : integer; height : integer );
var
ration : single;
begin
ratio := width / height;
//我們 shading模範--Gouraud(smooth).
glShadeModel((GL_SMOOTH);
//挑揀出再殺掉.
glCullFace((GL_BACK);
glFrontFace((GL_CCW);
glEnable((GL_CULL_FACE);
//設定純顏色.
glClearColor((0,0,0,0);
//建立我們觀察孔.
glViewport( 0, 0, width, height );
{*
*改變成投影矩陣和裝置
*我們調查容量.
*}
glMatrixMode((GL_PROJECTION);
glLoadIdentity;
{*
*練習:
*用一向glFrustum呼叫代替這個.
*}
gluPerspective((60.0,比率,1.0,1024.0);
end;
var
width, height, bpp : integer;
flags : integer;
info : PSDL_VideoInfo;
begin
//關於目前影像設置的資訊.
info := nil;
//我們窗戶的度.
width := 0;
height := 0;
//在我們窗戶的小塊中彩色的深度.
bpp:=0;
//我們將變為SDL_SetVideoMode通過的旗幟.
lags := 0;
//首先預置SDL的影像子系統.
if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) then
begin
// Failed, exit.
MessageBox(0, PChar(Format('Video initialization failed : %s',
[SDL_GetError])), 'Error', MB_OK or MB_ICONHAND);
quit_tutorial( 1 );
end;
// Let's get some video information.
info := SDL_GetVideoInfo;
if( info <> nil ) then
begin
// This should probably never happen.
MessageBox(0, PChar(Format('Video query failed : %s', [SDL_GetError])),
'Error', MB_OK or MB_ICONHAND);
quit_tutorial( 1 );
end;
{*
* Set our width/height to 640/480 (you would
* of course let the user decide this in a normal
* app). We get the bpp we will request from
* the display. On X11, VidMode can't change
* resolution, so this is probably being overly
* safe. Under Win32, ChangeDisplaySettings
* can change the bpp.
*}
width := 640;
height := 480;
bpp = info.vfmt.BitsPerPixel;
{*
* Now, we want to setup our requested
* window attributes for our OpenGL window.
* We want *at least* 5 bits of red, green
* and blue. We also want at least a 16-bit
* depth buffer.
*
* The last thing we do is request a double
* buffered window. '1' turns on double
* buffering, '0' turns it off.
*
* Note that we do not use SDL_DOUBLEBUF in
* the flags to SDL_SetVideoMode. That does
* not affect the GL attribute state, only
* the standard 2D blitting setup.
*}
SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
{*
* We want to request that SDL provide us
* with an OpenGL window, in a fullscreen
* video mode.
*
* EXERCISE:
* Make starting windowed an option, and
* handle the resize events properly with
* glViewport.
*}
flags := SDL_OPENGL or SDL_FULLSCREEN;
{*
* Set the video mode
*}
if ( SDL_SetVideoMode( width, height, bpp, flags ) = 0 ) then
begin
/*
* This could happen for a variety of reasons,
* including DISPLAY not being set, the specified
* resolution not being available, etc.
*/
MessageBox(0, PChar(Format('Video mode set failed : %s',
[SDL_GetError])), 'Error', MB_OK or MB_ICONHAND);
quit_tutorial( 1 );
end;
{*
* At this point, we should have a properly setup
* double-buffered window for use with OpenGL.
*}
setup_opengl( width, height );
{*
* Now we want to begin our normal app process--
* an event loop with a lot of redrawing.
*}
while( true ) do
begin
// Process incoming events.
process_events;
// Draw the screen.
draw_screen;
end;
{*
* EXERCISE:
* Record timings using SDL_GetTicks() and
* and print out frames per second at program
* end.
*}
// Never reached.
exit;
end;