例子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;