OpenGL 超级宝典笔记 —— 位图

编程入门 行业动态 更新时间:2024-10-27 20:31:16

OpenGL 超级宝典笔记 —— <a href=https://www.elefans.com/category/jswz/34/1763618.html style=位图"/>

OpenGL 超级宝典笔记 —— 位图

位图

最初的电子计算机,只能显示单色(绿色或琥珀色)图形,每一个像素只有两种状态打开和关闭。在计算器图形学前期,图像数据是用位图来表示的,位图就是一系列的 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 超级宝典笔记 —— 位图

本文发布于:2024-02-25 07:36:53,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1698248.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:位图   宝典   笔记   OpenGL

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!