本文继续介绍多重纹理使用。
多重纹理使用和单纹理差不多,不过要注意的是多重纹理不是标准OpenGL 1.1中的函数,需要先测试系统显卡驱动是否支持。
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Windows.Forms;
using Tao.Glfw;
using Tao.OpenGl;
namespace OpenGL
{
/// <summary>
/// 第四章 OpenGl 多重纹理 C# by 大师♂罗莊
/// </summary>
class OpenGLMultiTexture : Examplefirst
{
TextureLoad[] m_texture = new TextureLoad[4];
bool multitexturing=false;
/** 检查是否支持扩展 */
public OpenGLMultiTexture()
: base()
{
for (int i = 0; i < 4; i++)
{
m_texture[i] = new TextureLoad();//对象数组必须初始化
}
LoadTexture();
base.title = "第四章 OpenGl 多重纹理";
}
/// <summary>
/// 检查多重纹理支持
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
bool isExtensionSupported(string input)
{
string extension = Gl.glGetString(Gl.GL_EXTENSIONS);
return extension.IndexOf(input)>=0;
}
bool initMultiTexture()
{
/** 检查是否支持扩展 */
if (isExtensionSupported("GL_ARB_multitexture"))
{
return true;
}
else
return false;
}
/** 载入纹理数据 */
bool LoadTexture()
{
/// 文件名
String[] fileName = new String[4] { "wall.bmp", "lightmap.bmp", "bitmap.bmp", "fog.bmp" };
/// 载入四幅位图
for (int i = 0; i < 4; i++)
{
if (m_texture[i].Load(Path.Combine(Application.StartupPath, @"Image\" + fileName[i]).ToString()) == false) /**< 载入位图文件 */
{
MessageBox.Show("无法载入" + fileName[i]);
return false;
}
}
return true;
}
/// <summary>
/// 初始化视口投影,恢复原书的视口
/// </summary>
public override void iniView(int windowWidth, int windowHeight)
{
Glu.gluPerspective(45.0f, windowWidth / windowHeight, 1.0f, 100.0f);
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();
Gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
Gl.glClearDepth(1.0f);
Gl.glDepthFunc(Gl.GL_LEQUAL);
Gl.glEnable(Gl.GL_DEPTH_TEST);
Gl.glShadeModel(Gl.GL_SMOOTH);
Gl.glHint(Gl.GL_PERSPECTIVE_CORRECTION_HINT, Gl.GL_NICEST);
/** 初始化 */
if (!initMultiTexture())
{
MessageBox.Show("您的硬件和驱动不支持多重纹理");
return;
}
/** 载入纹理 */
///这里可以测试我们的材质类有没有造成内存泄漏问题。
if (!LoadTexture())
{
MessageBox.Show("无法载入纹理");
return;
}
}
/** 用户自定义的卸载函数 */
public new void Dispose()
{
base.Dispose();
for (int i = 0; i < 4; i++)
{
m_texture[i].FreeImage();
Gl.glDeleteTextures(1, m_texture[i].ID);
}
}
float wrap = 0; /**< 用于雾的流动 */
/// <summary>
/// 重载
/// </summary>
/// <param name="mouseX"></param>
/// <param name="currentTime"></param>
public override void Update(float milliseconds)
{
//按下ESC结束
isRunning = ((Glfw.glfwGetKey(Glfw.GLFW_KEY_ESC) == Glfw.GLFW_RELEASE) &&
Glfw.glfwGetWindowParam(Glfw.GLFW_OPENED) == Gl.GL_TRUE);
///** 当按下空格时,开启或关闭多重纹理 */
if (Glfw.glfwGetKey(Glfw.GLFW_KEY_SPACE ) == Glfw.GLFW_RELEASE)
{
multitexturing = false;
}
else
{
multitexturing = true;//开启
}
wrap += milliseconds/10; //动画
}
/// <summary>
/// 重载,使用Draw方法绘图
/// </summary>
/// <param name="mouseX"></param>
/// <param name="currentTime"></param>
public override void DrawGLScene(int mouseX, double currentTime)
{
Draw();
}
/** 绘制函数 */
void Draw()
{
/** 用户自定义的绘制过程 */
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
Gl.glLoadIdentity();
Gl.glTranslatef(0.0f, 0.0f, -10.0f);
/** 激活纹理0,并绑定纹理 */
Gl.glActiveTextureARB(Gl.GL_TEXTURE0_ARB);
Gl.glEnable(Gl.GL_TEXTURE_2D);
Gl.glBindTexture(Gl.GL_TEXTURE_2D, m_texture[0].ID[0]);
/** 激活纹理1,并绑定纹理 */
Gl.glActiveTextureARB(Gl.GL_TEXTURE1_ARB);
/** 如果多重纹理启用,则启用该纹理 */
if (multitexturing)
Gl.glEnable(Gl.GL_TEXTURE_2D);
else
Gl.glDisable(Gl.GL_TEXTURE_2D);
Gl.glBindTexture(Gl.GL_TEXTURE_2D, m_texture[1].ID[0]);
/** 绘制一个四方形墙面 */
Gl.glPushMatrix();
Gl.glTranslatef(-2.5f, 0f, 0f);
Gl.glScalef(2.0f, 2.0f, 2.0f);
Gl.glBegin(Gl.GL_QUADS);
/** 左上点 */
Gl.glMultiTexCoord2fARB(Gl.GL_TEXTURE0_ARB, 0.0f, 1.0f);
Gl.glMultiTexCoord2fARB(Gl.GL_TEXTURE1_ARB, 0.0f, 1.0f);
Gl.glVertex3f(-1, 1, 0);
/** 左下点 */
Gl.glMultiTexCoord2fARB(Gl.GL_TEXTURE0_ARB, 0.0f, 0.0f);
Gl.glMultiTexCoord2fARB(Gl.GL_TEXTURE1_ARB, 0.0f, 0.0f);
Gl.glVertex3f(-1, -1, 0);
/** 右下点 */
Gl.glMultiTexCoord2fARB(Gl.GL_TEXTURE0_ARB, 1.0f, 0.0f);
Gl.glMultiTexCoord2fARB(Gl.GL_TEXTURE1_ARB, 1.0f, 0.0f);
Gl.glVertex3f(1, -1, 0);
/** 右上点 */
Gl.glMultiTexCoord2fARB(Gl.GL_TEXTURE0_ARB, 1.0f, 1.0f);
Gl.glMultiTexCoord2fARB(Gl.GL_TEXTURE1_ARB, 1.0f, 1.0f);
Gl.glVertex3f(1, 1, 0);
Gl.glEnd(); /**< 绘制结束 */
Gl.glPopMatrix();
/** 激活纹理0,并绑定纹理 */
Gl.glActiveTextureARB(Gl.GL_TEXTURE0_ARB);
Gl.glEnable(Gl.GL_TEXTURE_2D);
Gl.glBindTexture(Gl.GL_TEXTURE_2D, m_texture[2].ID[0]);
/** 激活纹理1,并绑定纹理 */
Gl.glActiveTextureARB(Gl.GL_TEXTURE1_ARB);
/** 如果多重纹理启用,则启用该纹理 */
if (multitexturing)
Gl.glEnable(Gl.GL_TEXTURE_2D);
else
Gl.glDisable(Gl.GL_TEXTURE_2D);
Gl.glBindTexture(Gl.GL_TEXTURE_2D, m_texture[3].ID[0]);
Gl.glTranslatef(2.5f, 0, 0);
Gl.glScalef(2.0f, 2.0f, 2.0f);
Gl.glBegin(Gl.GL_QUADS);
/** 左上点 */
Gl.glMultiTexCoord2fARB(Gl.GL_TEXTURE0_ARB, 0.0f, 1.0f);
Gl.glMultiTexCoord2fARB(Gl.GL_TEXTURE1_ARB, 0.0f - wrap, 1.0f);
Gl.glVertex3f(-1, 1, 0);
/** 左下点 */
Gl.glMultiTexCoord2fARB(Gl.GL_TEXTURE0_ARB, 0.0f, 0.0f);
Gl.glMultiTexCoord2fARB(Gl.GL_TEXTURE1_ARB, 0.0f - wrap, 0.0f);
Gl.glVertex3f(-1, -1, 0);
/** 右下点 */
Gl.glMultiTexCoord2fARB(Gl.GL_TEXTURE0_ARB, 1.0f, 0.0f);
Gl.glMultiTexCoord2fARB(Gl.GL_TEXTURE1_ARB, 1.0f - wrap, 0.0f);
Gl.glVertex3f(1, -1, 0);
/** 右上点 */
Gl.glMultiTexCoord2fARB(Gl.GL_TEXTURE0_ARB, 1.0f, 1.0f);
Gl.glMultiTexCoord2fARB(Gl.GL_TEXTURE1_ARB, 1.0f - wrap, 1.0f);
Gl.glVertex3f(1, 1, 0);
Gl.glEnd();
Gl.glFlush();
}
}
}