CREATING OUR FIRST OBJECTS

 Our previous blog was about primitive types with opengl, however the time has come to draw objects. The logic about functions and the code structure is same but, the implementation of course will differ to draw objects such as disk, cylinder, torus etc. Let me to give you the our first lines of code even it is he same:

#include <GLTools.h>	// OpenGL toolkit
#include <GLMatrixStack.h>
#include <GLFrame.h>
#include <GLFrustum.h>
#include <GLBatch.h>
#include <GLGeometryTransform.h>

#include <math.h>
#ifdef __APPLE__
#include <glut/glut.h>
#else
#define FREEGLUT_STATIC
#include <GL/glut.h>
#endif

// An assortment of needed classes
GLShaderManager	shaderManager;
GLMatrixStack		modelViewMatrix;
GLMatrixStack		projectionMatrix;
GLFrame		     cameraFrame;
GLFrame             objectFrame;
GLFrustum		     viewFrustum;

GLTriangleBatch     sphereBatch;
GLTriangleBatch     torusBatch;
GLTriangleBatch     cylinderBatch;
GLTriangleBatch     coneBatch;
GLTriangleBatch     diskBatch;


GLGeometryTransform	transformPipeline;
M3DMatrix44f		shadowMatrix;

void SetupRC();
void DrawWireFramedBatch(GLTriangleBatch* pBatch);
void RenderScene(void);
void SpecialKeys(int key, int x, int y);
void KeyPressFunc(unsigned char key, int x, int y);
void ChangeSize(int w, int h);

GLfloat vGreen[] = { 0.0f, 1.0f, 0.0f, 1.0f };
GLfloat vBlack[] = { 0.0f, 0.0f, 0.0f, 1.0f };


// Keep track of effects step
int nStep = 0;
// This function does any needed initialization on the rendering context. 
// This is the first opportunity to do any OpenGL related tasks.
void SetupRC()
	{
    // Gray background
    glClearColor(0.7f, 0.7f, 0.7f, 1.0f );
	shaderManager.InitializeStockShaders();
	glEnable(GL_DEPTH_TEST);
	transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix);
	cameraFrame.MoveForward(-15.0f);
    // Sphere
    gltMakeSphere(sphereBatch, 3.0, 10, 20);
    // Torus
    gltMakeTorus(torusBatch, 3.0f, 0.75f, 15, 15);

A hollow cylinder is made with the function gltMakeCylinder.

void gltMakeCylinder(GLTriangleBatch& cylinderBatch, GLfloat baseRadius, 
                     GLfloat topRadius, GLfloat fLength, GLint numSlices, GLint numStacks);

Cylinders grow up the positive z-axis from zero, and you can specify both the base and top radius. Figure 4.19 shows a cylinder with two equal radii, and Figure 4.20 shows one with one end set to zero. This essentially makes a cone, but you could just as easily make a funnel shape as well. The numSlices parameter is the number of triangle pairs that circle the z-axis, and the numStacks parameter is the number of rings stacked from the bottom to the top of the cylinder.

    // Cylinder
    gltMakeCylinder(cylinderBatch, 2.0f, 2.0f, 3.0f, 13, 2);
    // Cone
    gltMakeCylinder(coneBatch, 2.0f, 0.0f, 3.0f, 13, 2);

Our final surface is the disk. Disks are drawn with loops of triangle bands divided into some number of slices. You can specify an inner radius for a washer type shape or leave it zero to make the disk solid. The gltMakeDisk function, with a by now familiar looking API does the work of filling a GLTriangleBatch with the disk shape.

void gltMakeDisk(GLTriangleBatch& diskBatch, GLfloat innerRadius, 
                 GLfloat outerRadius, GLint nSlices, GLint nStacks);
    // Disk
    gltMakeDisk(diskBatch, 1.5f, 3.0f, 13, 3);
    } //we are ending thr setupRC

Now the remained logic same as the previous blog as i mentioned before. however i will write the code anyway. At the end you will see the output objects and the downloadable souce code.

void DrawWireFramedBatch(GLTriangleBatch* pBatch)
    {
    shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vGreen);
    pBatch->Draw();
    // Draw black outline
    glPolygonOffset(-1.0f, -1.0f);
    glEnable(GL_LINE_SMOOTH);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_POLYGON_OFFSET_LINE);
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    glLineWidth(2.5f);
    shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vBlack);
    pBatch->Draw();
    
    // Restore polygon mode and depht testing
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    glDisable(GL_POLYGON_OFFSET_LINE);
    glLineWidth(1.0f);
    glDisable(GL_BLEND);
    glDisable(GL_LINE_SMOOTH);
    }

// Called to draw scene
void RenderScene(void)
	{    
	// Clear the window with current clearing color
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

	modelViewMatrix.PushMatrix();
		M3DMatrix44f mCamera;
		cameraFrame.GetCameraMatrix(mCamera);
		modelViewMatrix.MultMatrix(mCamera);

        M3DMatrix44f mObjectFrame;
        objectFrame.GetMatrix(mObjectFrame);
        modelViewMatrix.MultMatrix(mObjectFrame);
        shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vBlack);
        switch(nStep) {
            case 0:
                DrawWireFramedBatch(&sphereBatch);
                break;
            case 1:
                DrawWireFramedBatch(&torusBatch);
                break;
            case 2:
                DrawWireFramedBatch(&cylinderBatch);
                break;
            case 3:
                DrawWireFramedBatch(&coneBatch);
                break;
            case 4:
                DrawWireFramedBatch(&diskBatch);
                break;
            }	
	modelViewMatrix.PopMatrix();
	// Flush drawing commands
	glutSwapBuffers();
    }

// Respond to arrow keys by moving the camera frame of reference
void SpecialKeys(int key, int x, int y)
    {
	if(key == GLUT_KEY_UP)
		objectFrame.RotateWorld(m3dDegToRad(-5.0f), 1.0f, 0.0f, 0.0f);   
	if(key == GLUT_KEY_DOWN)
		objectFrame.RotateWorld(m3dDegToRad(5.0f), 1.0f, 0.0f, 0.0f);	
	if(key == GLUT_KEY_LEFT)
		objectFrame.RotateWorld(m3dDegToRad(-5.0f), 0.0f, 1.0f, 0.0f);    
	if(key == GLUT_KEY_RIGHT)
		objectFrame.RotateWorld(m3dDegToRad(5.0f), 0.0f, 1.0f, 0.0f);    
	glutPostRedisplay();
    }
///////////////////////////////////////////////////////////////////////////////
// A normal ASCII key has been pressed.
// In this case, advance the scene when the space bar is pressed
void KeyPressFunc(unsigned char key, int x, int y)
	{
	if(key == 32) {
		nStep++;
		if(nStep > 4)
			nStep = 0;
		}      
    switch(nStep)
        {
        case 0: 
            glutSetWindowTitle("Sphere");
            break;
        case 1:
            glutSetWindowTitle("Torus");
            break;
        case 2:
            glutSetWindowTitle("Cylinder");
            break;
        case 3:
            glutSetWindowTitle("Cone");
            break;
        case 4:
            glutSetWindowTitle("Disk");
            break;
        }               
    glutPostRedisplay();
	}

///////////////////////////////////////////////////////////////////////////////
// Window has changed size, or has just been created. In either case, we need
// to use the window dimensions to set the viewport and the projection matrix.
void ChangeSize(int w, int h)
	{
	glViewport(0, 0, w, h);
	viewFrustum.SetPerspective(35.0f, float(w) / float(h), 1.0f, 500.0f);
	projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());
	modelViewMatrix.LoadIdentity();
	}

///////////////////////////////////////////////////////////////////////////////
// Main entry point for GLUT based programs
int main(int argc, char* argv[])
	{
	gltSetWorkingDirectory(argv[0]);
	
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
	glutInitWindowSize(800, 600);
	glutCreateWindow("Sphere");
    glutReshapeFunc(ChangeSize);
    glutKeyboardFunc(KeyPressFunc);
    glutSpecialFunc(SpecialKeys);
    glutDisplayFunc(RenderScene);
        
	GLenum err = glewInit();
	if (GLEW_OK != err) {
		fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
		return 1;
		}	
	SetupRC();
	glutMainLoop();
	return 0;
	}

Reklamlar

Bir Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Twitter resmi

Twitter hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Google+ fotoğrafı

Google+ hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Connecting to %s