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使用了三种类型的锁机 ...
随机推荐
- saiku 展示优化第二步(要诀和技巧)
经历了上几篇博客的分享,可以无密码登录 : http://www.cnblogs.com/liqiu/p/5246015.html 随着使用的深入,公司需要将现有的报表平台与saiku整合,其中最便捷 ...
- c++ 访问者模式(visitor pattern)
概述: 我们去银行柜台办业务,一般情况下会开几个个人业务柜台的,你去其中任何一个柜台办理都是可以的.我们的访问者模式可以很好付诸在这个场景中:对于银行柜 台来说,他们是不用变化的,就是说今天和明天提供 ...
- 3-5年的PHPer常见的面试题
看到有很多,的总结一下,比较适合有一定经验的PHPer 1.平时喜欢哪些php书籍及博客?CSDN.虎嗅.猎云 2.js闭包是什么? 3.for与foreach哪个更快? 4.php鸟哥是谁?能不能讲 ...
- Java知多少(105)套接字(Socket)
网络应用模式主要有: 主机/终端模式:集中计算,集中管理: 客户机/服务器(Client/Server,简称C/S)模式:分布计算,分布管理: 浏览器/服务器模式:利用Internet跨平台. www ...
- C#调用Java类
C#调用Java类 (2011-01-07 14:02:05) 转载▼ 分类: Java学习 1. 在Eclipse中新建名称为hello的java project,此工程仅包含一个文件hell ...
- 实战:ASP.NET MVC中把Views下面的视图放到Views文件夹外
园子里写的文章的都是把控制器从传统的项目中的Controllers拿出来单独放,但很少几乎没有把视图从Views拿出去这样的文章,今天来写一个. 其实很简单!一步步解决问题就行了,下面记录如下,供需要 ...
- ruby -- 进阶学习(六) devise修改邮件发送者邮箱
在config/environment.rb/development.rb或者config/environment/production.rb中, 简单示范例子: Text03::Applicatio ...
- sqlserver -- 学习笔记(七)获取同组数据的前两条记录
不啰嗦,直接上图,大概实现效果如下: 有上面这样一份数据,将他们按照userAccount和submitTime进行分组,然后提前每组数据的前两条记录 提取后数据如下: 实现的SQL如下: selec ...
- Web程序员开发App系列 - 调试Android和IOS手机代码(补图)
Web程序员开发App系列 Web程序员开发App系列 - 认识HBuilder Web程序员开发App系列 - 申请苹果开发者账号 Web程序员开发App系列 - 调试Android和iOS手机代码 ...
- CentOS 7.2 MySQL 5.7 主从配置
MySQL的安装:CentOS 7.2 yum方式安装MySQL 5.7 两台服务器分别如下: Master:192.168.1.100 Slave:192.168.1.101 Master配置: 编 ...