Drawing 3D geometric primitives

In this recipe, we will learn how to draw the following 3D geometric shapes:

  • Cube
  • Sphere
  • Line
  • Torus
  • Cylinder

Getting ready

Include the necessary header to draw in OpenGL using Cinder commands and statements. Add the following code to the top of your source file:

#include "cinder/gl/gl.h"
#include "cinder/Camera.h"

using namespace ci;

How to do it…

We will create several geometric primitives using Cinder's methods for drawing in 3D.

  1. Declare the member variables with information of our primitives:
    Vec3f mCubePos, mCubeSize;
    Vec3f mSphereCenter;
    float mSphereRadius; 
    Vec3f mLineBegin, mLineEnd; 
    Vec3f mTorusPos;
    float mTorusOuterRadius, mTorusInnerRadius; 
    Vec3f mCylinderPos;
    float mCylinderBaseRadius, mCylinderTopRadius, mCylinderHeight;
  2. Initialize the member variables with the position and sizes of the geometry. Add the following code in the setup method:
    mCubePos = Vec3f( 100.0f, 300.0f, 100.0f );
    mCubeSize = Vec3f( 100.0f, 100.0f, 100.0f );
    
    mSphereCenter = Vec3f( 500, 250, 0.0f );
    mSphereRadius = 100.0f;
    
    mLineBegin = Vec3f( 200, 0, 200 );
    mLineEnd = Vec3f( 500, 500, -200 );
    
    mTorusPos = Vec3f( 300.0f, 100.0f, 0.0f );
    mTorusOuterRadius = 100.0f;
    mTorusInnerRadius = 20.0f;
    
    mCylinderPos = Vec3f( 500.0f, 0.0f, -200.0f );
    mCylinderBaseRadius = 50.0f;
    mCylinderTopRadius = 80.0f;
    mCylinderHeight = 100.0f;
  3. Before we draw the shapes, let's also create a camera to rotate around our shapes to give us a better sense of perspective. Declare a ci::CameraPersp object:
    CameraPerspmCamera;
  4. Initialize it in the setup method:
    mCamera = CameraPersp( getWindowWidth(), getWindowHeight(), 60.0f );
  5. In the update method, we will make the camera rotate around our scene. Add the following code in the update method:
    Vec2f windowCenter = getWindowCenter();
    floatcameraAngle = getElapsedSeconds();
    floatcameraDist = 450.0f;
    float x = sinf( cameraAngle ) * cameraDist + windowCenter.x;
    float z = cosf( cameraAngle ) * cameraDist;
    mCamera.setEyePoint( Vec3f( x, windowCenter.y, z ) );
    mCamera.lookAt( Vec3f( windowCenter.x, windowCenter.y, 0.0f ) );
  6. In the draw method, we will clear the background with black and use mCamera to define the window's matrices. We will also enable OpenGL to read and write to the depth buffers. Add the following code in the draw method:
      gl::clear( Color::black() ); 
      gl::setMatrices( mCamera );
      gl::enableDepthRead();
      gl::enableDepthWrite();
  7. Cinder allows you to draw filled and stroked cubes, so let's draw a cube with a white fill and black stroke:
    gl::color( Color::white() );
    gl::drawCube( mCubePos, mCubeSize );
    gl::color( Color::black() );
    gl::drawStrokedCube( mCubePos, mCubeSize );
  8. Let's define the drawing color again as white, and draw a sphere with mSphereCenter and mSphereRadius as the sphere's position and radius, and the number of segments as 30.
    gl::color( Color::white() );
    gl::drawSphere( mSphereCenter, mSphereRadius, 30 );
  9. Draw a line that begins at mLineBegin and ends at mLineEnd:
    gl::drawLine( mLineBegin, mLineEnd );
  10. Cinder draws a Torus at the coordinates of the origin [0,0]. So, we will have to translate it to the desired position at mTorusPos. We will be using mTorusOuterRadius and mTorusInnerRadius to define the shape's inner and outer sizes:
    gl::pushMatrices();
    gl::translate( mTorusPos );
    gl::drawTorus( mTorusOutterRadius, mTorusInnerRadius );
    gl::popMatrices();
  11. Finally, Cinder will draw a cylinder at the origin [0,0], so we will have to translate it to the position defined in mCylinderPosition. We will also be using mCylinderBaseRadius and mCylinderTopRadius, to set the cylinder's bottom and top sizes and mCylinderHeight, to set its height:
    gl::pushMatrices();
    gl::translate( mCylinderPos );
    gl::drawCylinder( mCylinderBaseRadius, mCylinderTopRadius, mCylinderHeight );
    gl::popMatrices();
    How to do it…

How it works…

Cinder's drawing methods use OpenGL calls internally to provide fast and easy drawing routines.

The method ci::gl::color sets the drawing color so that all shapes will be drawn with that color until another color is set by calling ci::gl::color again.

See also

To learn more about OpenGL transformations such as translation, scale, and rotation, please read the recipe Rotating, scaling, and translating.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.125.205