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

多重纹理只在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. 允许CEF跨域访问iframe

    默认情况下,如果嵌入本地Web页面,并在页面内部使用iframe来显示一个在线页面,加载的过程中会触发一个未捕获异常,虚函数CefV8ContextHandler::OnUncaughtExcepti ...

  2. DS1337 时钟芯片在 C8051F 上的实现

    一.DS1337介绍 DS1337串行实时时钟芯片是一种低功耗.全部采用BCD码的时钟日历芯片,它带有两个可编程的定时闹钟和一个可编程的方波输出.其地址和数据可通过I2C总线串行传输,能提供秒.分.时 ...

  3. Unity3d导出Android的apk文件时相关问题的解决办法

    今天上午着手将一个unity3d开发的小游戏build到android手机上运行,结果遇到了不少问题. 首先遇到的第一个问题是在build到一半的时候,弹出如下报错: Error building P ...

  4. 【Android】Activity生命周期(亲测)

    测试手机:Nexus 5   系统:4.4 一.测试 测试代码: package com.example.androidalarm; import android.app.Activity; impo ...

  5. SNF开发平台WinForm之三-开发-单表选择控件创建-SNF快速开发平台3.3-Spring.Net.Framework

    3.1运行效果: 3.2开发实现: 3.2.1 这个开发与第一个开发操作步骤是一致的,不同之处就是在生成完代码之后,留下如下圈红程序,其它删除. 第一个开发地址:开发-单表表格编辑管理页面 http: ...

  6. Gamma Gamma~!!!

    左图是没有进行gamma矫正的,右图是进行了gamma矫正的.以前一直以为是Tone Map的公式计算有问题,后来看PBR的paper时候,终于明白了gamma的重要性,一改,果然发现颜色不想以前那么 ...

  7. codeforces MUH and Cube Walls

    题意:给定两个序列a ,b, 如果在a中存在一段连续的序列使得 a[i]-b[0]==k, a[i+1]-b[1]==k.... a[i+n-1]-b[n-1]==k 就说b串在a串中出现过!最后输出 ...

  8. Mina、Netty、Twisted一起学(一):实现简单的TCP服务器

    MINA.Netty.Twisted为什么放在一起学习?首先,不妨先分别看一下它们官方网站对其的介绍: MINA: Apache MINA is a network application frame ...

  9. Hya.io – 基于 Web 的数字音频工作站

    Hya.io 是基于 Web 的音频应用程序,通过 Web MIDI ,音频合成器,音序以及大量的插件来支持硬件 MIDI .您可以添加插件到工作区,将其连接到路由音频,进行播放和实验. HYA 支持 ...

  10. IOS中对象的归档

    ios提供了两个类 NSKeyedArichiver NSKeyedUnarchiver对自定义对象进行归档 和解档操作 归档常见方法 - (void)encodeObject:(id)objv fo ...