s'more work

This commit is contained in:
Rusty Striker 2023-07-22 15:47:51 +03:00
parent 57262da912
commit da1a25ddfc
6 changed files with 155 additions and 28 deletions

View file

@ -1,4 +1,4 @@
OBJ = ui.o vec.o OBJ = ui.o vec.o cow.o
CFLAGS = -g -Wall CFLAGS = -g -Wall
build: $(OBJ) build: $(OBJ)

View file

@ -8,8 +8,6 @@ Code here is published under the [AGPL-v3](https://www.gnu.org/licenses/agpl-3.0
- Add menu - partially done - Add menu - partially done
- Adjust ambient light - Adjust ambient light
- help
- quit
- Allow changing the move/rotation speed(or just a multiplier) - Allow changing the move/rotation speed(or just a multiplier)
- Create a cow - Create a cow
- Head - Head
@ -20,15 +18,17 @@ Code here is published under the [AGPL-v3](https://www.gnu.org/licenses/agpl-3.0
- Nose - Nose
- Eyes - Eyes
- Allow user control of the cow - Allow user control of the cow
- Movement - turn and move - Movement - turn and move - WIP
- Head - Head
- Tail - Tail
- Legs? (optional) - Legs? (optional)
- Change camera position to be cow point of view - Change camera position to be cow point of view
- Add popping-floating text of funny cow thoughts - Add popping-floating text of funny cow thoughts
- Add multiple objects(that is not the cow) - Add multiple objects(that is not the cow)
- at least 3
- on needs to be metalic
- User controlled light source - User controlled light source
- Add light source - Add light source
- move the light - move the light
- change intensity - change intensity
- Add Textures and stuff :) - Add Textures and stuff :)(optional)

78
cow.c Normal file
View file

@ -0,0 +1,78 @@
#include <GL/freeglut_std.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include "cow.h"
#include "vec.h"
#include <math.h>
#include <stdio.h>
vec3 headRot;
const vec3 headLimit = { 90.0, 90.0 ,90.0 };
vec3 cowPos = { 0.0, 6.0, 0.0 };
float cowRot = 0.0; // rotation along the Y axis
const float COW_ROT_SPEED = 5.0;
const float COW_MOVE_SPEED = 1.0;
enum COW_CONTROL control;
float deg2rad(float deg) {
return deg * 3.14 / 180.0;
}
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);
// movement
vec3 dir = vec3_new((c == 'd') - (c == 'a'), 0.0, (c == 'w') - (c == 's'));
vec3 r = vec3_splat(0.0);
float rot = deg2rad(cowRot);
r.z = cosf(rot) * dir.z + sinf(rot) * dir.x;
r.x = -sinf(rot) * dir.z + cosf(rot) * dir.x;
cowPos = vec3_add(cowPos, vec3_mult(r, COW_MOVE_SPEED));
glutPostRedisplay();
}
void drawCow() {
glMatrixMode(GL_MODELVIEW);
glEnable(GL_COLOR_MATERIAL);
glPushMatrix();
// 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();
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();
glDisable(GL_COLOR_MATERIAL);
}
void onCowKeyboardInput(char key) {
switch(control) {
case COW_CONTROL_MOVE:
cowMove(key);
break;
default:
break;
}
}
void updateCowControl(enum COW_CONTROL c) {
control = c;
}

18
cow.h Normal file
View file

@ -0,0 +1,18 @@
#ifndef COWS_ARE_COOL
#define COWS_ARE_COOL
/*
Helper file(with cow.c) to de-clutter mmn_17.c by taking all cow logic to another file
*/
enum COW_CONTROL {
COW_CONTROL_MOVE,
COW_CONTROL_HEAD,
COW_CONTROL_TAIL,
COW_CONTROL_NONE
};
void drawCow();
void onCowKeyboardInput(char key);
void updateCowControl(enum COW_CONTROL control);
#endif

3
help.h
View file

@ -3,7 +3,8 @@ const unsigned char helpString[] =
"Left/Middle mouse to control camera rotation/Position.\n" "Left/Middle mouse to control camera rotation/Position.\n"
"Scroll wheel to control camera zoom.\n" "Scroll wheel to control camera zoom.\n"
"WASD keys to control the cow.\n" "WASD keys to control the cow.\n"
"Different parts of the cow can be controlled by select\n a different part in the right click menu(under 'Control Cow').\n" "QE to rotate cow(when in control movement mode).\n"
"Different parts of the cow can be controlled by selecting\n a different part in the right click menu(under 'Control Cow').\n"
"Left click/scroll wheel on a slider to change its value.\n" "Left click/scroll wheel on a slider to change its value.\n"
"ESC to close this popup, ESC again to exit the program.\n" "ESC to close this popup, ESC again to exit the program.\n"
; ;

View file

@ -8,12 +8,12 @@
#include "ui.h" #include "ui.h"
#include "grass_texture_color.h" #include "grass_texture_color.h"
#include "help.h" #include "help.h"
#include "cow.h"
// close enough // close enough
#define PI 3.14 #define PI 3.14
// Camera rotation and stuff // Camera rotation and stuff
float camRadius = 10.0; float camRadius = 40.0;
vec3 camCenter = { 0.0, 0.0, 0.0 }; vec3 camCenter = { 0.0, 0.0, 0.0 };
vec3 camRot = { -PI * 0.125, 0.0, 0.0 }; vec3 camRot = { -PI * 0.125, 0.0, 0.0 };
struct { struct {
@ -48,11 +48,22 @@ int lastMouseX = 0, lastMouseY = 0;
ui_slider* draggedSlider = NULL; ui_slider* draggedSlider = NULL;
ui_button buttons[] = {}; // TODO: maybe delete? the menu thing is easier to work with ui_button buttons[] = {}; // TODO: maybe delete? the menu thing is easier to work with
ui_slider sliders[] = { ui_slider sliders[] = {
{ { // ambient red
/* pos */ { { 0.9, 0.7, 0.0 }, { -50.0, -5.0, 0.0 } }, /* pos */ { { 0.9, 0.9, 0.0 }, { -50.0, -10.0, 0.0 } },
/* size */ { 100.0, 10.0, 10.0 }, /* size */ { 100.0, 10.0, 10.0 },
0.1 0.0
},
{ // ambient green
/* pos */ { { 0.9, 0.9, 0.0 }, { -50.0, -40.0, 0.0 } },
/* size */ { 100.0, 10.0, 10.0 },
0.0
},
{ // ambient blue
/* pos */ { { 0.9, 0.9, 0.0 }, { -50.0, -70.0, 0.0 } },
/* size */ { 100.0, 10.0, 10.0 },
0.3
} }
}; };
void drawUi(void) { void drawUi(void) {
@ -75,6 +86,13 @@ void drawUi(void) {
for(ui_slider* s = sliders; s < sliders + sizeof sliders / sizeof(ui_slider); s += 1) { for(ui_slider* s = sliders; s < sliders + sizeof sliders / sizeof(ui_slider); s += 1) {
ui_slider_draw(s); ui_slider_draw(s);
} }
// sliders labels
glColor3f(1.0, 1.0, 1.0);
unsigned char t[] = "Ambient light";
glRasterPos2f(wWidth * 0.9 - glutBitmapLength(GLUT_BITMAP_TIMES_ROMAN_24, t) * 0.5, wHeight * 0.90 + 20.0);
glutBitmapString(GLUT_BITMAP_TIMES_ROMAN_24, t);
glRasterPos2f(wWidth * 0.9 - 75.0, wHeight * 0.9 - 10.0);
glutBitmapString(GLUT_BITMAP_TIMES_ROMAN_24, (unsigned char*)"r\ng\nb");
if(settings.showHelp) { if(settings.showHelp) {
glColor3f(0.3, 0.3, 0.3); glColor3f(0.3, 0.3, 0.3);
@ -84,6 +102,9 @@ void drawUi(void) {
glVertex3f(wWidth * 0.9, wHeight * 0.9, 0.0); glVertex3f(wWidth * 0.9, wHeight * 0.9, 0.0);
glVertex3f(wWidth * 0.1, wHeight * 0.9, 0.0); glVertex3f(wWidth * 0.1, wHeight * 0.9, 0.0);
glEnd(); glEnd();
glColor3f(1.0,1.0,1.0);
glRasterPos2f(wWidth * 0.12, wHeight * 0.8);
glutBitmapString(GLUT_BITMAP_TIMES_ROMAN_24, helpString);
} }
int err = glGetError(); int err = glGetError();
@ -94,7 +115,6 @@ void drawUi(void) {
void drawWorld(void) { void drawWorld(void) {
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
// set perspective camera // set perspective camera
GLdouble wWidth = (GLdouble) glutGet(GLUT_WINDOW_WIDTH); GLdouble wWidth = (GLdouble) glutGet(GLUT_WINDOW_WIDTH);
GLdouble wHeight = (GLdouble) glutGet(GLUT_WINDOW_HEIGHT); GLdouble wHeight = (GLdouble) glutGet(GLUT_WINDOW_HEIGHT);
@ -112,11 +132,19 @@ void drawWorld(void) {
gluPerspective(90, wWidth / wHeight , 1.0, 500.0); gluPerspective(90, wWidth / wHeight , 1.0, 500.0);
// Lights // Lights
glEnable(GL_LIGHTING); glEnable(GL_LIGHTING);
// Ambient light
GLfloat ambient[] = { sliders[0].value, sliders[1].value, sliders[2].value, 1.0 };
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
glEnable(GL_LIGHT0); glEnable(GL_LIGHT0);
// Directional light - aka light // Directional light - aka light
GLfloat light1[] = { 0.0, 1.0, 0.0, 0.0 }; GLfloat light1[] = { 0.0, 1.0, 0.0, 0.0 };
glLightfv(GL_LIGHT0, GL_POSITION, light1); glLightfv(GL_LIGHT0, GL_POSITION, light1);
GLfloat lightColor[] = {0.5, 0.4, 0.1, 1.0};
glLightfv(GL_LIGHT0, GL_AMBIENT, lightColor);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor);
glLightfv(GL_LIGHT0, GL_SPECULAR, lightColor);
// World // World
drawCow();
// Ground // Ground
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, settings.textureFilter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, settings.textureFilter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, settings.textureFilter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, settings.textureFilter);
@ -131,14 +159,6 @@ void drawWorld(void) {
glTexCoord2f(1.0, 0.0); glVertex3f(50.0, 0.0, -50.0); glTexCoord2f(1.0, 0.0); glVertex3f(50.0, 0.0, -50.0);
glEnd(); glEnd();
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glTranslatef(0.0, 5.0, 0.0);
glScalef(3.0, 3.0, 3.0);
glColor3f(1.0, 1.0, 1.0);
glutSolidDodecahedron();
glPopMatrix();
} }
void display(void) { void display(void) {
@ -242,9 +262,7 @@ void keyboardEvent(unsigned char c, int x, int y) {
exit(0); exit(0);
} }
} }
if(c == 'a') { onCowKeyboardInput(c);
glutPostRedisplay();
}
} }
void onMenuItem(int item) { void onMenuItem(int item) {
@ -258,13 +276,23 @@ void onMenuItem(int item) {
settings.showHelp ^= 1; settings.showHelp ^= 1;
glutPostRedisplay(); glutPostRedisplay();
break; break;
case 3: // reste view
camRadius = 40.0;
camCenter = vec3_new(0.0, 0.0, 0.0);
camRot = vec3_new(-PI * 0.125, 0.0, 0.0);
glutPostRedisplay();
break;
case 4: // quit
glutLeaveMainLoop();
exit(0);
} }
} }
void onControlCowMenu(int item) { void onControlCowMenu(int item) {
lastMouseButton = GLUT_RIGHT_BUTTON; lastMouseButton = GLUT_RIGHT_BUTTON;
printf("Control cow: %d\n", item); updateCowControl(item);
} }
void onFilterMenu(int item) { void onFilterMenu(int item) {
lastMouseButton = GLUT_RIGHT_BUTTON; lastMouseButton = GLUT_RIGHT_BUTTON;
GLenum filters[] = { GL_LINEAR, GL_NEAREST }; GLenum filters[] = { GL_LINEAR, GL_NEAREST };
@ -274,9 +302,9 @@ void onFilterMenu(int item) {
void menuSetup() { void menuSetup() {
// control cow sub-menu // control cow sub-menu
menus.cowControl = glutCreateMenu(onControlCowMenu); menus.cowControl = glutCreateMenu(onControlCowMenu);
glutAddMenuEntry("Movement", 0); glutAddMenuEntry("Movement", COW_CONTROL_MOVE);
glutAddMenuEntry("Head", 1); glutAddMenuEntry("Head", COW_CONTROL_HEAD);
glutAddMenuEntry("Tail", 2); glutAddMenuEntry("Tail", COW_CONTROL_TAIL);
// filters // filters
menus.filters = glutCreateMenu(onFilterMenu); menus.filters = glutCreateMenu(onFilterMenu);
glutAddMenuEntry("Linear", 0); glutAddMenuEntry("Linear", 0);
@ -287,7 +315,9 @@ void menuSetup() {
glutAddSubMenu("Texture filters", menus.filters); glutAddSubMenu("Texture filters", menus.filters);
glutAddMenuEntry("Lock Y position", 0); glutAddMenuEntry("Lock Y position", 0);
glutAddMenuEntry("Change to Cow POV", 1); glutAddMenuEntry("Change to Cow POV", 1);
glutAddMenuEntry("Reset view", 3);
glutAddMenuEntry("Help", 2); glutAddMenuEntry("Help", 2);
glutAddMenuEntry("Quit", 4);
glutAttachMenu(GLUT_RIGHT_BUTTON); glutAttachMenu(GLUT_RIGHT_BUTTON);
} }
@ -298,7 +328,7 @@ int main(int argc, char** argv) {
glutInitWindowSize(800, 500); glutInitWindowSize(800, 500);
glutInitWindowPosition(450, 450); glutInitWindowPosition(450, 450);
/* create window and set callbacks */ /* create window and set callbacks */
glutCreateWindow("World of Cow"); glutCreateWindow("World of Cow - Aviv Romem");
glutDisplayFunc(display); glutDisplayFunc(display);
glutMouseFunc(mouseEvent); glutMouseFunc(mouseEvent);
glutKeyboardFunc(keyboardEvent); glutKeyboardFunc(keyboardEvent);