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

Posted 肉松松鼠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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();
}
View Code

3.运行截图

 

以上是关于OpenGL编程 基础篇对象的变换——用实心体绘制3D场景的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL基础篇——使用面向对象方法封装OpenGL函数

在 OpenGL 中绘制一个实心立方体

OpenGL学习——绘制三角形

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

shader编程-二维空间中使用矩阵实现物体的旋转缩放平移变换(WebGL-Shader开发基础03)

shader编程-二维空间中使用矩阵实现物体的旋转缩放平移变换(WebGL-Shader开发基础03)