上次我们介绍了OpenGL的环境构建和二维对象的绘制,这次我们来讲讲三维对象的绘制:

绘制代码如下:

Github代码仓库

// opengltest2.cpp : Defines the entry point for the console application.
// #include "stdafx.h"
#include <GL/glut.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define PI 3.1415926
//金字塔初始旋转角度
GLfloat rtri = ;
//用户自定义三维空间的齐次坐标矩阵(4X4)——用于输出查看变化矩阵的变化
typedef float Mat44[];
//自定义初始化opengl 环境
void init(void)
{
//设置背景色——用于填充背景
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
//设置多边形填充模式为smooth 方式
glShadeModel(GL_SMOOTH);
//打开深度测试开关——用于检测物体间的z 深度差异
glEnable(GL_DEPTH_TEST);
//线的抗锯齿开关
glEnable(GL_LINE_SMOOTH);
//启用抗锯齿效果
glHint(GL_LINE_SMOOTH,GL_NICEST);
//指定混合函数
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//启用色彩混合状态
glEnable(GL_BLEND);
}
//输出4X4 矩阵的结果
void outputmat(const Mat44 &mat) {
for(int i = ; i < ; i++) {
for(int j = ; j < ; j++)
printf("%.3f ", mat[i * + j]);
printf("\n");
}
} //自定义绘制圆函数
void glCircle()
{
double n=;//分段数
float R=1.0;//半径
int i;
//将绘图前的模型变换矩阵压入堆栈
glPushMatrix();
//设置颜色RGB 与透明度值(0.5)
glColor4f(0.0,0.2,0.8, 0.5);
//发出准备绘图命令
glBegin(GL_TRIANGLE_FAN);
glVertex2f(0.0,0.0);
for(i=; i<=n; i++)
glVertex2f(R*cos(*PI/n*i), R*sin(*PI/n*i));
//发出结束绘图命令
glEnd();
//绘图后,恢复绘图前的模型变换矩阵
//这样,对当前图形的变换对后面图形绘制不影响
glPopMatrix();
} //opengl 用户自定义绘图函数
void display(void)
{
//清除颜色缓存和深度缓存
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//装入单位转换矩阵[1 0 0 0; 0 1 0 0; 0 0 1 0; 0 0 0 1]
glLoadIdentity();
//平移变换命令——之后绘制的所有对象将沿Z 轴向屏幕内移动5 个单位
glTranslatef(0.0f,0.0f,-5.0f);
//旋转变换命令——后绘制的所有对象将沿Y 轴正向旋转rtri 个角度单位
glRotatef(rtri,0.0f,1.0f,0.0f);
//以下绘制的对象沿X 轴转动10 度
//glRotatef(10, 1, 0, 0);
//查看当前的4X4 矩阵变量
Mat44 mat;
//取得模型-视图变换矩阵
glGetFloatv(GL_MODELVIEW_MATRIX, mat);
//在DOS 控制台查看上述变换后的总变换矩阵结果
outputmat(mat);
//设置点元大小为5 个像素
glPointSize();
//发出命令:开始绘制点
glBegin(GL_POINTS);
glColor3f(, , );//点的颜色为红色
glVertex3f(0.7, 0.5, 0.4);//顶点(vertex)位置:(0.7, 0.5, 0.4)
glColor3f(, , );
glVertex3f(0.7, 0.5, -0.4);
glEnd();//结束绘制点
//绘制坐标轴--X,Y,Z
glBegin(GL_LINES);
glColor3f(, , );
glVertex3f(, , );
glVertex3f(, , );
glColor3f(, , );
glVertex3f(,,);
glVertex3f(,,);
glColor3f(, , );
glVertex3f(, , );
glVertex3f(, , );
glEnd();
//绘制2 个三角形
glBegin(GL_TRIANGLES);
glColor4f(, , , 0.5);
glVertex2f(-0.7, );
glVertex2f(0.5, );
glVertex2f(, 0.5);
glColor4f(, , , 0.5);
glVertex3f(-0.5, -0.2, );
glVertex3f(0.8, -0.2, 0.3);
glVertex3f(, 0.2, -0.5);
glEnd();
//绘制实心的圆环——在原有变换基础上,又增加了新的变换;
//为了不影响后续对象的变换,采用压栈的方式,保存当前变换矩阵
glPushMatrix();
{
glTranslatef(0.0f, 0.0f, -3.0f);//用于实心圆环的变换
glColor4f(1.0f, 0.0f, 0.0f, 0.5);
glutSolidTorus(0.3, 0.7, 30.0f, 30.0f);//绘制实心圆环
}
glPopMatrix(); //从堆栈中恢复已压栈的变换矩阵
//绘制实心球
glPushMatrix();
{
glTranslatef(1.0f, 1.0f, 3.0f);//增加了变换
glColor4f(0.0f, 1.0f, 0.0f, 0.5);
glTranslatef(0.5, , );
glutSolidSphere(0.4f, 30.0f, 30.0f);//绘制球体
glTranslatef(, , -);
glutSolidSphere(0.4f, 30.0f, 30.0f);//绘制球体
}
glPopMatrix();
//glScalef( 2.0, 2.0, 0.0 ); //比例变换
//开始绘制直线段
glBegin(GL_LINES);
glColor3f(, , );
glVertex3f(, , );
glVertex3f(, , );
glColor3f(, , );
glVertex3f(, , );
glVertex3f(, , );
glColor3f(, , );
glVertex3f(, , );
glVertex3f(, , );
glEnd();
//平移变换
glTranslatef(-, , );
glCircle();
//平移变换
glTranslatef(, , );
//绘制立方体线框
glColor4f(, , , 0.5);
glRotatef(, , , );
glutWireCube();
rtri += 0.3;//全局的旋转变量加0.3 度
//用缓冲区所绘制的对象替换窗口内容——适合于双缓冲技术
glutSwapBuffers();//交换双缓存
} //用户自定义窗口调整大小事件的处理函数
//在这个函数中要求设置视口、投影、透视变换的相关参数
void reshape (int w, int h)
{
//设置视口参数为整个窗口范围内
glViewport(, , (GLsizei) w, (GLsizei) h);
//设置投影参数:投影矩阵初始为单位阵
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
//设置透视参数: 眼睛或摄像机的视角参数为60 度,视景体的宽度和高度比,视距(焦距)
//(near)和视径(far)参数
//near = 1, far = 100, Z 轴负向顺着视线方向指向屏幕内
//X 轴正向向右,Y 轴正向向上,坐标原点在屏幕中心处
gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 100.0);
//设置摄像机的位置及姿态参数:
//摄像机位置(cX, cY, cZ)
//视点所观察中心位置Ow(oX, oY, oZ)
//摄像机位姿参数——摄像机顶部矢量
gluLookAt(, , , 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
//设置矩阵模式为模型-视图变换模式,以便于后面的自定义显示函数继续本模式
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
} //用户自定义键盘事件处理函数
void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 'x':
case : //ESC 键盘
exit();
break;
default:
break;
}
} int main(int argc, char** argv)
{
//用命令行参数初始化OpenGL
glutInit(&argc, argv);
//使用RGB 色彩、双缓存和深度模式
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
//初始化绘图窗口大小参数
glutInitWindowSize(, );
//窗口左上角坐标参数
glutInitWindowPosition(, );
//创建窗口
glutCreateWindow("OpenGL HelloWorld");
//用户自定义初始化绘图环境函数
init();
//用户指定的绘图函数,display 名可变
glutDisplayFunc(display);
//窗口调整大小事件的处理函数
glutReshapeFunc(reshape);
//窗口键盘处理事件的处理函数
glutKeyboardFunc(keyboard);
//设置窗口空闲时调用的函数
glutIdleFunc(display);
//进入glut 函数库的主循环
glutMainLoop();
return ;
}

效果如下:

记得搭建好OpenGL的环境,可以参照这篇文章:http://www.cnblogs.com/OctoptusLian/p/6834669.html

祝Coding愉快~~~

OpenGL基本框架与三维对象绘制的更多相关文章

  1. OpenGL新手框架

    开始学习用OpenGL,也就想显示一些点,以为挺简单的,哎,看了两天才会画三维的点,做个总结. 使用OpenGL的基本流程 int main(int argv, char *argc[]) { //初 ...

  2. 现代3D图形编程学习--opengl使用不同的缓存对象(译者添加)

    现代3D图形编程学习系列翻译地址 http://www.cnblogs.com/grass-and-moon/category/920962.html opengl使用不同的缓存对象 在设置颜色一章中 ...

  3. [转]OpenGL通过VBO实现顶点数组绘制顶点

    #include "stdlib.h" #include <OpenGL/glext.h> #include <GLUT/GLUT.h> #define B ...

  4. 浅析jQuery框架与构造对象

    这是一些分析jQuery框架的文字    面向的读者应具备以下要求 1.非常熟悉HTML 2.非常熟悉javascript语法知识 3.熟悉javascript面向对象方面的知识 4.熟练使用jQue ...

  5. PhiloGL学习(4)——三维对象、加载皮肤

    前言 上一篇文章中介绍了如何响应鼠标和键盘事件,本文介绍如何加载三维对象并实现给三维对象添加一个漂亮的皮肤. 一. 原理分析 我对三维的理解为:所谓三维对象无非是多个二维对象拼接到一起,贴图就更简单了 ...

  6. Spring.NET依赖注入框架学习-- 泛型对象的创建和使用

    Spring.NET依赖注入框架学习-- 泛型对象的创建和使用 泛型对象的创建方法和普通对象是一样的. 通过构造器创建泛型对象 下面是一个泛型类的代码: namespace GenericsPlay ...

  7. VS2010/MFC编程入门之四十(文档、视图和框架:各对象之间的关系)

    前面一节中鸡啄米进行了文档.视图和框架的概述,本节主要讲解文档.视图.框架结构中各对象之间的关系. 各个对象之间的关系 文档.视图.框架结构中涉及到的对象主要有:应用程序对象.文档模板对象.文档对象. ...

  8. 科学计算三维可视化---TVTK入门(创建和显示三维对象)

    一:创建一个基本的三维对象 (一)长方体操作 traits:就是TVTK对象的属性 (1)对象属性操作 >>> from tvtk.api import tvtk >>& ...

  9. OpenGL三角形的双面不同颜色的绘制

    对于一个三角形,我要给它正反面不同的颜色.然后通过旋转,看出它的效果. 我只想到了2种方法,下面我来写一下这两种方法. 第一种方法,通过角度的判断重设glColor3f的参数(这种方法局限性很大,不推 ...

随机推荐

  1. mysql创建唯一索引

    查看索引  show index from 数据库表名 alter table 数据库add index 索引名称(数据库字段名称) PRIMARY KEY(主键索引) ALTER TABLE `ta ...

  2. redhat7.2 安装docker

    # wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo # sed -i  ' ...

  3. SecureCRT常用快捷键

    Alt + B + B --打开新连接 Ctrl + A --光标移到行首 Ctrl + E --光标移到行末 Ctrl + B --光标前移一个字符 Ctrl + F --光标后移一个字符 Ctrl ...

  4. 每日英语:Got a Case of the Mondays? Blame the Sunday Blues

    Welcome to Monday morning at the office. Did you have trouble sleeping last night? Was your stomach ...

  5. Linux命令行删除文件到回收站

    先说方法,原理后面分析. 由于我使用的是Ubuntu14,这里以该系统为主,其他系统略有区别. 可以新加别名del,用于删除文件. alias del='mv -t ~/.local/share/Tr ...

  6. C++的虚函数试题,常考!!

    #include <iostream> #include <cstring> #include <string.h> #include <stdio.h> ...

  7. Android Toolbar的使用 顶部标题栏+后退键

    最近设计安卓里面有个标题栏,里面有个后退键,可以完成后退之类的功能. 好,刚好可以用Toolbar去实现 上代码:activity_main.xml <?xml version="1. ...

  8. 微服务之springCloud-docker-feign-hystrix-ribbon(七)

    简介 在上一节中,我们讨论了feign+hystrix在项目开发中,除了考虑正常的调用之外,负载均衡和故障转移也是关注的重点,这也是feign + ribbon+hystrix的优势所在,本节我们就讨 ...

  9. StreamingContext.getOrCreate

    /** */ object AppRealTime { def main(args: Array[String]): Unit = { ) { println("please input a ...

  10. [转]Java中的POJO类

    简单的Java对象(Plain Old Java Objects)实际就是普通JavaBeans,使用POJO名称是为了避免和EJB混淆起来, 而且简称比较直接. 其中有一些属性及其getter se ...