本文由lanbinfeng原创,转载请注明出处https://blog.csdn.net/lanbinfeng/article/details/82814952
魔兽世界作为MMO游戏的标杆,它的渲染效果也是一直让人叹为观止的。学习它的渲染细节,尝试它的渲染方式,大概是那些要成为渲染工程师、技术美术的一条捷径吧。魔兽世界的地图是由地形、水体、建筑物、摆设物品、天空、灯光、粒子动画和模型动画组成的。本系列的文章将用C#和OpenGL去解析和渲染魔兽世界的地图。至于为什么舍近求远使用C#而非C++,大概是为了方便将其改成Unity3D导入插件吧。
OpenGL是一组渲染接口。它只提供了在一个表面上渲染需要的相关的接口,至于怎么把表面嵌入窗口、怎么管理键鼠的输入、怎么解析和组织要渲染的资源这些它都不包含。windows只包含了OpenGL 1.0的模拟驱动,高版本的驱动则是包含在显卡驱动包里的。如果在调用OpenGL api时遇到各种异常访问,那大概就是因为你的OpenGL版本太低的缘故,我们使用的是1.4版本。
GLU则是另一个非常流行的OpenGL的辅助库,它实现了一组实用的窗口管理、键盘鼠标输入输出、一组非常实用的功能函数。使用它能大大简化我们在周边支撑环境的开发。
Windows中OpenGL是一组标准的WIndows API ,需要从opengl32.dll导入。VC++里有可以直接使用的头文件和LIB库,在C#中则要自己导入或者使用开源库了。我们使用的是CSGL这个库,下载地址https://excellmedia.dl.sourceforge.net/project/csgl/CsGL/1.4.1/csgl.1.4.1.dll.zip
下载了这个库,直接在工程中引用。然后创建一个类继承自CsGL.OpenGL.OpenGLControl。再把这个组件放到Form上就可以了。代码如下:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.Controls.Add(_glView);
_glView.Dock = DockStyle.Fill;
GL.glMatrixMode(GL.GL_PROJECTION);
GL.glLoadIdentity();
GL.gluPerspective(45.0f, (double)_glView.Size.Width / (double)_glView.Size.Height, 1.0f, 1024.0f);
GL.glMatrixMode(GL.GL_MODELVIEW);
GL.glLoadIdentity();
GLU.gluLookAt(5, 5, 5, 0, 0, 0, 0, 1, 0);
GL.glEnable(GL.GL_DEPTH_TEST);
Timer timer = new Timer();
timer.Interval = 10;
timer.Tick += delegate{
_glView.glDraw();
};
timer.Start();
}
private GlView _glView = new GlView();
}
struct Vector3
{
public Vector3(float x, float y, float z)
{
_x = x;
_y = y;
_z = z;
}
public float _x, _y, _z;
};
class GlView : OpenGLControl
{
public override void glDraw()
{
GL.glClearColor(0.1f, 0.1f, 0.2f, 1.0f);
GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
// 立方体的8个顶点坐标
Vector3[] vertex_list = {
new Vector3( -0.5f, -0.5f, -0.5f ),
new Vector3( 0.5f, -0.5f, -0.5f ),
new Vector3( -0.5f, 0.5f, -0.5f ),
new Vector3( 0.5f, 0.5f, -0.5f ),
new Vector3( -0.5f, -0.5f, 0.5f ),
new Vector3( 0.5f, -0.5f, 0.5f ),
new Vector3( -0.5f, 0.5f, 0.5f ),
new Vector3( 0.5f, 0.5f, 0.5f )
};
int[] index_list = {
0, 2, 3, 1,
0, 4, 6, 2,
0, 1, 5, 4,
4, 5, 7, 6,
1, 3, 7, 5,
2, 6, 7, 3,
};
GL.glDisable(GL.GL_CULL_FACE);
GL.glBegin(GL.GL_QUADS);
GL.glColor3f(0.5f, 0.5f, 0.5f);
for (int i = 0; i < 6; ++i)
{
for (int j = 0; j < 4; ++j)
{
Vector3 pos = vertex_list[index_list[i * 4 + j]];
GL.glColor3f(0.1f * i, 0.1f * i, 0.1f * i);
GL.glVertex3f(pos._x, pos._y, pos._z);
}
}
GL.glEnd();
this.SwapBuffer();
}
}
运行效果:
本文由lanbinfeng原创,转载请注明出处https://blog.csdn.net/lanbinfeng/article/details/8281495