anjali 's cg report wit code

56
NITTE MEENAKSHI INSTITUTE OF TECHNOLOGY DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING (AN AUTONOMOUS INSTITUTION AFFILIATED TO V.T.U(BELGAUM)) YELAHANKA,BANGALORE-560 064 PROJECT ON SIMULATION OF SHADOW FUN USING OpenGL IN COMPUTER GRAPHICS SUBMITTED BY ANJALI BANSAL

Upload: kiran-purushotaman

Post on 09-Nov-2014

113 views

Category:

Documents


4 download

DESCRIPTION

cg

TRANSCRIPT

Page 1: Anjali 's CG REPORT Wit Code

NITTE MEENAKSHI INSTITUTE OF TECHNOLOGY

DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING(AN AUTONOMOUS INSTITUTION AFFILIATED TO V.T.U(BELGAUM))

YELAHANKA,BANGALORE-560 064

PROJECT ON

SIMULATION OF SHADOW FUN USING OpenGL IN COMPUTER GRAPHICS

SUBMITTED BY

ANJALI BANSAL -(INT08CS016)

BHAKTHI VISHWANATH -(INTO8CS028)

Page 2: Anjali 's CG REPORT Wit Code

Shadow Fun

NITTE MEENAKSHI INSTITUTE OF TECHNOLOGY

DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING(AN AUTONOMOUS INSTITUTION AFFILIATED TO V.T.U(BELGAUM))

YELAHANKA,BANGALORE-560 064

CERTIFICATE

This is to certify that the MINI PROJECT report entitled,”Simulation of shadow fun in OpenGL” has been successfully completed by Anjali bansal (INT08CS016) and Bhakthi vishwanath(INT08CS028) in partial fulfillment for VI semester in CS&E under the guidance and supervision of Mrs.Nirmala and Mrs.Chaitra during the year 2011

STAFF IN_CHARGE

1…………………………… 2…………………………Mrs.Nirmala Mrs.Chaitra ………………………………. HOD of Dept. of CS&E Dr.Nalini N

EXAMINERS: 1…………………………. 2…………………………

Department Of CSE Page | 2

Page 3: Anjali 's CG REPORT Wit Code

Shadow Fun

ABSTRACT

This project is a simulation of Shadow Fun using OpenGL in computer graphics. Here, we make use of Top Down approach. The users can make use of this simulation in knowing many important facts such as the planetary motion, rotation and revolution of the planets and the Sun, etc.

OpenGL (Open Graphics Library) is a standard specification defining a cross-language, cross-platform API for writing applications that produce 2D and 3D computer graphics, describing a set of functions and the precise behaviors that they must perform.

Our mini project titled “Shadow Fun” in Computer Graphics is implemented using OpenGL. This project would enable users to witness the simulation of shadow fun using a Computer System. The users can zoom in on the objects. With all these maneuver abilities, one can use this for education purpose or could be compiled into a Computer screen saver.

ACKNOWLEDGEMENT

Department Of CSE Page | 3

Page 4: Anjali 's CG REPORT Wit Code

Shadow Fun

\

The satisfaction and euphoria that accompany the successful completion of any task

would be but incomplete without mention of the people who made it possible, whose

constant guidance and encouragement crowned our efforts with success.

We consider ourselves proud, to be part of NMIT family, the institution which stood by

our way in all our endeavors.

It gives us immense pleasure in expressing our gratitude to our guides Mrs.Nirmala

and Mrs.Chaitra,department of CS&E,for their valuable advice,timely

suggestions,encouragement and guidance throughout the course of this project.

We wish to thank our Head of the Department, Mrs.Nalini N for her magnanimous

benignity and benevolence.We humbly convey our thankfulness to Prof.Nagaraj,

Principal,NMIT,Bangalore for providing us an opportunity to carry out this project.

CONTENTS

Department Of CSE Page | 4

Page 5: Anjali 's CG REPORT Wit Code

Shadow Fun

1.INTRODUCTION

This

project is a simulation of Shadow Fun using OpenGL in computer graphics. Here, we make use of Top Down approach. The users can make use of this simulation in knowing many important facts such as the planetary motion, rotation and revolution of the planets and the Sun, etc. OpenGL (Open Graphics Library) is a standard specification defining a cross-language, cross-platform API for writing applications that produce 2D and 3D computer graphics, describing a set of functions and the precise behaviors that they must perform. Top Down approach refers to the programming-oriented approach to computer grachics.

Department Of CSE Page | 5

1.Introduction

-1.1 Flow diagram 6

2.Literature survey

-2.1 Scope

-2.2 Requirement specification

-2.3 System requirements

7

7

8

3.Design

-3.1 Function description

-3.2 Flow diagram

-3.3 System implementation

-3.4 Source code

-3.5 System testing

10

11

12

12-38

38

4.Result

-4.1 Screen shots 39-41

5.Conclusion 42

6.Bibliography

-6.1 Texts

-6.2 Links

43

43

Page 6: Anjali 's CG REPORT Wit Code

Shadow Fun

1.1Flow Diagram

Start Calls

Draws

Adds Returns data

Right-click

Quit

2.LITERATURE SURVEY

2.1 SCOPE:Our mini project titled “Shadow Fun” in Computer Graphics is implemented using OpenGL. This project would enable users to witness the simulation of shadow fun using a Computer System. The users can zoom in on the objects. With all these maneuver abilities, one can use this for education purpose or could be compiled into a Computer screen saver.

2.2 REQUIREMENT SPECIFICATIONS:

2.2.1 Details of the Software

Department Of CSE Page | 6

MAIN( ) INITSCENE( ) DISPLAY

SCENE LIGHTING

MENU

EXIT

Page 7: Anjali 's CG REPORT Wit Code

Shadow Fun

Here, the coding of our project is done in Microsoft Visual C++ which is a commercial integrated development environment (IDE) with OpenGL (Open Graphics Library) which is a standard specification to produce 2D and 3D computer graphics. We use, the OpenGL Utility Toolkit called GLUT which is a library of utilities for OpenGL programs

2.2.2 Microsoft Visual C++

Microsoft Visual C++ is a commercial integrated development environment (IDE) product engineered by Microsoft for the C, C++ and C++/CLI programming languages. It has tools for developing and debugging C++ code, especially code written for the Microsoft Windows API, OpenGL API, the DirectX API and the Microsoft .NET Framework.

2.2.3 OpenGL and GLUT

OpenGL (Open Graphics Library) is a standard specification defining a cross-language, cross-platform API for writing applications that produce 2D and 3D computer graphics, describing a set of functions and the precise behaviors that they must perform. From this specification, hardware vendors create implementations - libraries of functions created to match the functions stated in the OpenGL specification, making use of hardware acceleration where possible. Hardware vendors have to meet specific tests to be able to qualify their implementation as an OpenGL implementation. GLUT is the OpenGL Utility Toolkit, a window system independent toolkit for writing OpenGL programs. It implements a simple windowing application programming interface (API) for OpenGL. GLUT makes it considerably easier to learn about and explore OpenGL programming. GLUT provides a portable API so you can write a single OpenGL program that works across all PC and workstation OS platforms.

2.3 SYSTEM REQUIREMENTS: 2.3.1 Hardware Configuration

A computer system with the following minimum requirements: 1 GHz or faster 32-bit(x86) or 64-bit(x64) processor 512 MB RAM 20MB available disk space DirectX 9 graphics processor (optional)

2.3.2 Software Configuration

A computer system with the following minimum software installed: Microsoft Visual C++ 6.0 or above installed with any of its variants i.e., Express

Edition or Professional Edition

Department Of CSE Page | 7

Page 8: Anjali 's CG REPORT Wit Code

Shadow Fun

GLUT API version 3 or above

3. SYSTEM DESIGN

The system is divided into different modules in terms of functions such as Sphere( ), Cone( ), generateshadowvolume( ), Menu( ), rendershadow( ), Scene( ). Menu are subdivided into 6 functions, each representing different planets of the solar system as shown in the following diagram

Department Of CSE Page | 8

Shadow Fun

Page 9: Anjali 's CG REPORT Wit Code

Shadow Fun

3.1 FUNCTION DESCRIPTION:

Sphere( ): To draw a 3d sphere.

Cone( ): To draw a 3d cone.

Scene( ): Here the objects which are created are placed inside an closed room which has grey textured walls and checker board texture for the floor.

Render shadow( ): It s used to enable the shadows and its also used to disable the shadow and lighting.

Department Of CSE Page | 9

Sphere Cone GenerateShadow volume Menu

Render Shadow

Scene

Object Shape

Viewpoint Render mode Action Step Rotate

Page 10: Anjali 's CG REPORT Wit Code

Shadow Fun

Main( ): When user clicks the right mouse button a menu pops out on the screen showing the different option available to implement on the objects present in the scene .The content inside the menu are.

Shape Viewing option Action Shadow render

Menu( ): The above mentioned option have been divided into submenus which are called in this function.

Idle( ):This function is used to continue it’s given operation until another operation is selected by the user.

Key( ):In this function we are using keyboard to stop n start the motions in the scene and to change the light source position. The keys used to do certain functions are:

Arrow keys :To move the light source position in the scene. Space:To stop the movements in the scene. Enter:To stop the light source.

3.2 FLOW DIAGRAM:

Start Calls

Draws

Adds Returns data

Department Of CSE Page | 10

MAIN( ) INITSCENE( ) DISPLAY

SCENE LIGHTING

Page 11: Anjali 's CG REPORT Wit Code

Shadow Fun

Right-click

Quit

3.3 SYSTEM IMPLEMENTATIONS:

glutInit(int *argcv, char **argv); The two arguments allow the user to pass command-line arguments.

glutCreateWindow(char *title); This function is used to give the title to the window.

glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); This function is used to initialize a window of size 640x480

void glutDisplayFunc(void (*func)(void)); This function sends the graphics to the screen.

void glutKeyboardFunc(void (*func) (unsigned char key, int x, int y));

Department Of CSE Page | 11

MENU

EXIT

Page 12: Anjali 's CG REPORT Wit Code

Shadow Fun

Parameters: func - The name of the function that will process the "normal" keyboard

events. Passing NULL as an argument causes GLUT to ignore "normal" keys.

key - indicates the ASCII code of the key pressed

glutAddMenuEntry- This function adds an entry into the menu.

glutCreateMenu- This function will create a new menu.

glutAddSubMenu- This function will add a submenu into the existing menu to have more options.

3.4 SORCE CODE

#include <assert.h>#include <stdio.h>#include <stdlib.h>#include <math.h>#include <GL/glut.h>

#ifdef GLU_VERSION_1_2

#ifndef CALLBACK#define CALLBACK#endif

#ifndef M_PI#define M_PI 3.14159265#endif

const float uniquePassThroughValue = 34567.0;

#define SmallerOf(a,b) ((a) < (b) ? (a) : (b))

int stencilBits;

enum { DL_BALL = 1, DL_CONE, DL_LIGHT, DL_SHADOW_VOLUME, DL_SPHERE,

Department Of CSE Page | 12

Page 13: Anjali 's CG REPORT Wit Code

Shadow Fun

DL_ICO, DL_TORUS, DL_CUBE, DL_SHADOW_VOLUME_TOP, DL_BASE_SHADOW_VOLUME};enum { M_TORUS, M_CUBE, M_SPHERE, M_ICO, M_DOUBLE_TORUS, M_ANGLE, M_BOUNDARY,M_NO_SHADOW, M_NO_LIGHT, M_FRONT_VOLUME, M_BACK_VOLUME, M_SHADOW,M_LIGHT_SOURCE_VIEW, M_NORMAL_VIEW, M_SPIN, M_SWING, M_STOP};

enum { X, Y, Z};

const int TEXDIM = 64;

int shape;GLfloat maxRadius;int renderMode = M_SHADOW;int view = M_NORMAL_VIEW;int renderBoundary = 0;GLfloat angle = 0.0;int frontFace = 1;int rotatingObject = 1;int swingingLight = 1;float swingTime = M_PI / 2.0;

GLfloat lightDiffuse[4] ={1.0, 0.0, 0.0, 1.0};GLfloat lightPos[4] ={60.0, 50.0, -350.0, 1.0};GLfloat objectPos[4] ={40.0, 30.0, -360.0, 1.0};GLfloat sceneEyePos[4] ={0.0, 0.0, 0.0, 0.0};

struct VertexHolder { struct VertexHolder *next; GLfloat v[2];};

Department Of CSE Page | 13

Page 14: Anjali 's CG REPORT Wit Code

Shadow Fun

typedef struct _ShadowVolumeMemoryPool { int refcnt;

GLUtesselator *tess; GLfloat viewScale; GLfloat *combineList; int combineListSize; int combineNext; struct VertexHolder *excessList;} ShadowVolumeMemoryPool;

typedef struct _ShadowVolumeState { ShadowVolumeMemoryPool *pool; GLfloat shadowProjectionDistance; GLfloat extentScale; int saveFirst; GLfloat *firstVertex;} ShadowVolumeState;

ShadowVolumeState *svs;static void CALLBACKbegin(GLenum type, void *shadowVolumeState){ ShadowVolumeState *svs = (ShadowVolumeState *) shadowVolumeState; assert(type == GL_LINE_LOOP); if (renderBoundary) { glBegin(type); } else { svs->saveFirst = 1; glBegin(GL_TRIANGLE_FAN); glColor3f(0, 1, 0); glVertex3f(0.0, 0.0, 0.0); }}

static void CALLBACKvertex(void *data, void *shadowVolumeState){ ShadowVolumeState *svs = (ShadowVolumeState *) shadowVolumeState; GLfloat *v = data;

if (renderBoundary) {

Department Of CSE Page | 14

Page 15: Anjali 's CG REPORT Wit Code

Shadow Fun

glVertex2fv(v); } else { if (svs->saveFirst) { svs->firstVertex = v; svs->saveFirst = 0; } glColor3f(0, 0, 1); glVertex3f(svs->extentScale * v[X], svs->extentScale * v[Y], svs->shadowProjectionDistance); }}

static void CALLBACKend(void *shadowVolumeState){ShadowVolumeState *svs = (ShadowVolumeState *) shadowVolumeState;if (!renderBoundary) {glColor3f(0, 0, 1);glVertex3f(svs->extentScale * svs->firstVertex[X], svs->extentScale * svs>firstVertex[Y], svs->shadowProjectionDistance); } glEnd();}

static voidfreeExcessList(ShadowVolumeMemoryPool * pool){ struct VertexHolder *holder, *next;

holder = pool->excessList; while (holder) { next = holder->next; free(holder); holder = next; } pool->excessList = NULL;}static void CALLBACKcombine(GLdouble coords[3], void *d[4], GLfloat w[4], void **dataOut, void *shadowVolumeState){ ShadowVolumeState *svs = (ShadowVolumeState *) shadowVolumeState;

Department Of CSE Page | 15

Page 16: Anjali 's CG REPORT Wit Code

Shadow Fun

ShadowVolumeMemoryPool *pool = svs->pool; struct VertexHolder *holder; GLfloat *new;

if (pool->combineNext >= pool->combineListSize) { holder = (struct VertexHolder *) malloc(sizeof(struct VertexHolder)); holder->next = pool->excessList; pool->excessList = holder; new = holder->v; } else { new = &pool->combineList[pool->combineNext * 2]; } new[0] = coords[0]; new[1] = coords[1]; *dataOut = new; pool->combineNext++;}static void CALLBACKerror(GLenum errno){ printf("ERROR: %s\n", gluErrorString(errno));}static voidprocessFeedback(GLint size, GLfloat * buffer, ShadowVolumeState * svs){ ShadowVolumeMemoryPool *pool = svs->pool; GLfloat *loc, *end, *eyeLoc; GLdouble v[3]; int token, nvertices, i; GLfloat passThroughToken; int watchingForEyePos; if (pool->combineNext > pool->combineListSize) { freeExcessList(pool); pool->combineListSize = pool->combineNext; pool->combineList = realloc(pool->combineList, sizeof(GLfloat) * 2 * pool>combineListSize); } pool->combineNext = 0; watchingForEyePos = 0; eyeLoc = NULL; glColor3f(1, 1, 1); gluTessBeginPolygon(pool->tess, svs); loc = buffer;

Department Of CSE Page | 16

Page 17: Anjali 's CG REPORT Wit Code

Shadow Fun

end = buffer + size; while (loc < end) { token = *loc; loc++; switch (token) { case GL_POLYGON_TOKEN: nvertices = *loc; loc++; assert(nvertices >= 3); gluTessBeginContour(pool->tess); for (i = 0; i < nvertices; i++) { v[0] = loc[0]; v[1] = loc[1]; v[2] = 0.0; gluTessVertex(pool->tess, v, loc); loc += 2; } gluTessEndContour(pool->tess); break; case GL_PASS_THROUGH_TOKEN: passThroughToken = *loc; if (passThroughToken == uniquePassThroughValue) { watchingForEyePos = !watchingForEyePos; } else { /* Ignore everything else. */ fprintf(stderr, "ERROR: Unexpected feedback token 0x%x (%d).\n", token, token); } loc++; break; case GL_POINT_TOKEN:if (watchingForEyePos) { fprintf(stderr, "WARNING: Eye point possibly within the shadow volume.\n")fprintf(stderr, " Program should be improved to handle this.\n");eyeLoc = loc; watchingForEyePos = 0; } else { fprintf(stderr, "ERROR: Unexpected feedback token 0x%x (%d).\n", token, token); } loc += 2;

Department Of CSE Page | 17

Page 18: Anjali 's CG REPORT Wit Code

Shadow Fun

break; default: fprintf(stderr, "ERROR: Unexpected feedback token 0x%x (%d).\n", token, token); } } gluTessEndPolygon(pool->tess); if (eyeLoc && renderBoundary) { glColor3f(0, 1, 0); glPointSize(7.0); glBegin(GL_POINTS); glVertex2fv(eyeLoc); glEnd(); }}static GLfloatvdot(const GLfloat * v1, const GLfloat * v2){ return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]; }static voidvcross(const GLfloat * v1, const GLfloat * v2, GLfloat * cross){ assert(v1 != cross && v2 != cross); cross[0] = (v1[1] * v2[2]) - (v1[2] * v2[1]); cross[1] = (v1[2] * v2[0]) - (v1[0] * v2[2]); cross[2] = (v1[0] * v2[1]) - (v1[1] * v2[0]);}

voidsvsFreeShadowVolumeState(ShadowVolumeState * svs){ if (svs->pool) { svs->pool->refcnt--; if (svs->pool->refcnt == 0) { if (svs->pool->excessList) { freeExcessList(svs->pool); } if (svs->pool->combineList) { free(svs->pool->combineList); } if (svs->pool->tess) { gluDeleteTess(svs->pool->tess);

Department Of CSE Page | 18

Page 19: Anjali 's CG REPORT Wit Code

Shadow Fun

} free(svs->pool); } }free(svs);}ShadowVolumeState *svsCreateShadowVolumeState(GLfloat shadowProjectionDistance, ShadowVolumeState * shareSVS){ ShadowVolumeState *svs; ShadowVolumeMemoryPool *pool; GLUtesselator *tess; svs = (ShadowVolumeState *) malloc(sizeof(ShadowVolumeState)); if (svs == NULL) { return NULL; } svs->pool = NULL; if (shareSVS == NULL) { pool = (ShadowVolumeMemoryPool *) malloc(sizeof(ShadowVolumeMemoryPool)); if (pool == NULL) { svsFreeShadowVolumeState(svs); return NULL; } pool->refcnt = 1; pool->excessList = NULL; pool->combineList = NULL; pool->combineListSize = 0; pool->combineNext = 0; pool->tess = NULL; svs->pool = pool; tess = gluNewTess(); if (tess == NULL) { svsFreeShadowVolumeState(svs); return NULL; } gluTessProperty(tess, GLU_TESS_BOUNDARY_ONLY, GL_TRUE); gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO); gluTessCallback(tess, GLU_TESS_BEGIN_DATA, (void (CALLBACK*)()) begin);

Department Of CSE Page | 19

Page 20: Anjali 's CG REPORT Wit Code

Shadow Fun

gluTessCallback(tess, GLU_TESS_VERTEX_DATA, (void (CALLBACK*)()) vertex); gluTessCallback(tess, GLU_TESS_COMBINE_DATA, (void (CALLBACK*)()) combine); gluTessCallback(tess, GLU_TESS_END_DATA, (void (CALLBACK*)()) end); gluTessCallback(tess, GLU_TESS_ERROR, (void (CALLBACK*)()) error); pool->tess = tess; } else { pool = shareSVS->pool; pool->refcnt++; } svs->pool = pool; svs->shadowProjectionDistance = shadowProjectionDistance;

return svs;}

intsvsGenerateShadowVolume(ShadowVolumeState * svs, void (*renderFunc) (void), int feedbackBufferSizeGuess, GLfloat maxRadius, GLfloat lightPos[3], GLfloat objectPos[3], GLfloat eyePos[3]){ static GLfloat unit[3] = {0.0, 0.0, 1.0}; static GLfloat *feedbackBuffer = NULL; static int bufferSize = 0; GLfloat axis[3], lightDelta[3], eyeDelta[3]; GLfloat nnear, ffar; /* Avoid Intel C keywords. Grumble. */ GLfloat lightDistance, eyeDistance, angle, fieldOfViewRatio, fieldOfViewAngle, topScale, viewScale; GLint returned; if (svs->pool->viewScale == 0.0) { GLfloat maxViewSize[2];

glGetFloatv(GL_MAX_VIEWPORT_DIMS, maxViewSize); printf("max viewport = %gx%g\n", maxViewSize[0], maxViewSize[1]); svs->pool->viewScale = SmallerOf(maxViewSize[0], maxViewSize[1]) / 2.0; }

Department Of CSE Page | 20

Page 21: Anjali 's CG REPORT Wit Code

Shadow Fun

viewScale = svs->pool->viewScale;

if (bufferSize > feedbackBufferSizeGuess) { feedbackBufferSizeGuess = bufferSize; } /* Calculate the light's distance from the object being shadowed. */ lightDelta[X] = objectPos[X] - lightPos[X]; lightDelta[Y] = objectPos[Y] - lightPos[Y]; lightDelta[Z] = objectPos[Z] - lightPos[Z]; lightDistance = sqrt(lightDelta[X] * lightDelta[X] + lightDelta[Y] * lightDelta[Y] + lightDelta[Z] * lightDelta[Z]);

/* Determine the appropriate field of view. We want to use as narrow a field of view as possible to not waste resolution, but not narrower than the object. Add 50% extra slop. */ fieldOfViewRatio = maxRadius / lightDistance; if (fieldOfViewRatio > 0.99) { fprintf(stderr, "WARNING: Clamping FOV to 164 degrees for determining shadow boundary.\n"); fprintf(stderr, " Light distance = %g, object maxmium radius = %g\n", lightDistance, maxRadius);

/* 2*asin(0.99) ~= 164 degrees. */ fieldOfViewRatio = 0.99; } /* Pre-compute scaling factors for the near and far extent of the shadow volume. */ svs->extentScale = svs->shadowProjectionDistance * fieldOfViewRatio / viewScale;

glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity();

nnear = 0.5 * (lightDistance - maxRadius); if (nnear < 0.0001) { fprintf(stderr, "WARNING: Clamping near clip plane to 0.0001 because light source too near.\n"); fprintf(stderr, " Light distance = %g, object maxmium radius = %g\n", lightDistance, maxRadius); nnear = 0.0001; } ffar = 2.0 * (lightDistance + maxRadius);

Department Of CSE Page | 21

Page 22: Anjali 's CG REPORT Wit Code

Shadow Fun

if (eyePos) { eyeDelta[X] = eyePos[X] - lightPos[X]; eyeDelta[Y] = eyePos[Y] - lightPos[Y]; eyeDelta[Z] = eyePos[Z] - lightPos[Z]; eyeDistance = 1.05 * sqrt(eyeDelta[X] * eyeDelta[X] + eyeDelta[Y] * eyeDelta[Y] + eyeDelta[Z] * eyeDelta[Z]); if (eyeDistance > ffar) { ffar = eyeDistance; } } fieldOfViewAngle = 2.0 * asin(fieldOfViewRatio) * 180 / M_PI; gluPerspective(fieldOfViewAngle, 1.0, nnear, ffar);

glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); /* XXX Need to update "up vector". Degenerate when light directly above or below the object. */ gluLookAt(lightPos[X], lightPos[Y], lightPos[Z], objectPos[X], objectPos[Y], objectPos[Z], 0.0, 1.0, 0.0); /* up is in positive Y direction */

glPushAttrib(GL_VIEWPORT_BIT); glViewport(-viewScale, -viewScale, 2 * viewScale, 2 * viewScale);

doFeedback:

/* XXX Careful, some systems still don't understand realloc of NULL. */ if (bufferSize < feedbackBufferSizeGuess) { bufferSize = feedbackBufferSizeGuess; /* XXX Add 32 words of slop (an extra cache line) to end for buggy hardware that uses DMA to return feedback results but that sometimes overrun the buffer. Yuck. */ feedbackBuffer = realloc(feedbackBuffer, bufferSize * sizeof(GLfloat) + 32 * 4); } glFeedbackBuffer(bufferSize, GL_2D, feedbackBuffer);

(void) glRenderMode(GL_FEEDBACK);

(*renderFunc) ();

/* Render the eye position. The eye position is "bracketed" by unique pass

Department Of CSE Page | 22

Page 23: Anjali 's CG REPORT Wit Code

Shadow Fun

through tokens. These bracketing pass through tokens let us determine if the eye position was clipped or not. This helps us determine whether the eye position is possibly within the shadow volume or not. If the point is clipped, the eye position is not in the shadow volume. If the point is not clipped, a more complicated test is necessary to determine if the eye position is really in the shadow volume or not. See processFeedback. */ if (eyePos) { glPassThrough(uniquePassThroughValue); glBegin(GL_POINTS); glVertex3fv(eyePos); glEnd(); glPassThrough(uniquePassThroughValue); } returned = glRenderMode(GL_RENDER);#if 0 if (returned == -1) {#else /* XXX RealityEngine workaround. */ if (returned == -1 || returned == feedbackBufferSizeGuess) {#endif feedbackBufferSizeGuess = feedbackBufferSizeGuess + (feedbackBufferSizeGuess >> 1); goto doFeedback; /* Try again with larger feedback buffer. */ } glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glPopAttrib(); /* Restore viewport. */

if (renderBoundary) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(-viewScale, viewScale, -viewScale, viewScale); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); processFeedback(returned, feedbackBuffer, svs); } else { glNewList(DL_BASE_SHADOW_VOLUME, GL_COMPILE); vcross(unit, lightDelta, axis); angle = acos(vdot(unit, lightDelta) / lightDistance) * 180.0 / M_PI; glRotatef(angle, axis[X], axis[Y], axis[Z]);

Department Of CSE Page | 23

Page 24: Anjali 's CG REPORT Wit Code

Shadow Fun

processFeedback(returned, feedbackBuffer, svs); glEndList();

glNewList(DL_SHADOW_VOLUME, GL_COMPILE); glPushMatrix(); glTranslatef(lightPos[X], lightPos[Y], lightPos[Z]); glCallList(DL_BASE_SHADOW_VOLUME); glPopMatrix(); glEndList();

glNewList(DL_SHADOW_VOLUME_TOP, GL_COMPILE); glPushMatrix(); glTranslatef(lightPos[X], lightPos[Y], lightPos[Z]); topScale = (lightDistance + maxRadius) / svs->shadowProjectionDistance; glScalef(topScale, topScale, topScale); glCallList(DL_BASE_SHADOW_VOLUME); glPopMatrix(); glEndList(); } return returned;}

GLfloat objectMaxRadius[] ={ 8.0 + 2.0, /* M_TORUS */ 12.0 / 2.0 * 1.142, /* M_CUBE */ 8.0, /* M_SPHERE */ 8.0, /* M_ICO */ 8.0 + 2.0, /* M_DOUBLE_TORUS */};

voidrenderShadowingObject(void){ static int torusList = 0, cubeList = 0, sphereList = 0, icoList = 0;

glPushMatrix(); glTranslatef(objectPos[X], objectPos[Y], objectPos[Z]); glRotatef(angle, 1.0, 0.3, 0.0); switch (shape) { case M_TORUS: if (torusList) { glCallList(torusList);

Department Of CSE Page | 24

Page 25: Anjali 's CG REPORT Wit Code

Shadow Fun

} else { torusList = DL_TORUS; glNewList(torusList, GL_COMPILE_AND_EXECUTE); glutSolidTorus(2.0, 8.0, 8, 15); glEndList(); } break; case M_CUBE: if (cubeList) { glCallList(cubeList); } else { cubeList = DL_CUBE; glNewList(cubeList, GL_COMPILE_AND_EXECUTE); glutSolidCube(12.0); glEndList(); } break; case M_SPHERE: if (sphereList) { glCallList(sphereList); } else { sphereList = DL_SPHERE; glNewList(sphereList, GL_COMPILE_AND_EXECUTE); glutSolidSphere(8.0, 10, 10); glEndList(); } break; case M_ICO: if (icoList) { glCallList(icoList); } else { icoList = DL_ICO; glNewList(icoList, GL_COMPILE_AND_EXECUTE); glEnable(GL_NORMALIZE); glPushMatrix(); glScalef(8.0, 8.0, 8.0); glutSolidIcosahedron(); glPopMatrix(); glDisable(GL_NORMALIZE); glEndList(); } break; case M_DOUBLE_TORUS:

Department Of CSE Page | 25

Page 26: Anjali 's CG REPORT Wit Code

Shadow Fun

if (torusList) { glCallList(torusList); } else { torusList = DL_TORUS; glNewList(torusList, GL_COMPILE_AND_EXECUTE); glutSolidTorus(2.0, 8.0, 8, 15); glEndList(); } glRotatef(90, 0, 1, 0); glCallList(torusList); break; } glPopMatrix();}

voidsphere(void){ glPushMatrix(); glTranslatef(60.0, -50.0, -400.0); glCallList(DL_BALL); glPopMatrix();}

voidcone(void){ glPushMatrix(); glTranslatef(-40.0, -40.0, -400.0); glCallList(DL_CONE); glPopMatrix();}

voidscene(void){ /* material properties for objects in scene */ static GLfloat wall_mat[] = {1.0, 1.0, 1.0, 1.0}; static GLfloat shad_mat[] = {1.0, 0.1, 0.1, 1.0};

glMatrixMode(GL_PROJECTION);

Department Of CSE Page | 26

Page 27: Anjali 's CG REPORT Wit Code

Shadow Fun

glLoadIdentity(); if (view == M_LIGHT_SOURCE_VIEW) { gluPerspective(45.0, 1.0, 0.1, 600.0); } else { gluPerspective(33.0, 1.0, 1.0, 600.0); } glMatrixMode(GL_MODELVIEW); glLoadIdentity(); if (view == M_LIGHT_SOURCE_VIEW) { gluLookAt(lightPos[X], lightPos[Y], lightPos[Z], objectPos[X], objectPos[Y], objectPos[Z], 0.0, 1.0, 0.); /* up is in positive Y direction */ } else { gluLookAt(0.0, 0.0, 0.0, 0.0, 0.0, -100.0, 0.0, 1.0, 0.); /* up is in positive Y direction */ } /* Place light 0 in the right place. */ glLightfv(GL_LIGHT0, GL_POSITION, lightPos);

/* Note: wall verticies are ordered so they are all front facing this lets me do back face culling to speed things up. */

glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wall_mat);

/* Floor with checkerboard texture. */ glEnable(GL_TEXTURE_2D);

glColor3f(0, 0, 0);

/* Since we want to turn texturing on for floor only, we have to make floor a separate glBegin()/glEnd() sequence. You can't turn texturing on and off between begin and end calls */ glBegin(GL_QUADS); glNormal3f(0.0, 1.0, 0.0); glTexCoord2i(0, 0); glVertex3f(-100.0, -100.0, -320.0); glTexCoord2i(4, 0); glVertex3f(100.0, -100.0, -320.0); glTexCoord2i(4, 4); glVertex3f(100.0, -100.0, -520.0); glTexCoord2i(0, 4); glVertex3f(-100.0, -100.0, -520.0);

Department Of CSE Page | 27

Page 28: Anjali 's CG REPORT Wit Code

Shadow Fun

glEnd();

glDisable(GL_TEXTURE_2D);

/* Walls. */

glBegin(GL_QUADS); /* Left wall. */ glNormal3f(1.0, 0.0, 0.0); glVertex3f(-100.0, -100.0, -320.0); glVertex3f(-100.0, -100.0, -520.0); glVertex3f(-100.0, 100.0, -520.0); glVertex3f(-100.0, 100.0, -320.0);

/* Right wall. */ glNormal3f(-1.0, 0.0, 0.0); glVertex3f(100.0, -100.0, -320.0); glVertex3f(100.0, 100.0, -320.0); glVertex3f(100.0, 100.0, -520.0); glVertex3f(100.0, -100.0, -520.0);

/* Ceiling. */ glNormal3f(0.0, -1.0, 0.0); glVertex3f(-100.0, 100.0, -320.0); glVertex3f(-100.0, 100.0, -520.0); glVertex3f(100.0, 100.0, -520.0); glVertex3f(100.0, 100.0, -320.0);

/* Back wall. */ glNormal3f(0.0, 0.0, 1.0); glVertex3f(-100.0, -100.0, -520.0); glVertex3f(100.0, -100.0, -520.0); glVertex3f(100.0, 100.0, -520.0); glVertex3f(-100.0, 100.0, -520.0); glEnd();

cone();

sphere();

glPushMatrix(); glTranslatef(lightPos[X], lightPos[Y], lightPos[Z]); glCallList(DL_LIGHT);

Department Of CSE Page | 28

Page 29: Anjali 's CG REPORT Wit Code

Shadow Fun

glPopMatrix();

/* Draw shadowing object. */ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, shad_mat);

renderShadowingObject();}

voidgenerateShadowVolume(void){ GLfloat *eyePos;

if (view == M_LIGHT_SOURCE_VIEW) { eyePos = lightPos; } else { eyePos = sceneEyePos; } svsGenerateShadowVolume(svs, renderShadowingObject, 250, maxRadius, lightPos, objectPos, eyePos);}

voiddisplay(void){ if (renderBoundary) { glClear(GL_COLOR_BUFFER_BIT); glDisable(GL_LIGHTING); glDisable(GL_DEPTH_TEST); generateShadowVolume(); glEnable(GL_LIGHTING); } else { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); switch (renderMode) { case M_NO_SHADOW: glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHT0); scene(); break; case M_NO_LIGHT: /* Render scene without the light source enabled (conceptually, the

Department Of CSE Page | 29

Page 30: Anjali 's CG REPORT Wit Code

Shadow Fun

entire scene is "in the shadow"). */ glEnable(GL_DEPTH_TEST); glDisable(GL_LIGHT0); scene(); break; case M_FRONT_VOLUME: case M_BACK_VOLUME: generateShadowVolume();

glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHT0); scene(); if (frontFace) { glFrontFace(GL_CW); } else { glFrontFace(GL_CCW); } glCallList(DL_SHADOW_VOLUME); glFrontFace(GL_CCW); break; case M_SHADOW: /* Construct DL_SHADOW_VOLUME display list for the scene's current shadow volume. */ generateShadowVolume();

/* 1st scene pass. */ glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHT0); scene();

/* 1st shadow volume pass: Enable stencil to increment the stencil value of pixels that pass the depth test when drawing the front facing polygons of the shadow volume. Do not update the depth buffer while rendering the shadow volume. */ glDisable(GL_LIGHTING); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glEnable(GL_STENCIL_TEST); glDepthMask(GL_FALSE); glStencilFunc(GL_ALWAYS, 0, 0); glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); glCullFace(GL_FRONT); glCallList(DL_SHADOW_VOLUME);

Department Of CSE Page | 30

Page 31: Anjali 's CG REPORT Wit Code

Shadow Fun

/* 2nd shadow volume pass: Now, draw the back facing polygons of the shadow volume except decrement pixels that pass the depth test. Again, do not update the depth buffer. */ glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); glCullFace(GL_BACK); glCallList(DL_SHADOW_VOLUME);

glDisable(GL_CULL_FACE); glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); glCallList(DL_SHADOW_VOLUME_TOP); glEnable(GL_CULL_FACE);

/* Now, pixels that lie within the shadow volume are tagged with a one stencil value. Empty shadowed regions of the shadow volume get incremented, then decremented, to resolve to a net zero stencil value. */

/* 2nd scene pass (render shadowed region): Re-enable update of the depth and color buffer (use GL_LEQUAL for depth buffer so we can over-write depth values again with color. Switch back to backface culling and disable the light source. Only update pixels with a stencil value of one (shadowed). */ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);#if 0 glDepthFunc(GL_EQUAL);#else glDepthMask(GL_TRUE); glDepthFunc(GL_LEQUAL);#endif glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glStencilFunc(GL_EQUAL, 1, 1); glDisable(GL_LIGHT0); glEnable(GL_LIGHTING); scene();

/* Put state back to sane modes. */ glDepthMask(GL_TRUE); glDepthFunc(GL_LESS); glDisable(GL_STENCIL_TEST); break; } } glutSwapBuffers();

Department Of CSE Page | 31

Page 32: Anjali 's CG REPORT Wit Code

Shadow Fun

}

voididle(void){ if (rotatingObject) { angle += 10.0; } if (swingingLight) { swingTime += 0.05; lightPos[X] += 2 * cos(swingTime); } glutPostRedisplay();}

voidmenu(int value){ switch (value) { case M_TORUS: case M_CUBE: case M_SPHERE: case M_ICO: case M_DOUBLE_TORUS: shape = value; maxRadius = objectMaxRadius[value]; glutPostRedisplay(); break; case M_ANGLE: angle += 10.0; glutPostRedisplay(); break; case M_BOUNDARY: renderBoundary = 1; glutPostRedisplay(); break; case M_FRONT_VOLUME: case M_BACK_VOLUME: frontFace = (value == M_FRONT_VOLUME); /* FALLTHROUGH */ case M_NO_SHADOW: case M_NO_LIGHT: case M_SHADOW:

Department Of CSE Page | 32

Page 33: Anjali 's CG REPORT Wit Code

Shadow Fun

renderBoundary = 0; renderMode = value; glutPostRedisplay(); break; case M_LIGHT_SOURCE_VIEW: case M_NORMAL_VIEW: view = value; glutPostRedisplay(); break; case M_STOP: swingingLight = 0; rotatingObject = 0; glutIdleFunc(NULL); break; case M_SPIN: rotatingObject = 1; glutIdleFunc(idle); break; case M_SWING: swingingLight = 1; glutIdleFunc(idle); break; case 666: svsFreeShadowVolumeState(svs); exit(0); break; }}

voidvisible(int vis){ if (vis == GLUT_VISIBLE && swingingLight && rotatingObject) { glutIdleFunc(idle); } else { glutIdleFunc(NULL); }}

voidkey(unsigned char c, int x, int y){ switch (c) {

Department Of CSE Page | 33

Page 34: Anjali 's CG REPORT Wit Code

Shadow Fun

case 27: /* Escape. */ svsFreeShadowVolumeState(svs); exit(0); break; case 13: /* Return. */ swingingLight = !swingingLight; swingTime = M_PI / 2.0; break; case ' ': /* Space. */ if (rotatingObject || swingingLight) { rotatingObject = 0; swingingLight = 0; glutIdleFunc(NULL); } else { rotatingObject = 1; swingingLight = 1; glutIdleFunc(idle); } break; }}

voidspecial(int key, int x, int y){ switch (key) { case GLUT_KEY_HOME: frontFace = !frontFace; glutPostRedisplay(); break; case GLUT_KEY_UP: lightPos[Y] += 10.0; glutPostRedisplay(); break; case GLUT_KEY_DOWN: lightPos[Y] -= 10.0; glutPostRedisplay(); break; case GLUT_KEY_PAGE_UP: lightPos[Z] += 10.0; glutPostRedisplay(); break; case GLUT_KEY_PAGE_DOWN:

Department Of CSE Page | 34

Page 35: Anjali 's CG REPORT Wit Code

Shadow Fun

lightPos[Z] -= 10.0; glutPostRedisplay(); break; case GLUT_KEY_RIGHT: lightPos[X] += 10.0; glutPostRedisplay(); break; case GLUT_KEY_LEFT: lightPos[X] -= 10.0; glutPostRedisplay(); break; }}

GLfloat *makeTexture(int maxs, int maxt){ int s, t; static GLfloat *texture;

texture = (GLfloat *) malloc(maxs * maxt * sizeof(GLfloat)); for (t = 0; t < maxt; t++) { for (s = 0; s < maxs; s++) { texture[s + maxs * t] = ((s >> 4) & 0x1) ^ ((t >> 4) & 0x1); } } return texture;}

voidinitScene(void){ GLfloat *tex; GLUquadricObj *qobj; static GLfloat sphere_mat[] = {1.0, 0.5, 0.0, 1.0}; static GLfloat cone_mat[] = {0.0, 0.5, 1.0, 1.0}; glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_CULL_FACE); glCullFace(GL_BACK);

Department Of CSE Page | 35

Page 36: Anjali 's CG REPORT Wit Code

Shadow Fun

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

qobj = gluNewQuadric();

glNewList(DL_BALL, GL_COMPILE); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, sphere_mat); gluSphere(qobj, 20.0, 20, 20); glEndList();

glNewList(DL_CONE, GL_COMPILE); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cone_mat); glRotatef(-90.0, 1.0, 0.0, 0.0); gluDisk(qobj, 0.0, 20.0, 20, 1); gluCylinder(qobj, 20.0, 0.0, 60.0, 20, 20); glEndList();

glNewList(DL_LIGHT, GL_COMPILE); glDisable(GL_LIGHTING); glColor3f(0.9, 0.9, 0.6); gluSphere(qobj, 5.0, 20, 20); glEnable(GL_LIGHTING); glEndList();

gluDeleteQuadric(qobj);

/* load pattern for current 2d texture */ tex = makeTexture(TEXDIM, TEXDIM); glTexImage2D(GL_TEXTURE_2D, 0, 1, TEXDIM, TEXDIM, 0, GL_RED, GL_FLOAT, tex); free(tex);}

intmain(int argc, char **argv){ int shapeMenu, viewMenu, actionMenu, renderModeMenu; svs = svsCreateShadowVolumeState(1000.0, NULL); glutInitDisplayString("stencil>=1 rgb double depth samples"); glutInit(&argc, argv); glutCreateWindow("shadowfun");

Department Of CSE Page | 36

Page 37: Anjali 's CG REPORT Wit Code

Shadow Fun

stencilBits = glutGet(GLUT_WINDOW_STENCIL_SIZE); printf("bits of stencil = %d\n", stencilBits); glutDisplayFunc(display); glutVisibilityFunc(visible); glutSpecialFunc(special); glutKeyboardFunc(key); initScene(); shapeMenu = glutCreateMenu(menu); glutAddMenuEntry("Torus", M_TORUS); glutAddMenuEntry("Cube", M_CUBE); glutAddMenuEntry("Sphere", M_SPHERE); glutAddMenuEntry("Icosahedron", M_ICO); glutAddMenuEntry("Double Torus", M_DOUBLE_TORUS); viewMenu = glutCreateMenu(menu); glutAddMenuEntry("Normal view", M_NORMAL_VIEW); glutAddMenuEntry("Light source view", M_LIGHT_SOURCE_VIEW);

renderModeMenu = glutCreateMenu(menu); glutAddMenuEntry("With shadow", M_SHADOW); glutAddMenuEntry("With front shadow volume", M_FRONT_VOLUME); glutAddMenuEntry("With back shadow volume", M_BACK_VOLUME); glutAddMenuEntry("Without shadow", M_NO_SHADOW); glutAddMenuEntry("Without light", M_NO_LIGHT); glutAddMenuEntry("2D shadow boundary", M_BOUNDARY);

actionMenu = glutCreateMenu(menu); glutAddMenuEntry("Spin object", M_SPIN); glutAddMenuEntry("Swing light", M_SWING); glutAddMenuEntry("Stop", M_STOP);

glutCreateMenu(menu); glutAddSubMenu("Object shape", shapeMenu); glutAddSubMenu("Viewpoint", viewMenu); glutAddSubMenu("Render mode", renderModeMenu); glutAddSubMenu("Action", actionMenu); glutAddMenuEntry("Step rotate", M_ANGLE); glutAddMenuEntry("Quit", 666); glutAttachMenu(GLUT_RIGHT_BUTTON);

menu(M_DOUBLE_TORUS);

glutMainLoop(); return 0; /* ANSI C requires main to return int. */

Department Of CSE Page | 37

Page 38: Anjali 's CG REPORT Wit Code

Shadow Fun

}

#elseint main(int argc, char** argv){ fprintf(stderr, "This program requires the new tesselator API in GLU 1.2.\n"); fprintf(stderr, "Your GLU library does not support this new interface, sorry.\n"); return 0;}#endif /* GLU_VERSION_1_2 */

3.5 SYSTEM TESTING:

The project is tested on different machines which meet the above stated requirements and it is indeed compatible and portable.The shadow fun is tested for each possible options shown in the menu,i.e light source movement,changing the viewing source,object shapes,controlling the position of the light and step rotation.

4. RESULT

4.1 SCREEN SHOT:

Department Of CSE Page | 38

Page 39: Anjali 's CG REPORT Wit Code

Shadow Fun

Department Of CSE Page | 39

Page 40: Anjali 's CG REPORT Wit Code

Shadow Fun

Department Of CSE Page | 40

Page 41: Anjali 's CG REPORT Wit Code

Shadow Fun

5. CONCLUSION

Department Of CSE Page | 41

Page 42: Anjali 's CG REPORT Wit Code

Shadow Fun

The project has the capability to evolve i.e., a whole lot of new features can be added to it. This project is a simulation of Shadow Fun which is implemented by unleashing the power of Computer Graphics using OpenGL. It could be used for various education and non-educationl purposes as stated above. This project has enabled us to understand computer graphics concepts through their implementations. We were also able to appreciate these concepts when their effects were realized. Improvements can be made to the Shadow Fun as stated above.

6. BIBLIOGRAPHY

Department Of CSE Page | 42

Page 43: Anjali 's CG REPORT Wit Code

Shadow Fun

6.1 TEXTS:

1.Interactive Computer Graphics A Top Down Approach with OpenGL by Edward Angel2.Computer Graphics by James D Foley, Andries Van Dam, Steven K Feiner and John F Hughes

6.2 LINKS:

1.opengl.softalizer.com/reviews.html 2.glprogramming.com/red/chapter14.html 3.wn.com/OpenGL_3D_Engine_%5BHD_720p%5D 4.www.freedownloadmanager.org/.../opengl-shadows-sample-2365347.html5. www.filebuzz.com/findsoftware/Road...Simulation...Opengl/2.html

Department Of CSE Page | 43