发信人: yxy (田丝丝#冬眠的小肥鹰), 信区: GAME_Designer 
标  题: OPENGL(9) 
发信站: BBS 水木清华站 (Tue Jan 20 16:29:11 1998) 
 
OPENGL的位图和图象 
 
与一般的位图定义不同,OPENGL中的位图是指用每个象素只有一位信息; 
而图象一个象素可以包括多个信息(R、G、B、Alpha值)。 
另外位图可以用于掩码,遮掩别的图象,而图象的数据则简单的覆盖先前 
的存在的数据或者与之融合。 
 
(一)位图(BITMAP)和字符(FONT) 
常常用来对窗口相应区域屏蔽,比如当前颜色为红色,则在矩阵中元素值为 
1的地方用红色取代,0的地方保持不变。位图常用在字符显示。 
 
光栅位置: 
void glRasterPos{234}{sifd}[v](TYPE x,TYPE y,TYPE z,TYPE w); 
设置当前所画位图或图象的原点。一般颜色的设置应该放在glRasterPos*() 
的前面,则紧跟其后的位图都继承当前设置的这种颜色。 
 
位图显示: 
void glBitmap(GLsizei width,GLsizei height,GLfloat xbo,GLflaot ybo, 
              GLfloat xbi,GLfloat ybi,const GLubyte *bitmap); 
xbo,ybo定义位图的原点,详细可参见例子: 
////////////////////////////////////////////////////////////////// 
//sample.cpp 
#include "glos.h" 
#include <GL/gl.h> 
#include <GL/glaux.h> 
#include "windows.h" 
void myinit(void); 
void CALLBACK  display(void); 
void CALLBACK  reshape(GLsizei w,GLsizei h); 
//定义字符位图,从下到上(即第一个数据是字模的最下一行,依次类推): 
//       11111111 
//       11111111 
//       11000011 
//       11000011 
//       11000011 
//       11111111 
//       11111111 
//       11000011 
//       11000011 
//       11000011 
//       11111111 
//       11111111 
//组成一个 8 字  
GLubyte rasters[12]={0xff,0xff,0xc3,0xc3,0xc3,0xff,0xff, 
0xc3,0xc3,0xc3,0xff,0xff}; 
 
void myinit(void) 

    auxInitDisplayMode(AUX_SINGLE|AUX_RGBA); 
        auxInitPosition(0,0,500,500); 
        auxInitWindow("sample1"); 
        glClearColor(0.0,0.0,0.0,0.0); 
        glClear(GL_COLOR_BUFFER_BIT); 
 
//描述位图数据在计算机内存中的存储方式,不必深究 
    glPixelStorei(GL_UNPACK_ALIGNMENT,1); 
 

 
void CALLBACK reshape(GLsizei w,GLsizei h) 

 
glViewport(0,0,w,h); 
glMatrixMode(GL_PROJECTION); 
glLoadIdentity(); 
glOrtho(0,w,0,h,-1.0,1.0); 
glMatrixMode(GL_MODELVIEW); 
glLoadIdentity(); 

 
void CALLBACK display(void) 

    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 
 
//先定义红色填充: 
    glColor3f(1.0,0.0,1.0); 
        glRasterPos2i(100,200); 
//在2个不同位置绘制 8 (紫色) 
        glBitmap(8,12,0.0,0.0,20.0,20.0,rasters); 
        glBitmap(8,12,0.0,0.0,20.0,20.0,rasters); 
 
//绘制另一个 8 (黄色) 
        glColor3f(1.0,1.0,0.0); 
        glRasterPos2i(150,200); 
    glBitmap(8,12,0.0,0.0,0.0,0.0,rasters); 
 
    glFlush(); 

void main(void) 

    myinit(); 
     
    auxReshapeFunc(reshape); 
    auxMainLoop(display); 

//end of sample 
/////////////////////////////////////////////////////// 
 
(二)图象 
 
字符显示只是个小内容,我想大家也许会更关心图象的显示 
1.象素读写 
OPENGL提供基本象素读写函数: 
void glReadPixels( GLint x, GLint y, GLsizei width, GLsizei height,  
                   GLenum format, GLenum type, GLvoid *pixels );  
函数参数(x,y)定义图象区域左下角坐标,width height描述图象宽高。 
pixel是指针,指向图象数据数组。format指出数据元素格式(索引或 
R、G、B、A值): 
 
format:                   说明: 
GL_INDEX                  单个颜色索引 
GL_RGB                    依次 红、绿、蓝分量 
GL_RED                    单个红色分量 
GL_GREEN                  单个绿色分量 
GL_BLUE                   单个蓝色分量 
GL_ALPHA                  单个Alpha值 
GL_LUMINANCE_ALPHA         
GL_STENCIL_INDEX          单个模板索引 
GL_DEPTH_COMPONENT        单个深度分量 
 
而type指出元素数据类型: 
type: 
GL_UNSIGNED_BYTE          无符号8位整数 
GL_BYTE                   8位整数 
GL_BITMAP                 无符号8位整数数组中单个数位 
GL_UNSIGNED_SHORT         无符号16位整数 
GL_SHORT                  16位整数 
GL_UNSIGNED_INT           无符号32位整数 
GL_INT                    32位整数 
GL_FLOAT                  单精度浮点数 
 
类似的写象素函数: 
void glDrawPixels( GLsizei width, GLsizei height, GLenum format,  
                   GLenum type, const GLvoid *pixels );  
 
2.象素拷贝 
void glCopyPixels( GLint x, GLint y, GLsizei width,  
                   GLsizei height, GLenum type );  
这个函数很类似先用glReadPixels()然后调用glDrawPixels(),但是它不消耗 
系统内存,只是拷贝, 
type可以是:GL_COLOR GL_STENCIL GL_DEPTH 
在拷贝前,type要按如下方式转换成format: 
1)type为GL_DEPTH GL_STENCIL 那么format 对应应该是GL_DEPTH_COMPONENT 
或GL_STENCIL_INDEX 
2)type为GL_COLOR 那么format 应该是GL_RGB或GL_COLOR_INDEX。 
 
3.图象缩放 
void glPixelZoom(GLfloat zoomx,GLfloat zoomy); 
zoomx zoomy是X Y方向的缩放因子。缺省是1.0。 
#include "glos.h" 
#include <GL/gl.h> 
#include <GL/glaux.h> 
#include "windows.h" 
void myinit(void); 
void CALLBACK  display(void); 
void CALLBACK  reshape(GLsizei w,GLsizei h); 
 
void myinit(void) 

    auxInitDisplayMode(AUX_SINGLE|AUX_RGBA); 
        auxInitPosition(0,0,500,500); 
        auxInitWindow("sample1"); 
        glClearColor(0.0,0.0,0.0,0.0); 
        glClear(GL_COLOR_BUFFER_BIT); 
 
//      glPixelStorei(GL_UNPACK_ALIGNMENT,1); 
 

 
void CALLBACK reshape(GLsizei w,GLsizei h) 

 
glViewport(0,0,w,h); 
glMatrixMode(GL_PROJECTION); 
glLoadIdentity(); 
 
if(w<=h) 
 gluOrtho2D(0.0,15.0,0.0,15.0*(GLfloat)h/(GLfloat)w); 
else 
 gluOrtho2D(0.0,15.0*(GLfloat)w/(GLfloat)h,0.0,15.0); 
 
glMatrixMode(GL_MODELVIEW); 
glLoadIdentity(); 

 
void draw() 

//绘制一个彩色三角形(2D) 
glBegin(GL_TRIANGLES); 
  glColor3f(1.0,0.0,0.0); 
  glVertex2f(2.0,3.0); 
  glColor3f(0.0,1.0,0.0); 
  glVertex2f(12.0,3.0); 
  glColor3f(0.0,0.0,1.0); 
  glVertex2f(7.0,12.0); 
glEnd(); 

 
void CALLBACK display(void) 

  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 
 
//在屏幕上方绘制原始图象 
    glPushMatrix(); 
        glLoadIdentity(); 
        glTranslatef(4.0,8.0,0.0); 
        glScalef(0.5,0.5,0.5); 
        draw(); 
        glPopMatrix(); 
 
        int i; 
        for(i=0;i<5;i++) 
        { 
//循环5次画出5个拷贝 
//先定义显示缩放因子(递增) 
          glPixelZoom(1.0+0.1*i,1.0+0.1*i); 
//再定义拷贝原点(越来越向右上) 
          glRasterPos2i(1+i*2,i); 
//图象拷贝 
          glCopyPixels(160,310,180,160,GL_COLOR); 
        } 
 
  glFlush(); 

void main(void) 

    myinit(); 
     
    auxReshapeFunc(reshape); 
    auxMainLoop(display); 

//end of sample 
//////////////////////////////////////////////////////////// 
 
这个例子在屏幕上方中央绘制一个彩色三角 
然后在下面从左到右,依次绘制它的拷贝,拷贝位置不断向右上方向 
而且(通过增加缩放因子)新的拷贝变的越来越大。 
当然后绘制的拷贝会遮盖前面的图形。 
 
-- 
※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 166.111.74.90]