first commit
This commit is contained in:
799
CS4451/proj4/Renderer.cpp
Normal file
799
CS4451/proj4/Renderer.cpp
Normal file
@@ -0,0 +1,799 @@
|
||||
#include "Renderer.h"
|
||||
#include "defs.h"
|
||||
#include "structs.h"
|
||||
|
||||
#include <GL/glut.h>
|
||||
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <time.h> //For FPS
|
||||
|
||||
#ifndef CLK_TCK
|
||||
#define CLK_TCK CLOCKS_PER_SEC
|
||||
#endif
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#define VPD_MIN 200
|
||||
#define VPD_DEFAULT 800
|
||||
#define VPD_MAX 1024
|
||||
|
||||
#ifndef max
|
||||
#define max(a,b) ( (a) > (b) ? (a) : (b) )
|
||||
#endif
|
||||
|
||||
#ifndef min
|
||||
#define min(a,b) ( (a) < (b) ? (a) : (b) )
|
||||
#endif
|
||||
|
||||
inline GLvoid reshape(GLint vpw, GLint vph) {
|
||||
Renderer::getInstance()->window_resize(vpw,vph);
|
||||
}
|
||||
|
||||
inline GLvoid draw() {
|
||||
if (!Renderer::getInstance()->drawShadows) {
|
||||
Renderer::getInstance()->render();
|
||||
} else {
|
||||
Renderer::getInstance()->renderWithShadows();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Renderer Renderer::instance;
|
||||
Renderer * Renderer::getInstance()
|
||||
{
|
||||
return & instance;
|
||||
}
|
||||
|
||||
|
||||
Renderer::Renderer() {
|
||||
|
||||
spheres = new vector<Sphere*>;
|
||||
triangles = new vector<Triangle*>;
|
||||
lights = new vector<Light*>;
|
||||
|
||||
this->vpd = VPD_DEFAULT;
|
||||
this->viewAngle = -1.;
|
||||
|
||||
lightCenter = gluNewQuadric();
|
||||
|
||||
this->primitivesOnly = true;
|
||||
this->drawShadows = true;
|
||||
this->backFaceCull = true;
|
||||
|
||||
}
|
||||
|
||||
Renderer::~Renderer() {
|
||||
delete spheres;
|
||||
delete triangles;
|
||||
delete lights;
|
||||
}
|
||||
|
||||
void Renderer::apply_attributes(MaterialAttributes attrib, float alpha) {
|
||||
GLfloat mat_specular[4] = { attrib.k_s, attrib.k_s, attrib.k_s, alpha };
|
||||
//GLfloat mat_ambient_and_diffuse[4] = { 0.5, 0.5, 0.5, 1.0 };
|
||||
GLfloat mat_ambient[4] = { attrib.k_ar, attrib.k_ag, attrib.k_ab, alpha };
|
||||
GLfloat mat_diffuse[4] = { attrib.k_dr, attrib.k_dg, attrib.k_db, alpha };
|
||||
|
||||
#ifdef _NV_OPENGL
|
||||
GLfloat mat_shininess[1] = { (attrib.n_spec * 5. ) };
|
||||
#else //_ATI_OPENGL
|
||||
GLfloat mat_shininess[1] = { (attrib.n_spec) };
|
||||
#endif
|
||||
|
||||
/*mat_specular[0] = mat_ambient_and_diffuse[0] = r;
|
||||
mat_specular[1] = mat_ambient_and_diffuse[1] = g;
|
||||
mat_specular[2] = mat_ambient_and_diffuse[2] = b;*/
|
||||
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular);
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_ambient);
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
|
||||
}
|
||||
|
||||
GLvoid Renderer::init_lightsource ( GLvoid )
|
||||
{
|
||||
Light l = *(Renderer::getInstance()->lights->front());
|
||||
|
||||
//Light 0 parameters
|
||||
GLfloat light_diffuse[] = { l.intensity, l.intensity, l.intensity, 1.0 };
|
||||
#ifdef _NV_OPENGL
|
||||
GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
|
||||
#else //_ATI_OPENGL
|
||||
GLfloat light_specular[] = { l.intensity, l.intensity, l.intensity, 1.0 };
|
||||
#endif
|
||||
|
||||
GLfloat light_position[] = { l.center.x, l.center.y, l.center.z, 0 };
|
||||
|
||||
//Set Light 0 properties
|
||||
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
|
||||
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
|
||||
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
|
||||
glLightf(GL_LIGHT0,GL_CONSTANT_ATTENUATION,1.0);
|
||||
glLightf(GL_LIGHT0,GL_LINEAR_ATTENUATION,0.0);
|
||||
glLightf(GL_LIGHT0,GL_QUADRATIC_ATTENUATION,0.0);
|
||||
|
||||
//Enable light0
|
||||
glEnable(GL_LIGHT0);
|
||||
}
|
||||
|
||||
void Renderer::fixVertexDirection(Triangle* t) {
|
||||
|
||||
if (checkTriangle(t,viewport)) {
|
||||
Point temp = t->a2;
|
||||
t->a2 = t->a3;
|
||||
t->a3 = temp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the Triangle sceneID
|
||||
* Initializes all the Sphere quadrics
|
||||
* Sets the view angle
|
||||
*/
|
||||
void Renderer::init_scene() {
|
||||
triangleScene = glGenLists(1);
|
||||
|
||||
glNewList(triangleScene,GL_COMPILE);
|
||||
|
||||
glBegin(GL_TRIANGLES);
|
||||
|
||||
vector<Triangle*>::iterator t_iterator = triangles->begin();
|
||||
Triangle *t;
|
||||
Point normal;
|
||||
Point lightCenter;
|
||||
|
||||
for(;t_iterator != triangles->end(); t_iterator++) {
|
||||
t = *t_iterator;
|
||||
|
||||
fixVertexDirection(t);
|
||||
|
||||
apply_attributes(t->m_attr);
|
||||
|
||||
this->calculateNormal(&normal,t);
|
||||
|
||||
lightCenter = (lights->front())->center;
|
||||
|
||||
if (this->checkTriNormal(normal,lightCenter)) {
|
||||
glNormal3f(-normal.x,-normal.y,-normal.z);
|
||||
} else {
|
||||
glNormal3f(normal.x,normal.y,normal.z);
|
||||
}
|
||||
|
||||
glVertex3f(t->a1.x,t->a1.y,t->a1.z);
|
||||
glVertex3f(t->a2.x,t->a2.y,t->a2.z);
|
||||
glVertex3f(t->a3.x,t->a3.y,t->a3.z);
|
||||
}
|
||||
|
||||
glEnd();
|
||||
|
||||
//glEndList();*/
|
||||
|
||||
|
||||
|
||||
vector<Sphere*>::iterator s_iter = spheres->begin();
|
||||
for (; s_iter != spheres->end(); s_iter++) {
|
||||
apply_attributes((*s_iter)->m_attr);
|
||||
(*s_iter)->glSphere = gluNewQuadric();
|
||||
gluQuadricOrientation((*s_iter)->glSphere,GLU_OUTSIDE);
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef((*s_iter)->center.x, (*s_iter)->center.y, (*s_iter)->center.z);
|
||||
gluSphere((*s_iter)->glSphere, (*s_iter)->radius, 64, 64);
|
||||
glPopMatrix();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
glEndList();
|
||||
|
||||
|
||||
//Initialize the view
|
||||
this->viewAngle = 2.*(180./M_PI)*
|
||||
atan(fabs(viewport.y - l.y) / fabs(viewport.z - l.z));
|
||||
|
||||
//printf("viewAngle: %f\n",viewAngle);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* returns true if the light and the normal are on opposite sides
|
||||
*/
|
||||
bool Renderer::checkTriNormal(Point normal, Point lightCenter) {
|
||||
return (
|
||||
(lightCenter.x*normal.x) +
|
||||
(lightCenter.y*normal.y) +
|
||||
(lightCenter.z*normal.z) < 0);
|
||||
}
|
||||
|
||||
void Renderer::calculateNormal(Point *dest, Triangle* triangle) {
|
||||
Point a1a2, a1a3;
|
||||
Point a1 = triangle->a1, a2 = triangle->a2, a3 = triangle->a3;
|
||||
|
||||
a1a2.x = a2.x - a1.x;
|
||||
a1a2.y = a2.y - a1.y;
|
||||
a1a2.z = a2.z - a1.z;
|
||||
|
||||
a1a3.x = a3.x - a1.x;
|
||||
a1a3.y = a3.y - a1.y;
|
||||
a1a3.z = a3.z - a1.z;
|
||||
|
||||
Point::cross(*dest,a1a2,a1a3);
|
||||
|
||||
}
|
||||
|
||||
bool Renderer::checkTriangle(Triangle* triangle, Point lightCenter) {
|
||||
Point normal;
|
||||
|
||||
this->calculateNormal(&normal,triangle);
|
||||
return checkTriNormal(normal,lightCenter);
|
||||
}
|
||||
|
||||
void Renderer::getVector(Point *dest, Point *to, Point *from) {
|
||||
dest->x = to->x - from->x;
|
||||
dest->y = to->y - from->y;
|
||||
dest->z = to->z - from->z;
|
||||
}
|
||||
|
||||
void Renderer::generateTriangleShadows() {
|
||||
vector<Triangle*>::iterator t_iter = triangles->begin();
|
||||
Triangle* t;
|
||||
for (int i =0; t_iter != triangles->end(); t_iter++, i++) {
|
||||
|
||||
t = *t_iter;
|
||||
|
||||
Light light = *(lights->front());
|
||||
|
||||
|
||||
//TODO: MAKE A QUAD STRIP!
|
||||
|
||||
Point la1, la2, la3;
|
||||
|
||||
getVector(&la1,&t->a1,&light.center);
|
||||
getVector(&la2,&t->a2,&light.center);
|
||||
getVector(&la3,&t->a3,&light.center);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
if (!checkTriangle(t,light.center)) {
|
||||
|
||||
/*
|
||||
a1' a1 a3 a3'
|
||||
a3' a3 a2 a2'
|
||||
a2' a2 a1 a1'
|
||||
*/
|
||||
|
||||
glVertex4f(la1.x, la1.y, la1.z, 0);
|
||||
glVertex3f(t->a1.x,t->a1.y,t->a1.z);
|
||||
glVertex3f(t->a3.x,t->a3.y,t->a3.z);
|
||||
glVertex4f(la3.x, la3.y, la3.z, 0);
|
||||
|
||||
glVertex4f(la3.x, la3.y, la3.z, 0);
|
||||
glVertex3f(t->a3.x,t->a3.y,t->a3.z);
|
||||
glVertex3f(t->a2.x,t->a2.y,t->a2.z);
|
||||
glVertex4f(la2.x, la2.y, la2.z, 0);
|
||||
|
||||
glVertex4f(la2.x, la2.y, la2.z, 0);
|
||||
glVertex3f(t->a2.x,t->a2.y,t->a2.z);
|
||||
glVertex3f(t->a1.x,t->a1.y,t->a1.z);
|
||||
glVertex4f(la1.x, la1.y, la1.z, 0);
|
||||
|
||||
} else {
|
||||
/*
|
||||
a1 a1' a3' a3
|
||||
a3 a3' a2' a2
|
||||
a2 a2' a1' a1
|
||||
*/
|
||||
|
||||
glColor3d(1, 0, 0);
|
||||
glVertex3f(t->a1.x,t->a1.y,t->a1.z);
|
||||
glVertex4f(la1.x, la1.y, la1.z, 0);
|
||||
glVertex4f(la3.x, la3.y, la3.z, 0);
|
||||
glVertex3f(t->a3.x,t->a3.y,t->a3.z);
|
||||
|
||||
glVertex3f(t->a3.x,t->a3.y,t->a3.z);
|
||||
glVertex4f(la3.x, la3.y, la3.z, 0);
|
||||
glVertex4f(la2.x, la2.y, la2.z, 0);
|
||||
glVertex3f(t->a2.x,t->a2.y,t->a2.z);
|
||||
|
||||
glVertex3f(t->a2.x,t->a2.y,t->a2.z);
|
||||
glVertex4f(la2.x, la2.y, la2.z, 0);
|
||||
glVertex4f(la1.x, la1.y, la1.z, 0);
|
||||
glVertex3f(t->a1.x,t->a1.y,t->a1.z);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
|
||||
static inline Point wB(m_float B, Point& u, Point& v) {
|
||||
Point temp1,temp2;
|
||||
Point::mul(temp1,v,cos(B));
|
||||
Point::mul(temp2,u,sin(B));
|
||||
Point::add(temp1,temp1,temp2);
|
||||
return temp1;
|
||||
}
|
||||
|
||||
void Renderer::generateSphereShadows() {
|
||||
Light* light = this->lights->front();
|
||||
Point PL, LP, LC, temp, P, u, v;
|
||||
vector<Sphere*>::iterator s_iter;
|
||||
Sphere* s;
|
||||
m_float radius;
|
||||
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
for (s_iter = spheres->begin();
|
||||
s_iter != spheres->end();
|
||||
s_iter++)
|
||||
{
|
||||
s = *s_iter;
|
||||
|
||||
//LC
|
||||
Point::sub(LC,s->center,light->center);
|
||||
|
||||
m_float LClen = LC.magnitude();
|
||||
m_float PLlen = (pow(LClen,2) - pow(s->radius,2))/LClen;
|
||||
|
||||
radius = sqrt(pow(LC.magnitude(),2)
|
||||
- pow(s->radius,2) - pow(PLlen,2));//PL.magnitude(),2));
|
||||
|
||||
//printf("Radius %f\n",radius);
|
||||
|
||||
temp = Point::normalize(LC);
|
||||
Point::mul(temp, temp, PLlen);
|
||||
Point::add(P,light->center,temp);
|
||||
|
||||
//P.printMe();
|
||||
|
||||
if (fabs(LC.z) > fabs(LC.x)) {
|
||||
if (fabs(LC.x) > fabs(LC.y)) {
|
||||
u.x = -1. * LC.z;
|
||||
u.y = 0;
|
||||
u.z = LC.x;
|
||||
} else { //LC.x < LC.y
|
||||
u.x = 0;
|
||||
u.y = LC.z * -1.;
|
||||
u.z = LC.y;
|
||||
}
|
||||
} else { //|LC.z| < |LC.x|
|
||||
if (fabs(LC.z) > fabs(LC.y)) {
|
||||
u.x = -1. * LC.z;
|
||||
u.y = 0;
|
||||
u.z = LC.x;
|
||||
} else { //LC.z < LC.y
|
||||
u.x = -1. * LC.y;
|
||||
u.y = LC.x;
|
||||
u.z = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Point::mul(u,Point::normalize(u),radius);
|
||||
//u.printMe();
|
||||
//printf("length %f\n",u.magnitude());
|
||||
Point::cross(v,u,LC);
|
||||
Point::mul(v,Point::normalize(v),radius);
|
||||
|
||||
Point Q, Q2;
|
||||
Point Qb, Q2b;
|
||||
|
||||
for (int k = 0; k < 64; k++) {
|
||||
Point::add(Q, P,wB((k*2*M_PI) / 64,u,v));
|
||||
Point::add(Q2,P,wB(((k+1)*2*M_PI) / 64,u,v));
|
||||
|
||||
//Q.printMe();
|
||||
|
||||
getVector(&Qb, &Q, &light->center);
|
||||
getVector(&Q2b, &Q2, &light->center);
|
||||
|
||||
//Q.printMe();
|
||||
glVertex4f(Qb.x, Qb.y, Qb.z, 0);
|
||||
glVertex3f(Q.x,Q.y,Q.z);
|
||||
glVertex3f(Q2.x,Q2.y,Q2.z);
|
||||
glVertex4f(Q2b.x, Q2b.y, Q2b.z, 0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
glEnd();
|
||||
|
||||
}
|
||||
|
||||
m_uint Renderer::calculateShadowVolumes() {
|
||||
|
||||
apply_attributes(this->m_shadow_attrib,.2f);
|
||||
|
||||
generateTriangleShadows();
|
||||
generateSphereShadows();
|
||||
|
||||
//glEndList();
|
||||
return 0;//shadows;
|
||||
}
|
||||
|
||||
void Renderer::drawPrimitives(bool withLight) {
|
||||
|
||||
/* Do project fux0ring */
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
|
||||
//Set the perspective transformation
|
||||
gluPerspective(viewAngle,h.x/v.y,1,150);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
//Look at the right point in the world
|
||||
gluLookAt(viewport.x,viewport.y,viewport.z,
|
||||
viewport.x,viewport.y,l.z,
|
||||
v.x,v.y,v.z);
|
||||
|
||||
if (withLight) {
|
||||
init_lightsource();
|
||||
}
|
||||
glCallList(triangleScene);
|
||||
|
||||
//GLuint shadows = this->calculateShadowVolumes();
|
||||
//glDeleteLists(shadows,1);
|
||||
|
||||
/*vector<Sphere*>::iterator s_iter = spheres->begin();
|
||||
Sphere *s;
|
||||
for(int i = 0 ;s_iter != spheres->end();i++, s_iter++) {
|
||||
|
||||
s = *s_iter;
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
apply_attributes(s->m_attr);
|
||||
|
||||
glTranslatef(s->center.x,s->center.y,s->center.z);
|
||||
gluSphere(s->glSphere,s->radius,64,64);
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
}*/
|
||||
}
|
||||
|
||||
void Renderer::renderWithShadows(void) {
|
||||
/* ensure we're drawing to the correct GLUT window */
|
||||
glutSetWindow(wid);
|
||||
|
||||
/*
|
||||
* Clear all buffers
|
||||
*/
|
||||
|
||||
/* clear the color buffers */
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
|
||||
/********************************************************************/
|
||||
/* Step 2 - Draw the scene, no lighting only primitives and abience */
|
||||
|
||||
//Disable the LightSource
|
||||
glDisable(GL_LIGHT0);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
|
||||
//Enable Backface culling
|
||||
glEnable(GL_CULL_FACE);
|
||||
if (this->backFaceCull) {
|
||||
glCullFace(GL_BACK);
|
||||
} else {
|
||||
glCullFace(GL_FRONT);
|
||||
}
|
||||
//glCullFace(GL_BACK);
|
||||
|
||||
//Depth test to Less than or Equal
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
|
||||
//Draw the Primitives
|
||||
drawPrimitives(false);
|
||||
|
||||
glFlush();
|
||||
|
||||
/*****************************************************/
|
||||
/* Step 3 - Draw the shadow Polys with BackFace cull */
|
||||
|
||||
//Read only Depth and Color
|
||||
glDepthMask(0);
|
||||
glColorMask(0,0,0,0);
|
||||
|
||||
//Stencil Buffer writeable
|
||||
//glStencilMask(1);
|
||||
|
||||
//Stencil paramaters
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
glStencilOp(GL_KEEP,GL_KEEP,GL_INCR);
|
||||
glStencilFunc(GL_ALWAYS,0,~0);
|
||||
|
||||
/*glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluPerspective(viewAngle,h.x/v.y,1,150);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
gluLookAt(viewport.x,viewport.y,viewport.z,
|
||||
viewport.x,viewport.y,l.z,
|
||||
v.x,v.y,v.z);*/
|
||||
|
||||
//Draw Shadow Volumes
|
||||
this->calculateShadowVolumes();
|
||||
|
||||
glFlush();
|
||||
|
||||
/*****************************************************/
|
||||
/* Step 4 - Draw the shadow Polys with FrontFace cull */
|
||||
|
||||
//Front face culling
|
||||
glCullFace(GL_FRONT);
|
||||
|
||||
//Stencil Decrements
|
||||
glStencilOp(GL_KEEP,GL_KEEP,GL_DECR);
|
||||
glStencilFunc(GL_ALWAYS,0,~0);
|
||||
|
||||
/*glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluPerspective(viewAngle,h.x/v.y,1,150);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
gluLookAt(viewport.x,viewport.y,viewport.z,
|
||||
viewport.x,viewport.y,l.z,
|
||||
v.x,v.y,v.z);*/
|
||||
|
||||
this->calculateShadowVolumes();
|
||||
|
||||
glFlush();
|
||||
|
||||
/*************************************/
|
||||
/* Step 5 - Draw the fully lit scene */
|
||||
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
glStencilFunc(GL_EQUAL, 0, ~0);
|
||||
glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);
|
||||
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
|
||||
if (this->backFaceCull) {
|
||||
glCullFace(GL_BACK);
|
||||
} else {
|
||||
glCullFace(GL_FRONT);
|
||||
}
|
||||
|
||||
glDepthMask(1);
|
||||
glColorMask(1,1,1,1);
|
||||
|
||||
glEnable(GL_LIGHT0);
|
||||
|
||||
this->drawPrimitives(true);
|
||||
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
//glDeleteLists(shadows,1);
|
||||
|
||||
glFlush();
|
||||
|
||||
/* look at our handiwork */
|
||||
glutSwapBuffers();
|
||||
|
||||
#ifdef SHOW_FPS
|
||||
fps++;
|
||||
//printf("%d\n",fps);
|
||||
clock_t time = clock();
|
||||
if (time-lastClock >= CLK_TCK) {
|
||||
printf("Rendered %d frames in %f seconds\n",
|
||||
fps,(time-lastClock)/(float)CLK_TCK);
|
||||
lastClock = clock();
|
||||
fps = 0;
|
||||
}
|
||||
glutPostRedisplay();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void Renderer::render(void)
|
||||
{
|
||||
/* ensure we're drawing to the correct GLUT window */
|
||||
glutSetWindow(wid);
|
||||
|
||||
/* clear the color buffers */
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
drawPrimitives(true);
|
||||
|
||||
if (!this->primitivesOnly) {
|
||||
this->calculateShadowVolumes();
|
||||
}
|
||||
|
||||
/* flush the pipeline */
|
||||
glFlush();
|
||||
|
||||
/* look at our handiwork */
|
||||
glutSwapBuffers();
|
||||
|
||||
#ifdef SHOW_FPS
|
||||
fps++;
|
||||
//printf("%d\n",fps);
|
||||
clock_t time = clock();
|
||||
if (time-lastClock >= CLK_TCK) {
|
||||
printf("Rendered %d frames in %f seconds\n",
|
||||
fps,(time-lastClock)/(float)CLK_TCK);
|
||||
lastClock = clock();
|
||||
fps = 0;
|
||||
}
|
||||
glutPostRedisplay();
|
||||
#endif
|
||||
|
||||
//glutPostRedisplay();
|
||||
|
||||
}
|
||||
|
||||
void Renderer::init_opengl() {
|
||||
/* back-face culling on */
|
||||
glEnable(GL_CULL_FACE);
|
||||
glCullFace(GL_BACK); /* We want to cull the back */
|
||||
glFrontFace(GL_CCW);
|
||||
/*if (viewport.z - l.z < 0) {
|
||||
glFrontFace(GL_CW);
|
||||
} else {
|
||||
glFrontFace(GL_CCW);
|
||||
}*/
|
||||
|
||||
/* automatically scale normals to unit length after transformation */
|
||||
glEnable(GL_NORMALIZE);
|
||||
|
||||
//Enable Lighting
|
||||
glEnable(GL_LIGHTING);
|
||||
|
||||
/* clear to BLACK */
|
||||
glClearColor(0, 0, 0, 1.0);
|
||||
glClearStencil(0);
|
||||
|
||||
/* Enable depth test */
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
//Global parameter
|
||||
GLfloat light_ambient[] = { ambient, ambient, ambient, 1.0 };
|
||||
|
||||
//Set global ambience
|
||||
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, light_ambient);
|
||||
|
||||
//glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
|
||||
|
||||
//glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
|
||||
}
|
||||
|
||||
GLvoid Renderer::window_resize(GLint vpw, GLint vph)
|
||||
{
|
||||
glutSetWindow(wid);
|
||||
|
||||
/* maintain a square viewport, not too small, not too big */
|
||||
if( vpw < vph ) vpd = vph;
|
||||
else vpd = vpw;
|
||||
|
||||
if( vpd < VPD_MIN ) vpd = VPD_MIN;
|
||||
if( vpd > VPD_MAX ) vpd = VPD_MAX;
|
||||
|
||||
glViewport(0, 0, vpd, vpd);
|
||||
glutReshapeWindow(vpd, vpd);
|
||||
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
m_int Renderer::init_glut(m_int *argc, char **argv)
|
||||
{
|
||||
m_int id;
|
||||
|
||||
glutInit(argc,argv);
|
||||
|
||||
/* size and placement hints to the window system */
|
||||
glutInitWindowSize(vpd, vpd);
|
||||
glutInitWindowPosition(10,10);
|
||||
|
||||
/* double buffered, RGB color mode */
|
||||
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_STENCIL);
|
||||
|
||||
/* create a GLUT window (not drawn until glutMainLoop() is entered) */
|
||||
id = glutCreateWindow("cs4451 project 4: Super Cool Shadows!");
|
||||
|
||||
/* register callbacks */
|
||||
|
||||
/* window size changes */
|
||||
//glutReshapeFunc(NULL);
|
||||
glutReshapeFunc(reshape);
|
||||
|
||||
/* keypress handling when the current window has input focus */
|
||||
glutKeyboardFunc(keyboard_event);
|
||||
|
||||
/* mouse event handling */
|
||||
glutMouseFunc(mouse_button); /* button press/release */
|
||||
glutMotionFunc(button_motion); /* mouse motion w/ button down */
|
||||
glutPassiveMotionFunc(passive_motion); /* mouse motion with button up */
|
||||
|
||||
/* window obscured/revealed event handler */
|
||||
glutVisibilityFunc(NULL);
|
||||
|
||||
/* handling of keyboard SHIFT, ALT, CTRL keys */
|
||||
glutSpecialFunc(keyboard_special_event);
|
||||
|
||||
/* what to do when mouse cursor enters/exits the current window */
|
||||
glutEntryFunc(NULL);
|
||||
|
||||
/* what to do on each display loop iteration */
|
||||
glutDisplayFunc(draw);
|
||||
|
||||
/* Create the menu */
|
||||
|
||||
//Create the Zoom Menu
|
||||
GLint menuID = glutCreateMenu(menu);
|
||||
glutAddMenuEntry("Show Shadows (a)",MENU_SHADOWS);
|
||||
glutAddMenuEntry("Show Primitives Only (p)",MENU_PRIMITIVES_ONLY);
|
||||
glutAddMenuEntry("Show Shadow Volumes (v)",MENU_SHADOW_VOLUMES);
|
||||
glutAddMenuEntry("Clear to White (x)",MENU_CLEAR_WHITE);
|
||||
glutAddMenuEntry("Clear to Black (c)",MENU_CLEAR_BLACK);
|
||||
|
||||
glutSetMenu(menuID);
|
||||
|
||||
glutAttachMenu(GLUT_RIGHT_BUTTON);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
void Renderer::calculateDistance() {
|
||||
Point distances;
|
||||
m_float total = 0;
|
||||
|
||||
vector<Sphere*>::iterator s_iter;
|
||||
vector<Triangle*>::iterator t_iter;
|
||||
Point centerOfMass;
|
||||
|
||||
for (s_iter = spheres->begin();
|
||||
s_iter != spheres->end();
|
||||
s_iter++)
|
||||
{
|
||||
distances.x += this->viewport.x - (*s_iter)->center.x;
|
||||
distances.y += this->viewport.y - (*s_iter)->center.y;
|
||||
distances.z += this->viewport.z - (*s_iter)->center.z;
|
||||
total++;
|
||||
}
|
||||
|
||||
for (t_iter = triangles->begin();
|
||||
t_iter != triangles->end();
|
||||
t_iter++)
|
||||
{
|
||||
centerOfMass = this->centerOfTriangle(*t_iter);
|
||||
distances.x += this->viewport.x - centerOfMass.x;
|
||||
distances.y += this->viewport.y - centerOfMass.y;
|
||||
distances.z += this->viewport.z - centerOfMass.z;
|
||||
total++;
|
||||
}
|
||||
|
||||
distances.x /= total;
|
||||
distances.y /= total;
|
||||
distances.z /= total;
|
||||
|
||||
this->distanceToCenter = distances;
|
||||
|
||||
//distances.printMe();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user