歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> OpenGL超級寶典學習筆記——位圖

OpenGL超級寶典學習筆記——位圖

日期:2017/3/1 9:32:22   编辑:Linux編程

位圖

最初的電子計算機,只能顯示單色(綠色或琥珀色)圖形,每一個像素只有兩種狀態打開和關閉。在計算器圖形學前期,圖像數據是用位圖來表示的,位圖就是一系列的0和1,表示打開或關閉的像素值。下圖就是用位圖表示的一匹馬:

下圖是同一匹馬的灰度圖,在這個像素圖中有256種不同強度的灰度級。

位圖這個術語也常應用於包含灰度級和全彩色的圖像數據,特別是在Windows平台上有相應的位圖格式.BMP文件。嚴格地講,這是對位圖這個術語的誤用。在此處(正確地說),位圖是只有打開和關閉這兩種值的二進制圖。我們用像素圖來表示那些包含全彩色和強度值的圖像數據。

位圖數據

位圖是從底往上構建的,也就是說位圖的第一行數據代表著位圖圖像的最底部的一行。下面是一個例子,創建一個512X512的窗口,在窗口中填充16行、16列篝火圖像的位圖:

#include "gltools.h"
//篝火位圖
GLubyte fire[128] = { 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xc0,
0x00, 0x00, 0x01, 0xf0,
0x00, 0x00, 0x07, 0xf0,
0x0f, 0x00, 0x1f, 0xe0,
0x1f, 0x80, 0x1f, 0xc0,
0x0f, 0xc0, 0x3f, 0x80,
0x07, 0xe0, 0x7e, 0x00,
0x03, 0xf0, 0xff, 0x80,
0x03, 0xf5, 0xff, 0xe0,
0x07, 0xfd, 0xff, 0xf8,
0x1f, 0xfc, 0xff, 0xe8,
0xff, 0xe3, 0xbf, 0x70,
0xde, 0x80, 0xb7, 0x00,
0x71, 0x10, 0x4a, 0x80,
0x03, 0x10, 0x4e, 0x40,
0x02, 0x88, 0x8c, 0x20,
0x05, 0x05, 0x04, 0x40,
0x02, 0x82, 0x14, 0x40,
0x02, 0x40, 0x10, 0x80,
0x02, 0x64, 0x1a, 0x80,
0x00, 0x92, 0x29, 0x00,
0x00, 0xb0, 0x48, 0x00,
0x00, 0xc8, 0x90, 0x00,
0x00, 0x85, 0x10, 0x00,
0x00, 0x03, 0x00, 0x00,
0x00, 0x00, 0x10, 0x00 };

void RenderScene()
{

glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0f, 0.0f, 0.0f);

for (int y = 0; y < 16; ++y)
{
//設置光柵的位置
glRasterPos2i(0, 32 * y);

for (int x = 0; x < 16; ++x)
{
//繪制位圖,繪制完成後,在x軸上移動32個像素
glBitmap(32, 32, 0.0f, 0.0f, 32.0f, 0.0f, fire);
}
}

glutSwapBuffers();
}

void ChangeSize(int w, int h)
{
if (h == 0)
h = 1;

glViewport(0, 0, (GLsizei)w, (GLsizei)h);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//設置投影的大小與屏幕的寬高對應
gluOrtho2D(0.0, (GLdouble)w, 0.0, (GLdouble)h);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

void SetupRC()
{
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
}

int main(int args, char *argv[])
{
glutInit(&args, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
//創建512X512的窗口
glutInitWindowSize(512, 512);

glutCreateWindow("BITMPAS");
glutDisplayFunc(RenderScene);
glutReshapeFunc(ChangeSize);
SetupRC();
glutMainLoop();

return 0;
}

效果:

光柵位置

for (int y = 0; y < 16; ++y)
{
//設置光柵化的位置
glRasterPos2i(0, 32 * y);
for (int x = 0; x < 16; ++x)
{
//繪制位圖,繪制完成後,在x軸上移動32個像素
glBitmap(32, 32, 0.0f, 0.0f, 32.0f, 0.0f, fire);
}
}

glRasterPos2i(0, y*32); glRasterPos與glVertex一樣有兩個參數,三個參數和不同類型的版本。 設置光柵的位置(位圖的左下角的位置)。所有的光柵化操作會從當前的光柵位置開始繪制位圖。如果當前的光柵位置超出了窗口,將是非法的,任何需要光柵位置的OpenGL操作都將失敗。

在這個例子中,我們故意設置OpenGL的投影與窗口的大小匹配,這樣我們就相當於用窗口的坐標來指定位圖的位置。然而這樣的方式有時不太方便,所以OpenGL提供了另外一個可選的函數,允許你設置光柵的位置為窗口的坐標,從而忽略變換矩陣和投影對坐標的影響。

void glWindowPos2i(GLint x, GLint y);

設置光柵位置時需要注意的一個地方,在glRasterPos或者glWindowPos調用之前設置的顏色將被當做位圖的顏色。在glRasterPos和glWindowPos之後調用glColor不會影響位圖的顏色。

繪制位圖

最終我們調用繪制位圖的命令,把位圖繪制到顏色緩沖區。

glBitmap(32, 32, 0.0, 0.0, 32.0, 0.0, fire);

glBitmap函數把圖像數據拷貝到顏色緩沖區的當前的光柵位置,並且可以進行可選的移動光柵位置的操作。

void glBitmap(GLsize width, GLsize height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, GLubyte *bitmap);

頭兩個參數指定為位圖的寬和高,xorig和yorig指定位圖數據的原點。xmove和ymove指定在渲染完位圖之後,光柵位置往x軸和y軸移動多少個像素。bitmap是一個指向位圖數據的指針。PS:當一幅位圖被繪制時,圖像中只有位模式為1的片段才會在顏色緩沖區中被創建,為0則不會影響當前的顏色緩沖區。

OpenGL超級寶典 第4版 中文版PDF+英文版+源代碼 見 http://www.linuxidc.com/Linux/2013-10/91413.htm

OpenGL編程指南(原書第7版)中文掃描版PDF 下載 http://www.linuxidc.com/Linux/2012-08/67925.htm

OpenGL 渲染篇 http://www.linuxidc.com/Linux/2011-10/45756.htm

Ubuntu 13.04 安裝 OpenGL http://www.linuxidc.com/Linux/2013-05/84815.htm

OpenGL三維球體數據生成與繪制【附源碼】 http://www.linuxidc.com/Linux/2013-04/83235.htm

Ubuntu下OpenGL編程基礎解析 http://www.linuxidc.com/Linux/2013-03/81675.htm

如何在Ubuntu使用eclipse for c++配置OpenGL http://www.linuxidc.com/Linux/2012-11/74191.htm

更多《OpenGL超級寶典學習筆記》相關知識 見 http://www.linuxidc.com/search.aspx?where=nkey&keyword=34581

Copyright © Linux教程網 All Rights Reserved