本文基础:C#+OpenGL编程之环境搭建
原书用了12个样本球显示各种材质效果,原书的auxSolidSphere这个函数,C# 没有封装,我就把例程修改为12个正方形。
using System; using System.Collections.Generic; using System.Text; using Tao.OpenGl; using Tao.Glfw; namespace OpenGL { /// <summary> /// 第四章 OpenGl 材质 C# by 大师♂罗莊 /// </summary> class Material : Examplefirst { public Material() : base() { base.title = "第四章 OpenGl 材质"; } /// <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.GL_LIGHT0 float[] ambient = new float[] { 0.0f, 0.0f, 0.0f, 1.0f }; /**< 环境光 */ float[] diffuse = new float[] { 1.0f, 1.0f, 1.0f, 1.0f }; /**< 漫射光 */ float[] specular = new float[] { 1.0f, 1.0f, 1.0f, 1.0f };/**< 镜面光 */ float[] position = new float[] { 0.0f, 3.0f, 2.0f, 0.0f };/**< 光源位置 */ ///设置光源属性 Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_AMBIENT, ambient); Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_DIFFUSE, diffuse); Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_POSITION, position); ///初始化 Gl.glClearColor(0.0f, 0.2f, 0.2f, 0.0f); Gl.glClearDepth(1.0f); Gl.glDepthFunc(Gl.GL_LEQUAL); Gl.glEnable(Gl.GL_DEPTH_TEST); Gl.glShadeModel(Gl.GL_SMOOTH); Gl.glEnable(Gl.GL_LIGHTING); /**< 启用光源 */ Gl.glEnable(Gl.GL_LIGHT0); /**< 启用0号光源 */ Gl.glEnable(Gl.GL_NORMALIZE); } /// <summary> /// 重载,使用Draw方法绘图 /// </summary> /// <param name="mouseX"></param> /// <param name="currentTime"></param> public override void DrawGLScene(int mouseX, double currentTime) { Draw(); } /// <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); } /** 绘制函数 */ void Draw() { /** 用户自定义的绘制过程 */ ///定义材质属性值 float[] no_mat = new float[] { 0.0f, 0.0f, 0.0f, 1.0f }; /** < 无材质颜色 */ float[] mat_ambient = new float[] { 0.7f, 0.7f, 0.7f, 1.0f }; /** < 环境颜色 */ float[] mat_ambient_color = new float[] { 0.8f, 0.6f, 0.2f, 1.0f }; float[] mat_diffuse = new float[] { 0.2f, 0.5f, 0.8f, 1.0f };/** < 散射颜色 */ float[] mat_specular = new float[] { 1.0f, 1.0f, 1.0f, 1.0f };/** < 镜面反射颜色 */ float[] no_shininess = new float[] { 0.0f }; /** < 镜面反射指数为0 */ float[] low_shininess = new float[] { 5.0f }; /** < 镜面反射指数为5.0 */ float[] high_shininess = new float[] { 100.0f }; /** < 镜面反射指数为100.0 */ float[] mat_emission = new float[] { 0.3f, 0.2f, 0.3f, 0.0f }; /** < 发射光颜色 */ //清除缓存并重置单位矩阵 Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT); Gl.glLoadIdentity(); /** 第一行第一列绘制的球仅有漫反射光而无环境光和镜面光。*/ Gl.glPushMatrix(); Gl.glTranslatef(-2.0f, 1.75f, -6.0f); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_AMBIENT, no_mat); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_DIFFUSE, mat_diffuse); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SPECULAR, no_mat); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SHININESS, no_shininess); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_EMISSION, no_mat); auxSolidSphere(0.3f); Gl.glPopMatrix(); /** 第一行第二列绘制的球有漫反射光和镜面光,并有低高光,而无环境光 。*/ Gl.glPushMatrix(); Gl.glTranslatef(-0.75f, 1.75f, -6.0f); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_AMBIENT, no_mat); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_DIFFUSE, mat_diffuse); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SPECULAR, mat_specular); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SHININESS, low_shininess); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_EMISSION, no_mat); auxSolidSphere(0.3f); Gl.glPopMatrix(); /** 第一行第三列绘制的球有漫反射光和镜面光,并有很亮的高光,而无环境光 。*/ Gl.glPushMatrix(); Gl.glTranslatef(0.75f, 1.75f, -6.0f); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_AMBIENT, no_mat); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_DIFFUSE, mat_diffuse); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SPECULAR, mat_specular); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SHININESS, high_shininess); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_EMISSION, no_mat); auxSolidSphere(0.3f); Gl.glPopMatrix(); /** 第一行第四列绘制的球有漫反射光和辐射光,而无环境和镜面反射光。*/ Gl.glPushMatrix(); Gl.glTranslatef(2.0f, 1.75f, -6.0f); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_AMBIENT, no_mat); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_DIFFUSE, mat_diffuse); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SPECULAR, no_mat); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SHININESS, no_shininess); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_EMISSION, mat_emission); auxSolidSphere(0.3f); Gl.glPopMatrix(); /** 第二行第一列绘制的球有漫反射光和环境光,而镜面反射光。*/ Gl.glPushMatrix(); Gl.glTranslatef(-2.0f, 0.0f, -6.0f); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_AMBIENT, mat_ambient); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_DIFFUSE, mat_diffuse); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SPECULAR, no_mat); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SHININESS, no_shininess); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_EMISSION, no_mat); auxSolidSphere(0.3f); Gl.glPopMatrix(); /** 第二行第二列绘制的球有漫反射光、环境光和镜面光,且有低高光。*/ Gl.glPushMatrix(); Gl.glTranslatef(-0.75f, 0.0f, -6.0f); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_AMBIENT, mat_ambient); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_DIFFUSE, mat_diffuse); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SPECULAR, mat_specular); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SHININESS, low_shininess); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_EMISSION, no_mat); auxSolidSphere(0.3f); Gl.glPopMatrix(); /** 第二行第三列绘制的球有漫反射光、环境光和镜面光,且有很亮的高光。*/ Gl.glPushMatrix(); Gl.glTranslatef(0.75f, 0.0f, -6.0f); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_AMBIENT, mat_ambient); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_DIFFUSE, mat_diffuse); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SPECULAR, mat_specular); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SHININESS, high_shininess); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_EMISSION, no_mat); auxSolidSphere(0.3f); Gl.glPopMatrix(); /** 第二行第四列绘制的球有漫反射光、环境光和辐射光,而无镜面光。*/ Gl.glPushMatrix(); Gl.glTranslatef(2f, 0.0f, -6.0f); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_AMBIENT, mat_ambient); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_DIFFUSE, mat_diffuse); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SPECULAR, no_mat); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SHININESS, no_shininess); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_EMISSION, mat_emission); auxSolidSphere(0.3f); Gl.glPopMatrix(); /** 第三行第一列绘制的球有漫反射光和有颜色的环境光,而无镜面光。*/ Gl.glPushMatrix(); Gl.glTranslatef(-2.0f, -1.75f, -6.0f); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_AMBIENT, mat_ambient_color); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_DIFFUSE, mat_diffuse); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SPECULAR, no_mat); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SHININESS, no_shininess); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_EMISSION, no_mat); auxSolidSphere(0.3f); Gl.glPopMatrix(); /** 第三行第二列绘制的球有漫反射光和有颜色的环境光以及镜面光,且有低高光。*/ Gl.glPushMatrix(); Gl.glTranslatef(-0.75f, -1.75f, -6.0f); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_AMBIENT, mat_ambient_color); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_DIFFUSE, mat_diffuse); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SPECULAR, mat_specular); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SHININESS, low_shininess); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_EMISSION, no_mat); auxSolidSphere(0.3f); Gl.glPopMatrix(); /** 第三行第三列绘制的球有漫反射光和有颜色的环境光以及镜面光,且有很亮的高光。*/ Gl.glPushMatrix(); Gl.glTranslatef(0.75f, -1.75f, -6.0f); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_AMBIENT, mat_ambient_color); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_DIFFUSE, mat_diffuse); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SPECULAR, mat_specular); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SHININESS, high_shininess); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_EMISSION, no_mat); auxSolidSphere(0.3f); Gl.glPopMatrix(); /** 第三行第四列绘制的球有漫反射光和有颜色的环境光以及辐射光,而无镜面光。*/ Gl.glPushMatrix(); Gl.glTranslatef(2f, -1.75f, -6.0f); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_AMBIENT, mat_ambient_color); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_DIFFUSE, mat_diffuse); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SPECULAR, no_mat); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SHININESS, no_shininess); Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_EMISSION, mat_emission); auxSolidSphere(0.3f); Gl.glPopMatrix(); Gl.glFlush(); /**< 强制执行所有的OpenGl.GL命令 */ } /// <summary> /// 由于没有auxSolidSphere这个辅助函数,我做了修改,改为正方形 /// </summary> /// <param name="p"></param> private void auxSolidSphere(float p) { Gl.glColor3f(0.5f, 0.5f, 0.5f); /**< 灰色 */ Gl.glScalef(p, p, p); DrawCube(); } public void DrawCube() { Gl.glBegin(Gl.GL_QUADS); Gl.glColor3f(1, 0, 0); Gl.glVertex3f(-1.0f, -1.0f, -1.0f); Gl.glVertex3f(-1.0f, 1.0f, -1.0f); Gl.glVertex3f(1.0f, 1.0f, -1.0f); Gl.glVertex3f(1.0f, -1.0f, -1.0f); Gl.glColor3f(1, 1, 0); Gl.glVertex3f(-1.0f, -1.0f, -1.0f); Gl.glVertex3f(1.0f, -1.0f, -1.0f); Gl.glVertex3f(1.0f, -1.0f, 1.0f); Gl.glVertex3f(-1.0f, -1.0f, 1.0f); Gl.glColor3f(1, 0, 1); Gl.glVertex3f(-1.0f, -1.0f, -1.0f); Gl.glVertex3f(-1.0f, -1.0f, 1.0f); Gl.glVertex3f(-1.0f, 1.0f, 1.0f); Gl.glVertex3f(-1.0f, 1.0f, -1.0f); Gl.glColor3f(0, 1, 0); Gl.glVertex3f(-1.0f, -1.0f, 1.0f); Gl.glVertex3f(1.0f, -1.0f, 1.0f); Gl.glVertex3f(1.0f, 1.0f, 1.0f); Gl.glVertex3f(-1.0f, 1.0f, 1.0f); Gl.glColor3f(0, 0, 1); Gl.glVertex3f(-1.0f, 1.0f, -1.0f); Gl.glVertex3f(-1.0f, 1.0f, 1.0f); Gl.glVertex3f(1.0f, 1.0f, 1.0f); Gl.glVertex3f(1.0f, 1.0f, -1.0f); Gl.glColor3f(0, 1, 1); Gl.glVertex3f(1.0f, -1.0f, -1.0f); Gl.glVertex3f(1.0f, 1.0f, -1.0f); Gl.glVertex3f(1.0f, 1.0f, 1.0f); Gl.glVertex3f(1.0f, -1.0f, 1.0f); Gl.glEnd(); } } }