上次我们介绍了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. android studio - No compatible file types found

    今天在使用AS新建一个C++类时候,输完了类名,对话框却显示下面的提示,一直不知道为什么 [解决方案] 在app目录下的build.gradle文件中添加下列代码: externalNativeBui ...

  2. angular的uiRouter服务学习(3)

    本篇接着上一篇 angular的uiRouter服务学习(2) 继续讲解uiRouter的用法 本篇主要讲解uiRouter的多个命名的视图 我们可以给ui-view元素添加ui-view的值来给它命 ...

  3. IIS写权限漏洞 (HTTP PUT方法利用)

    该漏洞的产生原因来源于服务器配置不当造成,利用IIS PUT Scaner扫描有漏洞的iis,此漏洞主要是因为服务器开启了 webdav的组件导致的可以扫描到当前的操作,具体操作其实是通过webdav ...

  4. 【转】解决Lost connection to MySQL server during query错误方法

    初步判断是MySQL可能挂掉了,在系统服务里面查看MySQL的进程并没有停止. 最开始考虑是数据库结构不对,但是我是通过Navicat for MySQL的备份和恢复备份导入数据,应该表结构都在备份文 ...

  5. Mysql查看连接数相关信息

    MySQL查看连接数相关信息在 数据库:INFORMATION_SCHEMA 表:PROCESSLIST 表结构如下: mysql> desc PROCESSLIST; +---------+- ...

  6. maven pom属性 详解

    pom.xml文件(实践用):<project xmlns="http://maven.apache.org/POM/4.0.0"   xmlns:xsi="htt ...

  7. Python3在指定路径下递归定位文件中出现的字符串

    [本文出自天外归云的博客园] 脚本功能:在指定的路径下递归搜索,找出指定字符串在文件中出现的位置(行信息). 用到的python特性: 1. PEP 318 -- Decorators for Fun ...

  8. decode和encode

    作者:于洋链接:https://www.zhihu.com/question/23374078/answer/69732605来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出 ...

  9. JAVA-JSP内置对象之response对象

    相关资料:<21天学通Java Web开发> response对象1.response对象用来给客户端传送输出信息. 方法                                 ...

  10. ASP.NET学习笔记(5)——原生Ajax基本操作

    说明(2017-11-4 15:32:49): 1. 回北京后又快一个月了,上次在家写的下回预告,到底是没把加水印写完,而且这次也不想写.. 2. 上次许的愿,十月份看完asp.net,已经泡汤了,翻 ...