comments!
This commit is contained in:
parent
a1292ce40f
commit
e2d8466e93
8 changed files with 95 additions and 50 deletions
|
@ -6,6 +6,5 @@ Code here is published under the [AGPL-v3](https://www.gnu.org/licenses/agpl-3.0
|
|||
|
||||
# TODO
|
||||
|
||||
- Add popping-floating text of funny cow thoughts when in cow view
|
||||
- Construct the required pdf with explanations and screenshots
|
||||
- Properly comment the code :/
|
||||
- Properly comment the code :/
|
||||
- Construct the required pdf with explanations and screenshots
|
57
cow.c
57
cow.c
|
@ -7,6 +7,7 @@
|
|||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// positional variables
|
||||
vec3 headRot = { 0.0, 0.0, 0.0 };
|
||||
const vec3 headLimit = { 30.0, 30.0, 45.0 };
|
||||
vec3 tailRot = { 0.0, 0.0, 0.0 };
|
||||
|
@ -22,20 +23,21 @@ enum COW_CONTROL control;
|
|||
float deg2rad(float deg) {
|
||||
return deg * 3.14 / 180.0;
|
||||
}
|
||||
|
||||
/// Adds a rotation and wraps around(wraps around the +- 180 mark, so -190 turns to 170)
|
||||
float addAndWrapRot(float rot, float add) {
|
||||
rot += add;
|
||||
if(rot > 180.0) { rot -= 360.0; }
|
||||
else if(rot < -180.0) { rot += 360.0; }
|
||||
return rot;
|
||||
}
|
||||
/// Adds a rotation and makes sure the result is within the limit
|
||||
float addAndLimitRot(float rot, float add, float limit) {
|
||||
rot += add;
|
||||
if(rot > limit) { rot = limit; }
|
||||
else if(rot < -limit) { rot = -limit; }
|
||||
return rot;
|
||||
}
|
||||
|
||||
// controls the cow movement based on keyboard input
|
||||
void cowMove(char c) {
|
||||
// check for rotations
|
||||
cowRot = addAndWrapRot(cowRot, ((c == 'e') - (c == 'q')) * COW_ROT_SPEED);
|
||||
|
@ -49,19 +51,20 @@ void cowMove(char c) {
|
|||
cowPos = vec3_add(cowPos, vec3_mult(r, COW_MOVE_SPEED));
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
// conrols cow head rotation(movement is a result of the offset of rotation) on keyboard input
|
||||
void cowHead(char c) {
|
||||
headRot.z = addAndLimitRot(headRot.z, ((c == 'e') - (c == 'q')) * COW_ROT_SPEED, headLimit.z);
|
||||
headRot.y = addAndLimitRot(headRot.y, ((c == 'a') - (c == 'd')) * COW_ROT_SPEED, headLimit.y);
|
||||
headRot.x = addAndLimitRot(headRot.x, ((c == 's') - (c == 'w')) * COW_ROT_SPEED, headLimit.x);
|
||||
glutPostRedisplay();
|
||||
}
|
||||
// controls cow tail rotaion on keyboard input
|
||||
void cowTail(char c) {
|
||||
tailRot.y = addAndLimitRot(tailRot.y, ((c == 'a') - (c == 'd')) * COW_ROT_SPEED, tailLimit.y);
|
||||
tailRot.x = addAndLimitRot(tailRot.x, ((c == 's') - (c == 'w')) * COW_ROT_SPEED, tailLimit.x);
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
// Draws the cow... will skip drawing the head parts when in cow point of view
|
||||
void drawCow(char cowsPOV) {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glEnable(GL_COLOR_MATERIAL);
|
||||
|
@ -76,47 +79,61 @@ void drawCow(char cowsPOV) {
|
|||
glScalef(1.2, 1.2, 2.3);
|
||||
glutSolidSphere(1.0, 16, 16);
|
||||
glPopMatrix(); // cow body scale
|
||||
if(!cowsPOV) {
|
||||
if(!cowsPOV) { // only draw head if we are not looking from within it
|
||||
// head
|
||||
glPushMatrix(); // head center
|
||||
glPushMatrix(); // head center - offset for the head rotation, allows for head movement relative to rotation easily
|
||||
glTranslatef(0.0, 1.0, 1.8);
|
||||
glRotatef(headRot.y, 0.0, 1.0, 0.0);
|
||||
glRotatef(headRot.x, 1.0, 0.0, 0.0);
|
||||
// glTranslatef(0.0, 0.0, 1.0);
|
||||
glRotatef(headRot.z, 0.0, 0.0 ,1.0);
|
||||
|
||||
glPushMatrix(); // head sphere 1
|
||||
glScalef(0.6, 0.4, 0.7);
|
||||
glutSolidSphere(1.0, 8, 8);
|
||||
|
||||
glPopMatrix(); // head sphere 1
|
||||
|
||||
glPushMatrix(); // head sphere 2
|
||||
glTranslatef(0.0, 0.3, -0.3);
|
||||
glScalef(0.6, 0.45, 0.75);
|
||||
glutSolidSphere(1.0, 8, 8);
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
// eyes :)
|
||||
glColor3f(0.0,0.0,0.0); // Eyes black as night
|
||||
|
||||
glPushMatrix(); // eye 1
|
||||
glTranslatef(-0.3, 0.5, 0.0);
|
||||
glScalef(0.17, 0.17, 0.17);
|
||||
glutSolidSphere(1.0, 8, 8);
|
||||
|
||||
glPopMatrix(); // eye 1
|
||||
|
||||
glPushMatrix(); // eye 2
|
||||
glTranslatef(0.3, 0.5, 0.0);
|
||||
glScalef(0.17, 0.17, 0.17);
|
||||
glutSolidSphere(1.0, 8, 8);
|
||||
|
||||
glPopMatrix(); // eye 2
|
||||
|
||||
glColor3f(0.8,0.4,0.11); // go back to the normal cow color
|
||||
// EARS! they look like little pancakes to the side of the head
|
||||
|
||||
glPushMatrix(); // ear 1
|
||||
glTranslatef(-0.7, 0.5, -0.4);
|
||||
glScalef(0.3, 0.18, 0.07);
|
||||
glutSolidSphere(1.0, 8, 8);
|
||||
|
||||
glPopMatrix(); // ear 1
|
||||
|
||||
glPushMatrix(); // ear 2
|
||||
glTranslatef(0.7, 0.5, -0.4);
|
||||
glScalef(0.3, 0.18, 0.07);
|
||||
glutSolidSphere(1.0, 8, 8);
|
||||
|
||||
glPopMatrix(); // ear 2
|
||||
|
||||
// Add a little teapon earing :D
|
||||
glPushMatrix();
|
||||
glColor3f(1.0, 1.0, 1.0);
|
||||
|
@ -124,26 +141,34 @@ void drawCow(char cowsPOV) {
|
|||
glRotatef(146.0, 0.0, 1.0, 0.0);
|
||||
glRotatef(-90.0, 1.0, 0.0, 0.0);
|
||||
glRotatef(90.0, 0.0, 1.0, 0.0);
|
||||
glCullFace(GL_FRONT); // for some reason, teapot normals are backwards to all other
|
||||
glCullFace(GL_FRONT); // for some reason, teapot normals are backwards compared to other shapes, maybe a bug in freeglut 3.4.0-1(artix world repo)
|
||||
glutSolidTeapot(0.17);
|
||||
glCullFace(GL_BACK);
|
||||
glCullFace(GL_BACK); // reset face culling
|
||||
|
||||
glPopMatrix(); // teapot!
|
||||
|
||||
glPushMatrix(); // little nose
|
||||
glColor3f(0.9, 0.3, 0.4);
|
||||
glTranslatef(0.0, 0.1, 0.6);
|
||||
glScalef(0.3, 0.15, 0.14);
|
||||
glutSolidSphere(1.0, 8, 8);
|
||||
|
||||
glPopMatrix(); // little nose
|
||||
|
||||
glPopMatrix(); // head center
|
||||
}
|
||||
// tins
|
||||
glColor3f(0.9, 0.3, 0.4);
|
||||
|
||||
glPushMatrix(); // TINS!
|
||||
glTranslatef(0.0, -1.0, -0.58);
|
||||
glScalef(0.7, 0.4, 0.7);
|
||||
glutSolidSphere(1.0, 8, 8);
|
||||
|
||||
glPopMatrix(); // Thins!
|
||||
|
||||
glColor3f(0.8,0.4,0.11); // go back to the normal cow color
|
||||
// looping over this array makes changes much easier as the legs should be mirrored in both x and z directions
|
||||
vec3 legs[] = {
|
||||
vec3_new(1.0, 0.0, 1.0), vec3_new(-1.0, 0.0, 1.0),
|
||||
vec3_new(1.0, 0.0, -1.0), vec3_new(-1.0, 0.0, -1.0)
|
||||
|
@ -153,6 +178,7 @@ void drawCow(char cowsPOV) {
|
|||
glTranslatef(0.5 * legs[i].x, -1.2, 1.4 * legs[i].z);
|
||||
glScalef(0.4, 1.2, 0.4);
|
||||
glutSolidSphere(1.0, 8, 8);
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
// now a tail
|
||||
|
@ -163,7 +189,9 @@ void drawCow(char cowsPOV) {
|
|||
glTranslatef(0.0, -0.83, 0.0);
|
||||
glScalef(0.2, 1.0, 0.2);
|
||||
glutSolidSphere(1.0, 8, 8);
|
||||
|
||||
glPopMatrix(); // Tails(from sonic the hedgehog)
|
||||
|
||||
// Give the cow a little flashlight because its dark outside
|
||||
glPushMatrix(); // fl
|
||||
glTranslatef(0.5, -1.2, 1.4);
|
||||
|
@ -184,12 +212,17 @@ void drawCow(char cowsPOV) {
|
|||
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, dir);
|
||||
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 30.0);
|
||||
glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 2.0);
|
||||
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.005);
|
||||
|
||||
glPopMatrix(); // fl
|
||||
|
||||
glPopMatrix(); // cow pos
|
||||
|
||||
// reset color material or else it will garbage all the colors next frame(for non color material enabled objects)
|
||||
glColor3f(1.0, 1.0, 1.0);
|
||||
glDisable(GL_COLOR_MATERIAL);
|
||||
}
|
||||
|
||||
// controls which body part to move based on the `control` variable, called from the keyboard event callback of the main file
|
||||
void onCowKeyboardInput(char key) {
|
||||
switch(control) {
|
||||
case COW_CONTROL_MOVE:
|
||||
|
@ -205,11 +238,11 @@ void onCowKeyboardInput(char key) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// updates the control mode, based on the right click submenu(the first one)
|
||||
void updateCowControl(enum COW_CONTROL c) {
|
||||
control = c;
|
||||
}
|
||||
|
||||
// rotates the camera to the cow's perspective
|
||||
void setCameraToCowPOV() {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
|
||||
// grass texture taken from polyhaven, downscaled to 128x128 and transformed into a C array
|
||||
const unsigned char grass_color_128[] = {
|
||||
0x56, 0x8b, 0x88, 0xff, 0x55, 0x87, 0x87, 0xff, 0x5d, 0x8a, 0x8d, 0xff, 0x5a, 0x81, 0x89, 0xff, 0x63, 0x87, 0x91, 0xff, 0x69, 0x8b, 0x98, 0xff, 0x5a, 0x7d, 0x8b, 0xff, 0x61, 0x86, 0x94, 0xff, 0x65, 0x8c, 0x9a, 0xff, 0x5b, 0x85, 0x92, 0xff, 0x5c, 0x86, 0x93, 0xff, 0x65, 0x8c, 0x9a, 0xff, 0x5c, 0x80, 0x90, 0xff, 0x76, 0x97, 0xa7, 0xff, 0x73, 0x8e, 0xa2, 0xff, 0x6f, 0x8a, 0x9e, 0xff, 0x68, 0x86, 0x99, 0xff, 0x6c, 0x8d, 0x9d, 0xff, 0x64, 0x86, 0x96, 0xff, 0x5d, 0x80, 0x8d, 0xff, 0x5f, 0x86, 0x8f, 0xff, 0x66, 0x8d, 0x95, 0xff, 0x5a, 0x7f, 0x87, 0xff, 0x71, 0x96, 0x9e, 0xff, 0x6a, 0x8a, 0x97, 0xff, 0x66, 0x86, 0x93, 0xff, 0x60, 0x7e, 0x8f, 0xff, 0x6b, 0x89, 0x9a, 0xff, 0x66, 0x87, 0x96, 0xff, 0x62, 0x85, 0x93, 0xff, 0x58, 0x7b, 0x88, 0xff, 0x56, 0x7f, 0x88, 0xff, 0x5a, 0x88, 0x8f, 0xff, 0x56, 0x86, 0x8a, 0xff, 0x5b, 0x8b, 0x8f, 0xff, 0x4f, 0x7f, 0x83, 0xff, 0x60, 0x8d, 0x90, 0xff, 0x66, 0x93, 0x96, 0xff, 0x5b, 0x85, 0x8a, 0xff, 0x4f, 0x79, 0x7e, 0xff, 0x51, 0x7b, 0x82, 0xff, 0x50, 0x7a, 0x81, 0xff, 0x5f, 0x88, 0x91, 0xff, 0x5e, 0x87, 0x90, 0xff, 0x56, 0x7d, 0x8b, 0xff, 0x57, 0x7e, 0x8c, 0xff, 0x56, 0x7f, 0x8e, 0xff, 0x61, 0x85, 0x95, 0xff, 0x6b, 0x86, 0x9a, 0xff, 0x60, 0x78, 0x8c, 0xff, 0x5b, 0x73, 0x89, 0xff, 0x71, 0x89, 0x9f, 0xff, 0x77, 0x92, 0xa7, 0xff, 0x75, 0x90, 0xa5, 0xff, 0x64, 0x7f, 0x93, 0xff, 0x68, 0x83, 0x97, 0xff, 0x64, 0x82, 0x95, 0xff, 0x63, 0x81, 0x92, 0xff, 0x60, 0x81, 0x91, 0xff, 0x55, 0x76, 0x85, 0xff, 0x64, 0x86, 0x93, 0xff, 0x60, 0x82, 0x8f, 0xff, 0x63, 0x86, 0x90, 0xff, 0x5f, 0x81, 0x8e, 0xff, 0x5e, 0x7b, 0x8a, 0xff, 0x50, 0x6f, 0x7e, 0xff, 0x51, 0x74, 0x81, 0xff, 0x5f, 0x89, 0x90, 0xff, 0x55, 0x85, 0x89, 0xff, 0x41, 0x74, 0x76, 0xff, 0x55, 0x85, 0x89, 0xff, 0x51, 0x7f, 0x86, 0xff, 0x57, 0x7e, 0x8c, 0xff, 0x67, 0x89, 0x99, 0xff, 0x73, 0x90, 0xa5, 0xff, 0x71, 0x8c, 0xa0, 0xff, 0x67, 0x82, 0x96, 0xff, 0x61, 0x7e, 0x8d, 0xff, 0x60, 0x7f, 0x8e, 0xff, 0x60, 0x82, 0x8f, 0xff, 0x67, 0x89, 0x99, 0xff, 0x64, 0x88, 0x98, 0xff, 0x60, 0x81, 0x94, 0xff, 0x65, 0x86, 0x99, 0xff, 0x6e, 0x8b, 0xa0, 0xff, 0x82, 0x9f, 0xb4, 0xff, 0x6b, 0x83, 0x9b, 0xff, 0x71, 0x89, 0xa1, 0xff, 0x78, 0x8c, 0xa5, 0xff, 0x73, 0x87, 0xa0, 0xff, 0x72, 0x86, 0x9f, 0xff, 0x71, 0x85, 0x9e, 0xff, 0x69, 0x7e, 0x94, 0xff, 0x7a, 0x8f, 0xa5, 0xff, 0x74, 0x89, 0x9e, 0xff, 0x68, 0x7d, 0x93, 0xff, 0x76, 0x87, 0xa1, 0xff, 0x62, 0x76, 0x8f, 0xff, 0x72, 0x8e, 0x9f, 0xff, 0x6a, 0x8d, 0x97, 0xff, 0x67, 0x91, 0x96, 0xff, 0x5c, 0x8d, 0x8b, 0xff, 0x57, 0x8c, 0x83, 0xff, 0x43, 0x7b, 0x70, 0xff, 0x4a, 0x7f, 0x72, 0xff, 0x58, 0x8a, 0x80, 0xff, 0x5c, 0x8a, 0x84, 0xff, 0x66, 0x8e, 0x8d, 0xff, 0x5c, 0x80, 0x88, 0xff, 0x75, 0x95, 0xa2, 0xff, 0x7c, 0x98, 0xa9, 0xff, 0x7b, 0x96, 0xaa, 0xff, 0x64, 0x81, 0x96, 0xff, 0x5e, 0x7b, 0x90, 0xff, 0x62, 0x80, 0x93, 0xff, 0x67, 0x85, 0x96, 0xff, 0x5c, 0x7d, 0x8d, 0xff, 0x5a, 0x7d, 0x8a, 0xff, 0x61, 0x87, 0x93, 0xff, 0x56, 0x81, 0x8a, 0xff, 0x54, 0x84, 0x8a, 0xff, 0x56, 0x8a, 0x90, 0xff, 0x45, 0x7c, 0x81, 0xff, 0x45, 0x7d, 0x82, 0xff, 0x51, 0x88, 0x8d, 0xff, 0x54, 0x8b, 0x90, 0xff, 0x55, 0x89, 0x8f, 0xff, 0x4b, 0x7f, 0x85, 0xff,
|
||||
0x53, 0x84, 0x86, 0xff, 0x5d, 0x8d, 0x8f, 0xff, 0x61, 0x8b, 0x92, 0xff, 0x5c, 0x83, 0x8c, 0xff, 0x4c, 0x6e, 0x7b, 0xff, 0x63, 0x84, 0x93, 0xff, 0x63, 0x84, 0x94, 0xff, 0x6f, 0x91, 0xa1, 0xff, 0x64, 0x8b, 0x99, 0xff, 0x4b, 0x75, 0x82, 0xff, 0x50, 0x7a, 0x87, 0xff, 0x5e, 0x85, 0x93, 0xff, 0x60, 0x84, 0x94, 0xff, 0x64, 0x85, 0x95, 0xff, 0x62, 0x80, 0x93, 0xff, 0x64, 0x82, 0x95, 0xff, 0x60, 0x81, 0x91, 0xff, 0x74, 0x96, 0xa6, 0xff, 0x5d, 0x82, 0x90, 0xff, 0x59, 0x7f, 0x8b, 0xff, 0x59, 0x83, 0x8a, 0xff, 0x5e, 0x88, 0x8f, 0xff, 0x65, 0x8c, 0x94, 0xff, 0x68, 0x8d, 0x95, 0xff, 0x65, 0x88, 0x92, 0xff, 0x6e, 0x8e, 0x9b, 0xff, 0x72, 0x91, 0xa0, 0xff, 0x6a, 0x88, 0x99, 0xff, 0x6a, 0x89, 0x98, 0xff, 0x59, 0x7a, 0x89, 0xff, 0x58, 0x7b, 0x88, 0xff, 0x5e, 0x85, 0x8e, 0xff, 0x5d, 0x89, 0x90, 0xff, 0x5c, 0x8b, 0x8f, 0xff, 0x5f, 0x8e, 0x92, 0xff, 0x5f, 0x8e, 0x92, 0xff, 0x61, 0x8e, 0x92, 0xff, 0x64, 0x91, 0x95, 0xff, 0x5a, 0x84, 0x89, 0xff, 0x4f, 0x79, 0x7e, 0xff, 0x4b, 0x75, 0x7c, 0xff, 0x4c, 0x75, 0x7e, 0xff, 0x6b, 0x94, 0x9d, 0xff, 0x6a, 0x92, 0x9e, 0xff, 0x54, 0x7b, 0x89, 0xff, 0x65, 0x8c, 0x9a, 0xff, 0x69, 0x90, 0x9f, 0xff, 0x4e, 0x72, 0x82, 0xff, 0x69, 0x84, 0x98, 0xff, 0x70, 0x89, 0x9d, 0xff, 0x5c, 0x74, 0x8a, 0xff, 0x64, 0x7f, 0x94, 0xff, 0x6f, 0x8a, 0x9f, 0xff, 0x79, 0x94, 0xa9, 0xff, 0x7f, 0x9a, 0xae, 0xff, 0x69, 0x84, 0x98, 0xff, 0x70, 0x8e, 0xa1, 0xff, 0x61, 0x7f, 0x90, 0xff, 0x61, 0x82, 0x92, 0xff, 0x6d, 0x8e, 0x9d, 0xff, 0x59, 0x7b, 0x88, 0xff, 0x69, 0x8b, 0x98, 0xff, 0x65, 0x88, 0x92, 0xff, 0x65, 0x85, 0x92, 0xff, 0x5a, 0x79, 0x88, 0xff, 0x6e, 0x8d, 0x9c, 0xff, 0x62, 0x85, 0x92, 0xff, 0x59, 0x83, 0x8a, 0xff, 0x57, 0x87, 0x8b, 0xff, 0x59, 0x8c, 0x8e, 0xff, 0x57, 0x87, 0x8b, 0xff, 0x54, 0x82, 0x89, 0xff, 0x61, 0x88, 0x96, 0xff, 0x60, 0x82, 0x92, 0xff, 0x6d, 0x8b, 0x9e, 0xff, 0x7b, 0x96, 0xaa, 0xff, 0x69, 0x85, 0x96, 0xff, 0x6b, 0x88, 0x97, 0xff, 0x6c, 0x8b, 0x9a, 0xff, 0x63, 0x84, 0x93, 0xff, 0x61, 0x82, 0x92, 0xff, 0x62, 0x84, 0x94, 0xff, 0x6d, 0x8d, 0xa0, 0xff, 0x5f, 0x7f, 0x92, 0xff, 0x5d, 0x7a, 0x8f, 0xff, 0x67, 0x82, 0x97, 0xff, 0x6a, 0x82, 0x9a, 0xff, 0x79, 0x8f, 0xa8, 0xff, 0x7d, 0x93, 0xac, 0xff, 0x75, 0x89, 0xa2, 0xff, 0x7d, 0x91, 0xaa, 0xff, 0x67, 0x7b, 0x94, 0xff, 0x7e, 0x92, 0xab, 0xff, 0x6d, 0x84, 0x9a, 0xff, 0x70, 0x87, 0x9d, 0xff, 0x78, 0x8d, 0xa3, 0xff, 0x67, 0x7b, 0x94, 0xff, 0x6b, 0x81, 0x9a, 0xff, 0x6e, 0x8a, 0x9b, 0xff, 0x62, 0x84, 0x91, 0xff, 0x6a, 0x94, 0x99, 0xff, 0x5e, 0x8c, 0x8d, 0xff, 0x5a, 0x8e, 0x87, 0xff, 0x50, 0x85, 0x7c, 0xff, 0x51, 0x85, 0x7b, 0xff, 0x4e, 0x7f, 0x77, 0xff, 0x5c, 0x89, 0x86, 0xff, 0x5e, 0x85, 0x87, 0xff, 0x65, 0x89, 0x91, 0xff, 0x6a, 0x8a, 0x97, 0xff, 0x73, 0x8f, 0xa0, 0xff, 0x60, 0x7e, 0x91, 0xff, 0x6b, 0x88, 0x9d, 0xff, 0x62, 0x7f, 0x94, 0xff, 0x5a, 0x78, 0x8b, 0xff, 0x54, 0x75, 0x85, 0xff, 0x62, 0x83, 0x93, 0xff, 0x5d, 0x80, 0x8e, 0xff, 0x5b, 0x81, 0x8d, 0xff, 0x51, 0x7c, 0x85, 0xff, 0x45, 0x74, 0x7c, 0xff, 0x40, 0x72, 0x78, 0xff, 0x42, 0x79, 0x7e, 0xff, 0x44, 0x7b, 0x80, 0xff, 0x4d, 0x84, 0x89, 0xff, 0x47, 0x7b, 0x81, 0xff, 0x45, 0x79, 0x7f, 0xff, 0x4b, 0x7d, 0x83, 0xff,
|
||||
|
|
1
help.h
1
help.h
|
@ -1,3 +1,4 @@
|
|||
// help text
|
||||
const unsigned char helpString[] =
|
||||
"World of Cow by Aviv Romem\n"
|
||||
"Left/Middle mouse to control camera rotation/Position.\n"
|
||||
|
|
56
mmn_17.c
56
mmn_17.c
|
@ -20,6 +20,7 @@ vec3 lightPos = { 0.0, 10, 25.0 };
|
|||
float camRadius = 40.0;
|
||||
vec3 camCenter = { 0.0, 0.0, 0.0 };
|
||||
vec3 camRot = { -PI * 0.25, PI, 0.0 };
|
||||
// some stuff to remember
|
||||
struct {
|
||||
unsigned char lockYMovement: 1;
|
||||
unsigned char showHelp: 1;
|
||||
|
@ -34,15 +35,15 @@ struct {
|
|||
int cowControl;
|
||||
int filters;
|
||||
} menus; // to simply hold the menues in a labed manner
|
||||
|
||||
// holding the lists, although only 1 was used
|
||||
struct {
|
||||
GLuint grass;
|
||||
} lists;
|
||||
|
||||
// Ui stuff
|
||||
int lastMouseButton = GLUT_LEFT_BUTTON;
|
||||
int lastMouseX = 0, lastMouseY = 0;
|
||||
ui_slider* draggedSlider = NULL;
|
||||
int lastMouseButton = GLUT_LEFT_BUTTON; // for camera movement/rotation, also used with the sliders
|
||||
int lastMouseX = 0, lastMouseY = 0; // for camera movement/rotation
|
||||
ui_slider* draggedSlider = NULL; // helps when dragging a slider
|
||||
ui_slider sliders[] = {
|
||||
{ // ambient red
|
||||
/* pos */ { { 0.9, 0.9, 0.0 }, { -50.0, -10.0, 0.0 } },
|
||||
|
@ -123,17 +124,19 @@ struct {
|
|||
sliders, sliders + 1, sliders + 2, sliders + 3, sliders + 4, sliders + 5, sliders + 6,
|
||||
sliders + 7, sliders + 8, sliders + 9, sliders + 10, sliders + 11
|
||||
};
|
||||
|
||||
// generate a list for the grass, using a list makes it much faster
|
||||
// and the correct way to make them wiggle a bit(wind) is using a vertex shader
|
||||
// but that was not in the scope of the course
|
||||
void generateGrassVertexList() {
|
||||
lists.grass = glGenLists(1);
|
||||
glNewList(lists.grass, GL_COMPILE);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_CULL_FACE); // disable culling so we could see the grass from both directions
|
||||
for(float x = -50.0; x < 50.0; x += 1.0) {
|
||||
for(float z = -50.0; z < 50.0; z += 1.0) {
|
||||
float tx = -0.03 * (rand() % 21), tz = -0.03 * (rand() % 21);
|
||||
float tx = -0.03 * (rand() % 21), tz = -0.03 * (rand() % 21); // give the grass a bit of randomness in their looks
|
||||
glPushMatrix();
|
||||
glTranslatef(x, 0.0, z);
|
||||
glRotatef(rand() % 360, 0.0, 1.0, 0.0);
|
||||
glTranslatef(x, 0.0, z); // move the grass to the locaiton on grid
|
||||
glRotatef(rand() % 360, 0.0, 1.0, 0.0); // rotate by a random amount
|
||||
glBegin(GL_TRIANGLES);
|
||||
glColor3f(0.0, 0.3, 0.0);
|
||||
glVertex3f(0.0, 0.0, 0.0);
|
||||
|
@ -152,7 +155,7 @@ void generateGrassVertexList() {
|
|||
glEnable(GL_CULL_FACE);
|
||||
glEndList();
|
||||
}
|
||||
|
||||
// draws a tree based on the radius and the height in a location based on the matrix stack
|
||||
void drawTree(float rad, float height) {
|
||||
// Bark
|
||||
glEnable(GL_COLOR_MATERIAL);
|
||||
|
@ -165,7 +168,7 @@ void drawTree(float rad, float height) {
|
|||
glColor3f(0.0, 1.0, 0.0);
|
||||
glPushMatrix();
|
||||
glTranslatef(0.0, height, 0.0);
|
||||
|
||||
// leaves, 5 green balls
|
||||
vec3 ts[] = {
|
||||
vec3_new(1.0, 0.0, 0.0), vec3_new(-1.0, 0.0, 0.0),
|
||||
vec3_new(0.0, 0.0, -1.0), vec3_new(0.0, 0.0, 1.0),
|
||||
|
@ -175,14 +178,14 @@ void drawTree(float rad, float height) {
|
|||
vec3 t = ts[i];
|
||||
glPushMatrix();
|
||||
glTranslatef(t.x * rad, t.y * rad, t.z * rad);
|
||||
glutSolidSphere(rad, 8, 8);
|
||||
glutSolidSphere(rad * 1.5, 8, 8);
|
||||
glPopMatrix();
|
||||
}
|
||||
glPopMatrix();
|
||||
glColor3f(1.0, 1.0, 1.0);
|
||||
glDisable(GL_COLOR_MATERIAL);
|
||||
}
|
||||
|
||||
// rotates a vector by the camera rotation
|
||||
vec3 rotateByCameraRotation(vec3 v) {
|
||||
vec3 r;
|
||||
// rotate along the x axis(yz plane)
|
||||
|
@ -207,7 +210,7 @@ void drawUi(void) {
|
|||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluOrtho2D(0.0, wWidth, 0.0, wHeight);
|
||||
|
||||
// draw sliders
|
||||
for(ui_slider* s = sliders; s < sliders + sizeof sliders / sizeof(ui_slider); s += 1) {
|
||||
ui_slider_draw(s);
|
||||
}
|
||||
|
@ -231,7 +234,7 @@ void drawUi(void) {
|
|||
glutBitmapString(GLUT_BITMAP_TIMES_ROMAN_24, t2);
|
||||
glRasterPos2f(140.0, wHeight * 0.9 - 10.0);
|
||||
glutBitmapString(GLUT_BITMAP_TIMES_ROMAN_24, side);
|
||||
|
||||
// show help if needed
|
||||
if(settings.showHelp) {
|
||||
glColor3f(0.3, 0.3, 0.3);
|
||||
glBegin(GL_QUADS);
|
||||
|
@ -244,7 +247,7 @@ void drawUi(void) {
|
|||
glRasterPos2f(wWidth * 0.12, wHeight * 0.8);
|
||||
glutBitmapString(GLUT_BITMAP_TIMES_ROMAN_24, helpString);
|
||||
}
|
||||
|
||||
// check for errors
|
||||
int err = glGetError();
|
||||
if(err != 0) {
|
||||
printf("opengl error %d: %s\n", err, gluErrorString(err));
|
||||
|
@ -256,7 +259,6 @@ void drawWorld(void) {
|
|||
// set perspective camera
|
||||
GLdouble wWidth = (GLdouble) glutGet(GLUT_WINDOW_WIDTH);
|
||||
GLdouble wHeight = (GLdouble) glutGet(GLUT_WINDOW_HEIGHT);
|
||||
// Calculate current camera position from rotation
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
@ -264,6 +266,7 @@ void drawWorld(void) {
|
|||
setCameraToCowPOV();
|
||||
}
|
||||
else {
|
||||
// Calculate current camera position from rotation
|
||||
vec3 cp = vec3_new(0.0, 0.0, camRadius);
|
||||
cp = rotateByCameraRotation(cp);
|
||||
cp = vec3_add(cp, camCenter);
|
||||
|
@ -305,7 +308,7 @@ void drawWorld(void) {
|
|||
glPopMatrix();
|
||||
// World
|
||||
drawCow(settings.cowsPOV);
|
||||
// Ground
|
||||
// Ground - with a low res grass texture
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, settings.textureFilter);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, settings.textureFilter);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, grass_color_128);
|
||||
|
@ -319,6 +322,7 @@ void drawWorld(void) {
|
|||
glTexCoord2f(1.0, 0.0); glVertex3f(50.0, 0.0, -50.0);
|
||||
glEnd();
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
// draw some trees
|
||||
glPushMatrix();
|
||||
glTranslatef(25.0, 0.0, 25.0);
|
||||
drawTree(3.0, 20.0);
|
||||
|
@ -362,10 +366,11 @@ void display(void) {
|
|||
}
|
||||
|
||||
void mouseEvent(int button, int state, int x, int y) {
|
||||
// save the last mouse position
|
||||
lastMouseX = x; lastMouseY = y;
|
||||
if(state == 0) lastMouseButton = button;
|
||||
if(state == 0 && button == GLUT_LEFT_BUTTON) {
|
||||
|
||||
// check if a slider needs to be dragged
|
||||
for(ui_slider* s = sliders; s < sliders + sizeof sliders / sizeof(ui_slider); s += 1) {
|
||||
if(ui_slider_mouse_over(s, x, y)) {
|
||||
ui_slider_onclick(s, x, y);
|
||||
|
@ -373,6 +378,7 @@ void mouseEvent(int button, int state, int x, int y) {
|
|||
}
|
||||
}
|
||||
}
|
||||
// release the dragged slider(if there was one)
|
||||
else if(state == 1 && button == GLUT_LEFT_BUTTON) {
|
||||
draggedSlider = NULL;
|
||||
}
|
||||
|
@ -381,7 +387,7 @@ void mouseEvent(int button, int state, int x, int y) {
|
|||
|
||||
void mouseMotionEvent(int x, int y) {
|
||||
if(lastMouseButton == GLUT_LEFT_BUTTON) {
|
||||
if(draggedSlider != NULL) {
|
||||
if(draggedSlider != NULL) { // drag a slider if needed
|
||||
if(ui_slider_mouse_over(draggedSlider, x, y)) {
|
||||
ui_slider_onclick(draggedSlider, x, y);
|
||||
}
|
||||
|
@ -398,6 +404,7 @@ void mouseMotionEvent(int x, int y) {
|
|||
|
||||
}
|
||||
else if(lastMouseButton == GLUT_MIDDLE_BUTTON) {
|
||||
// drag the camera
|
||||
vec3 moveX = rotateByCameraRotation(vec3_new(1.0, 0.0, 0.0));
|
||||
vec3 moveY = rotateByCameraRotation(vec3_new(0.0, 1.0, 0.0));
|
||||
|
||||
|
@ -414,6 +421,7 @@ void mouseMotionEvent(int x, int y) {
|
|||
}
|
||||
|
||||
void mouseWheelEvent(int wheel, int dir, int x, int y) {
|
||||
// slide a slider, if no sliders slided the zoom the camera
|
||||
char slided = 0;
|
||||
for(ui_slider* s = sliders; s < sliders + sizeof sliders / sizeof(ui_slider); s += 1) {
|
||||
if(ui_slider_mouse_over(s, x, y)) {
|
||||
|
@ -430,7 +438,7 @@ void mouseWheelEvent(int wheel, int dir, int x, int y) {
|
|||
}
|
||||
|
||||
void keyboardEvent(unsigned char c, int x, int y) {
|
||||
if(c == '\e') {
|
||||
if(c == '\e') { // exit help, or program
|
||||
if(settings.showHelp) {
|
||||
settings.showHelp = 0;
|
||||
glutPostRedisplay();
|
||||
|
@ -452,7 +460,7 @@ void keyboardEvent(unsigned char c, int x, int y) {
|
|||
glutPostRedisplay();
|
||||
}
|
||||
}
|
||||
|
||||
// main right click menu
|
||||
void onMenuItem(int item) {
|
||||
lastMouseButton = -1; // to prevent jumps in view position/rotation
|
||||
switch(item) {
|
||||
|
@ -483,13 +491,13 @@ void onMenuItem(int item) {
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
// cow control sub menu
|
||||
void onControlCowMenu(int item) {
|
||||
lastMouseButton = GLUT_RIGHT_BUTTON;
|
||||
settings.controlLight = 0;
|
||||
updateCowControl(item);
|
||||
}
|
||||
|
||||
// filter sub menu
|
||||
void onFilterMenu(int item) {
|
||||
lastMouseButton = GLUT_RIGHT_BUTTON;
|
||||
GLenum filters[] = { GL_LINEAR, GL_NEAREST };
|
||||
|
|
8
ui.c
8
ui.c
|
@ -5,16 +5,16 @@
|
|||
#include <GL/glut.h>
|
||||
#include <GL/gl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// originally i also had a ui button, but the right click menu made it much simpler, but that was to allow easily changing the colors for both buttons and sliders
|
||||
#define BACK_COLOR 0.3, 0.35, 0.35
|
||||
|
||||
void ui_slider_draw(ui_slider* s) {
|
||||
int wWidth = glutGet(GLUT_WINDOW_WIDTH);
|
||||
int wHeight = glutGet(GLUT_WINDOW_HEIGHT);
|
||||
|
||||
// calculate position based on the different ui_pos items
|
||||
vec3 pos = vec3_add(s->position.absolute, vec3_new(s->position.relative.x * wWidth, s->position.relative.y * wHeight, 0.0));
|
||||
vec3 ext = s->size;
|
||||
|
||||
// center position
|
||||
vec3 slider = vec3_add(pos, vec3_new(ext.x * s->value, ext.y * 0.5, 0.0));
|
||||
glBegin(GL_QUADS);
|
||||
// draw background line
|
||||
|
@ -31,7 +31,7 @@ void ui_slider_draw(ui_slider* s) {
|
|||
glVertex3f(slider.x - ext.z, slider.y + ext.z, 0.0);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
// checks if the mouse is hovering over the slider
|
||||
char ui_slider_mouse_over(ui_slider* s, int mouseX, int mouseY) {
|
||||
int wWidth = glutGet(GLUT_WINDOW_WIDTH);
|
||||
int wHeight = glutGet(GLUT_WINDOW_HEIGHT);
|
||||
|
|
3
vec.c
3
vec.c
|
@ -20,9 +20,6 @@ vec3 vec3_sub(vec3 a, vec3 b) {
|
|||
vec3 r = { a.x - b.x, a.y - b.y, a.z - b.z };
|
||||
return r;
|
||||
}
|
||||
float vec3_dot(vec3 a, vec3 b) {
|
||||
return a.x * b.x + a.y * b.y + a.z * b.z;
|
||||
}
|
||||
|
||||
vec3 vec3_mult(vec3 a, float s) {
|
||||
vec3 r = { a.x * s, a.y * s, a.z * s };
|
||||
|
|
13
vec.h
13
vec.h
|
@ -1,20 +1,27 @@
|
|||
#ifndef _VEC
|
||||
#define _VEC
|
||||
|
||||
// Vectors and matrices are really useful when doing 2D/3D, esp in games
|
||||
// sadly, i did not really need much more than that, and even the limited usage i had was not as fun as usual
|
||||
// because the way C doesnt allow to define different operators for structs(that is, i cannot do vec3 + vec3)
|
||||
// I know i could have chosen to use c++ or python but i oppose using c++ and decided to take the opportunity to work
|
||||
// on my C programming skills(and i also dont like python)
|
||||
typedef struct _vec3 {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
} vec3;
|
||||
|
||||
// (x, y, z)
|
||||
vec3 vec3_new(float x, float y, float z);
|
||||
// (f, f, f)
|
||||
vec3 vec3_splat(float f);
|
||||
// a + b
|
||||
vec3 vec3_add(vec3 a, vec3 b);
|
||||
// a - b
|
||||
vec3 vec3_sub(vec3 a, vec3 b);
|
||||
float vec3_dot(vec3 a, vec3 b);
|
||||
vec3 vec3_mult(vec3 a, float s);
|
||||
|
||||
// Some opengl extensions to support these vectors
|
||||
// Some opengl extensions to support these vectors - more could be defined, but the usage of the vec struct was annoying
|
||||
void glVertexVec(vec3 v);
|
||||
void glColorVec(vec3 v);
|
||||
|
||||
|
|
Loading…
Reference in a new issue