OpenGL编程 基础篇(七)对象的变换——用实心体绘制3D场景

1.函数介绍

GLUT提供几种现成的对象,包括球体、圆锥体、圆环面、5个柏拉图立体,以及著名的茶壶。每个形状都可以作为一种线框的模型,也可以作为一种实心模型,每个面均已覆盖上材质。

以下列表是用于绘制这些对象的函数。

  • void glutWireSphere(GLdouble radius, GLint slices, GLint stacks); 线框球
  • void glutSolidSphere(GLdouble radius, GLint slices, GLint stacks); 实心球
  • void glutWireCube(GLdouble size); 线框立方体
  • void glutSolidCube(GLdouble size); 实心立方体
  • void glutWireTorus(GLdouble innerRadius, GLdouble outerRadius, GLint nsides, GLint rings); 线框圆环
  • void glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius, GLint nsides, GLint rings); 实心圆环
  • void glutWireIcosahedron(void); 线框20面体
  • void glutSolidIcosahedron(void); 实心20面体
  • void glutWireOctahedron(void); 线框8面体
  • void glutSolidOctahedron(void); 实心8面体
  • void glutWireTetrahedron(void); 线框4面体
  • void glutSolidTetrahedron(void); 实心4面体
  • void glutWireDodecahedron(GLdouble radius); 线框12面体
  • void glutSolidDodecahedron(GLdouble radius); 实心12面体
  • void glutWireCone(GLdouble radius, GLdouble height, GLint slices, GLint stacks); 线框圆锥体
  • void glutSolidCone(GLdouble radius, GLdouble height, GLint slices, GLint stacks); 实心圆锥体
  • void glutWireTeapot(GLdouble size); 线框茶壶
  • void glutSolidTeapot(GLdouble size); 实心茶壶

函数中,radius表示球体的半径,slices表示球体围绕z轴分割的数目,stacks表示球体沿着z轴分割的数目。

绘制中心在模型坐标原点,半径为radius的球体,球体围绕z轴分割slices次,球体沿着z轴分割stacks次

2.示例:用实心体绘制的3D场景

#include "stdafx.h"
#include <windows.h>
#include <gl/glut.h>

int X, Y;

//<<<<<<<<<<<<<<< wall >>>>>>>>>>>>>>>>
void wall(double thickness)
{ // draw thin wall with top = xz-plane, corner at origin
    glPushMatrix();
    glTranslated(0.5, 0.5 * thickness, 0.5);
    glScaled(1.0, thickness, 1.0);
    glutSolidCube(1.0);
    glPopMatrix();
}
//<<<<<<<<<<<<<<<<<< tableLeg >>>>>>>>>>>>>>>>>>>
void tableLeg(double thick, double len)
{
    glPushMatrix();
    glTranslated(0, len / 2, 0);
    glScaled(thick, len, thick);
    glutSolidCube(1.0);
    glPopMatrix();
}
//<<<<<<<<<<<<<<<<<<<<< jack part >>>>>>>>>>>>>
void jackPart()
{ // draw one axis of the unit jack - a stretched sphere
    glPushMatrix();
    glScaled(0.2, 0.2, 1.0);
    glutSolidSphere(1, 15, 15);
    glPopMatrix();
    glPushMatrix();
    glTranslated(0, 0, 1.2); // ball on one end
    glutSolidSphere(0.2, 15, 15);
    glTranslated(0, 0, -2.4);
    glutSolidSphere(0.2, 15, 15); // ball on the other end
    glPopMatrix();
}
//<<<<<<<<<<<<<<<<<<< jack >>>>>>>>>>>>>>>>>>>>
void jack()
{ // draw a unit jack out of spheroids
    glPushMatrix();
    jackPart();
    glRotated(90.0, 0, 1, 0);
    jackPart();
    glRotated(90.0, 1, 0, 0);
    jackPart();
    glPopMatrix();
}
//<<<<<<<<<<<<<<<<<<<<<<< table >>>>>>>>>>>>>>>>>>>>
void table(double topWid, double topThick, double legThick, double legLen)
{ // draw the table - a top and four legs

    glPushMatrix(); // draw the table top
    glTranslated(0, legLen, 0);
    glScaled(topWid, topThick, topWid);
    glutSolidCube(1.0);
    glPopMatrix();
    double dist = 0.95 * topWid / 2.0 - legThick / 2.0;
    glPushMatrix();
    glTranslated(dist, 0, dist);
    tableLeg(legThick, legLen);
    glTranslated(0, 0, -2 * dist);
    tableLeg(legThick, legLen);
    glTranslated(-2 * dist, 0, 2 * dist);
    tableLeg(legThick, legLen);
    glTranslated(0, 0, -2 * dist);
    tableLeg(legThick, legLen);
    glPopMatrix();
}
//<<<<<<<<<<<<<<<<<<<<< displaySolid >>>>>>>>>>>>>>>>>>>>>>
void displaySolid(void)
{
    // set properties of the surface material
    GLfloat mat_ambient[] = { 0.7f, 0.7f, 0.7f, 1.0f }; // gray
    GLfloat mat_diffuse[] = { 0.6f, 0.6f, 0.6f, 1.0f };
    GLfloat mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
    GLfloat mat_shininess[] = { 50.0f };

    glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
    glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
    // set the light source properties
    GLfloat lightIntensity[] = { 0.7f, 0.7f, 0.7f, 1.0f };
    GLfloat light_position[] = { 2.0f, 6.0f, 3.0f, 0.0f };
    glLightfv(GL_LIGHT0, GL_POSITION, light_position);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, lightIntensity);

    // set the camera
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    double winHt = 1.0; // half-height of the window
    glOrtho(-winHt * 64 / 48.0, winHt * 64 / 48.0, -winHt, winHt, 0.1, 100.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(5 - 10.0*X / 640, 2 - 4.0*Y / 480, 2, 0, 0.25, 0, 0.0, 1.0, 0.0);
    // start drawing
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the screen
    glPushMatrix();
    glTranslated(0.4, 0.4, 0.6);
    glRotated(45, 0, 0, 1);
    glScaled(0.08, 0.08, 0.08);
    jack(); // draw the jack
    glPopMatrix();
    glPushMatrix();
    glTranslated(0.6, 0.38, 0.5);
    glRotated(30, 0, 1, 0);
    glutSolidTeapot(0.08); // draw the teapot
    glPopMatrix();
    glPushMatrix();
    glTranslated(0.25, 0.42, 0.35); // draw the sphere
    glutSolidSphere(0.1, 15, 15);
    glPopMatrix();
    glPushMatrix();
    glTranslated(0.4, 0, 0.4);
    table(0.6, 0.02, 0.02, 0.3); // draw the table
    glPopMatrix();
    wall(0.02); // wall #1: in xz-plane
    glPushMatrix();
    glRotated(90.0, 0.0, 0.0, 1.0);
    wall(0.02); // wall #2: in yz-plane
    glPopMatrix();
    glPushMatrix();
    glRotated(-90.0, 1.0, 0.0, 0.0);
    wall(0.02); // wall #3: in xy-plane
    glPopMatrix();
    glutSwapBuffers();
}
/////////////////////////////passiveMouse/////////////////////////////////
void passiveMouse(int x, int y)
{
    X = x;
    Y = 480 - y;
    glutPostRedisplay();
}
//<<<<<<<<<<<<<<<<<<<<<< main >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
void main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(640, 480);
    glutInitWindowPosition(100, 100);
    glutCreateWindow("shaded example - 3D scene");
    glutDisplayFunc(displaySolid);

    glEnable(GL_LIGHTING); // enable the light source
    glEnable(GL_LIGHT0);
    glShadeModel(GL_SMOOTH);
    glEnable(GL_DEPTH_TEST); // for hidden surface removal
    glEnable(GL_NORMALIZE); // normalize vectors for proper shading

    glClearColor(0.1f, 0.1f, 0.1f, 0.0f); // background is light gray
    glViewport(0, 0, 640, 480);
    glutPassiveMotionFunc(passiveMouse);
    glutMainLoop();
}

3.运行截图

时间: 2024-08-29 09:55:16

OpenGL编程 基础篇(七)对象的变换——用实心体绘制3D场景的相关文章

OpenGL编程 基础篇(五)世界窗口和视口

一.基本定义 世界窗口:在世界坐标系中定义一个对齐的矩形(aligned rectangle,即矩阵的边与坐标轴平行)的窗口,这个世界窗口外的部分被裁减并不被绘制.OpenGL会自动地做剪裁. 视口:在显示器的屏幕窗口上定义一个对齐的矩形的视口,OpenGL会自动建立世界窗口和视口的变换(包括缩放和平移).当世界窗口中所有对象都被绘制时,对象在世界窗 口中的部分会被自动地映射到视口中----换句话说,被映射到屏幕坐标中,即像素在显示器上的坐标. 二.相关函数介绍 1.对于二维绘图来说,世界窗口由

OpenGL编程 基础篇(六)OpenGL中几种光照参数

一.定义 1.GL_AMBIENT:环境光,经过很多次反射后最终遗留在环境中的光线强度(颜色). 2.GL_DIFFUSE:漫反射,表示光线照射到该材质上,经过漫反射后形成的光线强度(颜色). 3.GL_SPECULAR:镜面反射,表示光线照射到该材质上,经过镜面反射后形成的光线强度(颜色). 注:通常,GL_AMBIENT和GL_DIFFUSE都取相同的值,可以达到比较真实的效果.使用GL_AMBIENT_AND_DIFFUSE可以同时设置GL_AMBIENT和GL_DIFFUSE属性. 4.

OpenGL编程 基础篇(四)与鼠标的交互

当用户按下或释放鼠标按钮.按下按钮时移动鼠标或按下和松开键盘按键时,就会产生一个相关事件.程序员可以用每类事件注册一个回调函数,例如使用如下函数: glutMouseFunc(myMouse):利用按下或释放鼠标按钮时发生的事件来注册myMouse glutMotionFunc(myMovedMouse):利用按下按钮同时移动鼠标的事件来注册myMovedMouse glutKeyboardFunc(myKeyboard):利用按下和松开键盘按键的事件来注册myKeyboard 1.用鼠标交互

Java多线程编程基础之线程对象

在进入java平台的线程对象之前,基于基础篇(一)的一些问题,我先插入两个基本概念. [线程的并发与并行] 在单CPU系统中,系统调度在某一时刻只能让一个线程运行,虽然这种调试机制有多种形式(大多数是时间片轮巡为主),但无论如何,要通过不断切换需要运行的线程让其运行的方式就叫并发(concurrent).而在多CPU系统中,可以让两个以上的线程同时运行,这种可以同时让两个以上线程同时运行的方式叫做并行(parallel). 在上面包括以后的所有论述中,请各位朋友谅解,我无法用最准确的词语来定义储

黑马程序员——Java基础篇之对象归要

1.static关键字 1.1.static可以修饰成员变量,成员方法,还有类(其中这里的类是内部类) 1.2.static修饰的部分会随着类的加载而加载: 加载过程:当JVM执行static修饰的代码时,会在内存的共享区给static部分开辟一个空间,供该类持有,static部分不是某个对象的部分,而是该类共有的,所以当一个函数会被多个对象调用时,最好定义成static,这样比较节省空间. 1.3.静态方法只能访问静态成员 原因:如果静态方法中调用了非静态的变量,那么由于静态方法是随着类的加载

Linux中的shell脚本编程——基础篇

概述: shell脚本在Linux系统管理员的运维工作中非常重要.shell脚本能够帮助我们很方便的管理服务器,因为我们可以指定一个任务计划,定时的去执行某一个脚本以满足我们的需求.本篇将从编程基础.脚本基本格式.变量.运算.条件测试这几个方面详细介绍shell脚本编程的基础内容,也是我们必须要掌握熟练的内容. 一.编程环境 1.程序:指令+数据 程序编程的风格有两种: 过程式:以指令为中心,数据服务与指令 对象式:以数据为中心,指令服务于数据 2.程序的执行方式: □计算机:只能识别二进制文件

shell 脚本编程基础篇

一级标题 二级标题 1.编程基础 Linus:Talk is cheap, show me the code 程序组成 程序:算法+数据结构 数据:是程序的核心 算法:处理数据的方式 数据结构:数据在计算机中的类型和组织方式 面向过程语言 做一件事情,排出个步骤,第一步干什么,第二步干什么,如果出现情况A,做什么处理,如 果出现了情况B,做什么处理 问题规模小,可以步骤化,按部就班处理 以指令为中心,数据服务于指令 C,shell 面向对象语言 一种认识世界.分析世界的方法论.将万事万物抽象为各

windows编程基础之内核对象

      学好windows编程,理解内核对象还是至关重要的(●'?'●).闲话不多说,下面先来了解一下关于内核对象的知识:       内核对象(kernel object):内核对象是用于管理进程.线程和文件等诸多种类的大量资源.       内核对象的分类:进程对象,线程对象,互斥量(mutex)对象,信号量(semaphore)对象,事件对象,作业对象,文件对象,文件映射对象,管道(pipe)对象,邮件槽(mailslot)对象,I/O完成端口对象,线程池工厂(thread pool 

Python Socket编程基础篇

Socket网络编程 socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,对于文件用打开.读写.关闭模式来操作.socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO.打开.关闭) socket和file的区别: file模块是针对某个指定