一、目的

掌握OpenGL中纹理对象的创建、绑定与使用方法。

二、简单介绍

1,连接静态库

#pragma comment(lib, "glut32.lib")
#pragma comment(lib, "glaux.lib")

2,载入位图图像到内存(这是固定用法)

AUX_RGBImageRec *LoadBMP(CHAR *Filename)
{
FILE *File = NULL; // 文件句柄
if (!Filename) // 确保文件名已提供
{
return NULL; // 如果没提供,返回 NULL
}
File = fopen(Filename, "r"); // 尝试打开文件
if (File) // 判断文件存在与否
{
fclose(File); // 关闭句柄
return auxDIBImageLoadA(Filename); // 载入位图并返回指针
}
return NULL; // 如果载入失败,返回 NULL
}

3,载入位图并转换成纹理(固定用法)

int LoadGLTextures(GLuint *texture, char *bmp_file_name, int texture_id)
{
int Status = FALSE; // 状态指示器
// 创建纹理的存储空间
AUX_RGBImageRec *TextureImage[];
memset(TextureImage, , sizeof(void *) * ); // 将指针设为 NULL
// 载入位图,检查有无错误,如果位图没找到则退出
if (TextureImage[] = LoadBMP(bmp_file_name))
{
Status = TRUE; // 将 Status 设为 TRUE
//生成(generate)纹理
glGenTextures(texture_id, texture); //&texture[0]);
//绑定2D纹理对象
glBindTexture(GL_TEXTURE_2D, *texture); //texture[0]);
//关联图像数据与纹理对象
glTexImage2D(GL_TEXTURE_2D, , , TextureImage[]->sizeX, TextureImage[]->sizeY, , GL_RGB, GL_UNSIGNED_BYTE, TextureImage[]->data);
//图形绘制时所使用的滤波器参数
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // 线形滤波
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // 线形滤波
} //释放图像的内存,因为已经生成纹理了,没用了
if (TextureImage[]) // 纹理是否存在
{
if (TextureImage[]->data) // 纹理图像是否存在
{
free(TextureImage[]->data); // 释放纹理图像占用的内存
}
free(TextureImage[]); // 释放图像结构
}
else
printf("纹理不存在");
return Status; // 返回 Status
}

4,开始绘制

void DrawCube(void)         // 从这里开始进行所有的绘制
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕和深度缓存 glLoadIdentity(); // 重置当前的模型观察矩阵 glBindTexture(GL_TEXTURE_2D, texture[]); // 选择纹理
glBegin(GL_QUADS);
// 前面
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // 纹理和四边形的左下
glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f, -1.0f, 1.0f); // 纹理和四边形的右下
glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, 1.0f, 1.0f); // 纹理和四边形的右上
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // 纹理和四边形的左上
// 后面
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // 纹理和四边形的右下
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // 纹理和四边形的右上
glTexCoord2f(0.0f, 1.0f); glVertex3f(1.0f, 1.0f, -1.0f); // 纹理和四边形的左上
glTexCoord2f(0.0f, 0.0f); glVertex3f(1.0f, -1.0f, -1.0f); // 纹理和四边形的左下 glFlush(); //glutSwapBuffers();
}

根据坐标关系,依次类推出顶面、底面、左面、右面的绘制方式。

三、示例代码

Github地址

#include "stdafx.h"
#include <GL/glut.h> //引用相关包
#include <windows.h>
#include <GL/glaux.h>
#include <stdio.h>
#include <stdlib.h> //注意下面的编译指令——告诉编译器要连接的静态库
#pragma comment(lib, "glut32.lib")
#pragma comment(lib, "glaux.lib") GLfloat xrot = ; // X 旋转量
GLfloat yrot = ; // Y 旋转量
GLfloat zrot = ; // Z 旋转量
GLuint texture[]; // 存储一个纹理---数组 //载入位图图象到内存——固定用法
AUX_RGBImageRec *LoadBMP(CHAR *Filename)
{
FILE *File = NULL; // 文件句柄
if (!Filename) // 确保文件名已提供
{
return NULL; // 如果没提供,返回 NULL
}
File = fopen(Filename, "r"); // 尝试打开文件
if (File) // 判断文件存在与否
{
fclose(File); // 关闭句柄
return auxDIBImageLoadA(Filename); // 载入位图并返回指针
}
return NULL; // 如果载入失败,返回 NULL
} //载入位图(调用上面的代码)并转换成纹理——固定用法
//参数:纹理指针、bmp文件名、用户指定的纹理编号
int LoadGLTextures(GLuint *texture, char *bmp_file_name, int texture_id)
{
int Status = FALSE; // 状态指示器
// 创建纹理的存储空间
AUX_RGBImageRec *TextureImage[];
memset(TextureImage, , sizeof(void *) * ); // 将指针设为 NULL
// 载入位图,检查有无错误,如果位图没找到则退出
if (TextureImage[] = LoadBMP(bmp_file_name))
{
Status = TRUE; // 将 Status 设为 TRUE
//生成(generate)纹理
glGenTextures(texture_id, texture); //&texture[0]);
//绑定2D纹理对象
glBindTexture(GL_TEXTURE_2D, *texture); //texture[0]);
//关联图像数据与纹理对象
glTexImage2D(GL_TEXTURE_2D, , , TextureImage[]->sizeX, TextureImage[]->sizeY, , GL_RGB, GL_UNSIGNED_BYTE, TextureImage[]->data);
//图形绘制时所使用的滤波器参数
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // 线形滤波
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // 线形滤波
} //释放图像的内存,因为已经生成纹理了,没用了
if (TextureImage[]) // 纹理是否存在
{
if (TextureImage[]->data) // 纹理图像是否存在
{
free(TextureImage[]->data); // 释放纹理图像占用的内存
}
free(TextureImage[]); // 释放图像结构
}
else
printf("纹理不存在");
return Status; // 返回 Status
} void DrawCube(void) // 从这里开始进行所有的绘制
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕和深度缓存 glLoadIdentity(); // 重置当前的模型观察矩阵 glTranslatef(0.0f, 0.0f, -5.0f); // 移入屏幕 5 个单位
glRotatef(xrot, 1.0f, 0.0f, 0.0f); // 绕X轴旋转
glRotatef(yrot, 0.0f, 1.0f, 0.0f); // 绕Y轴旋转
glRotatef(zrot, 0.0f, 0.0f, 1.0f); // 绕Z轴旋转 glBindTexture(GL_TEXTURE_2D, texture[]); // 选择纹理
glBegin(GL_QUADS);
// 前面
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // 纹理和四边形的左下
glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f, -1.0f, 1.0f); // 纹理和四边形的右下
glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, 1.0f, 1.0f); // 纹理和四边形的右上
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // 纹理和四边形的左上
// 后面
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // 纹理和四边形的右下
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // 纹理和四边形的右上
glTexCoord2f(0.0f, 1.0f); glVertex3f(1.0f, 1.0f, -1.0f); // 纹理和四边形的左上
glTexCoord2f(0.0f, 0.0f); glVertex3f(1.0f, -1.0f, -1.0f); // 纹理和四边形的左下
// 顶面
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // 纹理和四边形的左上
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // 纹理和四边形的左下
glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f, 1.0f, 1.0f); // 纹理和四边形的右下
glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, 1.0f, -1.0f); // 纹理和四边形的右上
// 底面
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // 纹理和四边形的右上
glTexCoord2f(0.0f, 1.0f); glVertex3f(1.0f, -1.0f, -1.0f); // 纹理和四边形的左上
glTexCoord2f(0.0f, 0.0f); glVertex3f(1.0f, -1.0f, 1.0f); // 纹理和四边形的左下
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // 纹理和四边形的右下
// 右面
glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f, -1.0f, -1.0f); // 纹理和四边形的右下
glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, 1.0f, -1.0f); // 纹理和四边形的右上
glTexCoord2f(0.0f, 1.0f); glVertex3f(1.0f, 1.0f, 1.0f); // 纹理和四边形的左上
glTexCoord2f(0.0f, 0.0f); glVertex3f(1.0f, -1.0f, 1.0f); // 纹理和四边形的左下
// 左面
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // 纹理和四边形的左下
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // 纹理和四边形的右下
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // 纹理和四边形的右上
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // 纹理和四边形的左上
glEnd(); glFlush(); //glutSwapBuffers(); xrot += 0.3f; // X 轴旋转
yrot += 0.2f; // Y 轴旋转
zrot += 0.4f; // Z 轴旋转
} void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清楚颜色数据和深度数据(清屏)
glLoadIdentity(); // 重置视图
glTranslatef(0.0f, 0.0f, -5.0f);
DrawCube();
glutSwapBuffers(); //交换缓冲区。显示图形
} //初始化
void init(void)
{
glClearColor(1.0, 1.0, 1.0, 0.0); //清理颜色,为黑色,(也可认为是背景颜色)
glCullFace(GL_BACK); //背面裁剪(背面不可见)
glEnable(GL_CULL_FACE); //启用裁剪
glEnable(GL_TEXTURE_2D);
LoadGLTextures(&texture[], "mf.bmp", ); //载入纹理贴图
//LoadGLTextures(&texture[1], "mf1.bmp", 2); //载入纹理贴图
} //当窗口大小改变时,会调用这个函数
void reshape(GLsizei w, GLsizei h)
{
//这里小说明一下:矩阵模式是不同的,他们各自有一个矩阵。投影相关
//只能用投影矩阵。(只是目前情况下哦,等我学多了可能就知道为什么了。)
glViewport(, , w, h); //设置视口
glMatrixMode(GL_PROJECTION); //设置矩阵模式为投影变换矩阵,
glLoadIdentity(); //变为单位矩阵
gluPerspective(, (GLfloat)w / h, , ); //设置投影矩阵 glMatrixMode(GL_MODELVIEW); //设置矩阵模式为视图矩阵(模型)
glLoadIdentity(); //变为单位矩阵
} //键盘输入事件函数
void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 'x': //当按下键盘上d时,以沿X轴旋转为主
xrot += 1.0f; //设置旋转增量
glutPostRedisplay(); //重绘函数
break;
case 'y':
yrot += 1.0f;
glutPostRedisplay();
break;
case 'z':
zrot += 1.0f;
glutPostRedisplay();
break;
default:
break;
}
} int main(int argc, char *argv[])
{
glutInit(&argc, argv); //固定格式
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE); //注意这里
glutInitWindowSize(, ); //显示框的大小
glutInitWindowPosition(, ); //确定显示框左上角的位置
glutCreateWindow("OpenGL纹理贴图");
init(); //初始化资源,这里一定要在创建窗口以后,不然会无效。
LoadGLTextures(&texture[], "mf.bmp", );
glutDisplayFunc(display);
glutReshapeFunc(reshape); //绘制图形时的回调
glutKeyboardFunc(keyboard);
glutMainLoop();
return ;
}

四、注意

1.贴图文件大小必须为:宽、高都必须为2的整数次幂,格式必须为BMP。

2.贴图需要放在相应文件夹下,在编译器中直接运行此程序可能会看不到贴图效果。

点开箭头所指的文件夹

放置需要贴纹理的位图文件

五、总结

这是我在学校做的图形学纹理贴图实验,放暑假了一直忙着准备考研,今天突然想起应该把以前做的实验整理一下,于是找到了这个实验。

纹理贴图是一个很有趣的实验,它就像一层嫁衣,为你所创建的目标对象披上一件外衣,让别人看着赏心悦目,当然我目前所学的只是对规则物体进行纹理贴图,以后还会遇到不规则的物体等。

用OpenGL进行立方体表面纹理贴图的更多相关文章

  1. IOS 中openGL使用教程3(openGL ES 入门篇 | 纹理贴图(texture)使用)

    在这篇文章中,我们将学习如何在openGL中使用纹理贴图. penGL中纹理可以分为1D,2D和3D纹理,我们在绑定纹理对象的时候需要指定纹理的种类.由于本文将以一张图片为例,因此我们为我们的纹理对象 ...

  2. OpenGL 纹理贴图

    前一节实例代码中有个贴图操作. 今天就简单说明一下纹理贴图... 为了使用纹理贴图.我们首先需要启用纹理贴图功能. 我们可以在Renderer实现的onSurfaceCreated中定义启用: // ...

  3. 基于Cocos2d-x学习OpenGL ES 2.0系列——纹理贴图(6)

    在上一篇文章中,我们介绍了如何绘制一个立方体,里面涉及的知识点有VBO(Vertex Buffer Object).IBO(Index Buffer Object)和MVP(Modile-View-P ...

  4. (转载)Cocos2dx-OpenGL ES2.0教程:纹理贴图(6)

    在上一篇文章中,我们介绍了如何绘制一个立方体,里面涉及的知识点有VBO(Vertex Buffer Object).IBO(Index Buffer Object)和MVP(Modile-View-P ...

  5. [图形学] Chp18 OpenGL表面纹理函数

    以2D表面为例展示纹理贴图,用opengl设置一个2D纹理,颜色存储在32*32*3的数组中,对应的纹理坐标为0<=s, t<=1.0. 画出几个正方形表面,分别以GL_CLAMP(纹理坐 ...

  6. Android OpenGL ES 开发(九): OpenGL ES 纹理贴图

    一.概念 一般说来,纹理是表示物体表面的一幅或几幅二维图形,也称纹理贴图(texture).当把纹理按照特定的方式映射到物体表面上的时候,能使物体看上去更加真实.当前流行的图形系统中,纹理绘制已经成为 ...

  7. 从零开始的openGL——四、纹理贴图与n次B样条曲线

    前言 在上篇文章中,介绍了如何加载绘制模型以及鼠标交互的实现,并且遗留了个问题,就是没有模型表面没有纹理,看起来很丑.这篇文章将介绍如何贴纹理,以及曲线的绘制. 纹理贴图 纹理加载 既然是贴图,那首先 ...

  8. (转)使用OpenGL显示图像(七)Android OpenGLES2.0——纹理贴图之显示图片

    转:http://blog.csdn.net/junzia/article/details/52842816 前面几篇博客,我们将了Android中利用OpenGL ES 2.0绘制各种形体,并在上一 ...

  9. android ndk调用OpenGL 实现纹理贴图Texture

    android ndk调用OpenGL 实现纹理贴图Texture 时间 2014-06-25 05:24:39  CSDN博客 原文  http://blog.csdn.net/chrisfxs/a ...

随机推荐

  1. hdu 1217 Arbitrage (最小生成树)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1217 /************************************************* ...

  2. psycopg事务

    1.事务的特性 原子性,要么完成,要么都不完成 2.psycopg的事务特点 在psycopg中,事务是由connection处理的,当第一次一个命令发送给数据库时(开启数据库操作游标), 一个事务就 ...

  3. raise EnvironmentError("%s not found" % (mysql_config.path,)) EnvironmentError: mysql_config not found 解决办法

    报错信息如下: Downloading https://pypi.tuna.tsinghua.edu.cn/packages/a5/e9/51b544da85a36a68debe7a7091f068d ...

  4. 【ARM】2410裸机系列-流水灯

    开发环境   1.硬件平台:FS2410(s3c2410) 2.主机:Ubuntu 12.04 LTS LED原理图 LED的GPIO的配置 配置GPFCON寄存器,设置GPF4-7为输出 配置GPF ...

  5. webpack的css处理

    webpack打包处理css的时候需要两个loader: style-loader 和css-loader 安装: npm install style-loader css-loader --save ...

  6. WebService中方法的重载

    阅读目录 一:WebService中的方法是否允许重载? 二:为什么WebService中不支持方法的重载? 三:如何解决WebService中方法的重载? 一:WebService中的方法是否允许重 ...

  7. HTML <meta> 标签 和 http-equiv

    前言 经常在写HTML,但是对于meta 的设置却一直疏于关注. <meta> 是什么 <meta> 是一个HTML的标签(辅助性标签). 它的位置位于文档的头部  <h ...

  8. [转载]生活在 Emacs 中

    Brian Bilbrey2002 年 8 月 20 日发布 教程简介 本教程讲什么? Emacs 是一个流行的无模式文本编辑器,有许多强大的功能.本教程将教您使用 Emacs 的基础知识.为了让您很 ...

  9. IBM ILOG JViews Charts 产品及功能介绍

    摘抄连接:http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1004_lidb_ilogjchart/ IBM I ...

  10. thinkphp继承高级model后的乐观锁运用(测试中)

    <?php class IndexAction extends Action { private $d_user; private $user; private $arr; public fun ...