800 lines
19 KiB
C++
800 lines
19 KiB
C++
#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();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|