我们知道,大千世界,千奇百态,但是其基本组成都是一样的,都是由原子所组成。不同的原子经过各种各样的变换,构成了我们多姿多彩的世界。对于计算机图形学也是这样,那些逼真,酷炫的场景都离不开组成这些模型的基本图元。我们从绘制一个三角形开始。
绘制三角形
在图形学中,绘制一个三角形,只需要固定它的三个顶点即可。顶点的确定使用下面的函数
glVertex3f(x, y, z);
这个函数是在我们完成了自己的OpenGL“Hello World”程序后接触的最常见,最常用的函数之一。OpenGL的函数命名非常规范,对于这个函数,gl表示其属于GL库(glu开头的函数表示属于GLU库,glut开头的表示GLUT库);中间的Vertex表示的是函数的功能,首字母大写;数字3表示的是参数的个数;f表示的是参数的类型,x, y, z均为float类型。
另一组常见的函数就是glBegin()和glEnd()。其中前者的参数可以是GL_POINTS(点),GL_LINES(线),GL_TRIANGLES(三角形),GL_QUADS/GL_POLYGONS(多
边形)等。如果要绘制一个三角形,使用GL_TRIANGLES即可。
绘制三角形代码
#include "freeglut\freeglut.h"
void renderScene(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glBegin(GL_TRIANGLES);
//设置三角形的颜色为红色
glColor3f(1.0f, 0.0f, 0.0f);
//三角形三个顶点的坐标
glVertex3f(-0.5, -0.5, 0.0);
glVertex3f(0.5, -0.5, 0.0);
glVertex3f(0.0, 0.5, 0.0);
glEnd();
glutSwapBuffers();
}
int main(int argc, char *argv[]) {
//初始化
glutInit(&argc, argv);
//创建窗口显示模式
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
//设置初始窗口位置
glutInitWindowPosition(100, 100);
//初始化窗口大小
glutInitWindowSize(320, 320);
//创建顶层窗口,窗口名字
glutCreateWindow("HelloTriangle");
//注册当前窗口的回调函数
glutDisplayFunc(renderScene);
//设置窗口背景颜色
glClearColor(1.0f, 1.0f, 0.0f, 0.5f);
//事件处理循环
glutMainLoop();
return 0;
}
PS:这里使用的是freeglut库,关于这个库的配置方法,可以参考这里.这个配置方法对我起了很大的帮助,不过截至完成这篇博客的时间,这个网页居然不存在了,之后有时间希望我能自己再写一篇配置方法。
三角形顶点着色
除了绘制一个简单的三角形,我们可以通过着色让他更加好看一点。着色,缓存等知识其实不应该是初学者需要掌握的,因此这里的着色只是最简单的方法——给三角形的每个顶点都使用一次glColor3f(R,G, B)。
glBegin(GL_TRIANGLES);
//设置第一个顶点的颜色为红色
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(-0.5, -0.5, 0.0);
//设置第二个顶点的颜色为绿色
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(0.5, -0.5, 0.0);
//设置第三个顶点的颜色为蓝色
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(0.0, 0.5, 0.0);
glEnd();
修改后的代码的运行结果如下:
基本图元组合绘画
使用一些基本图元可以构成一幅画,这里本人自己小试牛刀,抛砖引玉,给大家学习做一个简单的示例,祝大家在OpenGL的学习道路上越走越远!!!
#include "freeglut/freeglut.h"
#include <cstdlib>
#include <ctime>
#include <math.h>
void renderScene(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
//画3个三角形表示松树
glColor3f(0.0, 1.0, 0.0);
glBegin(GL_TRIANGLES);
glVertex3f(-0.4, 0.6, 0.0);
glVertex3f(0.4, 0.6, 0.0);
glVertex3f(0.0, 1.0, 0.0);
glVertex3f(-0.6, 0.2, 0.0);
glVertex3f(0.6, 0.2, 0.0);
glVertex3f(0.0, 0.6, 0.0);
glVertex3f(-0.8, -0.3, 0.0);
glVertex3f(0.8, -0.3, 0.0);
glVertex3f(0.0, 0.2, 0.0);
glEnd();
//画1个多边形和1个三角形表示树干
glColor3f(0.54, 0.27, 0.07);
glBegin(GL_QUADS);
glVertex2f(-0.2, -0.3);
glVertex2f(-0.2, -1.0);
glVertex2f(0.2, -0.3);
glVertex2f(0.2, -1.0);
glEnd();
glBegin(GL_TRIANGLES);
glVertex3f(-0.2, -0.3, 0.0);
glVertex3f(0.2, -0.3, 0.0);
glVertex3f(0.0, -1.0, 0.0);
glEnd();
//画2条线段表示枝丫
glColor3f(0.0, 1.0, 0.0);
glLineWidth(4);
glBegin(GL_LINES);
glVertex2f(-0.2, -0.8);
glVertex2f(-0.4, -0.5);
glVertex2f(0.2, -0.95);
glVertex2f(0.5, -0.45);
glEnd();
//随机白点表示白雪皑皑
glColor3f(1.0, 1.0, 1.0);
glPointSize(3);
srand(time(NULL));
for (int i = 0; i < 50; i++) {
glBegin(GL_POINTS);
GLfloat x = rand() % (100 + 1) / (float)(50) - 1;
GLfloat y = rand() % (100 + 1) / (float)(50) - 1;
glVertex2f(x, y);
glEnd();
}
glutSwapBuffers();
}
int main(int argc, char *argv[]) {
//初始化
glutInit(&argc, argv);
//创建窗口显示模式
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
//设置初始窗口位置
glutInitWindowPosition(100, 100);
//初始化窗口大小
glutInitWindowSize(320, 320);
//创建顶层窗口,窗口名字
glutCreateWindow("雪松");
//注册当前窗口的回调函数
glutDisplayFunc(renderScene);
//设置窗口背景颜色
glClearColor(1.0f, 1.0f, 0.0f, 0.5f);
//事件处理循环
glutMainLoop();
return 0;
}
实现效果图: