diff --git a/README.md b/README.md index 2a6f367..724d71c 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Code here is published under the [AGPL-v3](https://www.gnu.org/licenses/agpl-3.0 - Add menu - partially done - Adjust ambient light - Allow changing the move/rotation speed(or just a multiplier) -- Create a cow +- Create a cow - IM SO BAD AT IT IM SO SORRY COWS - Head - Tail - Body @@ -18,13 +18,11 @@ Code here is published under the [AGPL-v3](https://www.gnu.org/licenses/agpl-3.0 - Nose - Eyes - Allow user control of the cow - - Movement - turn and move - WIP - - Head - Tail - Legs? (optional) -- Change camera position to be cow point of view +- Change camera position to be cow point of view - DONE, need to do the sub thing - Add popping-floating text of funny cow thoughts -- Add multiple objects(that is not the cow) +- Add multiple objects(that is not the cow)(is grass an object?) - at least 3 - on needs to be metalic - User controlled light source diff --git a/cow.c b/cow.c index 8c6d807..43692fd 100644 --- a/cow.c +++ b/cow.c @@ -6,7 +6,7 @@ #include #include -vec3 headRot; +vec3 headRot = { -30.0, 0.0, 0.0 }; const vec3 headLimit = { 90.0, 90.0 ,90.0 }; vec3 cowPos = { 0.0, 6.0, 0.0 }; @@ -20,16 +20,20 @@ float deg2rad(float deg) { return deg * 3.14 / 180.0; } +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; +} + void cowMove(char c) { // check for rotations - cowRot += ((c == 'e') - (c == 'q')) * COW_ROT_SPEED; - if(cowRot > 180.0) { cowRot -= 360.0; } - else if(cowRot < -180.0) { cowRot += 360.0; } - printf("rot: %f\n", cowRot); + cowRot = addAndWrapRot(cowRot, ((c == 'e') - (c == 'q')) * COW_ROT_SPEED); // movement - vec3 dir = vec3_new((c == 'd') - (c == 'a'), 0.0, (c == 'w') - (c == 's')); + vec3 dir = vec3_new((c == 'a') - (c == 'd'), 0.0, (c == 'w') - (c == 's')); vec3 r = vec3_splat(0.0); - float rot = deg2rad(cowRot); + float rot = -deg2rad(cowRot); r.z = cosf(rot) * dir.z + sinf(rot) * dir.x; r.x = -sinf(rot) * dir.z + cosf(rot) * dir.x; @@ -37,30 +41,61 @@ void cowMove(char c) { glutPostRedisplay(); } -void drawCow() { +void cowHead(char c) { + headRot.z = addAndWrapRot(headRot.z, ((c == 'e') - (c == 'q')) * COW_ROT_SPEED); + headRot.y = addAndWrapRot(headRot.y, ((c == 'a') - (c == 'd')) * COW_ROT_SPEED); + headRot.x = addAndWrapRot(headRot.x, ((c == 's') - (c == 'w')) * COW_ROT_SPEED); + glutPostRedisplay(); +} + +void drawCow(char cowsPOV) { glMatrixMode(GL_MODELVIEW); glEnable(GL_COLOR_MATERIAL); - glPushMatrix(); + glPushMatrix(); // cow pos // Main cow position - as center of cow body glTranslatef(cowPos.x, cowPos.y, cowPos.z); glRotatef(cowRot, 0.0, 1.0, 0.0); // Draw cow body - glPushMatrix(); + glPushMatrix(); // cow body scale glColor3f(0.8,0.4,0.11); glScalef(1.0, 1.0, 1.5); glutSolidSphere(4.0, 16, 16); - glPopMatrix(); - // head - glPushMatrix(); - glTranslatef(0.0, 0.0, 5.0); - 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); - glutSolidSphere(2.0, 16, 16); - glPopMatrix(); - - glPopMatrix(); + glPopMatrix(); // cow body scale + if(!cowsPOV) { + // head + glPushMatrix(); // head center + glTranslatef(0.0, 1.0, 5.0); + 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); + glutSolidSphere(2.0, 16, 16); + vec3 ePos = vec3_new(0.7, 0.8, 1.3); + vec3 pPos = vec3_new(0.0, 0.2, 0.5); + glPushMatrix(); // eye 1 + glTranslatef(ePos.x, ePos.y, ePos.z); + glColor3f(1.0, 1.0, 1.0); + glutSolidSphere(0.5, 8, 8); + glPushMatrix(); // pupil 1 + glTranslatef(pPos.x, pPos.y, pPos.z); + glColor3f(0.0, 0.0, 0.0); + glutSolidSphere(0.1, 8, 8); + glPopMatrix(); // pupil 1 + glPopMatrix(); // eye 1 + glPushMatrix(); // eye 2 + glTranslatef(-ePos.x, ePos.y, ePos.z); + glColor3f(1.0, 1.0, 1.0); + glutSolidSphere(0.5, 8, 8); + glPushMatrix(); // pupil 2 + glTranslatef(pPos.x, pPos.y, pPos.z); + glColor3f(0.0, 0.0, 0.0); + glutSolidSphere(0.1, 8, 8); + glPopMatrix(); // pupil 2 + glPopMatrix(); // eye 2 + glPopMatrix(); // head center + } + glPopMatrix(); // cow pos + glColor3f(1.0, 1.0, 1.0); glDisable(GL_COLOR_MATERIAL); } void onCowKeyboardInput(char key) { @@ -68,6 +103,8 @@ void onCowKeyboardInput(char key) { case COW_CONTROL_MOVE: cowMove(key); break; + case COW_CONTROL_HEAD: + cowHead(key); default: break; } @@ -75,4 +112,20 @@ void onCowKeyboardInput(char key) { void updateCowControl(enum COW_CONTROL c) { control = c; +} + +void setCameraToCowPOV() { + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + // rotate to look at Z+ + glRotatef(180.0, 0.0, 1.0, 0.0); + // head + glRotatef(-headRot.z, 0.0, 0.0 ,1.0); + glTranslatef(0.0, 0.0, -1.0); + glRotatef(-headRot.x, 1.0, 0.0, 0.0); + glRotatef(-headRot.y, 0.0, 1.0, 0.0); + glTranslatef(0.0, 0.0, -5.0); + // body + glTranslatef(-cowPos.x, -cowPos.y, -cowPos.z); + glRotatef(-cowRot, 0.0, 1.0, 0.0); } \ No newline at end of file diff --git a/cow.h b/cow.h index b2f2784..b7cf600 100644 --- a/cow.h +++ b/cow.h @@ -11,8 +11,9 @@ enum COW_CONTROL { COW_CONTROL_NONE }; -void drawCow(); +void drawCow(char cowsPOV); void onCowKeyboardInput(char key); void updateCowControl(enum COW_CONTROL control); +void setCameraToCowPOV(); #endif \ No newline at end of file diff --git a/mmn_17.c b/mmn_17.c index d3fb301..370515f 100644 --- a/mmn_17.c +++ b/mmn_17.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "ui.h" #include "grass_texture_color.h" #include "help.h" @@ -15,21 +16,48 @@ // Camera rotation and stuff float camRadius = 40.0; vec3 camCenter = { 0.0, 0.0, 0.0 }; -vec3 camRot = { -PI * 0.125, 0.0, 0.0 }; +vec3 camRot = { -PI * 0.25, PI, 0.0 }; struct { unsigned char lockYMovement: 1; unsigned char showHelp: 1; + unsigned char cowsPOV: 1; GLenum textureFilter; + } settings = { - 0, 0, GL_NEAREST, + 0, 0, 0, GL_NEAREST, }; struct { int main; int cowControl; int filters; } menus; // to simply hold the menues in a labed manner +GLuint grassList = -1; +void generateGrassVertexList() { + grassList = glGenLists(1); + glNewList(grassList, GL_COMPILE); + glDisable(GL_CULL_FACE); + for(float x = -50.0; x < 50.0; x += 1.0) { + for(float z = -50.0; z < 50.0; z += 1.0) { + glPushMatrix(); + glTranslatef(x, 0.0, z); + glRotatef(rand() % 360, 0.0, 1.0, 0.0); + glBegin(GL_TRIANGLES); + glVertex3f(0.0, 0.0, 0.0); + glVertex3f(0.5, 0.0, 0.0); + glVertex3f(0.0, 1.5, 0.0); + glVertex3f(0.0, 0.0, 0.0); + glVertex3f(0.0, 0.0, 0.5); + glVertex3f(0.0, 1.5, 0.0); + glEnd(); + glPopMatrix(); + } + } + glEnable(GL_CULL_FACE); + glEndList(); +} + vec3 rotateByCameraRotation(vec3 v) { vec3 r; // rotate along the x axis(yz plane) @@ -119,17 +147,22 @@ void drawWorld(void) { GLdouble wWidth = (GLdouble) glutGet(GLUT_WINDOW_WIDTH); GLdouble wHeight = (GLdouble) glutGet(GLUT_WINDOW_HEIGHT); // Calculate current camera position from rotation - vec3 cp = vec3_new(0.0, 0.0, camRadius); - cp = rotateByCameraRotation(cp); - cp = vec3_add(cp, camCenter); - vec3 up = rotateByCameraRotation(vec3_new(0.0, 1.0, 0.0)); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - gluLookAt(cp.x, cp.y, cp.z, camCenter.x, camCenter.y, camCenter.z, up.x, up.y, up.z); + if(settings.cowsPOV) { + setCameraToCowPOV(); + } + else { + vec3 cp = vec3_new(0.0, 0.0, camRadius); + cp = rotateByCameraRotation(cp); + cp = vec3_add(cp, camCenter); + vec3 up = rotateByCameraRotation(vec3_new(0.0, 1.0, 0.0)); + gluLookAt(cp.x, cp.y, cp.z, camCenter.x, camCenter.y, camCenter.z, up.x, up.y, up.z); + } glMatrixMode(GL_PROJECTION); glLoadIdentity(); - gluPerspective(90, wWidth / wHeight , 1.0, 500.0); + gluPerspective(90, wWidth / wHeight , 0.5, 500.0); // Lights glEnable(GL_LIGHTING); // Ambient light @@ -144,7 +177,7 @@ void drawWorld(void) { glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor); glLightfv(GL_LIGHT0, GL_SPECULAR, lightColor); // World - drawCow(); + drawCow(settings.cowsPOV); // Ground glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, settings.textureFilter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, settings.textureFilter); @@ -159,6 +192,16 @@ void drawWorld(void) { glTexCoord2f(1.0, 0.0); glVertex3f(50.0, 0.0, -50.0); glEnd(); glDisable(GL_TEXTURE_2D); + // Add a simple cube to see where the cow was originally facing + glPushMatrix(); + glTranslatef(0.0, 10.0, 50.0); + glEnable(GL_COLOR_MATERIAL); + glColor3f(1.0, 1.0, 1.0); + glutSolidCube(20.0); + glPopMatrix(); + glColor3f(0.1, 0.3, 0.0); + glCallList(grassList); + glDisable(GL_COLOR_MATERIAL); } void display(void) { @@ -272,6 +315,10 @@ void onMenuItem(int item) { settings.lockYMovement ^= 1; glutChangeToMenuEntry(3, settings.lockYMovement ? "Unlock Y position" : "Lock Y position", 0); break; + case 1: // cow pov + settings.cowsPOV ^= 1; + glutPostRedisplay(); + break; case 2: // Show help settings.showHelp ^= 1; glutPostRedisplay(); @@ -339,6 +386,7 @@ int main(int argc, char** argv) { glEnable(GL_CULL_FACE); glCullFace(GL_BACK); + generateGrassVertexList(); glutMainLoop(); return 0;