電腦遊戲製作開發設計論壇 首頁 電腦遊戲製作開發設計論壇
任何可以在PC上跑的遊戲都可以討論,主要以遊戲之製作開發為主軸,希望讓台灣的遊戲人有個討論、交流、教學、經驗傳承的園地
 
 常見問題常見問題   搜尋搜尋   會員列表會員列表   會員群組會員群組   會員註冊會員註冊 
 個人資料個人資料   登入檢查您的私人訊息登入檢查您的私人訊息   登入登入 

Google
[轉貼自程式設計俱樂部]glut 教學 - 把我的圖放到視窗上!!

 
發表新主題   回覆主題    電腦遊戲製作開發設計論壇 首頁 -> 遊戲程式高級班:DirectX、OpenGL及各種圖型函式庫
上一篇主題 :: 下一篇主題  
發表人 內容
satanupup
喜歡上這裡的冒險者


註冊時間: 2007-05-29
文章: 80

68.10 果凍幣

發表發表於: 2007-6-28, PM 1:58 星期四    文章主題: [轉貼自程式設計俱樂部]glut 教學 - 把我的圖放到視窗上!! 引言回覆

作者 : ma_hty(白老鼠(Gary))
這一次要介紹的, 是使用 glDrawPixels() 來畫圖.

這個, 會用到
"glut 教學 - 第一個視窗" 和
"glut 教學 - 讀取 bmp圖檔"
請先看畢這兩個教學, 才開始這個.

由教學一, 我們得到了基本的 glut 視窗,
由教學二, 我們讀取到 bmp圖檔,
現在, 接著要做的, 就是要把 圖檔畫到視窗上.
------------------------------------------------------------
/////////////////////////
// glutTest03.cpp
//
// Created by Gary Ho, ma_hty@hotmail.com, 2005
//


#include <stdio.h>

#include "glut.h"
#include "g_bmp.h"

GBmp bm0;

void display()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

glRasterPos2f( -bm0.w/640.0, -bm0.h/640.0 );
glDrawPixels( bm0.w, bm0.h, GL_RGB, GL_UNSIGNED_BYTE, bm0.rgb );

glutSwapBuffers();
}

void main()
{
glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGB );
glutInitWindowSize( 640, 640 );
glutCreateWindow( "hihi" );
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

glutDisplayFunc(display);

bm0.load( "blank.bmp" );

glutMainLoop();
}
------------------------------------------------------
這個程式 ( glutTest03.cpp ), 會先讀進 blank.bmp, 然後把它畫到視窗的中央.

接著, 我會更詳細的交代部份 glut 的 function 的意思.
----------------------
glRasterPos2f( -bm0.w/640.0, -bm0.h/640.0 ); //決定畫圖的位置.
glDrawPixels( bm0.w, bm0.h, GL_RGB, GL_UNSIGNED_BYTE, bm0.rgb ); //實在畫圖的程序
-----------------
如果你是初學 OpenGL, 可能你會疑惑, "為什麼 畫圖 和 畫圖的位置 會分在兩個不同的 function 去設定呢?"... ...

OpenGL 是 procedural 的模組, 根我們常用的 C++ Object 很不同的, 在 OpenGL 模組內, 它記錄著一大堆全域變數, OpenGL 載入時, 會同時把這些全城變數設成預設值, 如果你用不著的變數, 就讓它繼續是預設值, 不用管它就可以了.

因為 procedural 的關係, 你並沒有物件, 只有全域變數一大堆, 即是說, 如果你把變數改了, 其他會用這個變數的程序也會受影響. 請緊記.

glDrawPixels() 畫圖時畫到什麼位置, 由 OpenGL 之內的某個變數決定的, 要改這個, 你要使用 glRasterPos2f() 去改它.
-----------------
OpenGL 預設的座標系統,
(1,1) 在視窗的右上方,
(0,0) 在視窗中心,
(-1,-1) 在視窗的左下方.

這個, 跟 microsoft 的視窗座標 是完全不同的, 請注意.
------------
glutInitWindowSize( 640, 640 ); // 設定視窗大小
glutCreateWindow( "hihi" ); // 建立視窗, 並把 title 設為 "hihi"
glutDisplayFunc(display); // 註冊負責顯示的 function
glutMainLoop(); // 開始視窗的 message loop
-------------
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); // 清空畫面

每次重畫畫面時, 你也需要先清空畫面, 每一次畫圖, 圖其實也是畫到顯示卡的, 在顯示卡之內, 有一個剛畫的圖的 buffer, 如果你不先清空這個, 你就會重複的複到畫面上, 情況就好像, 你在紙上用鉛筆畫東西, 畫完了之後, 沒刷掉就再畫一樣.
------------glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

這個, 是對應著 glDrawPixels 而來的, 因為效率考慮, 所以,

OpenGL 預設, 你給 glDrawPixels 的圖檔資料, 它的每一個 row 的大小 ( 以 byte 來算 ), 也是可以給 4 整除的.

假設你的圖檔是 150x150, 每一個 row 的大小就會是 150 * 3 = 450 , 450 不能被 4 整除的. 如果要強行把它換成可以被 4 整除, 一般的做法, 就是在每一個 row 多加 2 bytes 沒用途的資料 (這個步驟我們叫 padding ), 如此 450 就會變成 452, 452 就可以被 4 整除了.

但是, 每 row 大小, 需要是多少的倍數, 雖然預設了是 4, 但是, 你是可以把它改成 1, 2, 4, 8, 其中任意一個的, 如果你設成 1, 這麼你就可以不用管 padding 的問題了 ( 因為什麼整數也可以被 1 整除呀 ), 但是, 懶散的結果, 就是程式 run-time 時慢一點點.

最好的做法, 應該直接使用 寬 可被 4 整除的圖.
-----------------
致 初學OpenGL的網友,

^^, 恭喜你, 竟然有心機看完這麼長的介紹, 到底... 得到什麼呢?... 就是... 一份功課 @@!!

功課一 :
"載入最少三個圖檔, 畫在畫面上不同的位置"
-------------------------
回頂端
檢視會員個人資料 發送私人訊息
從之前的文章開始顯示:   
發表新主題   回覆主題    電腦遊戲製作開發設計論壇 首頁 -> 遊戲程式高級班:DirectX、OpenGL及各種圖型函式庫 所有的時間均為 台灣時間 (GMT + 8 小時)
1頁(共1頁)

 
前往:  
無法 在這個版面發表文章
無法 在這個版面回覆文章
無法 在這個版面編輯文章
無法 在這個版面刪除文章
無法 在這個版面進行投票
可以 在這個版面附加檔案
可以 在這個版面下載檔案


Powered by phpBB © 2001, 2005 phpBB Group
正體中文語系由 phpbb-tw 維護製作