right click menu, now rotation is done using left click

This commit is contained in:
Rusty Striker 2023-07-16 17:47:09 +03:00
parent e067a7b974
commit 57262da912
3 changed files with 96 additions and 44 deletions

View file

@ -6,6 +6,11 @@ Code here is published under the [AGPL-v3](https://www.gnu.org/licenses/agpl-3.0
# TODO
- Add menu - partially done
- Adjust ambient light
- help
- quit
- Allow changing the move/rotation speed(or just a multiplier)
- Create a cow
- Head
- Tail
@ -21,10 +26,6 @@ Code here is published under the [AGPL-v3](https://www.gnu.org/licenses/agpl-3.0
- Legs? (optional)
- Change camera position to be cow point of view
- Add popping-floating text of funny cow thoughts
- Add menu
- Adjust ambient light
- help
- quit
- Add multiple objects(that is not the cow)
- User controlled light source
- Add light source

9
help.h Normal file
View file

@ -0,0 +1,9 @@
const unsigned char helpString[] =
"World of Cow by Aviv Romem\n"
"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"
"Left click/scroll wheel on a slider to change its value.\n"
"ESC to close this popup, ESC again to exit the program.\n"
;

122
mmn_17.c
View file

@ -7,6 +7,7 @@
#include <math.h>
#include "ui.h"
#include "grass_texture_color.h"
#include "help.h"
// close enough
#define PI 3.14
@ -17,10 +18,17 @@ vec3 camCenter = { 0.0, 0.0, 0.0 };
vec3 camRot = { -PI * 0.125, 0.0, 0.0 };
struct {
unsigned char lockYMovement: 1;
unsigned char showHelp: 1;
GLenum textureFilter;
} settings = {
0, GL_NEAREST,
0, 0, GL_NEAREST,
};
struct {
int main;
int cowControl;
int filters;
} menus; // to simply hold the menues in a labed manner
vec3 rotateByCameraRotation(vec3 v) {
vec3 r;
@ -38,23 +46,7 @@ vec3 rotateByCameraRotation(vec3 v) {
int lastMouseButton = GLUT_LEFT_BUTTON;
int lastMouseX = 0, lastMouseY = 0;
ui_slider* draggedSlider = NULL;
void changeFilterButton();
void lockYButton();
ui_button buttons[] = {
{
/* pos */ { { 0.9, 0.5, 0.0 }, { -65.0, -20.0, 0.0 } },
/* size */ { 130.0, 40.0, 0.0 },
/* onclick */ changeFilterButton,
/* text */ "Cycle filter",
0
},
{
{ { 0.9, 0.5, 0.0 }, { -50.0, 25.0, 0.0 } },
{ 100.0, 40.0, 0.0 },
lockYButton,
"Lock Y"
}
};
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 } },
@ -63,18 +55,6 @@ ui_slider sliders[] = {
}
};
void changeFilterButton() {
static int current = 0;
GLenum filters[] = { GL_NEAREST, GL_LINEAR };
current = (current + 1) % (sizeof(filters) / sizeof(GLenum));
settings.textureFilter = filters[current];
glutPostRedisplay();
}
void lockYButton() {
settings.lockYMovement ^= 1;
buttons[1].text = settings.lockYMovement ? "Unlock Y" : "Lock Y";
}
void drawUi(void) {
glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);
@ -96,6 +76,16 @@ void drawUi(void) {
ui_slider_draw(s);
}
if(settings.showHelp) {
glColor3f(0.3, 0.3, 0.3);
glBegin(GL_QUADS);
glVertex3f(wWidth * 0.1, wHeight * 0.1, 0.0);
glVertex3f(wWidth * 0.9, wHeight * 0.1, 0.0);
glVertex3f(wWidth * 0.9, wHeight * 0.9, 0.0);
glVertex3f(wWidth * 0.1, wHeight * 0.9, 0.0);
glEnd();
}
int err = glGetError();
if(err != 0) {
printf("opengl error %d: %s\n", err, gluErrorString(err));
@ -199,6 +189,15 @@ void mouseMotionEvent(int x, int y) {
ui_slider_onclick(draggedSlider, x, y);
}
}
else {
// rotate the camera
camRot.y -= (x - lastMouseX) * PI * 0.01;
if(camRot.y > 2 * PI) camRot.y -= 2 * PI;
else if(camRot.y < 0.0) camRot.y += 2 * PI;
camRot.x = fmin(PI * 0.5, fmax(-PI * 0.5, camRot.x - (y - lastMouseY) * 0.01 * PI));
}
}
else if(lastMouseButton == GLUT_MIDDLE_BUTTON) {
vec3 moveX = rotateByCameraRotation(vec3_new(1.0, 0.0, 0.0));
@ -212,14 +211,6 @@ void mouseMotionEvent(int x, int y) {
camCenter = vec3_add(camCenter, vec3_mult(moveX, (lastMouseX - x)));
camCenter = vec3_add(camCenter, vec3_mult(moveY, (y - lastMouseY)));
}
else if(lastMouseButton == GLUT_RIGHT_BUTTON) {
// rotate the camera
camRot.y -= (x - lastMouseX) * PI * 0.01;
if(camRot.y > 2 * PI) camRot.y -= 2 * PI;
else if(camRot.y < 0.0) camRot.y += 2 * PI;
camRot.x = fmin(PI * 0.5, fmax(-PI * 0.5, camRot.x - (y - lastMouseY) * 0.01 * PI));
}
lastMouseX = x; lastMouseY = y;
glutPostRedisplay();
}
@ -242,14 +233,64 @@ void mouseWheelEvent(int wheel, int dir, int x, int y) {
void keyboardEvent(unsigned char c, int x, int y) {
if(c == '\e') {
glutLeaveMainLoop();
exit(0);
if(settings.showHelp) {
settings.showHelp = 0;
glutPostRedisplay();
}
else {
glutLeaveMainLoop();
exit(0);
}
}
if(c == 'a') {
glutPostRedisplay();
}
}
void onMenuItem(int item) {
lastMouseButton = -1; // to prevent jumps in view position/rotation
switch(item) {
case 0: // Lock y
settings.lockYMovement ^= 1;
glutChangeToMenuEntry(3, settings.lockYMovement ? "Unlock Y position" : "Lock Y position", 0);
break;
case 2: // Show help
settings.showHelp ^= 1;
glutPostRedisplay();
break;
}
}
void onControlCowMenu(int item) {
lastMouseButton = GLUT_RIGHT_BUTTON;
printf("Control cow: %d\n", item);
}
void onFilterMenu(int item) {
lastMouseButton = GLUT_RIGHT_BUTTON;
GLenum filters[] = { GL_LINEAR, GL_NEAREST };
settings.textureFilter = filters[item];
}
void menuSetup() {
// control cow sub-menu
menus.cowControl = glutCreateMenu(onControlCowMenu);
glutAddMenuEntry("Movement", 0);
glutAddMenuEntry("Head", 1);
glutAddMenuEntry("Tail", 2);
// filters
menus.filters = glutCreateMenu(onFilterMenu);
glutAddMenuEntry("Linear", 0);
glutAddMenuEntry("Nearest", 1);
menus.main = glutCreateMenu(onMenuItem);
glutAddSubMenu("Control Cow", menus.cowControl);
glutAddSubMenu("Texture filters", menus.filters);
glutAddMenuEntry("Lock Y position", 0);
glutAddMenuEntry("Change to Cow POV", 1);
glutAddMenuEntry("Help", 2);
glutAttachMenu(GLUT_RIGHT_BUTTON);
}
int main(int argc, char** argv) {
/* initialize glut and window */
glutInit(&argc, argv);
@ -263,6 +304,7 @@ int main(int argc, char** argv) {
glutKeyboardFunc(keyboardEvent);
glutMouseWheelFunc(mouseWheelEvent);
glutMotionFunc(mouseMotionEvent);
menuSetup();
// set up some rendering related stuff
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);