多重纹理就把多张贴图隔和在一起.比如下面示例中,一个表现砖墙的纹理,配合一个表现聚光灯效果的灰度图,就形成了砖墙被一个聚光灯照亮的效果,这便是所谓的光照贴图技术.

多重纹理只在OpenGL扩展库中才提供的.OpenGL和D3D比较起来,最大的一个优点是有扩展机制.

显卡硬件厂商开发出一项新功能,就可以针对新功能开发OpenGL扩展,软件开发人员通过这个扩展就可以使用新的硬件功能,而不用等新的OpenGL版来公布才能使用这个新功能.而D3D则必须等到新版本的DirectX发布后才能支持硬件的新功能.

下面的代码演示了如何使用扩展函数 GL_ARB_multitexture();

示例源代码:

 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SharpGL; namespace SharpGLWinformsApplication1
{
  //原创文章,出自"博客园, 猪悟能'S博客" : http://www.cnblogs.com/hackpig/
public partial class SharpGLForm : Form
{
static float wrap = ; // 用于雾的流动
SharpGL.SceneGraph.Assets.Texture[] textureAry = new SharpGL.SceneGraph.Assets.Texture[];
float[] fLightPosition = new float[] { 0.0f, 0.0f, 8.0f, 1.0f}; // 光源位置
float[] fLightAmbient = new float[] { 1f,1f, 1f, 1f }; // 环境光参数
float[] fLightDiffuse = new float[] { 1f,1f, 1f, 1f }; // 漫射光参数 bool multitexturing = true;
public SharpGLForm()
{
InitializeComponent();
} private void openGLControl_OpenGLDraw(object sender, PaintEventArgs e)
{
OpenGL gl = openGLControl.OpenGL;
gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
gl.LoadIdentity();
draw(gl);
} private void openGLControl_OpenGLInitialized(object sender, EventArgs e)
{
OpenGL gl = openGLControl.OpenGL;
String[] fileName = new String[] { "wall.bmp", "lightmap.bmp", "bitmap.bmp", "fog.bmp" };
for (int i = ; i < fileName.Length; i++)
{
textureAry[i] = new SharpGL.SceneGraph.Assets.Texture();
if (textureAry[i].Create(gl, fileName[i]))
{
textureAry[i].Id = i;
textureAry[i].Name = fileName[i]; }
} gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_AMBIENT, fLightAmbient);//环境光源
gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_DIFFUSE, fLightDiffuse);//漫射光源
gl.Light(OpenGL.GL_LIGHT0, OpenGL.GL_POSITION, fLightPosition);//光源位置
gl.Enable(OpenGL.GL_LIGHTING);//开启光照
gl.Enable(OpenGL.GL_LIGHT0); gl.ClearColor(0.0f, 0.0f, 0.0f, 0.5f);
gl.ClearDepth(1.0f);
gl.DepthFunc(OpenGL.GL_LEQUAL);
gl.Enable(OpenGL.GL_DEPTH_TEST);
gl.ShadeModel(OpenGL.GL_SMOOTH); gl.Hint(OpenGL.GL_PERSPECTIVE_CORRECTION_HINT, OpenGL.GL_NICEST);
gl.Enable(OpenGL.GL_NORMALIZE); if (!initMultiTexture(gl))
{
MessageBox.Show("您的硬件和驱动不支持多重纹理");
return;
}
} private void openGLControl_Resized(object sender, EventArgs e)
{
OpenGL gl = openGLControl.OpenGL;
gl.MatrixMode(OpenGL.GL_PROJECTION);
gl.LoadIdentity();
gl.Perspective(45f, (double)Width / (double)Height, , 100.0);
gl.MatrixMode(OpenGL.GL_MODELVIEW);
draw(gl);
} private void draw(OpenGL Gl)
{
Gl.LoadIdentity();
Gl.Translate(0.0f, 0.0f, -10.0f); //激活纹理0,并绑定纹理
Gl.ActiveTextureARB(OpenGL.GL_TEXTURE0_ARB);
Gl.Enable(OpenGL.GL_TEXTURE_2D);
textureAry[].Bind(Gl); Gl.ActiveTextureARB(OpenGL.GL_TEXTURE1_ARB);
//如果多重纹理启用,则启用该纹理
if (multitexturing)
Gl.Enable(OpenGL.GL_TEXTURE_2D);
else
Gl.Disable(OpenGL.GL_TEXTURE_2D);
textureAry[].Bind(Gl); // 绘制一个四方形墙面
Gl.PushMatrix();
{
Gl.Translate(-2.5f, 0f, 0f);
Gl.Scale(2.0f, 2.0f, 2.0f);
Gl.Begin(OpenGL.GL_QUADS);
{
//左上点 Gl.MultiTexCoord2ARB(OpenGL.GL_TEXTURE0_ARB, 0.0f, 1.0f);
Gl.MultiTexCoord2ARB(OpenGL.GL_TEXTURE1_ARB, 0.0f + wrap, 1.0f);
Gl.Vertex(-, , ); // 左下点
Gl.MultiTexCoord2ARB(OpenGL.GL_TEXTURE0_ARB, 0.0f, 0.0f);
Gl.MultiTexCoord2ARB(OpenGL.GL_TEXTURE1_ARB, 0.0f + wrap, 0.0f);
Gl.Vertex(-, -, ); // 右下点
Gl.MultiTexCoord2ARB(OpenGL.GL_TEXTURE0_ARB, 1.0f, 0.0f);
Gl.MultiTexCoord2ARB(OpenGL.GL_TEXTURE1_ARB, 1.0f + wrap, 0.0f);
Gl.Vertex(, -, ); // 右上点
Gl.MultiTexCoord2ARB(OpenGL.GL_TEXTURE0_ARB, 1.0f, 1.0f);
Gl.MultiTexCoord2ARB(OpenGL.GL_TEXTURE1_ARB, 1.0f + wrap, 1.0f);
Gl.Vertex(, , );
}
Gl.End();
}
Gl.PopMatrix(); Gl.ActiveTextureARB(OpenGL.GL_TEXTURE0_ARB);
Gl.Enable(OpenGL.GL_TEXTURE_2D);
textureAry[].Bind(Gl); Gl.ActiveTextureARB(OpenGL.GL_TEXTURE1_ARB);
if (multitexturing)
Gl.Enable(OpenGL.GL_TEXTURE_2D);
else
Gl.Disable(OpenGL.GL_TEXTURE_2D);
textureAry[].Bind(Gl); Gl.PushMatrix();
{
Gl.Translate(2.5f, , );
Gl.Scale(2.0f, 2.0f, 2.0f);
Gl.Begin(OpenGL.GL_QUADS);
{
// 左上点
Gl.MultiTexCoord2ARB(OpenGL.GL_TEXTURE0_ARB, 0.0f, 1.0f);
Gl.MultiTexCoord2ARB(OpenGL.GL_TEXTURE1_ARB, 0.0f - wrap, 1.0f);
Gl.Vertex(-, , ); // 左下点
Gl.MultiTexCoord2ARB(OpenGL.GL_TEXTURE0_ARB, 0.0f, 0.0f);
Gl.MultiTexCoord2ARB(OpenGL.GL_TEXTURE1_ARB, 0.0f - wrap, 0.0f);
Gl.Vertex(-, -, ); // 右下点
Gl.MultiTexCoord2ARB(OpenGL.GL_TEXTURE0_ARB, 1.0f, 0.0f);
Gl.MultiTexCoord2ARB(OpenGL.GL_TEXTURE1_ARB, 1.0f - wrap, 0.0f);
Gl.Vertex(, -, ); // 右上点
Gl.MultiTexCoord2ARB(OpenGL.GL_TEXTURE0_ARB, 1.0f, 1.0f);
Gl.MultiTexCoord2ARB(OpenGL.GL_TEXTURE1_ARB, 1.0f - wrap, 1.0f);
Gl.Vertex(, , );
}
Gl.End();
wrap += 0.01f;
}
Gl.PopMatrix(); Gl.Flush();
} /// <summary>
/// 检查多重纹理支持
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
bool isExtensionSupported(OpenGL gl, string input)
{
          //GetSting获取显卡所支持的全部扩展的信息
string extension = gl.GetString(OpenGL.GL_EXTENSIONS);
return extension.IndexOf(input) >= ;
} bool initMultiTexture(OpenGL gl)
{
//检查是否支持扩展
if (isExtensionSupported(gl,"GL_ARB_multitexture"))
{
return true;
}
else
return false;
} }
}

效果如下:

左边的四边形贴上了地砖和灯光效果的两张贴图.

右边的四边形贴上了风景和雾效果的两张贴图.

通过移动多重纹理X坐标实现了水平移动的效果.

代码基本和和普通的纹理映射没有非常大的区别,我没有什么好解析的.

本节源代码下载

原创文章,出自"博客园, 猪悟能'S博客" : http://www.cnblogs.com/hackpig/

SharpGL学习笔记(十六) 多重纹理映射的更多相关文章

  1. python3.4学习笔记(十六) windows下面安装easy_install和pip教程

    python3.4学习笔记(十六) windows下面安装easy_install和pip教程 easy_install和pip都是用来下载安装Python一个公共资源库PyPI的相关资源包的 首先安 ...

  2. (C/C++学习笔记) 十六. 预处理

    十六. 预处理 ● 关键字typeof 作用: 为一个已有的数据类型起一个或多个别名(alias), 从而增加了代码的可读性. typedef known_type_name new_type_nam ...

  3. SharpGL学习笔记(十五) 纹理映射

    纹理映射非常实用,在游戏场景中已经无所不在了. 一个较少的多边形构成的模形,配合好的纹理贴图进行映射,可以得到逼真的效果.游戏中的天空,地面,墙面,和植物都是纹理贴图进行映射的. 例如最终幻想8的男女 ...

  4. SharpGL学习笔记(十八) 解析3ds模型并显示

    笔者设想的3D仿真中的元件,是不可能都是“画”出来的.这样就玩复杂了,应该把任务分包出去,让善于制作模型的软件来制作三维模型,我们只需要解析并且显示它即可. 3dsmax制作三维模型的方便,快捷,专业 ...

  5. SharpGL学习笔记(十二) 光源例子:解决光源场景中的常见问题

    笔者学到光源这一节,遇到的问题就比较多了,收集了一些如下所述: (1) 导入的3ds模型,如果没有材质光照效果很奇怪.如下图 (2) 导入的3ds模型,有材质,灯光效果发暗,材质偏色,效果也很奇怪. ...

  6. SharpGL学习笔记(十九) 摄像机漫游

    所谓的摄像机漫游,就是可以在场景中来回走动. 现实中,我们通过眼睛观察东西,身体移动带动眼睛移动观察身边的事物,这也是在漫游. 在OpenGL中我们使用函数LookAt()来操作摄像机在三维场景中进行 ...

  7. SharpGL学习笔记(十四) 材质:十二个材质球

    材质颜色 OpenGL用材料对光的红.绿.蓝三原色的反射率来近似定义材料的颜色.象光源一样,材料颜色也分成环境.漫反射和镜面反射成分,它们决定了材料对环境光.漫反射光和镜面反射光的反射程度.在进行光照 ...

  8. JavaScript权威设计--CSS(简要学习笔记十六)

    1.Document的一些特殊属性 document.lastModified document.URL document.title document.referrer document.domai ...

  9. MySQL学习笔记十六:锁机制

    1.数据库锁就是为了保证数据库数据的一致性在一个共享资源被并发访问时使得数据访问顺序化的机制.MySQL数据库的锁机制比较独特,支持不同的存储引擎使用不同的锁机制. 2.MySQL使用了三种类型的锁机 ...

随机推荐

  1. vs2010 rdlc .net4.0 卸载 Appdomain 时出错。 (异常来自 HRESULT:0x80131015) 解决办法

    网上一看Appdomain出错,绝大部分都是说控件加载错误.经测试在.net 4.0环境下 rdlc报表很容易发生卸载 Appdomain 时出错. (异常来自 HRESULT:0x80131015) ...

  2. PowerShell 启动应用程序【转】

    当你在PowerShell中,启动带参数启动可执行应用程序时,可能会碰到参数解析的错误.最好的方式是使用命令 Start-Process,该命令有两个优点: 程序的路径和程序参数分开,可以使用-Fil ...

  3. java 动态创建数据库和动态连接数据库

    项目中有一个需求要动态创建数据库并且要动态连接数据库,本来以为还很难实现呢,在网上找了好久,都不是很理想,最后看到有人说创建数据库时,先连接到任意一个数据库,获得连接后用createStatement ...

  4. EF封装类,供参考!

    以下是我对EF DB FIRST 生成的ObjectContext类进行封装,代码如下,供参考学习: using System; using System.Collections.Generic; u ...

  5. Entity Framework优缺点及使用方法总结

    Entity Framework是M$提供的一个ORM框架,它旨在为小型应用程序中数据层的快速开发提供便利. nuget上185W多的下载量,说明.Net开发人员还是比较喜欢用EF的.但是EF在提供了 ...

  6. QCustomplot使用分享(一) 能做什么事

    一.QCustomPlot简介 之前在Qt之自绘制饼图这篇文章的说明中我简单的描述了下目前依赖于qt的第三方绘图库,此后我会针对自己使用QCustomPlot的情况做一总结,以方便大家参考 QCust ...

  7. Spring应用——事务管理

    事务基础:请参看:http://www.cnblogs.com/solverpeng/p/5720306.html 一.Spring 事务管理 1.前提:事务管理器 在使用 Spring 声明式事务管 ...

  8. Sql Server来龙去脉系列 必须知道的权限控制核心篇

    最近写了<Sql Server来龙去脉系列  必须知道的权限控制基础篇>,感觉反响比较大.这可能也说明了很多程序猿对数据库权限控制方面比较感兴趣,或者某些技术点了解的没有很透彻. 有些人看 ...

  9. MVC中在一个视图中,怎么加载另外一个视图?

    在RazorView.cshtml视图: <!--在视图中调用无返回值的方法,视图中调用无返回值的方法,要加上大括号--> <!--在一个视图中,直接加载另外一个视图--> @ ...

  10. 重构第21天 合并继承 (Collapse Hierarchy)

    理解:本文中的”合并继承”是指如果子类的属性和方法也适合于基类,那么就可以移除子类,从而减少依赖关系. 详解:上一篇我们讲到“提取子类”重构是指当基类中的一个责任不被所有的子类所需要时,将这些责任提取 ...