OpenGL(十一)——Qt OpenGL给多边形上色
一、前言
上篇文章介绍了绘制多边形的代码。
本篇介绍给多边形上色。
上篇的运行效果:
二、代码
上一篇中三角形和四边形的绘制方法。这一篇给三角形和四边形添加两种不同类型的着色方法。 *!使用单调着色(Flat coloring)给四边形涂上固定的一种颜色。 *!!使用平滑着色(Smooth coloring)将三角形的三个顶点的不同颜色混合在一起,创建漂亮的色彩混合。 我们只要修改第二篇中的NeHeWidget类中的paintGL()函数就可以了。
头文件:
#include <QObject>
#include <QWidget>
#include <qgl.h>
/*
*给多边形上色.
*/
class NeHe_3_Widget : public QGLWidget
{
Q_OBJECT
public:
NeHe_3_Widget(QWidget *parent = 0);
~NeHe_3_Widget();
protected:
void initializeGL(); //是用来初始化这个OpenGL窗口部件的,可以在里面设定一些有关选项.
void paintGL(); //是用来绘制OpenGL的窗口了,只要有更新发生,这个函数就会被调用.
void resizeGL( int width, int height ); //就是用来处理窗口大小变化这一事件的,width和height就是新的大小状态下的宽和高了,另外resizeGL()在处理完后会自动刷新屏幕。
};
cpp文件:
#include "nehe_3_widget.h"
#include <GL/glu.h>
NeHe_3_Widget::NeHe_3_Widget(QWidget *parent):QGLWidget(parent)
{
setGeometry(0,0, 640, 480);
}
NeHe_3_Widget::~NeHe_3_Widget()
{
}
void NeHe_3_Widget::initializeGL()
{
glShadeModel( GL_SMOOTH );
//这一行启用smooth shading(阴影平滑)。阴影平滑通过多边形精细的混合色彩,并对外部光进行平滑。我将在另一个教程中更详细的解释阴影平滑。
glClearColor( 0.0, 0.0, 0.0, 0.0 );
//这一行设置清除屏幕时所用的颜色。如果您对色彩的工作原理不清楚的话,我快速解释一下。色彩值的范围从0.0到1.0。0.0代表最黑的情况,1.0就 \
是最亮的情况。glClearColor后的第一个参数是红色,第二个是绿色,第三个是蓝色。最大值也是1.0,代表特定颜色分量的最亮情况。最后一个参数是 \
Alpha值。当它用来清除屏幕的时候,我们不用关心第四个数字。现在让它为0.0。我会用另一个教程来解释这个参数。\
通过混合三种原色(红、绿、蓝),您可以得到不同的色彩。希望您在学校里学过这些。因此,当您使用glClearColor(0.0, 0.0, 1.0, 0.0 ),\
您将用亮蓝色来清除屏幕。如果您用glClearColor(0.5, 0.0, 0.0, 0.0 )的话,您将使用中红色来清除屏幕。不是最亮(1.0),也不是最暗 (0.0)。\
要得到白色背景,您应该将所有的颜色设成最亮(1.0)。要黑色背景的话,您该将所有的颜色设为最暗(0.0)。
glClearDepth( 1.0 );
//设置深度缓存。
glEnable( GL_DEPTH_TEST );
//启用深度测试。
glDepthFunc( GL_LEQUAL );
//所作深度测试的类型。
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
}
void NeHe_3_Widget::resizeGL( int width, int height )
{
if ( height == 0 )
{
height = 1;
}
//防止height为0。
glViewport( 0, 0, (GLint)width, (GLint)height );
//重置当前的视口(Viewport)。
glMatrixMode( GL_PROJECTION );
//选择投影矩阵。
glLoadIdentity();
//重置投影矩阵。
gluPerspective( 45.0, (GLfloat)width/(GLfloat)height, 0.1, 100.0 );
//建立透视投影矩阵。
glMatrixMode( GL_MODELVIEW );
//选择模型观察矩阵。
glLoadIdentity();
//重置模型观察矩阵。
//! 上面几行为透视图设置屏幕。意味着越远的东西看起来越小。这么做创建了一个现实外观的场景。\
此处透视按照基于窗口宽度和高度的45度视角来计算。0.1,100.0是我们在场景中所能绘制深度的起点和终点。
}
void NeHe_3_Widget::paintGL()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
//清楚屏幕和深度缓存。
glLoadIdentity();
//重置当前的模型观察矩阵。
//当您调用glLoadIdentity()之后,您实际上将当前点移到了屏幕中心,X坐标轴从左至右,Y坐标轴从下至上,Z坐标轴从里至外。\
OpenGL屏幕中心的坐标值是X和Y轴上的0.0点。中心左面的坐标值是负值,右面是正值。移向屏幕顶端是正值,移向屏幕底端是负值。\
移入屏幕深处是负值,移出屏幕则是正值。
glTranslatef( -1.5, 0.0, -6.0 );
//glTranslatef(x, y, z)沿着 X, Y 和 Z 轴移动。根据前面的次序,下面的代码沿着X轴左移1.5个单位,Y轴不动(0.0),最后移入屏幕6.0个单位。\
注意在glTranslatef(x, y, z)中当您移动的时候,您并不是相对屏幕中心移动,而是相对与当前所在的屏幕位置。
//! 现在我们已经移到了屏幕的左半部分,并且将视图推入屏幕背后足够的距离以便我们可以看见全部的场景-创建三角形。
glBegin( GL_TRIANGLES );
//开始绘制三角形。
glColor3f( 1.0, 0.0, 0.0 );
//红色
//如果您还记得上节课的内容,这段代码在屏幕的左半部分绘制三角形。这一行代码是我们第一次使用命令glColor3f( r, g, b )。\
括号中的三个参数依次是红、绿、蓝三色分量。取值范围可以从0.0到1.0。类似于以前所讲的清除屏幕背景命令。我们将颜色设为红色(纯红色,无绿色,无蓝色)。
glVertex3f( 0.0, 1.0, 0.0 );
//上顶点。
//接下来的一行代码设置三角形的第一个顶点(三角形的上顶点),并使用当前颜色(红色)来绘制。\
从现在开始所有的绘制的对象的颜色都是红色,直到我们将红色改变成别的什么颜色
glColor3f( 0.0, 1.0, 0.0 );
//绿色.
glVertex3f( -1.0, -1.0, 0.0 );
//左下顶点。
glColor3f( 0.0, 0.0, 1.0 );
//蓝色
glVertex3f( 1.0, -1.0, 0.0 );
//右下顶点。
glEnd();
//三角形绘制结束。
//! glEnd()出现后,三角形将被填充。但是因为每个顶点有不同的颜色,因此看起来颜色从每个角喷出,并刚好在三角形的中心汇合
//! ,三种颜色相互混合。这就是平滑着色。
glTranslatef( 3.0, 0.0, 0.0 );
glColor3f( 0.5, 0.5, 1.0 );
//一次性将颜色设置为蓝色。
//! 现在我们绘制一个单调着色——蓝色的正方形。最重要的是要记住,设置当前色之后绘制的所有东东都是当前色的。
//! 以后您所创建的每个工程都要使用颜色。即便是在完全采用纹理贴图的时候,glColor3f仍旧可以用来调节纹理
//! 的色调。等等...,以后再说吧。
//! 我们必须要做的事只需将颜色一次性的设为我们想采用的颜色(本例采用蓝色),然后绘制场景。每个顶点都是蓝色的,
//! 因为我们没有告诉OpenGL要改变顶点的颜色。最后的结果是.....全蓝色的正方形。再说一遍,顺时针绘制的正方形
//! 意味着我们所看见的是四边形的背面。
glBegin( GL_QUADS );
//开始绘制四边形。
glVertex3f( -1.0, 1.0, 0.0 );
//左上顶点。
glVertex3f( 1.0, 1.0, 0.0 );
glVertex3f( 1.0, -1.0, 0.0 );
glVertex3f( -1.0, -1.0, 0.0 );
glEnd();
glTranslatef( -1.5, 0.0, 0.0 );
glColor3f( 1.0, 1.0, 0.0 );
glBegin( GL_LINES );
glVertex3f(0.0, 1.0, 0.0);
glVertex3f(0.0, -1.0, 0.0);
glEnd();
}
三、运行效果
在上色结束后,我们运行一下,看一下运行的效果。
可以看到,上色后的多边形效果。
下一篇:OpenGL(十二)——Qt OpenGL绕着坐标轴旋转多边形
本文原创作者:冯一川(ifeng12358@163.com),未经作者授权同意,请勿转载。