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

多重纹理只在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. JS - IE or not:判断是否为IE浏览器方法

    问题:使用JS判断是否为IE浏览器 方法: 1.IE='\v'=='v'  (失败!) if('\v'=='v') // true only in IE 2.IE=(!+"\v1" ...

  2. jar包制作

    1,利用jdk自带的工具制作 1) 首先要确保所有的java文件都被编译成了.class文件,可以用javac批量编译多个文件 javac c:\java\src\wz\learning\*.java ...

  3. 发布FTP服务,防火墙配置

    最近需要在Web服务器上发布一下FTP,不想安装Server-U之类的,就用IIS的了,安装好后,发现外网无法连接.经过测试,发现是防火墙的问题. 查找了下关于FTP的资料,ftp server支持两 ...

  4. Android之layout_alignBottom失效问题

    外面是一层RelativeLayout,前面的text和后面按钮都是设置centerParent_vertical,第二个hello是需要与第一个底部对齐,虽然设置alginBottom指向第一个he ...

  5. LevelDB(v1.3) 源码阅读之 Slice

    LevelDB(v1.3) 源码阅读系列使用 LevelDB v1.3 版本的代码,可以通过如下方式下载并切换到 v1.3 版本的代码: $ git clone https://github.com/ ...

  6. 使用UIKit制作卡牌游戏(二)ios游戏篇

    转自朋友Tommy 的翻译,自己只翻译了第三篇教程. 译者: Tommy | 原文作者: Matthijs Hollemans写于2012/07/06 原文地址: http://www.raywend ...

  7. 关于app.config不能即时保存读取的解决方案

    public void saveValue(string Name, string Value) { ConfigurationManager.AppSettings.Set(Name, Value) ...

  8. 学习Sass之安装Sass(一)

    为什么使用Sass 作为前端(html.javascript.css)的三大马车之一的css,一直以静态语言存在,HTML5火遍大江南北了.javascript由于NODE.JS而成为目前前后端统一开 ...

  9. [转载]QString 乱谈(3)-Qt5与中文

    原文地址http://blog.csdn.net/dbzhang800/article/details/7542672?reload 两个月前,简单写过QTextCodec中的setCodecForT ...

  10. CenOS6.3 ssh 公钥认证报错:Permission denied (publickey,gssapi-keyex,gssapi-with-mic)

    转载自 http://laowafang.blog.51cto.com/251518/1364298 1.说明: ssh无密码用户远程登录,一直以来使用是debian操作系统,对用户目录权限要求没有关 ...