计算机图形图像技术(OpenGL多视口、三维场景的真实感绘制与真实感图形)

一、实验原理

1、视口

(1)定义

视口是程序窗口中的一个矩形绘图区(如下图所示),在屏幕上打开一个窗口时,自动把视口设置为整个程序窗口的大小。可以定义一个比程序窗口小的视口,也可以在一个程序窗口中定义多个视口,达到分屏显示的目的。

(2)函数说明

    void glViewport(int left, int bottom, int width, int height)

①功能:设置视口在程序窗口中的位置和大小。

②参数:(left, bottom)是视口左下角在窗口中的坐标;(width, height)是视口的宽和高。

③说明:坐标原点位于程序窗口左下角,以像素为单位。默认视口为(0, 0, W, H),其中W、H分别表示程序窗口的宽和高。

 2、光源属性

(1)环境光成分

    glLightfv(GLenum light, GL_ AMBIENT, float *params)
    glLightiv(GLenum light, GL_ AMBIENT, int *params)

①功能:用于指定环境光成分的RGBA强度。

②说明:默认值为(0, 0, 0, 1),表示没有环境光。

(2)漫反射成分

    glLightfv(GLenum light, GL_ DIFFUSE, float *params)
    glLightiv(GLenum light, GL_ DIFFUSE, int *params)

①功能:用于指定漫反射成分的RGBA强度。

②说明:对于GL_LIGHT0,默认值为(1, 1, 1, 1),对于其他光源,默认值为(0, 0, 0, 0)。

(3)镜面反射成分

    glLightfv(GLenum light, GL_ SPECULAR, float *params)
    glLightiv(GLenum light, GL_ SPECULAR, int *params)

①功能:用于指定镜面反射成分的RGBA强度。

②说明:对于GL_LIGHT0,默认值为(1, 1, 1, 1),对于其他光源,默认值为(0, 0, 0, 0)。

(4)位置

    glLightfv(GLenum light, GL_POSITION, float *params)
    glLightiv(GLenum light, GL_POSITION, int *params)

①功能:用于指定光源位置的齐次坐标(x, y, z, w) 。

②说明:若w≠0,表示该光源是位置光源,距离场景较近,位置用齐次坐标(x, y, z, w)表示;若w=0,表示该光源是方向光源,距离场景无限远,方向用从(x, y, z)到坐标原点的射线方向表示。(x, y, z, w) 的默认值为(0, 0, 1, 0)。

3、材质属性

(1)漫反射系数

    glMaterialfv(GLenum face, GL_ DIFFUSE, float *params)

①功能:用于定义物体对光源漫反射成分的反射系数。

②说明:漫反射系数对物体的颜色起最重要的作用,默认值为(0.8, 0.8, 0.8, 1)。

(2)环境光反射系数

    glMaterialfv(GLenum face, GL_AMBIENT, float *params)

①功能:用于定义物体对环境光的反射系数。

②说明:环境光反射系数影响物体的整体颜色,因为直射到物体上的漫反射光最亮,而没有被直射的物体的环境光反射最明显。物体的环境光反射强度受全局环境光和光源环境光成分的双重影响。默认值为(0.2, 0.2, 0.2, 1)。

(3)同时指定漫反射、环境光反射系数

    glMaterialfv(GLenum face, GL_AMBIENT_AND_DIFFUSE, float *params)

①功能:用于同时指定漫反射系数和环境光反射系数。

②说明:默认值为(0.8, 0.8, 0.8, 1)。

(4)镜面反射系数

    glMaterialfv(GLenum face, GL_SPECULAR, float *params)

①功能:用于定义物体对光源镜面反射成分的反射系数,即亮斑的颜色。

②说明:默认值为(0, 0, 0, 1)。

(5)镜面反射指数

    glMaterialf(GLenum face, GL_SHINESS, float param)
    glMaterialfv(GLenum face, GL_SHINESS, float *params)

①功能:用于控制亮斑的大小和亮度,称为镜面反射指数或光洁度。

②说明:取值范围为[0, 128],值越大,亮斑的尺寸越小且亮度越高,默认值为0。

(6)发光

    glMaterialfv(GLenum face, GL_EMISSION, float *params)

功能:用于定义发光体的发光强度,默认值为(0, 0, 0, 1)。

4、光照处理部分相关函数

(1)光源和光照效果

    glEnable(GL_LIGHTi)     //开启i 号光源(0≤i≤8) 
    glDisable(GL_LIGHTi)    //关闭i 号光源(0≤i≤8) 
    glEnable(GL_LIGHTING)   //启用光照效果
    glDisable(GL_LIGHTING)  //禁止光照效果

(2)明暗模式

    glShadeModel(GL_SMOOTH) //光滑明暗模式,使用Gouraud算法
    glShadeModel(GL_FLAT)   //平面明暗模式,用其中一个顶点的颜色填充

二、算法程序

1、使用OpenGL、GLU和GLUT编写一个多视口演示程序。要求:

(1)屏幕窗口左下角1/4部分显示红色的填充矩形,该矩形的一对对角顶点是(0, 0)和(1, 1);

(2)屏幕窗口右下角1/4部分显示绿色的填充犹他茶壶,茶壶半径为0.4,并向右、上各移动0.5;

(3)屏幕窗口上部居中1/4部分显示蓝色的填充正三角形,该正三角形的左下角顶点是(0, 0),右下角顶点是(1, 0);

(4)裁剪窗口均为(-0.1, -0.1)~(1.1, 1.1),程序窗口的大小为(200, 200),背景为黑色,标题为“多视口演示”。

#include<GL/freeglut.h>
#include<math.h>
void Viewport(int x, int y, int w, int h) {
	glViewport(x, y, w, h);
	glLoadIdentity();
	gluOrtho2D(-0.1, 1.1, -0.1, 1.1);
}
void Triangle() {
	glBegin(GL_TRIANGLES);
	glVertex2f(0, 0);
	glVertex2f(1.0, 0);
	glVertex2f(0.5 , sqrt(3) / 2);
	glEnd();
}
void Paint() {
	int w = glutGet(GLUT_WINDOW_WIDTH) / 2;
	int h = glutGet(GLUT_WINDOW_HEIGHT) / 2;
	glClearColor(0, 0, 0, 0);
	glClear(GL_COLOR_BUFFER_BIT);
	Viewport(0, 0, w, h);
	glColor3f(1, 0, 0);
	glRectf(0, 0, 1, 1);
	Viewport(w, 0, w, h);
	glTranslatef(0.5, 0.5, 0);
	glColor3f(0, 1, 0);
	glutSolidTeapot(0.4);
	Viewport(w / 2, h, w, h);
	glColor3f(0, 0, 1);
	Triangle();
	glFlush();
}
int main(int argc, char *argv[]) {
	glutInit(&argc, argv);
	glutInitWindowSize(200, 200);
	glutCreateWindow("多视口演示");
	glutDisplayFunc(Paint);
	glutMainLoop();
	return 0; 
}

2、已知在一个空旷的场景中有一个粗糙的紫色球体,球体的右上角方向放置了一个白色的点光源,请使用OpenGL和GLUT编写一个程序模拟出球面上的光照效果(不考虑环境光)。

#include <GL/glut.h>
void Light() {
    float pos[] = {200, 200, 0, 1};
    glLightfv(GL_LIGHT0, GL_POSITION, pos);
    glEnable(GL_LIGHT0);
    glEnable(GL_LIGHTING);
}
void Material() {
    float mater[] = {1, 0, 1, 1};
    glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mater);
}
void Paint() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    gluPerspective(60, 1, 1, 1000);
    glTranslatef(0, 0, -2);
    glutSolidSphere(0.95, 100, 50);
    glFlush();
}
int main(int argc, char* argv[]) {
    glutInit(&argc, argv);
    glutInitWindowSize(300, 300);
    glutCreateWindow("粗糙的紫色球体");
    glutDisplayFunc(Paint);
    Light(), Material();
    glutMainLoop();
}

三、结果演示

1、多视口演示

2、粗糙的紫色球体

  • 22
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

有为肥宅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值