一、目的

掌握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[1];memset(TextureImage, 0, sizeof(void *) * 1);   // 将指针设为 NULL// 载入位图,检查有无错误,如果位图没找到则退出if (TextureImage[0] = 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, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);//图形绘制时所使用的滤波器参数glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // 线形滤波glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // 线形滤波
    }//释放图像的内存,因为已经生成纹理了,没用了if (TextureImage[0])        // 纹理是否存在
    {if (TextureImage[0]->data)      // 纹理图像是否存在
        {free(TextureImage[0]->data);    // 释放纹理图像占用的内存
        }free(TextureImage[0]);       // 释放图像结构
    }elseprintf("纹理不存在");return Status;          // 返回 Status
}

4,开始绘制

void DrawCube(void)         // 从这里开始进行所有的绘制
{glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕和深度缓存
glLoadIdentity();         // 重置当前的模型观察矩阵
glBindTexture(GL_TEXTURE_2D, texture[0]);      // 选择纹理
    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 = 0;   // X 旋转量
GLfloat  yrot = 0;   // Y 旋转量
GLfloat  zrot = 0;   // Z 旋转量
GLuint  texture[1];  // 存储一个纹理---数组//载入位图图象到内存——固定用法
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[1];memset(TextureImage, 0, sizeof(void *) * 1);   // 将指针设为 NULL// 载入位图,检查有无错误,如果位图没找到则退出if (TextureImage[0] = 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, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);//图形绘制时所使用的滤波器参数glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // 线形滤波glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // 线形滤波
    }//释放图像的内存,因为已经生成纹理了,没用了if (TextureImage[0])        // 纹理是否存在
    {if (TextureImage[0]->data)      // 纹理图像是否存在
        {free(TextureImage[0]->data);    // 释放纹理图像占用的内存
        }free(TextureImage[0]);       // 释放图像结构
    }elseprintf("纹理不存在");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[0]);      // 选择纹理
    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[0], "mf.bmp", 1);            //载入纹理贴图//LoadGLTextures(&texture[1], "mf1.bmp", 2);            //载入纹理贴图
}//当窗口大小改变时,会调用这个函数
void reshape(GLsizei w, GLsizei h)
{//这里小说明一下:矩阵模式是不同的,他们各自有一个矩阵。投影相关//只能用投影矩阵。(只是目前情况下哦,等我学多了可能就知道为什么了。)glViewport(0, 0, w, h);        //设置视口glMatrixMode(GL_PROJECTION);    //设置矩阵模式为投影变换矩阵,glLoadIdentity();                //变为单位矩阵gluPerspective(60, (GLfloat)w / h, 0, 1000);    //设置投影矩阵
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(600, 600);    //显示框的大小glutInitWindowPosition(100, 100); //确定显示框左上角的位置glutCreateWindow("OpenGL纹理贴图");init();  //初始化资源,这里一定要在创建窗口以后,不然会无效。LoadGLTextures(&texture[0], "mf.bmp", 1);glutDisplayFunc(display);glutReshapeFunc(reshape);                //绘制图形时的回调
    glutKeyboardFunc(keyboard);glutMainLoop();return 0;
}

四、注意

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

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

点开箭头所指的文件夹

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

五、总结

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

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

用OpenGL进行立方体表面纹理贴图相关推荐

  1. 现代opengl 设计入门,坐标系统和立方体的纹理贴图

    本文在 现代opengl 设计入门,纹理贴图 一文的基础上,引入opengl坐标系统,实现立方体的纹理贴图.介绍了opengl 的5个空间,3个变换矩阵.如果看这部分介绍比较繁琐,可以直接看看效果图, ...

  2. OpenGL基本概念入门——纹理贴图

    1. 创建纹理图像 OpenGL要求纹理的高度和宽度都必须是2的n次方大小,只有满足这个条件,这个纹理图片才是有效的.     一旦获取了像素值,我们就可以将这些数据传给OpenGL,让OpenGL生 ...

  3. OpenGL ES之十——纹理贴图(展示一张图片)

    概述 这是一个系列的Android平台下OpenGl ES介绍,从最基本的使用最终到VR图的展示的实现,属于基础篇.(后面针对VR视频会再有几篇文章,属于进阶篇) OpenGL ES之一--概念扫盲 ...

  4. OpenGL ES绘制3D纹理贴图

    最近看了<疯狂android讲义>的图形相关的内容,结合自己的理解,整理了一下. 下图是做出来的3D纹理贴图效果,手指在屏幕滑动时,图片可以随之转动. 要实现一个纹理贴图,很简单,大致需要 ...

  5. OpenGL总结6-圆柱纹理贴图

    圆柱纹理贴图我采用了OpenGL中的函数gluCylinder,这个函数会生成空心的圆柱,这个圆柱固定生成为底面位于xy面,z=0,顶面从z=0开始向z轴正方向,也就是说圆柱体是冲着我们生成的,如果想 ...

  6. 现代opengl 设计入门,纹理贴图

    上节 现代opengl 设计入门,着色器  介绍了着色器语言GLSL, 可以绘制多彩的三角形.这节介绍更高级的着色,纹理贴图. 先做纹理贴图的基本介绍,然后介绍其中几个重要设置:纹理环绕方式,纹理过滤 ...

  7. android 使用OPENGL ES实现三角形纹理贴图效果-纹理映射基础

    效果图:...... 编写Dad.java *在Dad构造器中创建和设置场景渲染器为主动渲染,并设置重写触屏时间回调方法以记录触控笔坐标,改变三角形坐标系的位置,使三角形能够在场景中转动 *为声明场景 ...

  8. 【OpenGL学习笔记④】——纹理贴图【SOIL2的配置 + 绘制木板 + 纹理环绕】

  9. OpenGL ES实现三棱锥纹理贴图

    这是老师布置的课后作业,闲来无事分享出来,也加深一遍自己的印象~ 自己定义一个MyRenderer.java类: package com.example.shiyan3_2;import androi ...

  10. Android Studio OpenGL ES绘制三棱锥/四面体的多纹理贴图 每个面使用一张图片渲染

    本文参考了王刚的<疯狂Android讲义(第3版)>P554-P559 要求:利用OpenGL ES绘制一个三棱锥,并对每个面进行纹理贴图,每个面使用不同的图片进行渲染. 环境:Andro ...

最新文章

  1. 不一样的命令行 – Windows PowerShell简介
  2. 什么是OKR?这就是OKR
  3. Python 实例方法、类方法、静态方法的区别与作用
  4. “相对论“ 2019-07-10
  5. AngularJS日期格式化
  6. A Scala Tutorial for Java programmers之(一)Scala入门:Scala例子,以及如何与Java交互
  7. 阿里分布式数据库服务实践
  8. Sql Server 2000 无法打开用户默认数据库。登录失败
  9. INFO: task java:27465 blocked for more than 120 seconds不一定是cache太大的问题
  10. centos最新版solr5.3.1安装和数据整理以及遇到的问题解答
  11. vba中find用法
  12. 用结构化思维策划一个会议
  13. vb调用python函数_vb.net / C# 调用 python
  14. struts2 拦截器
  15. Input鼠标键盘输入
  16. python求最小公倍数_Python 最小公倍数算法
  17. 建模是什么,建模定义,及学习方法
  18. 物理建模钢琴-Modartt Pianoteq Pro v6.7.0 WiN
  19. matlab图像处理二,图像缩放、旋转、修剪
  20. 【转载】租房被骗,选择忍让,成就黑中介的猖狂

热门文章

  1. MCU新趋势—Cortex M0/M3/M4 行业应用主题研讨会
  2. 职场谍战小说《监控》在广州日报连载
  3. 二十一天学通C语言:使用const声明指针变量
  4. 演说之禅:幻灯片的演说是多多益善吗?
  5. OLAP(On-line Analytical Processing,联机分析处理)
  6. PGM:贝叶斯网的参数估计
  7. android.mk ndk编译选项优化,Android NDK(ARM开发)使用NEON优化 - Fla
  8. 使用vue-print-nb插件页面空白以及打印没有样式问题
  9. php单例模式与工厂模式
  10. Xampp PHPStorm XDebug配置