第29课:Blitter函数 (参照NeHe)
这次教程中,我们将介绍类似于DirectDraw的blit(其实blit函数在许多绘图库都有),我们将用代码自己来实现它。它的作用非常简单,就是把一块纹理的贴到另一块纹理上。想想,有了这个函数,我们就可以自由拼接纹理了,是不是很棒?
这一课中,我们不但会实现blit函数,我们还将讲解如何来加载特定的*.raw图片。raw格式的图片,可以理解为CMOS或者CCD图像感应器将捕捉到的光源信号转化为数字信号的原始数据。可悲的是,Qt并没有提供加载raw图片的方法,所以我们只能自己写了(这是处理图像的一课,与OpenGL关系不大)!
程序运行时效果如下:
下面进入教程:
我们这次将在第06课的基础上修改代码,我们只讲解新的内容,旧的内容到这里大家应该掌握得很好了才对。首先打开myglwidget.h文件,将类声明修改如下:
#ifndef MYGLWIDGET_H
#define MYGLWIDGET_H
#include <QWidget>
#include <QGLWidget>
typedef struct Texture_Image //图像结构体
{
int width;
int height;
int format; //格式(图像每一像素内存)
unsigned char *data; //储存图像数据
}* P_TEXTURE_IMAGE;
class MyGLWidget : public QGLWidget
{
Q_OBJECT
public:
explicit MyGLWidget(QWidget *parent = 0);
~MyGLWidget();
protected:
//对3个纯虚函数的重定义
void initializeGL();
void resizeGL(int w, int h);
void paintGL();
void keyPressEvent(QKeyEvent *event); //处理键盘按下事件
private:
//为图像结构体分配内存
P_TEXTURE_IMAGE allocateTextureBuffer(GLuint w, GLuint h, GLuint f);
void deallocateTexture(P_TEXTURE_IMAGE t); //释放图像结构体内存
//读取图像结构体数据
void loadRAWData(const char *filename, P_TEXTURE_IMAGE buffer);
GLuint buildTexture(P_TEXTURE_IMAGE tex); //建立纹理
//将一个纹理贴到另一个纹理上
void blit(P_TEXTURE_IMAGE src, P_TEXTURE_IMAGE dst, int src_xstart,
int src_ystart, int src_width, int src_height,
int dst_xstart, int dst_ystart, bool blend, int alpha);
private:
bool fullscreen; //是否全屏显示
GLfloat m_xRot; //绕x轴旋转的角度
GLfloat m_