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
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
- Adjust ambient light
- help
- quit
- Allow changing the move/rotation speed(or just a multiplier)
- Create a cow
- Head
@ -20,15 +18,17 @@ 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
- Movement - turn and move - WIP
- Head
- Tail
- Legs? (optional)
- Change camera position to be cow point of view
- Add popping-floating text of funny cow thoughts
- Add multiple objects(that is not the cow)
- at least 3
- on needs to be metalic
- User controlled light source
- Add light source
- move the light
- 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"
"Scroll wheel to control camera zoom.\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"
"ESC to close this popup, ESC again to exit the program.\n"
;

View File

@ -8,12 +8,12 @@
#include "ui.h"
#include "grass_texture_color.h"
#include "help.h"
#include "cow.h"
// close enough
#define PI 3.14
// Camera rotation and stuff
float camRadius = 10.0;
float camRadius = 40.0;
vec3 camCenter = { 0.0, 0.0, 0.0 };
vec3 camRot = { -PI * 0.125, 0.0, 0.0 };
struct {
@ -48,11 +48,22 @@ int lastMouseX = 0, lastMouseY = 0;
ui_slider* draggedSlider = NULL;
ui_button buttons[] = {}; // TODO: maybe delete? the menu thing is easier to work with
ui_slider sliders[] = {
{
/* pos */ { { 0.9, 0.7, 0.0 }, { -50.0, -5.0, 0.0 } },
{ // ambient red
/* pos */ { { 0.9, 0.9, 0.0 }, { -50.0, -10.0, 0.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) {
@ -75,6 +86,13 @@ void drawUi(void) {
for(ui_slider* s = sliders; s < sliders + sizeof sliders / sizeof(ui_slider); s += 1) {
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) {
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.1, wHeight * 0.9, 0.0);
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();
@ -94,7 +115,6 @@ void drawUi(void) {
void drawWorld(void) {
glEnable(GL_DEPTH_TEST);
// set perspective camera
GLdouble wWidth = (GLdouble) glutGet(GLUT_WINDOW_WIDTH);
GLdouble wHeight = (GLdouble) glutGet(GLUT_WINDOW_HEIGHT);
@ -112,11 +132,19 @@ void drawWorld(void) {
gluPerspective(90, wWidth / wHeight , 1.0, 500.0);
// Lights
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);
// Directional light - aka light
GLfloat light1[] = { 0.0, 1.0, 0.0, 0.0 };
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
drawCow();
// Ground
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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);
glEnd();
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) {
@ -242,9 +262,7 @@ void keyboardEvent(unsigned char c, int x, int y) {
exit(0);
}
}
if(c == 'a') {
glutPostRedisplay();
}
onCowKeyboardInput(c);
}
void onMenuItem(int item) {
@ -258,13 +276,23 @@ void onMenuItem(int item) {
settings.showHelp ^= 1;
glutPostRedisplay();
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) {
lastMouseButton = GLUT_RIGHT_BUTTON;
printf("Control cow: %d\n", item);
updateCowControl(item);
}
void onFilterMenu(int item) {
lastMouseButton = GLUT_RIGHT_BUTTON;
GLenum filters[] = { GL_LINEAR, GL_NEAREST };
@ -274,9 +302,9 @@ void onFilterMenu(int item) {
void menuSetup() {
// control cow sub-menu
menus.cowControl = glutCreateMenu(onControlCowMenu);
glutAddMenuEntry("Movement", 0);
glutAddMenuEntry("Head", 1);
glutAddMenuEntry("Tail", 2);
glutAddMenuEntry("Movement", COW_CONTROL_MOVE);
glutAddMenuEntry("Head", COW_CONTROL_HEAD);
glutAddMenuEntry("Tail", COW_CONTROL_TAIL);
// filters
menus.filters = glutCreateMenu(onFilterMenu);
glutAddMenuEntry("Linear", 0);
@ -287,7 +315,9 @@ void menuSetup() {
glutAddSubMenu("Texture filters", menus.filters);
glutAddMenuEntry("Lock Y position", 0);
glutAddMenuEntry("Change to Cow POV", 1);
glutAddMenuEntry("Reset view", 3);
glutAddMenuEntry("Help", 2);
glutAddMenuEntry("Quit", 4);
glutAttachMenu(GLUT_RIGHT_BUTTON);
}
@ -298,7 +328,7 @@ int main(int argc, char** argv) {
glutInitWindowSize(800, 500);
glutInitWindowPosition(450, 450);
/* create window and set callbacks */
glutCreateWindow("World of Cow");
glutCreateWindow("World of Cow - Aviv Romem");
glutDisplayFunc(display);
glutMouseFunc(mouseEvent);
glutKeyboardFunc(keyboardEvent);