CMPS-3480 Computer Graphics
Lab-5
Elements of the lab:
We will do some coding together on Zoom. Do your work in your Odin 3480/5 folder. Start with your opengl.cpp program.
Some corrections have been made to the triangle_3d function.
At the top of the function, put in this code...
glViewport(0, 0, g.xres, g.yres);
glClearColor(0.0, 0.0, 0.0, 1.0);
//Sets 3D mode (with perspective)
glMatrixMode(GL_PROJECTION); glLoadIdentity();
gluPerspective(45.0, ((float)g.xres/g.yres), 1.0, 100.0);
//Now set the model-view matrix
glMatrixMode(GL_MODELVIEW); glLoadIdentity();
gluLookAt(g.camera_pos[0], g.camera_pos[1], g.camera_pos[2], 0,0,0, 0,1,0);
//Fill the object according to the vertex colors
glEnable(GL_COLOR_MATERIAL);
glShadeModel(GL_SMOOTH);
//Now setup the lighting. Added a 4th vector component.
glEnable(GL_LIGHTING);
float pos[4] = { 10, 2, 2, 1.0 };
float dif[4] = { .8, .8, .8, 1.0 };
float amb[4] = { .2, .2, .2, 1.0 };
glLightfv(GL_LIGHT0, GL_POSITION, pos);
glLightfv(GL_LIGHT0, GL_DIFFUSE, dif);
glLightfv(GL_LIGHT0, GL_AMBIENT, amb);
glEnable(GL_LIGHT0);
//light both sides of a polygon
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
//Setup a Z-buffer
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//
//Now draw the triangle and floor.
//
In class Wednesday we will add more components.
1. Construct a cone.
Use points-on-a-circle around the base of the cone.
Use a triangle-fan to make the bottom of the cone.
2. Calculate a surface normal using a cross-product.
Here are two ways to define a cross product function.
Macro
a and b are vectors.
result vector will be in c
#define VecCross(a,b,c) \
(c)[0]=(a)[1]*(b)[2]-(a)[2]*(b)[1]; \
(c)[1]=(a)[2]*(b)[0]-(a)[0]*(b)[2]; \
(c)[2]=(a)[0]*(b)[1]-(a)[1]*(b)[0]
A call to the macro looks like this:
VecCross(a,b,c);
Function
Requires a Vec definition such as
typedef float Flt;
typedef Flt Vec[3];
v0 and v1 are vectors.
Result is placed in dest.
void vecCrossProduct(Vec v0, Vec v1, Vec dest)
{
dest[0] = v0[1]*v1[2] - v1[1]*v0[2];
dest[1] = v0[2]*v1[0] - v1[2]*v0[0];
dest[2] = v0[0]*v1[1] - v1[0]*v0[1];
}
A call to the function looks like this:
vecCrossProduct(v0, v1, dest);
Here's how to find the cross product given 3 triangle vertices:
Three vertices are stored in float tri[3][3];
Vec v0, v1, dest;
v0[0] = tri[1][0] - tri[0][0];
v0[1] = tri[1][1] - tri[0][1];
v0[2] = tri[1][2] - tri[0][2];
v1[0] = tri[2][0] - tri[0][0];
v1[1] = tri[2][1] - tri[0][1];
v1[2] = tri[2][2] - tri[0][2];
vecCrossProduct(v0, v1, dest);
vecNormalize(dest);
Here is a vector normalization function:
void vecNormalize(Vec v)
{
float len = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
if (len == 0.0)
//Error, zero length vector. return a good vector with length 1.0.
v[0] = 0;
v[1] = 0;
v[2] = 1.0;
return;
}
v[0] = v[0] / len;
v[1] = v[1] / len;
v[2] = v[2] / len;
}
Here is a vector create function:
void vecSub(double *v1, double *v2, double *v3)
{
//subtract point v2 from v1 and get a vector
for (int i=0; i<3; i++)
v3[i] = v1[i] - v2[i];
}
We will apply this n Tuesday week-6 lab.
//==================================================================
//OpenGL texture map
//==================================================================
//Global
//class Image {
//public:
// int width, height;
// unsigned char *data;
//} img;
//
//==================================================================
//In program initialization
//==================================================================
//Get an image pixel stream (from lab1)
ifstream fin("image.ppm");
if (fin.fail()) {
cout << "ERROR - opening image\n";
exit(0);
}
unsigned char *data;
int width, height, maxcolor;
char p6[8];
fin >> p6;
fin >> img.width >> img.height;
int maxcolor;
fin >> maxcolor;
img.data = new unsigned char [img.width * img.height * 3];
fin.read((char *)img.data, 1);
fin.read((char *)img.data, img.width*img.height*3);
fin.close();
//==================================================================
//Allow 2-dimentional textures
glEnable(GL_TEXTURE_2D);
//==================================================================
//Create the texture map
GLuint tex; //in global
glGenTextures(1, &g.tex);
int w = img.width;
int h = img.height;
glBindTexture(GL_TEXTURE_2D, g.tex);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, 3, w, h, 0, GL_RGB,
GL_UNSIGNED_BYTE, img.data);
//==================================================================
//In render function
glBindTexture(GL_TEXTURE_2D, g.tex);
float w = 1.0;
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex2f(-w, w);
glTexCoord2f(1.0f, 0.0f); glVertex2f( w, w);
glTexCoord2f(1.0f, 1.0f); glVertex2f( w, -w);
glTexCoord2f(0.0f, 1.0f); glVertex2f(-w, -w);
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
//==================================================================