本文基础: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();
}
}
}