SharpGL学习笔记(十六) 多重纹理映射
多重纹理就把多张贴图隔和在一起.比如下面示例中,一个表现砖墙的纹理,配合一个表现聚光灯效果的灰度图,就形成了砖墙被一个聚光灯照亮的效果,这便是所谓的光照贴图技术.
多重纹理只在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学习笔记(十六) 多重纹理映射的更多相关文章
- python3.4学习笔记(十六) windows下面安装easy_install和pip教程
python3.4学习笔记(十六) windows下面安装easy_install和pip教程 easy_install和pip都是用来下载安装Python一个公共资源库PyPI的相关资源包的 首先安 ...
- (C/C++学习笔记) 十六. 预处理
十六. 预处理 ● 关键字typeof 作用: 为一个已有的数据类型起一个或多个别名(alias), 从而增加了代码的可读性. typedef known_type_name new_type_nam ...
- SharpGL学习笔记(十五) 纹理映射
纹理映射非常实用,在游戏场景中已经无所不在了. 一个较少的多边形构成的模形,配合好的纹理贴图进行映射,可以得到逼真的效果.游戏中的天空,地面,墙面,和植物都是纹理贴图进行映射的. 例如最终幻想8的男女 ...
- SharpGL学习笔记(十八) 解析3ds模型并显示
笔者设想的3D仿真中的元件,是不可能都是“画”出来的.这样就玩复杂了,应该把任务分包出去,让善于制作模型的软件来制作三维模型,我们只需要解析并且显示它即可. 3dsmax制作三维模型的方便,快捷,专业 ...
- SharpGL学习笔记(十二) 光源例子:解决光源场景中的常见问题
笔者学到光源这一节,遇到的问题就比较多了,收集了一些如下所述: (1) 导入的3ds模型,如果没有材质光照效果很奇怪.如下图 (2) 导入的3ds模型,有材质,灯光效果发暗,材质偏色,效果也很奇怪. ...
- SharpGL学习笔记(十九) 摄像机漫游
所谓的摄像机漫游,就是可以在场景中来回走动. 现实中,我们通过眼睛观察东西,身体移动带动眼睛移动观察身边的事物,这也是在漫游. 在OpenGL中我们使用函数LookAt()来操作摄像机在三维场景中进行 ...
- SharpGL学习笔记(十四) 材质:十二个材质球
材质颜色 OpenGL用材料对光的红.绿.蓝三原色的反射率来近似定义材料的颜色.象光源一样,材料颜色也分成环境.漫反射和镜面反射成分,它们决定了材料对环境光.漫反射光和镜面反射光的反射程度.在进行光照 ...
- JavaScript权威设计--CSS(简要学习笔记十六)
1.Document的一些特殊属性 document.lastModified document.URL document.title document.referrer document.domai ...
- MySQL学习笔记十六:锁机制
1.数据库锁就是为了保证数据库数据的一致性在一个共享资源被并发访问时使得数据访问顺序化的机制.MySQL数据库的锁机制比较独特,支持不同的存储引擎使用不同的锁机制. 2.MySQL使用了三种类型的锁机 ...
随机推荐
- Scala spark mongodb
最好的参考是Mongo官网的地址 https://docs.mongodb.com/spark-connector/getting-started/ 需要截图所示的包 代码地址 https://git ...
- 如何使用新浪微博账户进行应用登录验证(基于Windows Azure Mobile Service 集成登录验证)
使用三方账号登录应用应该对大家来说已经不是什么新鲜事儿了,但是今天为什么还要在这里跟大家聊这个话题呢,原因很简单 Windows Azure Mobiles Service Authenticatio ...
- ZooKeeper与Curator注册和监控
Curator提供了对zookeeper客户端的封装,并监控连接状态和会话session,特别是会话session过期后,curator能够重新连接zookeeper,并且创建一个新的session. ...
- 安装cvxpy遇到的问题与解决方案(ubuntu14.10,python 2.7.8)
应该说,cvxpy的安装说明是很棒的,一步一步非常清楚,www.cvxpy.org/en/latest/install/index.html 可是,我照着做完之后,还是不能import cvxpy,不 ...
- mark:如何使用FileZilla连接虚拟机上的Fedora
1. 下载FileZilla 2. 在虚拟机上安装SSH,http://linuxconfig.org/how-to-install-start-and-connect-to-ssh-server-o ...
- Java知多少(111)数据库之修改记录
修改数据表记录也有3种方案. 一.使用Statement对象 实现修改数据表记录的SQL语句的语法是: update表名 set 字段名1 = 字段值1,字段名2 = 字段值2,……where特 ...
- Intel HAXM安装错误处理:(TV-x) is not turned on
Android x86模拟器Intel Atom x86 System Image时提示Intel execute disable bit(xd) is not turned on 运行Elicpse ...
- 将XmlDocument转换成XDocument
XmlDocument xml=new XmlDocument(); xml.LoadXml(strXmlText); XmlReader xr=new XmlNodeReader(xml); XDo ...
- 简单的session共享的封装
目的 session存储在缓存服务器上(各种缓存服务器上均可,本文以memcached为例),但对开发者来说,他不用关注,只需要调用request.getSession()方法即可获取到session ...
- SQL SERVER 分布式事务(DTC)
BEGIN DISTRIBUTED TRANSACTION指定一个由 Microsoft 分布式事务处理协调器 (MS DTC) 管理的 Transact-SQL 分布式事务的起始. 语法BEGIN ...