OpenGL---在平面上贴纹理

21 篇文章 1 订阅
12 篇文章 0 订阅

bmp.h


class BMP
{
private:
    unsigned char * pBitmapData;          //纹理对象

public:
    int nRows, nCols;                     //bmp图像的尺寸
    unsigned int    texture_id;           //纹理ID

    BMP(){};
    ~BMP();
    bool readBMPFile(char *fileName);     //读取bmp图像
    void setTexture();                    //设置纹理
};

//析构,释放内存
BMP::~BMP()
{
    delete []pBitmapData;
    nRows = nCols = 0;
}

//读取位图
//由4部分组成:位图文件头、位图信息头、彩色表、图像数据阵列字节
bool BMP::readBMPFile(char *fileName)
{
    FILE                * fp;
    BITMAPFILEHEADER    bmpFH;
    BITMAPINFOHEADER    bmpIH;
    unsigned char       temp;

    // 读取二进制文件
    fp = fopen( fileName, "rb" ); 

    if( fp == NULL )
        return( false );

    // 位图文件头
    fread( ( void * )&bmpFH, sizeof( BITMAPFILEHEADER ), 1, fp );

    //文件的类型
    if( bmpFH.bfType != 0x4D42 ) 
    {
        fclose( fp );
        return( false );
    }

    // 位图信息头
    fread( ( void * )&bmpIH, sizeof( BITMAPINFOHEADER ), 1, fp );

    // 移动到图像开始的位置
    fseek( fp, bmpFH.bfOffBits, SEEK_SET );

    // 位图字节数量
    bmpIH.biSizeImage = bmpIH.biHeight * bmpIH.biWidth * ( bmpIH.biBitCount / 8 );

    // 分配内存
    pBitmapData = new unsigned char[ bmpIH.biSizeImage ];
    if( pBitmapData == NULL )
    {
        fclose( fp );
        return( false );
    }

    // 读取图像数据,每次1字节,共biSizeImage次
    fread( ( void * )pBitmapData, 1, bmpIH.biSizeImage, fp );
    if( pBitmapData == NULL ) 
    {
        fclose( fp );
        return( false );
    }

    for( int c = 0; c < bmpIH.biSizeImage; c += 3 ) 
    {
        // 交换红、蓝字节
        temp                    = pBitmapData[ c ];
        pBitmapData[ c ]        = pBitmapData[ c + 2 ];
        pBitmapData[ c + 2 ]    = temp;
    }

    fclose( fp );

    nCols   = bmpIH.biWidth;
    nRows   = bmpIH.biHeight;

    return( true );
}

//设置纹理
void BMP::setTexture()
{
    glGenTextures( 1, &texture_id ); 

    //绑定纹理对象
    glBindTexture( GL_TEXTURE_2D, texture_id );  

    //设置缩小放大的纹理过滤器

    //进行纹理放大过滤
    //GL_LINEAR:使用距离当前渲染像素中心最近的4个纹素的加权平均值
    //GL_NEAREST:使用距离当前渲染像素中心最近的纹素
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

    //进行纹理缩小过滤
    //使用双线性过滤对最接近当前多边形解析度的两个层级贴图层进行采样,
    //然后用这两个值进行线性插值,又叫做三线性过滤---必须显卡支持才会显示出纹理
    //glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );

    //为纹理对象指定纹理
    glTexImage2D( GL_TEXTURE_2D,  //二维纹理
                  0,              //贴图纹理的精细度等级
                  GL_RGB,         //纹理是以怎样的基本内部格式储存到显示卡内存中
                  nRows,          //纹理贴图的宽,2的幂
                  nCols,          //纹理贴图的高
                  0,              //当前纹理无边缘
                  GL_RGB,         //pBitmapData数组中的图像数据的格式
                  GL_UNSIGNED_BYTE, //纹理图像数据类型
                  pBitmapData );  //指针,指向直接生成或从现有文件中读取的图像
}

main.cpp

#include <windows.h> 
#include <gl/Gl.h>
#include <gl/Glu.h>
#include <gl/glut.h>
#include "stdio.h"
#include "stdlib.h"
#include "bmp.h"

#pragma comment(lib, "glut.lib")

const int windowWidth = 800;
const int windowHeight = 600;

BMP bmp;

void render()
{
    //清除屏幕和深度缓存
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    //再次绑定纹理对象
    glBindTexture( GL_TEXTURE_2D, bmp.texture_id );

    glBegin( GL_QUADS );

        //指定纹理坐标
        glTexCoord2f( 0.0, 0.0 );   glVertex3f( -4, -4, 0 );  //左下
        glTexCoord2f( 0.0, 1.0 );   glVertex3f( -4,  4, 0 );  //右下
        glTexCoord2f( 1.0, 1.0 );   glVertex3f(  4,  4, 0 );  //右上
        glTexCoord2f( 1.0, 0.0 );   glVertex3f(  4, -4, 0 );  //左上

    /*第2种
        glTexCoord2f( 0.0, 0.0 );   glVertex2f( 300, 400 );  //左下
        glTexCoord2f( 1.0, 0.0 );   glVertex2f( 500, 400 );  //右下
        glTexCoord2f( 1.0, 1.0 );   glVertex2f( 500, 200 );  //右上
        glTexCoord2f( 0.0, 1.0 );   glVertex2f( 300, 200 );  //左上
    */

    glEnd();

    glutSwapBuffers();
    glutPostRedisplay();
}

bool myInit()
{
    //指定颜色和纹理坐标的差值质量,选择最高质量选项
    glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );

    //指定反走样点的采样质量,如果应用较大的滤波函数
    //GL_NICEST在光栅化期间可以生成更多的像素段。
    glHint( GL_POLYGON_SMOOTH_HINT, GL_NICEST );

    //开启深度测试
    glEnable( GL_DEPTH_TEST );

    //开启二维纹理
    glEnable( GL_TEXTURE_2D );

    //读取纹理
    bmp.readBMPFile("b2.bmp");

    //设置纹理
    bmp.setTexture();

    //设置视角
    glMatrixMode( GL_PROJECTION ); 
    glLoadIdentity();
    gluPerspective(75, windowWidth/windowHeight, 1, 21);
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
    gluLookAt(1, 5, 5, 0, 0, 0, 0, 0, 1);

    /*第2种
    glMatrixMode( GL_PROJECTION ); 
    glLoadIdentity();
    gluOrtho2D( 0, windowWidth, 0, windowHeight );
    */ 

    return true;
}

int main()
{
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); 
    glutInitWindowPosition(50, 50); 
    glutInitWindowSize(windowWidth, windowHeight);
    glutCreateWindow("DEMO"); 

    myInit();
    glutDisplayFunc(render); 

    glutMainLoop(); 

    return 0;
}

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值