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

Google
[轉貼自程式設計俱樂部]glut 教學 - 讀取 bmp圖檔

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


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

68.10 果凍幣

發表發表於: 2007-6-28, PM 1:56 星期四    文章主題: [轉貼自程式設計俱樂部]glut 教學 - 讀取 bmp圖檔 引言回覆

作者 : ma_hty(白老鼠(Gary))
--------------------------------
甚麼說呢...
OpenGL 是沒有對圖檔的直接支援的, 它的 API 只是對應 3D Rendering 必需的, glut 也沒有, 每一次有人問關於讀取圖檔的問題, 我也會很懶散的說, 用外面的 library 吧.

但是, 讀取圖檔的功能, 縱然自己做出來的功能可能較差, 但是, 自己有能力處理, 才會安心的. 或是當成是個練習, 也是好事.

好吧, 就讓我們去寫程式讀圖檔.

code1------------------------------------------------------------------------
/////////////////////////
// g_bmp.h
//
// Created by Gary Ho, ma_hty@hotmail.com, 2005
//

#ifndef G_BMP_H
#define G_BMP_H

class GBmp
{
public:
int w,h;
unsigned char *rgb;

GBmp();
~GBmp();

void load( const char *spath );
void load( int width, int height );
void load( int width, int height, unsigned char *rgb_data );
void save( const char *spath );
void flip_vectical();

private:
void rb_swap();
};

#endif
code2-------------------------------------------------------------------------
/////////////////////////
// glutTest01.cpp
//
// Created by Gary Ho, ma_hty@hotmail.com, 2005
//

#include "g_bmp.h"

void main()
{
GBmp tbmp;
tbmp.load( "a.bmp" );
tbmp.flip_vectical();
tbmp.save( "b.bmp" );
}
-----------------------------------------------------
讀取 BMP 的部份, 在維持 易讀, 易用 和 盡量簡化 的原則下, 已是很簡單的.

glutTest01.cpp, 是一個範例, 它會讀入一個 a.bmp, 把它上下倒置, 然後存成叫 b.bmp 的檔案.

Bitmap 它支援很多種不同的資料格式, 如果要把 Bitmap 支援的都寫出來, 是很用人力的一件事, 因此, 我只寫了讀取 uncompressed RGB888 的 bitmap 檔 的功能, 用來存取 texture 這個應該夠用了.

如果你夠細心, 可能已發現 GBmp 這個 class, 除了, 存取的功能外, 只有一個上下倒置的功能, 提供這個功能的是有實質應用的, 就是, 由於 OpenGL 是假定 texture 都是 bottom-up scanline (由下而上) 的, 但是, bitmap 是 top-down scanline (由上而下), 因此, 把 bitmap 交給 OpenGL 之前, 你是必要把 bitmap 上下倒置的, 不然, 顯示出來的時候就會發生 texture 上下倒置 的情況.
code3--------------------------------------------------------------------
/////////////////////////
// g_bmp.cpp
//
// Created by Gary Ho, ma_hty@hotmail.com, 2005
//

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>

#include "g_bmp.h"

#pragma pack( push, 1 )
typedef struct _bmp_header_info
{
unsigned short bfType;
unsigned int bfSize;
unsigned short bfReserved1;
unsigned short bfReserved2;
unsigned int bfOffBits;

// bitmap header
unsigned int biSize;
int biWidth;
int biHeight;
unsigned short biPlanes;
unsigned short biBitCount;
unsigned int biCompression;
unsigned int biSizeImage;
int biXpelsPerMeter;
int biYpelsPerMeter;
unsigned int biClrUsed;
unsigned int biClrImportant;
} bmp_header_info;
#pragma pack( pop, 1 )

GBmp::GBmp()
{
memset( this, 0, sizeof(GBmp) );
}

GBmp::~GBmp()
{
if(rgb!=NULL)
free(rgb);
}

void GBmp::load( const char *spath )
{

bmp_header_info bhi;
{
FILE *f0 = fopen( spath, "rb" );
if( f0==NULL )
{
printf( "[Error] GBmp::load, file %s not found.\n", spath );
exit(-1);
}

fread( &bhi, sizeof(bmp_header_info), 1, f0 );
fclose(f0);
}

if( bhi.bfType != 'MB' )
{
printf( "[Error] GBmp::load, not bitmap file\n" );
exit(-1);
}

if( bhi.biCompression != 0 )
{
printf( "[Error] GBmp::load, only uncompressed bitmap is supported\n" );
exit(-1);
}

if( bhi.biBitCount != 24 )
{
printf( "[Error] GBmp::load, must be RGB888 bitmap\n" );
exit(-1);
}

if(rgb) free(rgb);

w = bhi.biWidth;
h = bhi.biHeight;
rgb = (unsigned char*) malloc( w*h*3*sizeof(unsigned char) );
{
FILE *f0 = fopen( spath, "rb" );
fseek( f0, bhi.bfOffBits, SEEK_SET );
int j;
for( j=0; j<h; j++ )
{
fread( &rgb[j*w*3], sizeof(unsigned char), w*3, f0 );
fseek( f0, (4-w*3%4)%4, SEEK_CUR );
}
fclose(f0);
}
rb_swap();
}

void GBmp::load( int width, int height )
{
if(rgb) free(rgb);

w = width;
h = height;
rgb = (unsigned char*) malloc( w*h*3*sizeof(unsigned char) );
memset( rgb, 0, w*h*3*sizeof(unsigned char) );
}

void GBmp::load( int width, int height, unsigned char *rgb_data )
{
if(rgb) free(rgb);

w = width;
h = height;
rgb = (unsigned char*) malloc( w*h*3*sizeof(unsigned char) );
memcpy( rgb, rgb_data, w*h*3*sizeof(unsigned char) );
}

void GBmp::flip_vectical()
{
unsigned char* tmp_rgb = (unsigned char*) malloc( w*h*3*sizeof(unsigned char) );
int j;
for( j=0; j<h; j++ )
memcpy( &tmp_rgb[j*w*3], &rgb[(h-j-1)*w*3], w*3*sizeof(unsigned char) );

memcpy( rgb, tmp_rgb, w*h*3*sizeof(unsigned char) );

free(tmp_rgb);
}

void GBmp::rb_swap()
{
unsigned char tmp;
int i,j;
for( j=0; j<h; j++ )
for( i=0; i<w; i++ )
{
tmp = rgb[(j*w+i)*3];
rgb[(j*w+i)*3] = rgb[(j*w+i)*3+2];
rgb[(j*w+i)*3+2] = tmp;
}
}
void GBmp::save( const char *spath )
{
bmp_header_info bhi;
bhi.bfType = 'MB';
bhi.bfSize = w*h*3*sizeof(unsigned char) + sizeof(bhi);
bhi.bfReserved1 = 0;
bhi.bfReserved2 = 0;
bhi.bfOffBits = sizeof(bhi);

bhi.biSize = 40;
bhi.biWidth = w;
bhi.biHeight = h;
bhi.biPlanes = 1;
bhi.biBitCount = 24;
bhi.biCompression = 0;
bhi.biSizeImage = 0;
bhi.biXpelsPerMeter = 0;
bhi.biYpelsPerMeter = 0;
bhi.biClrUsed = 0;
bhi.biClrImportant = 0;

int j;
GBmp a;
a.load( w,h, rgb );
a.rb_swap();
unsigned char pad[3] = {0};

FILE *f0 = fopen( spath, "wb" );
fwrite( &bhi, sizeof(bmp_header_info), 1, f0 );
for( j=0; j<h; j++ )
{
fwrite( &a.rgb[j*w*3], sizeof(unsigned char), w*3, f0 );
fwrite( pad, sizeof(unsigned char), (4-w*3%4)%4, f0 );
}
fclose(f0);
}
--------------------------------------------------------------------
噢... 有一點需要修正, Uncompressed Bitmap 它的 scanline 是 bottom-up ( 由下而上 ), 並不是之前說的 top-down ( 由上而下 )
---------------------
回頂端
檢視會員個人資料 發送私人訊息
從之前的文章開始顯示:   
發表新主題   回覆主題    電腦遊戲製作開發設計論壇 首頁 -> 遊戲程式高級班:DirectX、OpenGL及各種圖型函式庫 所有的時間均為 台灣時間 (GMT + 8 小時)
1頁(共1頁)

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


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