diff --git a/.gitignore b/.gitignore index 40960fe..e269c72 100644 --- a/.gitignore +++ b/.gitignore @@ -18,8 +18,8 @@ /TODO # Visual Studio Files -/OpenGL/x64/Debug /x64/Debug +/x64/Release *.db *.suo *.opendb diff --git a/game-template.vcxproj b/game-template.vcxproj index a0a390b..a91ce11 100644 --- a/game-template.vcxproj +++ b/game-template.vcxproj @@ -101,6 +101,7 @@ _DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true CompileAsC + true Windows @@ -134,16 +135,22 @@ true - Console + Windows true true true + opengl32.lib;%(AdditionalDependencies) + + + + + Default @@ -171,22 +178,29 @@ Default + + + + + + + @@ -194,6 +208,7 @@ + diff --git a/game-template.vcxproj.filters b/game-template.vcxproj.filters index 2076011..8c2f45b 100644 --- a/game-template.vcxproj.filters +++ b/game-template.vcxproj.filters @@ -46,6 +46,12 @@ {a58543b1-e451-49f9-8eeb-58b7a45fa8d0} + + {1e656dd0-50ee-4d6a-aecb-1fb3b9f7a250} + + + {854bd0cd-243c-4e01-b9c2-5102dc972d40} + @@ -99,6 +105,27 @@ Source Files\obj + + Source Files\obj\prim + + + Source Files\obj\prim + + + Source Files\obj + + + Source Files\obj + + + Source Files\obj + + + Source Files\util + + + Source Files\mode + @@ -149,6 +176,24 @@ Header Files\obj + + Header Files\util + + + Header Files\obj + + + Header Files\obj + + + Header Files\obj + + + Header Files\obj + + + Header Files\mode + diff --git a/game-template.vcxproj.user b/game-template.vcxproj.user index 728c708..9fbb550 100644 --- a/game-template.vcxproj.user +++ b/game-template.vcxproj.user @@ -1,13 +1,12 @@  - - + 2>&1 WindowsLocalDebugger Auto WindowsLocalDebugger - 2> &1 + 2>&1 \ No newline at end of file diff --git a/src/Makefile.am b/src/Makefile.am index 6333dae..f40f132 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,21 +1,27 @@ bin_PROGRAMS = main main_SOURCES = \ graphics/contexts/glxcontext.c \ + graphics/objects/actor.c \ + graphics/objects/collision_index.c \ + graphics/objects/hedrons.c \ + graphics/objects/prisms.c \ + graphics/objects/scene.c \ + graphics/objects/texture.c \ + graphics/primitives/collision/collision_box.c \ + graphics/primitives/collision/collision_router.c \ graphics/primitives/grid2d.c \ graphics/primitives/grid3d.c \ graphics/primitives/point2d.c \ graphics/primitives/point3d.c \ graphics/primitives/poly2d.c \ graphics/primitives/poly3d.c \ - graphics/objects/hedrons.c \ - graphics/objects/prisms.c \ - graphics/objects/scene.c \ - graphics/objects/texture.c \ input/glxevent.c \ + modes/actor_test.c \ modes/diamond.c \ modes/map.c \ modes/sandbox.c \ modes/scene_test.c \ modes/stage.c \ + util/veccomp.c \ main.c main_LDFLAGS = -lX11 diff --git a/src/graphics/contexts/glcontext.h b/src/graphics/contexts/glcontext.h index 13bf48a..441ce0a 100644 --- a/src/graphics/contexts/glcontext.h +++ b/src/graphics/contexts/glcontext.h @@ -11,9 +11,11 @@ extern "C" { #include #include #include +#include #include #include #include +#include #ifdef _WIN32 #include "wglcontext.h" @@ -21,15 +23,25 @@ extern "C" { #include "glxcontext.h" #endif /* _WIN32 */ +#define DEFAULT_WIDTH 640 +#define DEFAULT_HEIGHT 480 unsigned short xres; unsigned short yres; +double current_ratio; bool isfullscreen; +void drawframe(); void setwindowed(unsigned short w_xres, unsigned short w_yres); void setfullscreen(void); + +#ifndef NDEBUG +static GLenum gl_errno; +#endif /* NDEBUG */ #ifdef __cplusplus }; #endif /* __cplusplus */ #endif /* __GLCONTEXT_H__ */ + + diff --git a/src/graphics/contexts/glxcontext.c b/src/graphics/contexts/glxcontext.c index a2ab74c..82ac57d 100644 --- a/src/graphics/contexts/glxcontext.c +++ b/src/graphics/contexts/glxcontext.c @@ -16,7 +16,6 @@ void glxinit() int config_count; dpy = NULL; vis = NULL; - isfullscreen = true; /* open X display */ dpy = XOpenDisplay(NULL); @@ -35,9 +34,18 @@ void glxinit() /* determine default screen */ screen_number = XDefaultScreen(dpy); - /* get resolution */ - xres = XDisplayWidth(dpy, screen_number); - yres = XDisplayHeight(dpy, screen_number); + if (isfullscreen) { + /* get resolution */ + xres = XDisplayWidth(dpy, screen_number); + yres = XDisplayHeight(dpy, screen_number); + } + else { + xres = 640; + yres = 480; + } + + /* set aspect ratio */ + current_ratio = (double) xres / (double) yres; /* retrieve root window */ root = XRootWindow(dpy, screen_number); @@ -87,7 +95,8 @@ void glxinit() /* set input events */ attrs.event_mask = KeyPressMask | KeyReleaseMask | StructureNotifyMask | PointerMotionMask; - attrs.override_redirect = True; + + attrs.override_redirect = isfullscreen ? True : False; /* create window */ win = XCreateWindow( @@ -193,6 +202,9 @@ void glxfree(void) return; } +/* + * setwindowed - pop out to window of defined resolution + */ void setwindowed(unsigned short w_xres, unsigned short w_yres) { if (isfullscreen) { @@ -244,6 +256,9 @@ void setwindowed(unsigned short w_xres, unsigned short w_yres) return; } +/* + * setfullscreen - set to fullscreen at current resolution + */ void setfullscreen(void) { if (!isfullscreen) { @@ -277,6 +292,13 @@ void setfullscreen(void) exit(EXIT_FAILURE); } + /* determine default screen */ + screen_number = XDefaultScreen(dpy); + + /* get resolution */ + xres = XDisplayWidth(dpy, screen_number); + yres = XDisplayHeight(dpy, screen_number); + /* resize window */ XMoveResizeWindow(dpy, win, 0, 0, xres, yres); @@ -292,3 +314,11 @@ void setfullscreen(void) return; } + +/* + * render a frame + */ +void drawframe() { + glXSwapBuffers(dpy, window); + return; +} diff --git a/src/graphics/contexts/wglcontext.c b/src/graphics/contexts/wglcontext.c index 3bc3e59..fc913cf 100644 --- a/src/graphics/contexts/wglcontext.c +++ b/src/graphics/contexts/wglcontext.c @@ -20,7 +20,6 @@ void wglinit(HINSTANCE hInstance, int nShowCmd, WNDPROC wndproc) MONITORINFO monitor_info; PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL; monitor_info.cbSize = sizeof (MONITORINFO); - isfullscreen = true; /* save these properties for screen switching */ wgl_hInstance = hInstance; @@ -64,6 +63,9 @@ void wglinit(HINSTANCE hInstance, int nShowCmd, WNDPROC wndproc) /* get resolution */ xres = (unsigned short) (monitor_info.rcMonitor.right - monitor_info.rcMonitor.left); yres = (unsigned short) (monitor_info.rcMonitor.bottom - monitor_info.rcMonitor.top); + + /* set aspect ratio */ + current_ratio = (double) xres / (double) yres; /* set pixel format attributes */ PIXELFORMATDESCRIPTOR pfd = { @@ -89,11 +91,11 @@ void wglinit(HINSTANCE hInstance, int nShowCmd, WNDPROC wndproc) wnd = CreateWindow( L"MainWndClass" ,L"OpenGL" - ,WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN + ,(isfullscreen ? WS_POPUP : WS_OVERLAPPEDWINDOW) | WS_CLIPSIBLINGS | WS_CLIPCHILDREN ,0 ,0 - ,xres - ,yres + ,isfullscreen ? xres : DEFAULT_WIDTH + ,isfullscreen ? yres : DEFAULT_HEIGHT ,(HWND) NULL ,(HMENU) NULL ,hInstance @@ -126,8 +128,7 @@ void wglinit(HINSTANCE hInstance, int nShowCmd, WNDPROC wndproc) /* create context */ context = wglCreateContext(dc); - /* hide cursor */ - ShowCursor(FALSE); + if (isfullscreen) ShowCursor(FALSE); /* hide cursor on fullscreen */ /* associate context to window */ wglMakeCurrent(dc, context); @@ -215,6 +216,9 @@ void wglfree(HINSTANCE hInstance) return; } +/* + * setwindowed - pop out to window of defined resolution + */ void setwindowed(unsigned short w_xres, unsigned short w_yres) { RECT client_rect; @@ -264,6 +268,9 @@ void setwindowed(unsigned short w_xres, unsigned short w_yres) return; } +/* + * setfullscreen - set to fullscreen at current resolution + */ void setfullscreen(void) { if (!isfullscreen) { @@ -307,4 +314,12 @@ void setfullscreen(void) } return; -} \ No newline at end of file +} + +/* + * render a frame + */ +void drawframe() { + SwapBuffers(dc); + return; +} diff --git a/src/graphics/objects/actor.c b/src/graphics/objects/actor.c new file mode 100644 index 0000000..37fa434 --- /dev/null +++ b/src/graphics/objects/actor.c @@ -0,0 +1,4 @@ +/* + * actor - an acting object in 3D space + */ +#include "actor.h" diff --git a/src/graphics/objects/actor.h b/src/graphics/objects/actor.h new file mode 100644 index 0000000..0f5b986 --- /dev/null +++ b/src/graphics/objects/actor.h @@ -0,0 +1,59 @@ +/* + * actor - an acting object in 3D space + */ +#ifndef __ACTOR_H__ +#define __ACTOR_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* collision objects */ +#include "../primitives/collision.h" + +/* + * an actor is a type object + * an actor distinguishes itself from an environment + * types are defined by modes + * an actor has a current: + * type_router - do we call a generic type router + * model - model being displayed, TODO: need to implement model abstraction + * routine - current routine + * collision_data - collision info structure + * properties - TODO: implement abstraction for actor properties + * position + * size + * router - function that routes object routines + * two routine values are defined + * 0 - init + * 1 - free + * all others are implementation defined + * + * implementation: + * enumerate/define mode's actor types + * create object related functionality + * ensure defined routines above are provided + * provide an object routing method that calls routines + * using switch on routine values + * a router pointer is provided but mode may define + * type-wide routers too + * combinations of custom and type routers are allowed + * precedence is implementation dependent + * router methods will act on properties and collision data + */ +typedef struct actor { + signed short type; + bool type_router; + // model + signed char routine; + collision collision_data; + // properties + void (*router)(void); +} actor; +#define ACTOR_ROUTINE_NULL -1 + +#ifdef __cplusplus +}; +#endif /* __cplusplus */ + +#endif /* __ACTOR_H__ */ diff --git a/src/graphics/objects/collision_index.c b/src/graphics/objects/collision_index.c new file mode 100644 index 0000000..9627a41 --- /dev/null +++ b/src/graphics/objects/collision_index.c @@ -0,0 +1,4 @@ +/* + * collision_index - a collision index entry and helper objects + */ +#include "collision_index.h" diff --git a/src/graphics/objects/collision_index.h b/src/graphics/objects/collision_index.h new file mode 100644 index 0000000..6938e9b --- /dev/null +++ b/src/graphics/objects/collision_index.h @@ -0,0 +1,76 @@ +/* + * collision_index - a collision index entry and helper objects + */ +#ifndef __COLLISION_INDEX_H__ +#define __COLLISION_INDEX_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include "../primitives/collision.h" + +/* collision planning + * ------------------ +/* collision can be either defined as a geometric primitive or a mesh + * the goal is to, using the least memory, store and index the + * information needed by an object to calculate what will happen to + * to itself upon collision with an object. + * no individual object is going to calculate what happens to something + * that it has collided with, it only needs to know what it does after + * that collision + * + * collision shape + * + * shape types implemented by the engine + * the shape number is provided to a routing + * switch to determine which collision method is necessary + * + * collision index table + * + * the scene graph will contain a collision index table + * entries will contain the scene ID of the object + * the type of the object + * whether the collision is a mesh or not + * a shape enumeration, with a growing list of geometric primitives + * a pointer to a list of dimensions (defined by shape implementations) + * + * collision state + * + * the collision state object is populated with any collisions that have + * occurred in the past cycle, that way we don't recalc a collision + * we already calculated. the state will indicate which objects collided + * + */ + + + +/* + * collision_index - table of object metadata + * object_id - object ID in graph + * object_type - object type + * mesh - is this a collision mesh, if not is bounding geometry + * shape - pointer to list of dimensions + * shape dimensions must be defined by shapes themselves + * functions operating on a shape must know the number of dimensions + * used, shape can be vague, but shape-based collision must + * reduce to common dimensions + * mesh_data - implementation defined data structure, if a shape + * uses a mesh the receiving function must know what kind + * of data it interprets. if common functions are desired + * mesh data must be formatted or a wrapper providing + * necessary meta-data implemented + */ +typedef struct { + int object_id; + int object_type; + collision *collision_data; +} collision_index; + +/* TODO: Collision index allocation and adjustment methods */ + +#ifdef __cplusplus +}; +#endif /* __cplusplus */ + +#endif /* __COLLISION_INDEX_H__ */ diff --git a/src/graphics/objects/scene.c b/src/graphics/objects/scene.c index 8ea5ca0..cdd5a8a 100644 --- a/src/graphics/objects/scene.c +++ b/src/graphics/objects/scene.c @@ -2,3 +2,96 @@ * scene - a primitive scene graph */ #include "scene.h" + +void scene_projection_new(scene *graph, projection_type type, double x_axis, double y_axis, double near_plane, double far_plane) +{ + graph->prj[0] = -x_axis; + graph->prj[1] = x_axis; + graph->prj[2] = -y_axis; + graph->prj[3] = y_axis; + graph->prj[4] = near_plane; + graph->prj[5] = far_plane; + graph->prj_type = type; + + return; +} + +void scene_positionenv(scene *graph, double xpos, double ypos, double zpos) +{ + graph->environment_pos[0] = xpos; + graph->environment_pos[1] = ypos; + graph->environment_pos[2] = zpos; + + return; +} + +signed short scene_addnode(scene *graph, signed short type, bool type_router, signed char routine, void (*router)(void)) +{ + signed short id; + node **new_node = realloc(graph->nodes, ++graph->node_count * sizeof (node *)); + graph->nodes = new_node; + id = graph->node_count - 1; + graph->nodes[id] = malloc(sizeof (node)); + graph->nodes[id]->actor_entry.id = id; + graph->nodes[id]->actor_entry.actor_obj = malloc(sizeof (actor)); + graph->nodes[id]->actor_entry.actor_obj->type = type; + graph->nodes[id]->actor_entry.actor_obj->type_router = type_router; + graph->nodes[id]->actor_entry.actor_obj->routine = ACTOR_ROUTINE_NULL; + graph->nodes[id]->actor_entry.actor_obj->router = NULL; + graph->nodes[id]->children = NULL; + graph->nodes[id]->children_count = 0; + graph->nodes[id]->vertex_array = NULL; + graph->nodes[id]->normal_array = NULL; + graph->nodes[id]->color_array = NULL; + graph->nodes[id]->vao_indicies = NULL; + + return id; +} + +void scene_enforceboundingnode(scene *graph, signed short node_id) +{ + if (graph->nodes[node_id]->position[0] < graph->bounding_box[0]) + graph->nodes[node_id]->position[0] = graph->bounding_box[0]; + else if (graph->nodes[node_id]->position[0] > graph->bounding_box[1]) + graph->nodes[node_id]->position[0] = graph->bounding_box[1]; + + if (graph->nodes[node_id]->position[1] < graph->bounding_box[2]) + graph->nodes[node_id]->position[1] = graph->bounding_box[2]; + else if (graph->nodes[node_id]->position[1] > graph->bounding_box[3]) + graph->nodes[node_id]->position[1] = graph->bounding_box[3]; + + if (graph->nodes[node_id]->position[2] < graph->bounding_box[4]) + graph->nodes[node_id]->position[2] = graph->bounding_box[4]; + else if (graph->nodes[node_id]->position[2] > graph->bounding_box[5]) + graph->nodes[node_id]->position[2] = graph->bounding_box[5]; + + return; +} + +void scene_setchildnode(scene *graph, signed int parent, signed int child) +{ + node **children = realloc(graph->nodes[parent]->children, ++graph->nodes[parent]->children_count * sizeof (node *)); + graph->nodes[parent]->children = children; + graph->nodes[parent]->children[graph->nodes[parent]->children_count - 1] = graph->nodes[child]; + + return; +} + +void scene_skinnode(scene *graph, signed int node_id, GLdouble *verticies, GLdouble *normals, GLdouble *colors, GLubyte *vaos) +{ + graph->nodes[node_id]->vertex_array = verticies; + graph->nodes[node_id]->normal_array = normals; + graph->nodes[node_id]->color_array = colors; + graph->nodes[node_id]->vao_indicies = vaos; + + return; +} + +void scene_positionnode(scene *graph, signed short node_id, double xpos, double ypos, double zpos) +{ + graph->nodes[node_id]->position[0] = xpos; + graph->nodes[node_id]->position[1] = ypos; + graph->nodes[node_id]->position[2] = zpos; + + return; +} diff --git a/src/graphics/objects/scene.h b/src/graphics/objects/scene.h index 42c01ab..9d5988e 100644 --- a/src/graphics/objects/scene.h +++ b/src/graphics/objects/scene.h @@ -10,26 +10,77 @@ extern "C" { /* include GL for types */ #include "../contexts/glcontext.h" +/* actors */ +#include "actor.h" +/* collision detection */ +#include "collision_index.h" -enum projection_type { +typedef enum { PROJECTION_ORTHAGONAL ,PROJECTION_FRUSTUM -}; +} projection_type; + +typedef struct { + signed short id; + actor *actor_obj; +} scene_actor; +#define SCENE_ACTOR_NULL -1 +/* + * node in a scene graph + * a node has geometry TODO: implement model abstraction + * a node has children and a count on those children + * environment is a special secondary node in the scene that also has children, the scene is the parent node of these two + * + */ typedef struct node { + scene_actor actor_entry; + double position[3]; GLdouble *vertex_array; GLdouble *normal_array; GLdouble *color_array; GLubyte *vao_indicies; - void *children; + struct node **children; unsigned int children_count; + /* the node will be responsible for maintaining and cleaning its children records */ + /* note: a scene does not require a collision table + * this may be null if the scene does not implement + * any objects employing collision + * behavior of objects with collision in scenes + * with no index is undefined + */ } node; +/* scene graph + * contains the collection of actors in the scene, as well as the nodes that connect them + * actors can become orphaned, garbage handling is necessary + * + * the collision table is populated with collision information about the scene + * actors are responsible for inserting and removing themselves from the index + * the index can provide optimization functionality, actors will just perform requests for new data + * and freeing of old data + */ typedef struct scene { - GLdouble *prj; - char prj_type; + GLdouble prj[6]; + projection_type prj_type; + double bounding_box[6]; + collision_index *collision_table; + node **nodes; + int node_count; node *root_node; + node *camera; + node *environment; + double environment_pos[3]; } scene; + +void scene_projection_new(scene *graph, projection_type type, double x_axis, double y_axis, double near_plane, double far_plane); +void scene_positionenv(scene *graph, double xpos, double ypos, double zpos); + +signed short scene_addnode(scene *graph, signed short type, bool type_router, signed char routine, void (*router)(void)); +void scene_enforceboundingnode(scene *graph, signed short node_id); +void scene_setchildnode(scene *graph, signed int parent, signed int child); +void scene_skinnode(scene *graph, signed int node_id, GLdouble *verticies, GLdouble *normals, GLdouble *colors, GLubyte *vaos); +void scene_positionnode(scene *graph, signed short node_id, double xpos, double ypos, double zpos); #ifdef __cplusplus }; diff --git a/src/graphics/objects/texture.c b/src/graphics/objects/texture.c index 3cb63cd..aa1a30f 100644 --- a/src/graphics/objects/texture.c +++ b/src/graphics/objects/texture.c @@ -3,33 +3,36 @@ */ #include #include +#include #include "texture.h" /* general texture */ -texture *texture_new(unsigned int width, unsigned int height, unsigned int bpp) +texture *texture_new(size_t width, size_t height, size_t bpp) { - unsigned int data_size = width * height * bpp; - texture *texture = malloc(sizeof (texture)); - texture->data = (unsigned char *) malloc(data_size * sizeof (char)); - texture->width = width; - texture->height = height; - texture->bpp = bpp; + size_t data_size = width * height * bpp; + texture *new_texture = malloc(sizeof (texture)); + new_texture->data = malloc(data_size * sizeof (char)); + new_texture->width = width; + new_texture->height = height; + new_texture->bpp = bpp; - return texture; + return new_texture; } -void texture_free(texture *texture) +/* texture_rgba - uncompressed rgba data */ +texture_rgba *texture_rgba_new(FILE *rgba_data, size_t width, size_t height, size_t bpp) { - free(texture->data); - free(texture); + texture_rgba *new_texture = texture_new(width, height, bpp); + fread(new_texture->data, sizeof (char), width*height*bpp, rgba_data); + + return new_texture; } -/* texture_rgba - uncompressed rgba data */ -texture_rgba *texture_rgba_new(FILE *rgba_data, unsigned int width, unsigned int height, unsigned int bpp) +void texture_free(texture *texture_0) { - texture_rgba *texture = texture_new(width, height, bpp); - fread(texture->data, sizeof (char), (size_t) width*height*bpp, rgba_data); - - return texture; + free(texture_0->data); + free(texture_0); } + + diff --git a/src/graphics/objects/texture.h b/src/graphics/objects/texture.h index c3a3592..8838d43 100644 --- a/src/graphics/objects/texture.h +++ b/src/graphics/objects/texture.h @@ -8,17 +8,19 @@ extern "C" { #endif /* __cplusplus */ +#include "../../util/macros.h" + /* * texture - a raw texture consisting of uncompressed pixel data */ typedef struct texture { unsigned char *data; - unsigned int width; - unsigned int height; - unsigned int bpp; /* 2:RGB16, 3:RGB, 4:RGBA */ + size_t width; + size_t height; + size_t bpp; /* 2:RGB16, 3:RGB, 4:RGBA */ } texture; -texture *texture_new(unsigned int width, unsigned int height, unsigned int bpp); +texture *texture_new(size_t width, size_t height, size_t bpp); void texture_free(texture *texture); /* @@ -26,7 +28,7 @@ void texture_free(texture *texture); */ typedef texture texture_rgba; -texture_rgba *texture_rgba_new(FILE *rgba_data, unsigned int width, unsigned int height, unsigned int bpp); +texture_rgba *texture_rgba_new(FILE *rgba_data, size_t width, size_t height, size_t bpp); #ifdef __cplusplus }; diff --git a/src/graphics/primitives/collision.h b/src/graphics/primitives/collision.h new file mode 100644 index 0000000..8a3d04c --- /dev/null +++ b/src/graphics/primitives/collision.h @@ -0,0 +1,54 @@ +/* + * collision - basic collision routines and primitives + */ +#ifndef __COLLISION_H__ +#define __COLLISION_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include + +/* collision shape + * + * shape types implemented by the engine + * the shape number is provided to a routing + * switch to determine which collision method is necessary + */ +typedef enum { + COLLISION_BOUND_BOX + //,COLLISION_SPHERE +} e_collision_shape; + +/* + * collision + * + * collision is either a shape or implementation-defined mesh collision + */ +typedef struct { + bool mesh; + e_collision_shape shape; + double *dims; + void *mesh_data; +} collision; + +/* + * collision_router - collision primitives should be few + * method determination will be static and switch driven + * collision routing for mesh data is implemented by the object + */ +void collision_router(e_collision_shape shape_a, double *dim_a, e_collision_shape shape_b, double *dim_b); + +/* TODO: Implement box primitive + * all collision primitive to primitive relationships will be explicit + * if a relationship is not defined, collision between the object types + * is likewise undefined + */ +void collide_box_box(double *dim_a, double *dim_b); + +#ifdef __cplusplus +}; +#endif /* __cplusplus */ + +#endif /* __COLLISION_H__ */ diff --git a/src/graphics/primitives/collision/collision_box.c b/src/graphics/primitives/collision/collision_box.c new file mode 100644 index 0000000..4c1a10f --- /dev/null +++ b/src/graphics/primitives/collision/collision_box.c @@ -0,0 +1,8 @@ +/* box-related collision functions */ +#include "../collision.h" + +/* TODO */ +void collide_box_box(double *dim_a, double *dim_b) +{ + return; +} diff --git a/src/graphics/primitives/collision/collision_router.c b/src/graphics/primitives/collision/collision_router.c new file mode 100644 index 0000000..b97653c --- /dev/null +++ b/src/graphics/primitives/collision/collision_router.c @@ -0,0 +1,10 @@ +/* + * collision_router - routes primitives collisions + */ +#include "../collision.h" + +/* TODO */ +void collision_router(e_collision_shape shape_a, double *dim_a, e_collision_shape shape_b, double *dim_b) +{ + return; +} diff --git a/src/input/glxevent.c b/src/input/glxevent.c index 458fbee..927714e 100644 --- a/src/input/glxevent.c +++ b/src/input/glxevent.c @@ -66,6 +66,7 @@ void glxevent(Display *dpy) x_height = event_return.xconfigure.height; /* Keep OpenGL viewport in sync */ glViewport(0, 0, (GLsizei) x_width, (GLsizei) x_height); + current_ratio = x_width / x_height; #ifndef NDEBUG /* debuggers can uncapture the cursor */ @@ -88,134 +89,102 @@ void glxevent(Display *dpy) switch (XLookupKeysym(&event_return.xkey, 0)) { case XK_A: case XK_a: - if (key & KEY_A) - key_held |= KEY_A; key |= KEY_A; break; + case XK_B: + case XK_b: + key |= KEY_B; + break; case XK_C: case XK_c: - if (key & KEY_C) - key_held |= KEY_C; key |= KEY_C; break; case XK_D: case XK_d: - if (key & KEY_D) - key_held |= KEY_D; key |= KEY_D; break; + case XK_E: + case XK_e: + key |= KEY_E; + break; case XK_F: case XK_f: - if (key & KEY_F) - key_held |= KEY_F; key |= KEY_F; break; case XK_G: case XK_g: - if (key & KEY_G) - key_held |= KEY_G; key |= KEY_G; break; case XK_Q: case XK_q: - if (key & KEY_Q) - key_held |= KEY_Q; key |= KEY_Q; break; case XK_R: case XK_r: - if (key & KEY_R) - key_held |= KEY_R; key |= KEY_R; break; case XK_S: case XK_s: - if (key & KEY_S) - key_held |= KEY_S; key |= KEY_S; break; + case XK_T: + case XK_t: + key |= KEY_T; + break; case XK_V: case XK_v: - if (key & KEY_V) - key_held |= KEY_V; key |= KEY_V; break; case XK_W: case XK_w: - if (key & KEY_W) - key_held |= KEY_W; key |= KEY_W; break; case XK_X: case XK_x: - if (key & KEY_X) - key_held |= KEY_X; key |= KEY_X; break; case XK_Z: case XK_z: - if (key & KEY_Z) - key_held |= KEY_Z; key |= KEY_Z; break; case XK_KP_0: case XK_0: - if (key & KEY_0) - key_held |= KEY_0; key |= KEY_0; break; case XK_KP_1: case XK_1: - if (key & KEY_1) - key_held |= KEY_1; key |= KEY_1; break; case XK_KP_2: case XK_2: - if (key & KEY_2) - key_held |= KEY_2; key |= KEY_2; break; case XK_KP_3: case XK_3: - if (key & KEY_3) - key_held |= KEY_3; key |= KEY_3; break; case XK_KP_4: case XK_4: - if (key & KEY_4) - key_held |= KEY_4; key |= KEY_4; break; case XK_KP_5: case XK_5: - if (key & KEY_5) - key_held |= KEY_5; key |= KEY_5; break; case XK_KP_6: case XK_6: - if (key & KEY_6) - key_held |= KEY_6; key |= KEY_6; break; case XK_KP_7: case XK_7: - if (key & KEY_7) - key_held |= KEY_7; key |= KEY_7; break; case XK_KP_8: case XK_8: - if (key & KEY_8) - key_held |= KEY_8; key |= KEY_8; break; case XK_KP_9: case XK_9: - if (key & KEY_9) - key_held |= KEY_9; key |= KEY_9; break; default: @@ -230,107 +199,102 @@ void glxevent(Display *dpy) case XK_A: case XK_a: key &= ~KEY_A; - key_held &= ~KEY_A; + break; + case XK_B: + case XK_b: + key &= ~KEY_B; break; case XK_C: case XK_c: key &= ~KEY_C; - key_held &= ~KEY_C; break; case XK_D: case XK_d: key &= ~KEY_D; - key_held &= ~KEY_D; + break; + case XK_E: + case XK_e: + key &= ~KEY_E; break; case XK_F: case XK_f: key &= ~KEY_F; - key_held &= ~KEY_F; break; case XK_G: case XK_g: key &= ~KEY_G; - key_held &= ~KEY_G; + break; + case XK_Q: + case XK_q: + key &= ~KEY_Q; break; case XK_R: case XK_r: key &= ~KEY_R; - key_held &= ~KEY_R; break; case XK_S: case XK_s: key &= ~KEY_S; - key_held &= ~KEY_S; + break; + case XK_T: + case XK_t: + key &= ~KEY_T; break; case XK_V: case XK_v: key &= ~KEY_V; - key_held &= ~KEY_V; break; case XK_W: case XK_w: key &= ~KEY_W; - key_held &= ~KEY_W; break; case XK_X: case XK_x: key &= ~KEY_X; - key_held &= ~KEY_X; break; case XK_Z: case XK_z: key &= ~KEY_Z; - key_held &= ~KEY_Z; break; case XK_KP_0: case XK_0: key &= ~KEY_0; - key_held &= ~KEY_0; break; case XK_KP_1: case XK_1: key &= ~KEY_1; - key_held &= ~KEY_1; break; case XK_KP_2: case XK_2: key &= ~KEY_2; - key_held &= ~KEY_2; break; case XK_KP_3: case XK_3: key &= ~KEY_3; - key_held &= ~KEY_3; break; case XK_KP_4: case XK_4: key &= ~KEY_4; - key_held &= ~KEY_4; break; case XK_KP_5: case XK_5: key &= ~KEY_5; - key_held &= ~KEY_5; break; case XK_KP_6: case XK_6: key &= ~KEY_6; - key_held &= ~KEY_6; break; case XK_KP_7: case XK_7: key &= ~KEY_7; - key_held &= ~KEY_7; break; case XK_KP_8: case XK_8: key &= ~KEY_8; - key_held &= ~KEY_8; break; case XK_KP_9: case XK_9: key &= ~KEY_9; - key_held &= ~KEY_9; break; default: break; @@ -346,8 +310,3 @@ void glxevent(Display *dpy) return; } - -void capture_mouse(bool capture) -{ - -} diff --git a/src/input/input.h b/src/input/input.h index a598407..990279a 100644 --- a/src/input/input.h +++ b/src/input/input.h @@ -44,7 +44,6 @@ extern "C" { /* key masks */ unsigned long key; -unsigned long key_held; /* mouse state */ bool mouse_moved_x; diff --git a/src/input/wglevent.c b/src/input/wglevent.c index edab7df..1946160 100644 --- a/src/input/wglevent.c +++ b/src/input/wglevent.c @@ -42,106 +42,80 @@ LRESULT CALLBACK wndproc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) switch (wParam) { case 'A': case 'a': - if (key & KEY_A) - key_held |= KEY_A; key |= KEY_A; break; + case 'B': + case 'b': + key |= KEY_B; + break; case 'D': case 'd': - if (key & KEY_D) - key_held |= KEY_D; key |= KEY_D; break; + case 'E': + case 'e': + key |= KEY_E; + break; case 'F': case 'f': - if (key & KEY_F) - key_held |= KEY_F; key |= KEY_F; break; case 'Q': case 'q': - if (key & KEY_Q) - key_held |= KEY_Q; key |= KEY_Q; break; case 'R': case 'r': - if (key & KEY_R) - key_held |= KEY_R; key |= KEY_R; break; case 'S': case 's': - if (key & KEY_S) - key_held |= KEY_S; key |= KEY_S; break; + case 'T': + case 't': + key |= KEY_T; + break; case 'W': case 'w': - if (key & KEY_W) - key_held |= KEY_W; key |= KEY_W; break; case 'X': case 'x': - if (key & KEY_X) - key_held |= KEY_X; key |= KEY_X; break; case 'Z': case 'z': - if (key & KEY_Z) - key_held |= KEY_Z; key |= KEY_Z; break; case '0': - if (key & KEY_0) - key_held |= KEY_0; key |= KEY_0; break; case '1': - if (key & KEY_1) - key_held |= KEY_1; key |= KEY_1; break; case '2': - if (key & KEY_2) - key_held |= KEY_2; key |= KEY_2; break; case '3': - if (key & KEY_3) - key_held |= KEY_3; key |= KEY_3; break; case '4': - if (key & KEY_4) - key_held |= KEY_4; key |= KEY_4; break; case '5': - if (key & KEY_5) - key_held |= KEY_5; key |= KEY_5; break; case '6': - if (key & KEY_6) - key_held |= KEY_6; key |= KEY_6; break; case '7': - if (key & KEY_7) - key_held |= KEY_7; key |= KEY_7; break; case '8': - if (key & KEY_8) - key_held |= KEY_8; key |= KEY_8; break; case '9': - if (key & KEY_9) - key_held |= KEY_9; key |= KEY_9; break; default: @@ -156,82 +130,80 @@ LRESULT CALLBACK wndproc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case 'A': case 'a': key &= ~KEY_A; - key_held &= ~KEY_A; + break; + case 'B': + case 'b': + key &= ~KEY_B; break; case 'D': case 'd': key &= ~KEY_D; - key_held &= ~KEY_D; break; + case 'E': + case 'e': + key &= ~KEY_E; + break; case 'F': case 'f': key &= ~KEY_F; - key_held &= ~KEY_F; + break; + case 'Q': + case 'q': + key &= ~KEY_Q; break; case 'R': case 'r': key &= ~KEY_R; - key_held &= ~KEY_R; break; case 'S': case 's': key &= ~KEY_S; - key_held &= ~KEY_S; break; + case 'T': + case 't': + key &= ~KEY_T; + break; case 'W': case 'w': key &= ~KEY_W; - key_held &= ~KEY_W; break; case 'X': case 'x': key &= ~KEY_X; - key_held &= ~KEY_X; break; case 'Z': case 'z': key &= ~KEY_Z; - key_held &= ~KEY_Z; break; case '0': key &= ~KEY_0; - key_held &= ~KEY_0; break; case '1': key &= ~KEY_1; - key_held &= ~KEY_1; break; case '2': key &= ~KEY_2; - key_held &= ~KEY_2; break; case '3': key &= ~KEY_3; - key_held &= ~KEY_3; break; case '4': key &= ~KEY_4; - key_held &= ~KEY_4; break; case '5': key &= ~KEY_5; - key_held &= ~KEY_5; break; case '6': key &= ~KEY_6; - key_held &= ~KEY_6; break; case '7': key &= ~KEY_7; - key_held &= ~KEY_7; break; case '8': key &= ~KEY_8; - key_held &= ~KEY_8; break; case '9': key &= ~KEY_9; - key_held &= ~KEY_9; break; default: break; diff --git a/src/main.c b/src/main.c index 7bcd4b5..874a3de 100644 --- a/src/main.c +++ b/src/main.c @@ -9,7 +9,7 @@ #include "modes/modes.h" /* defaults */ -#define INITIAL_GM GM_DIAMONDS +#define INITIAL_GM GM_ACTOR_TEST #ifndef _WIN32 /* @@ -35,12 +35,11 @@ int main(int argc, char *argv[]) key = 0; /* initialize key bitfield here for now */ mouse_moved_x = false; mouse_moved_y = false; + isfullscreen = true; quit = false; - #ifndef NDEBUG - /* debugging can uncapture pointer */ - mouse_captured = true; - debug_cursor_changed = false; - #endif + + /* start in debug mode */ + debug_init; /* initialize OpenGL for X11 */ glxinit(); @@ -62,6 +61,9 @@ int main(int argc, char *argv[]) case GM_SCENE_TEST: scene_test_init(); break; + case GM_ACTOR_TEST: + actor_test_init(); + break; default: break; } @@ -86,44 +88,52 @@ int main(int argc, char *argv[]) switch (game_mode) { case GM_DIAMONDS: + /* run mode routine */ + diamond_routine(); /* process next frame */ diamond_render(); /* process movement */ diamond_input(); - /* run mode routine */ - diamond_routine(); break; case GM_MAP: + /* run mode routine */ + map_routine(); /* process next frame */ map_render(); /* process movement */ map_input(); - /* run mode routine */ - map_routine(); break; case GM_SANDBOX: + /* run mode routine */ + sandbox_routine(); /* process next frame */ sandbox_render(); /* process movement */ sandbox_input(); - /* run mode routine */ - sandbox_routine(); break; case GM_STAGE: + /* run mode routine */ + stage_routine(); /* process next frame */ stage_render(); /* process movement */ stage_input(); - /* run mode routine */ - stage_routine(); break; case GM_SCENE_TEST: + /* run mode routine */ + scene_test_routine(); /* process next frame */ scene_test_render(); /* process movement */ scene_test_input(); + break; + case GM_ACTOR_TEST: /* run mode routine */ - scene_test_routine(); + actor_test_routine(); + /* process next frame */ + actor_test_render(); + /* process movement */ + actor_test_input(); break; default: fprintf(stderr, "Unknown game mode: %d\n", game_mode); @@ -149,6 +159,9 @@ int main(int argc, char *argv[]) case GM_SCENE_TEST: scene_test_free(); break; + case GM_ACTOR_TEST: + actor_test_free(); + break; default: break; } @@ -182,12 +195,10 @@ int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _ key = 0; /* initialize key bitfield here for now */ mouse_moved_x = false; mouse_moved_y = false; + isfullscreen = true; quit = false; - #ifndef NDEBUG - /* debugging can uncapture pointer */ - mouse_captured = true; - debug_cursor_changed = false; - #endif + + debug_init; /* initialize OpenGL for WinAPI */ wglinit(hInstance, nShowCmd, wndproc); @@ -209,6 +220,9 @@ int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _ case GM_SCENE_TEST: scene_test_init(); break; + case GM_ACTOR_TEST: + actor_test_init(); + break; default: break; } @@ -231,52 +245,60 @@ int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _ /* begin processing events */ wglevent(wnd); - switch (game_mode) { - case GM_DIAMONDS: - /* process next frame */ - diamond_render(); - /* process movement */ - diamond_input(); - /* run mode routine */ - diamond_routine(); - break; - case GM_MAP: - /* process next frame */ - map_render(); - /* process input */ - map_input(); - /* run mode routine */ - map_routine(); - break; - case GM_SANDBOX: - /* process next frame */ - sandbox_render(); - /* process input */ - sandbox_input(); - /* run mode routine */ - sandbox_routine(); - break; + switch (game_mode) { + case GM_DIAMONDS: + /* run mode routine */ + diamond_routine(); + /* process next frame */ + diamond_render(); + /* process movement */ + diamond_input(); + break; + case GM_MAP: + /* run mode routine */ + map_routine(); + /* process next frame */ + map_render(); + /* process movement */ + map_input(); + break; + case GM_SANDBOX: + /* run mode routine */ + sandbox_routine(); + /* process next frame */ + sandbox_render(); + /* process movement */ + sandbox_input(); + break; case GM_STAGE: + /* run mode routine */ + stage_routine(); /* process next frame */ stage_render(); - /* process input */ + /* process movement */ stage_input(); - /* run mode routine */ - stage_routine(); break; case GM_SCENE_TEST: + /* run mode routine */ + scene_test_routine(); /* process next frame */ scene_test_render(); - /* process input */ + /* process movement */ scene_test_input(); + break; + case GM_ACTOR_TEST: /* run mode routine */ - scene_test_routine(); + actor_test_routine(); + /* process next frame */ + actor_test_render(); + /* process movement */ + actor_test_input(); break; - default: - fprintf(stderr, "Unknown game mode: %d\n", game_mode); - quit = true; - break; - } + default: + fprintf(stderr, "Unknown game mode: %d\n", game_mode); + quit = true; + break; + } } /* unload OpenGL assets */ @@ -296,6 +318,9 @@ int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _ case GM_SCENE_TEST: scene_test_free(); break; + case GM_ACTOR_TEST: + actor_test_free(); + break; default: break; } diff --git a/src/modes/actor_test.c b/src/modes/actor_test.c new file mode 100644 index 0000000..1e4432b --- /dev/null +++ b/src/modes/actor_test.c @@ -0,0 +1,552 @@ +/* + * actor_test - a test of scene graphs + */ +#include "actor_test.h" + +static GLdouble vertex_array[24] = { -1.0, 1.0, 1.0 + ,-1.0, -1.0, 1.0 + , 1.0, -1.0, 1.0 + , 1.0, 1.0, 1.0 + , 1.0, 1.0, -1.0 + , 1.0, -1.0, -1.0 + ,-1.0, -1.0, -1.0 + ,-1.0, 1.0, -1.0 }; + +static GLdouble normal_array[24] = { -1.0, 1.0, 1.0 + ,-1.0, -1.0, 1.0 + , 1.0, -1.0, 1.0 + , 1.0, 1.0, 1.0 + , 1.0, 1.0, -1.0 + , 1.0, -1.0, -1.0 + ,-1.0, -1.0, -1.0 + ,-1.0, 1.0, -1.0 }; + +static GLdouble color_array[24] = { 1.0, 0.0, 0.0 + ,0.0, 1.0, 0.0 + ,0.0, 0.0, 1.0 + ,1.0, 1.0, 0.0 + ,0.0, 1.0, 1.0 + ,1.0, 0.0, 1.0 + ,1.0, 1.0, 0.5 + ,0.5, 1.0, 1.0 }; + +static GLubyte vao_indicies[24] = { 0, 1, 2, 3 + ,3, 2, 5, 4 + ,4, 5, 6, 7 + ,7, 6, 1, 0 + ,7, 0, 3, 4 + ,1, 6, 5, 2 }; + + +static GLfloat fog_color[] = { 0.3f, 0.3f, 0.3f, 1.0f }; + +#define pointdistance(x, y) sqrt((y[0] - x[0])*(y[0] - x[0]) + (y[1] - x[1])*(y[1] - x[1]) + (y[2] - x[2])*(y[2] - x[2])) + +/* static nodes */ +static signed int environment_node; + +static signed int camera_node; + static GLdouble camera_view_x; + static GLdouble camera_view_y; + static veccomp2d camera_view_xz; + static bool z_adjusted = false; + +static signed int player_node; + static GLdouble player_move_forward; + static GLdouble player_move_right; + static GLdouble player_move_up; + static GLdouble player_vertical_vel; + static GLdouble player_vertical_accel; + static bool trigger_jump; + +static double motion_constant = 0.1; +static double gravity_constant = -0.09; + +/* + * actor_test_init - OpenGL init + */ +bool actor_test_init(void) +{ + #ifndef NDEBUG + printf("actor_test: init\n"); + #endif /* NDEBUG */ + + /* --- scene init --- */ + + /* create graph */ + graph = malloc(sizeof (scene)); + graph->nodes = NULL; + graph->node_count = 0; + + /* scene projection */ + scene_projection_new(graph, PROJECTION_FRUSTUM, current_ratio, 1.0, 1.0, 30.0); + + /* setup collision bounding box */ + graph->bounding_box[0] = -2.9; + graph->bounding_box[1] = 2.9; + graph->bounding_box[2] = -2.9; + graph->bounding_box[3] = 2.9; + graph->bounding_box[4] = -11.0; + graph->bounding_box[5] = -1.1; + + /* create node collection */ + + /* create node 00 - environment */ + environment_node = scene_addnode(graph, AT_ACTOR_ENVIRONMENT, false, ACTOR_ROUTINE_NULL, NULL); + scene_positionnode(graph, environment_node, 0.0, 0.0, 0.0); + scene_skinnode(graph, environment_node, vertex_array, normal_array, color_array, vao_indicies); + scene_positionenv(graph, 0.0, 0.0, 0.0); + + /* create node 01 - camera */ + camera_node = scene_addnode(graph, AT_ACTOR_CAMERA, false, ACTOR_ROUTINE_NULL, NULL); + scene_positionnode(graph, camera_node, 0.0, 0.0, -5.0); + scene_setchildnode(graph, environment_node, camera_node); + + /* create node 02 - player box */ + player_node = scene_addnode(graph, AT_ACTOR_BLOCK, false, ACTOR_ROUTINE_NULL, NULL); + scene_positionnode(graph, player_node, 0.0, 0.0, -2.0); + scene_skinnode(graph, player_node, vertex_array, normal_array, color_array, vao_indicies); + scene_setchildnode(graph, environment_node, player_node); + + /* assign environment */ + graph->environment = graph->nodes[environment_node]; + + /* assign camera */ + graph->camera = graph->nodes[camera_node]; + + /* assign environment as our root node */ + graph->root_node = graph->environment; + + /* --- OpenGL Init --- */ + + /* TODO: Create OpenGL "modes" that control all parameter switching */ + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glDisable(GL_TEXTURE_2D); + glDisable(GL_LIGHTING); + glDisable(GL_LIGHT0); + glDisable(GL_COLOR_MATERIAL); + glEnable(GL_FOG); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + /* color settings */ + glClearColor(fog_color[0], fog_color[1], fog_color[2], fog_color[3]); + glShadeModel(GL_SMOOTH); + + /* setup culling */ + glCullFace(GL_BACK); + + /* fog setup */ + glFogi(GL_FOG_MODE, GL_EXP); + glFogfv(GL_FOG_COLOR, fog_color); + glFogf(GL_FOG_DENSITY, 0.45f); + glFogf(GL_FOG_START, 1.0f); + glFogf(GL_FOG_END, 10.0f); + + /* setup projection */ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + switch(graph->prj_type) { + case PROJECTION_ORTHAGONAL: + glOrtho(graph->prj[0], graph->prj[1], graph->prj[2], graph->prj[3], graph->prj[4], graph->prj[5]); + break; + case PROJECTION_FRUSTUM: + glFrustum(graph->prj[0], graph->prj[1], graph->prj[2], graph->prj[3], graph->prj[4], graph->prj[5]); + break; + default: + fprintf(stderr, "Projection mode %d not supported.\n", graph->prj_type); + return false; + break; + } + + /* set initial camera angle */ + camera_view_x = 0.0; + camera_view_y = 0.0; + veccomp2d_calc(1.0, camera_view_x, &camera_view_xz); + + /* set player properties */ + player_move_forward = 0.0; + player_move_right = 0.0; + player_move_up = 0.0; + player_vertical_vel = 0.0; + player_vertical_accel = gravity_constant; + trigger_jump = false; + + return true; +} + +/* + * actor_test_render - OpenGL rendering + */ +bool actor_test_render(void) +{ + int i = 0, j = 0; + + /* clear the scene */ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + /* update projection if viewport changes shape */ + if (graph->prj[1] != current_ratio) { + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + graph->prj[0] = -current_ratio; + graph->prj[1] = current_ratio; + glFrustum(graph->prj[0], graph->prj[1], graph->prj[2], graph->prj[3], graph->prj[4], graph->prj[5]); + } + + /* begin rendering models */ + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glPushMatrix(); + /* perform camera transformation */ + glRotated(camera_view_x, 0.0, 1.0, 0.0); + glRotated(camera_view_y, camera_view_xz.x, 0.0, camera_view_xz.y); + glTranslated(graph->camera->position[0], graph->camera->position[1], graph->camera->position[2]); + + /* bind environment arrays */ + glVertexPointer(3, GL_DOUBLE, 0, graph->environment->vertex_array); + glNormalPointer(GL_DOUBLE, 0, graph->environment->normal_array); + glColorPointer(3, GL_DOUBLE, 0, graph->environment->color_array); + + /* draw wall */ + glPushMatrix(); + glTranslated(-2.0, 0.0, 0.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, -2.0, 0.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(2.0, 0.0, 0.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(2.0, 0.0, 0.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 2.0, 0.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 2.0, 0.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(-2.0, 0.0, 0.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(-2.0, 0.0, 0.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glPopMatrix(); + /* draw floor */ + glPushMatrix(); + glTranslated(-2.0, -4.0, 0.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(2.0, 0.0, 0.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, -2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, -2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, -2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, -2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, -2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(2.0, 0.0, 0.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glPopMatrix(); + /* draw walls */ + glPushMatrix(); + glRotated(90.0, 0.0, 0.0, 1.0); + glTranslated(-2.0, -4.0, 0.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(2.0, 0.0, 0.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, -2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, -2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, -2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, -2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, -2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(2.0, 0.0, 0.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glPopMatrix(); + glPushMatrix(); + glRotated(90.0, 0.0, 0.0, -1.0); + glTranslated(-2.0, -4.0, 0.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(2.0, 0.0, 0.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, -2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, -2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, -2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, -2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, -2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(2.0, 0.0, 0.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glPopMatrix(); + /* draw ceiling */ + glPushMatrix(); + glRotated(180.0, 0.0, 0.0, 1.0); + glTranslated(-2.0, -4.0, 0.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(2.0, 0.0, 0.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, -2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, -2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, -2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, -2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, -2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(2.0, 0.0, 0.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glTranslated(0.0, 0.0, 2.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glPopMatrix(); + + /* bind player arrays */ + glVertexPointer(3, GL_DOUBLE, 0, graph->nodes[player_node]->vertex_array); + glNormalPointer(GL_DOUBLE, 0, graph->nodes[player_node]->normal_array); + glColorPointer(3, GL_DOUBLE, 0, graph->nodes[player_node]->color_array); + + /* draw actor */ + glPushMatrix(); + glTranslated(graph->nodes[player_node]->position[0], graph->nodes[player_node]->position[1], -graph->nodes[player_node]->position[2]); + glScaled(0.1, 0.1, 0.1); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->nodes[player_node]->vao_indicies); + glPopMatrix(); + + glPopMatrix(); + + /* flush */ + glFlush(); + + /* display */ + drawframe(); + + return true; +} + +/* + * actor_test_input - handle movement + */ +bool actor_test_input(void) +{ + /* movement */ + /* w - forward */ if (key & KEY_W) player_move_forward += motion_constant; + /* s - back */ if (key & KEY_S) player_move_forward -= motion_constant; + /* a - left */ if (key & KEY_A) player_move_right -= motion_constant; + /* d - right */ if (key & KEY_D) player_move_right += motion_constant; + + /* e - jump */ if (key & KEY_E) { trigger_jump = true; } + + #ifndef NDEBUG + /* hot mode switching for debugging */ + if (KEY_ISNUM(key) && !(key & KEY_6)) { + actor_test_free(); + switch (key) { + case KEY_1: + diamond_init(); + game_mode = GM_DIAMONDS; + break; + case KEY_2: + map_init(); + game_mode = GM_MAP; + break; + case KEY_3: + sandbox_init(); + game_mode = GM_SANDBOX; + break; + case KEY_4: + stage_init(); + game_mode = GM_STAGE; + break; + case KEY_5: + scene_test_init(); + game_mode = GM_SCENE_TEST; + break; + default: + quit = true; + break; + } + } + + debug_pollkeys(key); + #endif /* NDEBUG */ + + return true; +} + +/* + * actor_test_routine - process object routine + */ +bool actor_test_routine(void) +{ + double camera_dist_x, camera_dist_y, camera_dist_z, camera_dist_z_adj; + double camera_move_forward = 0.0; + + /* player */ + /* motion */ + if (player_move_forward) { + graph->nodes[player_node]->position[0] += player_move_forward * camera_view_xz.y; + graph->nodes[player_node]->position[2] += player_move_forward * camera_view_xz.x; + camera_move_forward = player_move_forward; + player_move_forward = 0.0; + } + if (player_move_right) { + if (graph->nodes[player_node]->position[2] > graph->camera->position[2]) { + veccomp2d_calc(player_move_right, camera_view_x, &camera_view_xz); + graph->nodes[player_node]->position[0] += camera_view_xz.x; + graph->nodes[player_node]->position[2] -= camera_view_xz.y; + } else { + veccomp2d_calc(-player_move_right, camera_view_x, &camera_view_xz); + graph->nodes[player_node]->position[0] -= camera_view_xz.x; + graph->nodes[player_node]->position[2] += camera_view_xz.y; + } + player_move_right = 0.0; + } + /* jump */ + if (trigger_jump) { + player_vertical_vel = 0.5; + trigger_jump = false; + } + /* vertical accel and velocity */ + player_vertical_vel += player_vertical_accel; + graph->nodes[player_node]->position[1] += player_vertical_vel; + /* collision */ + scene_enforceboundingnode(graph, player_node); + + /* camera */ + /* move camera */ + if (pointdistance(graph->camera->position, graph->nodes[player_node]->position) > 5.0 && camera_move_forward > 0) { + graph->camera->position[0] -= camera_move_forward * camera_view_xz.y; + graph->camera->position[2] += camera_move_forward * camera_view_xz.x; + camera_move_forward = 0.0; + } + + + /* position camera */ + camera_dist_x = graph->nodes[player_node]->position[0] - graph->camera->position[0]; + camera_dist_y = graph->nodes[player_node]->position[1] - graph->camera->position[1]; + camera_dist_z = graph->nodes[player_node]->position[2] - graph->camera->position[2]; + camera_view_x = vecang2d_calc(camera_dist_x, camera_dist_z); + camera_dist_z_adj = sqrt(camera_dist_x * camera_dist_x + camera_dist_z * camera_dist_z); + camera_view_y = -vecang2d_calc(camera_dist_y, camera_dist_z_adj); + + /* normalize angles */ + camera_view_x = fmod(camera_view_x, 360); + camera_view_y = fmod(camera_view_y, 360); + + /* calculate y rotation vector */ + veccomp2d_calc(1.0, camera_view_x, &camera_view_xz); + return true; +} + +/* + * actor_test_free - OpenGL free + */ +bool actor_test_free(void) +{ + int node_count; + #ifndef NDEBUG + printf("actor_test: free\n"); + #endif /* NDEBUG */ + + for (node_count = 0; node_count < graph->node_count; node_count++) { + free(graph->nodes[node_count]->actor_entry.actor_obj); + free(graph->nodes[node_count]->children); + free(graph->nodes[node_count]); + } + free(graph->nodes); + free(graph); + + return true; +} + diff --git a/src/modes/actor_test.h b/src/modes/actor_test.h new file mode 100644 index 0000000..91de10f --- /dev/null +++ b/src/modes/actor_test.h @@ -0,0 +1,38 @@ +/* + * actor_test - a test of scene graphs + */ + +#ifndef __ACTOR_TEST_H__ +#define __ACTOR_TEST_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* common includes */ +#include "modes.h" +/* additional objects */ +#include "../graphics/objects/scene.h" +/* use vector component calcs */ +#include "../util/veccomp.h" + +/* game mode methods */ +bool actor_test_init(void); /* OpenGL init */ +bool actor_test_render(void); /* OpenGL rendering */ +bool actor_test_input(void); /* handle movement */ +bool actor_test_routine(void); /* process object routine */ +bool actor_test_free(void); /* OpenGL free */ + +/* assets */ +scene *graph; + +/* actor types - modes define actor types */ +#define AT_ACTOR_ENVIRONMENT 0 +#define AT_ACTOR_CAMERA 1 +#define AT_ACTOR_BLOCK 2 + +#ifdef __cplusplus +}; +#endif /* __cplusplus */ + +#endif /* __ACTOR_TEST_H__ */ diff --git a/src/modes/diamond.c b/src/modes/diamond.c index da122e3..cb394e5 100644 --- a/src/modes/diamond.c +++ b/src/modes/diamond.c @@ -104,11 +104,7 @@ bool diamond_render(void) glFlush(); - #ifdef WIN32 - SwapBuffers(dc); - #else - glXSwapBuffers(dpy, window); - #endif /* WIN32 */ + drawframe(); return true; } @@ -122,15 +118,14 @@ bool diamond_input(void) /* a - animate model */ if (key & KEY_A) diamond_angle++; #ifndef NDEBUG - /* r - windowed */ if (key & KEY_R) { setwindowed(640, 480); key &= ~KEY_R; } - /* f - fullscreen */ if (key & KEY_F) { setfullscreen(); key &= ~KEY_F; } - /* q - quit */ if (key & KEY_Q) quit = true; - /* v - uncapture mouse */ if (key & KEY_V) { mouse_captured = false; debug_cursor_changed = true; } - /* c - uncapture mouse */ if (key & KEY_C) { mouse_captured = true; debug_cursor_changed = true; } /* hot mode switching for debugging */ if (KEY_ISNUM(key) && !(key & KEY_1)) { diamond_free(); switch (key) { + case KEY_1: + diamond_init(); + game_mode = GM_DIAMONDS; + break; case KEY_2: map_init(); game_mode = GM_MAP; @@ -147,11 +142,17 @@ bool diamond_input(void) scene_test_init(); game_mode = GM_SCENE_TEST; break; + case KEY_6: + actor_test_init(); + game_mode = GM_ACTOR_TEST; + break; default: quit = true; break; } } + + debug_pollkeys(key); #endif /* NDEBUG */ return true; diff --git a/src/modes/map.c b/src/modes/map.c index a328050..ca57874 100644 --- a/src/modes/map.c +++ b/src/modes/map.c @@ -30,8 +30,8 @@ bool map_init(void) glCullFace(GL_BACK); /* prepare display lists */ - actor = glGenLists(1); - glNewList(actor, GL_COMPILE); + map_actor = glGenLists(1); + glNewList(map_actor, GL_COMPILE); tetrahedron(1.0); glEndList(); @@ -70,18 +70,14 @@ bool map_render(void) glEnd(); glTranslated(actor_x, actor_y, -actor_z); glRotated(actor_angle, 0.0, 1.0, 0.0); - glCallList(actor); + glCallList(map_actor); glPopMatrix(); /* flush */ glFlush(); /* display */ - #ifdef WIN32 - SwapBuffers(dc); - #else - glXSwapBuffers(dpy, window); - #endif /* WIN32 */ + drawframe(); return true; } @@ -100,11 +96,6 @@ bool map_input(void) /* x - zoom out */ if (key & KEY_X) actor_z += 0.1; #ifndef NDEBUG - /* r - windowed */ if (key & KEY_R) { setwindowed(640, 480); key &= ~KEY_R; } - /* f - fullscreen */ if (key & KEY_F) { setfullscreen(); key &= ~KEY_F; } - /* q - quit */ if (key & KEY_Q) quit = true; - /* v - uncapture mouse */ if (key & KEY_V) { mouse_captured = false; debug_cursor_changed = true; } - /* c - uncapture mouse */ if (key & KEY_C) { mouse_captured = true; debug_cursor_changed = true; } /* hot mode switching for debugging */ if (KEY_ISNUM(key) && !(key & KEY_2)) { map_free(); @@ -125,11 +116,17 @@ bool map_input(void) scene_test_init(); game_mode = GM_SCENE_TEST; break; + case KEY_6: + actor_test_init(); + game_mode = GM_ACTOR_TEST; + break; default: quit = true; break; } } + + debug_pollkeys(key); #endif /* NDEBUG */ return true; @@ -168,7 +165,7 @@ bool map_free(void) #endif /* NDEBUG */ /* free display lists */ - glDeleteLists(actor, 1); + glDeleteLists(map_actor, 1); return true; } diff --git a/src/modes/map.h b/src/modes/map.h index bc5c7f9..6df760f 100644 --- a/src/modes/map.h +++ b/src/modes/map.h @@ -21,7 +21,7 @@ bool map_routine(void); /* process mode behavior */ bool map_free(void); /* OpenGL free */ /* OpenGL lists */ -GLint actor; +GLint map_actor; /* properties */ GLdouble actor_x; diff --git a/src/modes/modes.h b/src/modes/modes.h index 203e355..2c58835 100644 --- a/src/modes/modes.h +++ b/src/modes/modes.h @@ -15,6 +15,8 @@ extern "C" { #include "../input/input.h" /* basic objects */ #include "../graphics/primitives/prim.h" +/* useful macros */ +#include "../util/macros.h" /* game modes */ int game_mode; @@ -28,6 +30,8 @@ int game_mode; #define GM_STAGE 3 #include "scene_test.h" #define GM_SCENE_TEST 4 +#include "actor_test.h" + #define GM_ACTOR_TEST 5 #ifdef __cplusplus }; diff --git a/src/modes/sandbox.c b/src/modes/sandbox.c index 193a1a7..a8e3089 100644 --- a/src/modes/sandbox.c +++ b/src/modes/sandbox.c @@ -185,11 +185,7 @@ bool sandbox_render(void) glFlush(); /* display */ - #ifdef WIN32 - SwapBuffers(dc); - #else - glXSwapBuffers(dpy, window); - #endif /* WIN32 */ + drawframe(); return true; } @@ -208,11 +204,6 @@ bool sandbox_input(void) /* x - zoom out */ if (key & KEY_X) sandbox_zoom -= 0.1; #ifndef NDEBUG - /* r - windowed */ if (key & KEY_R) { setwindowed(640, 480); key &= ~KEY_R; } - /* f - fullscreen */ if (key & KEY_F) { setfullscreen(); key &= ~KEY_F; } - /* q - quit */ if (key & KEY_Q) quit = true; - /* v - uncapture mouse */ if (key & KEY_V) { mouse_captured = false; debug_cursor_changed = true; } - /* c - uncapture mouse */ if (key & KEY_C) { mouse_captured = true; debug_cursor_changed = true; } /* hot mode switching for debugging */ if (KEY_ISNUM(key) && !(key & KEY_3)) { sandbox_free(); @@ -233,11 +224,17 @@ bool sandbox_input(void) scene_test_init(); game_mode = GM_SCENE_TEST; break; + case KEY_6: + actor_test_init(); + game_mode = GM_ACTOR_TEST; + break; default: quit = true; break; } } + + debug_pollkeys(key); #endif /* NDEBUG */ return true; diff --git a/src/modes/scene_test.c b/src/modes/scene_test.c index 621e73c..7967ab9 100644 --- a/src/modes/scene_test.c +++ b/src/modes/scene_test.c @@ -39,22 +39,101 @@ static GLubyte vao_indicies[24] = { 0, 1, 2, 3 static GLfloat fog_color[] = { 0.3f, 0.3f, 0.3f, 1.0f }; - + +static GLdouble forward; +static GLdouble right; static GLdouble xpos; static GLdouble ypos; static GLdouble zpos; static GLdouble view_x; static GLdouble view_y; +static veccomp2d view_xz; +static veccomp2d forward_xz; +static veccomp2d right_xz; + +static bool z_adjusted = false; + /* * scene_test_init - OpenGL init */ bool scene_test_init(void) { + node **root_node; + #ifndef NDEBUG printf("scene_test: init\n"); #endif /* NDEBUG */ + /* --- scene init --- */ + + /* create graph */ + graph = malloc(sizeof (scene)); + graph->node_count = 0; + graph->nodes = NULL; + + /* create environment */ + graph->environment = malloc(sizeof (node)); + graph->environment->actor_entry.id = SCENE_ACTOR_NULL; + graph->environment->children = NULL; + graph->environment->children_count = 0; + + /* create root node - camera */ + graph->root_node = malloc(sizeof (node)); + graph->root_node->actor_entry.id = 0; + graph->root_node->actor_entry.actor_obj = malloc(sizeof (actor)); + graph->root_node->actor_entry.actor_obj->type = ST_ACTOR_CAMERA; + graph->root_node->actor_entry.actor_obj->type_router = false; + graph->root_node->actor_entry.actor_obj->routine = ACTOR_ROUTINE_NULL; + graph->root_node->actor_entry.actor_obj->router = NULL; + + /* register root node in node collection */ + root_node = realloc(graph->nodes, ++graph->node_count * sizeof (node *)); + graph->nodes = root_node; + graph->nodes[graph->node_count - 1] = graph->root_node; + + /* scene projection */ + scene_projection_new(graph, PROJECTION_FRUSTUM, current_ratio, 1.0, 1.0, 30.0); + + /* setup camera properties */ + xpos = 0.0; + ypos = 0.0; + zpos = -((graph->prj[4] + graph->prj[5]) / 2); + view_x = 0.0; + view_y = 0.0; + forward = 0.0; + right = 0.0; + view_xz.x = 0.0; + view_xz.y = 0.0; + + /* scene geometry */ + graph->environment->vertex_array = vertex_array; + graph->environment->normal_array = normal_array; + graph->environment->color_array = color_array; + graph->environment->vao_indicies = vao_indicies; + + if (!z_adjusted) { + graph->environment->vertex_array[2] += zpos; + graph->environment->vertex_array[5] += zpos; + graph->environment->vertex_array[8] += zpos; + graph->environment->vertex_array[11] += zpos; + graph->environment->vertex_array[14] += zpos; + graph->environment->vertex_array[17] += zpos; + graph->environment->vertex_array[20] += zpos; + graph->environment->vertex_array[23] += zpos; + z_adjusted = true; + } + + /* setup collision bounding box */ + graph->bounding_box[0] = -3.0; + graph->bounding_box[1] = 3.0; + graph->bounding_box[2] = -3.0; + graph->bounding_box[3] = 3.0; + graph->bounding_box[4] = 3.0; + graph->bounding_box[5] = 7.0; + + /* --- OpenGL Init --- */ + /* TODO: Create OpenGL "modes" that control all parameter switching */ glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); @@ -86,29 +165,6 @@ bool scene_test_init(void) glMatrixMode(GL_PROJECTION); glLoadIdentity(); - /* setup scene graph */ - graph = (scene *) malloc(sizeof (graph)); - graph->prj = (GLdouble *) malloc(6 * sizeof (GLdouble)); - graph->root_node = (node *) malloc(sizeof (node)); - graph->root_node->children = NULL; - graph->root_node->children_count = 0; - - /* TODO: Create method in scene for setting up scene projection based on properties */ - /* scene projection */ - graph->prj[0] = -1.0; - graph->prj[1] = 1.0; - graph->prj[2] = -1.0; - graph->prj[3] = 1.0; - graph->prj[4] = 1.0; - graph->prj[5] = 11.0; - graph->prj_type = PROJECTION_FRUSTUM; - - xpos = 0.0; - ypos = 0.0; - zpos = -((graph->prj[4] + graph->prj[5]) / 2); - view_x = 0.0; - view_y = 0.0; - switch(graph->prj_type) { case PROJECTION_ORTHAGONAL: glOrtho(graph->prj[0], graph->prj[1], graph->prj[2], graph->prj[3], graph->prj[4], graph->prj[5]); @@ -121,25 +177,10 @@ bool scene_test_init(void) return false; break; } - - /* scene geometry */ - graph->root_node->vertex_array = vertex_array; - graph->root_node->normal_array = normal_array; - graph->root_node->color_array = color_array; - graph->root_node->vao_indicies = vao_indicies; - - graph->root_node->vertex_array[2] += zpos; - graph->root_node->vertex_array[5] += zpos; - graph->root_node->vertex_array[8] += zpos; - graph->root_node->vertex_array[11] += zpos; - graph->root_node->vertex_array[14] += zpos; - graph->root_node->vertex_array[17] += zpos; - graph->root_node->vertex_array[20] += zpos; - graph->root_node->vertex_array[23] += zpos; - glVertexPointer(3, GL_DOUBLE, 0, graph->root_node->vertex_array); - glNormalPointer(GL_DOUBLE, 0, graph->root_node->normal_array); - glColorPointer(3, GL_DOUBLE, 0, graph->root_node->color_array); + glVertexPointer(3, GL_DOUBLE, 0, graph->environment->vertex_array); + glNormalPointer(GL_DOUBLE, 0, graph->environment->normal_array); + glColorPointer(3, GL_DOUBLE, 0, graph->environment->color_array); return true; } @@ -149,209 +190,211 @@ bool scene_test_init(void) */ bool scene_test_render(void) { + int i = 0, j = 0; + /* clear the scene */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + /* update projection if viewport changes shape */ + if (graph->prj[1] != current_ratio) { + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + graph->prj[0] = -current_ratio; + graph->prj[1] = current_ratio; + glFrustum(graph->prj[0], graph->prj[1], graph->prj[2], graph->prj[3], graph->prj[4], graph->prj[5]); + } + /* begin rendering models */ glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glPushMatrix(); glRotated(view_x, 0.0, 1.0, 0.0); - if (view_x <= -270) - glRotated(view_y, -sin(degtorad(fmod(view_x, 90))), 0.0, cos(degtorad(fmod(view_x, 90)))); - else if (view_x <= -180) - glRotated(view_y, -cos(degtorad(fmod(view_x, 90))), 0.0, -sin(degtorad(fmod(view_x, 90)))); - else if (view_x <= -90) - glRotated(view_y, sin(degtorad(fmod(view_x, 90))), 0.0, -cos(degtorad(fmod(view_x, 90)))); - else if (view_x < 0) - glRotated(view_y, cos(degtorad(fmod(view_x, 90))), 0.0, sin(degtorad(fmod(view_x, 90)))); - else if (view_x < 90) - glRotated(view_y, cos(degtorad(fmod(view_x, 90))), 0.0, sin(degtorad(fmod(view_x, 90)))); /* the extra math does nothing useful!!! */ - else if (view_x < 180) - glRotated(view_y, -sin(degtorad(fmod(view_x, 90))), 0.0, cos(degtorad(fmod(view_x, 90)))); - else if (view_x < 270) - glRotated(view_y, -cos(degtorad(fmod(view_x, 90))), 0.0, -sin(degtorad(fmod(view_x, 90)))); - else - glRotated(view_y, sin(degtorad(fmod(view_x, 90))), 0.0, -cos(degtorad(fmod(view_x, 90)))); - /* TODO: Modify translation position calc to honor viewing angle */ + glRotated(view_y, view_xz.x, 0.0, view_xz.y); glTranslated(xpos, ypos, zpos + ((graph->prj[4] + graph->prj[5]) / 2)); + //glFlush(); /* viewport needs to execute first */ + /* draw actor */ + glPushMatrix(); + glScaled(0.1, 0.1, 0.1); + glTranslated(0.0, -20.0, -(1.0 / 0.1) * 7.0); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); + glPopMatrix(); /* draw wall */ glPushMatrix(); glTranslated(-2.0, 0.0, 0.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, -2.0, 0.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(2.0, 0.0, 0.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(2.0, 0.0, 0.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 2.0, 0.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 2.0, 0.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(-2.0, 0.0, 0.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(-2.0, 0.0, 0.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glPopMatrix(); /* draw floor */ glPushMatrix(); glTranslated(-2.0, -4.0, 0.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(2.0, 0.0, 0.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, -2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, -2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, -2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, -2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, -2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(2.0, 0.0, 0.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glPopMatrix(); /* draw walls */ glPushMatrix(); glRotated(90.0, 0.0, 0.0, 1.0); glTranslated(-2.0, -4.0, 0.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(2.0, 0.0, 0.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, -2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, -2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, -2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, -2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, -2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(2.0, 0.0, 0.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glPopMatrix(); glPushMatrix(); glRotated(90.0, 0.0, 0.0, -1.0); glTranslated(-2.0, -4.0, 0.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(2.0, 0.0, 0.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, -2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, -2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, -2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, -2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, -2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(2.0, 0.0, 0.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glPopMatrix(); /* draw ceiling */ glPushMatrix(); glRotated(180.0, 0.0, 0.0, 1.0); glTranslated(-2.0, -4.0, 0.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(2.0, 0.0, 0.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, -2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, -2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, -2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, -2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, -2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(2.0, 0.0, 0.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glTranslated(0.0, 0.0, 2.0); - glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->root_node->vao_indicies); + glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, graph->environment->vao_indicies); glPopMatrix(); glPopMatrix(); @@ -359,11 +402,7 @@ bool scene_test_render(void) glFlush(); /* display */ - #ifdef WIN32 - SwapBuffers(dc); - #else - glXSwapBuffers(dpy, window); - #endif /* WIN32 */ + drawframe(); return true; } @@ -374,21 +413,16 @@ bool scene_test_render(void) bool scene_test_input(void) { /* movement */ - /* w - up */ if (key & KEY_W || key_held & KEY_W) zpos += 0.3; - /* s - down */ if (key & KEY_S || key_held & KEY_S) zpos -= 0.3; - /* a - left */ if (key & KEY_A || key_held & KEY_A) xpos += 0.3; - /* d - right */ if (key & KEY_D || key_held & KEY_D) xpos -= 0.3; + /* w - up */ if (key & KEY_W) forward += 0.3; + /* s - down */ if (key & KEY_S) forward -= 0.3; + /* a - left */ if (key & KEY_A) right += 0.3; + /* d - right */ if (key & KEY_D) right -= 0.3; /* mouse controls view angle */ if (mouse_moved_x) view_x += 2.0 * (mouse_x_positive ? 1.0 : -1.0); if (mouse_moved_y) view_y += 2.0 * (mouse_y_positive ? 1.0 : -1.0); #ifndef NDEBUG - /* r - windowed */ if (key & KEY_R) { setwindowed(640, 480); key &= ~KEY_R; } - /* f - fullscreen */ if (key & KEY_F) { setfullscreen(); key &= ~KEY_F; } - /* q - quit */ if (key & KEY_Q) quit = true; - /* v - uncapture mouse */ if (key & KEY_V) { mouse_captured = false; debug_cursor_changed = true; } - /* c - uncapture mouse */ if (key & KEY_C) { mouse_captured = true; debug_cursor_changed = true; } /* hot mode switching for debugging */ if (KEY_ISNUM(key) && !(key & KEY_5)) { scene_test_free(); @@ -409,11 +443,17 @@ bool scene_test_input(void) stage_init(); game_mode = GM_STAGE; break; + case KEY_6: + actor_test_init(); + game_mode = GM_ACTOR_TEST; + break; default: quit = true; break; } } + + debug_pollkeys(key); #endif /* NDEBUG */ return true; @@ -424,14 +464,29 @@ bool scene_test_input(void) */ bool scene_test_routine(void) { + /* normalize angles */ view_x = fmod(view_x, 360); view_y = fmod(view_y, 360); - //if (xpos > 3) xpos = 3; - //if (xpos < -3) xpos = -3; - if (ypos > 3) ypos = 3; - if (ypos < -3) ypos = -3; - //if (zpos > (-graph->prj[4] - 1) + 2) zpos = (-graph->prj[4] - 1) + 2; - //if (zpos < -graph->prj[5] + 1) zpos = -graph->prj[5] + 1; + + /* calculate y rotation vector */ + veccomp2d_calc(1.0, view_x, &view_xz); + + /* calculation motion vector */ + if (forward) { + veccomp2d_calc(forward, view_x, &forward_xz); + xpos -= forward_xz.y; + zpos += forward_xz.x; + forward = 0.0; + } + if (right) { + veccomp2d_calc(right, view_x, &right_xz); + xpos += right_xz.x; + zpos += right_xz.y; + right = 0.0; + } + + + return true; } @@ -444,8 +499,11 @@ bool scene_test_free(void) printf("scene_test: free\n"); #endif /* NDEBUG */ - free(graph->prj); + free(graph->root_node->actor_entry.actor_obj); + free(graph->root_node); + free(graph->environment); free(graph); return true; } + diff --git a/src/modes/scene_test.h b/src/modes/scene_test.h index 0a2ebaf..813ba1c 100644 --- a/src/modes/scene_test.h +++ b/src/modes/scene_test.h @@ -13,6 +13,8 @@ extern "C" { #include "modes.h" /* additional objects */ #include "../graphics/objects/scene.h" +/* use vector component calcs */ +#include "../util/veccomp.h" /* game mode methods */ bool scene_test_init(void); /* OpenGL init */ @@ -24,6 +26,9 @@ bool scene_test_free(void); /* OpenGL free */ /* assets */ scene *graph; +/* actor types - modes define actor types */ +#define ST_ACTOR_CAMERA 0 + #ifdef __cplusplus }; #endif /* __cplusplus */ diff --git a/src/modes/stage.c b/src/modes/stage.c index f8f8f2e..037aca9 100644 --- a/src/modes/stage.c +++ b/src/modes/stage.c @@ -67,15 +67,15 @@ bool stage_init(void) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, menu_texture->width, menu_texture->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, menu_texture->data); - + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (unsigned int) menu_texture->width, (unsigned int) menu_texture->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, menu_texture->data); + glGenTextures(1, &stage_font_texture); glBindTexture(GL_TEXTURE_2D, stage_font_texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, font->width, font->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, font->data); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (unsigned int) font->width, (unsigned int) font->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, font->data); /* setup projection */ glMatrixMode(GL_PROJECTION); @@ -85,7 +85,7 @@ bool stage_init(void) box_width_hot = 0.0; box_height_hot = 0.0; box_display = false; - letter_height = font->height; + letter_height = (double) font->height; letter_width = font->width / 3.0; print_message = false; message_counter = 0.0; @@ -99,7 +99,7 @@ bool stage_init(void) bool stage_render(void) { /* clear the scene */ - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* begin rendering models */ glMatrixMode(GL_MODELVIEW); @@ -170,11 +170,7 @@ bool stage_render(void) glFlush(); /* display */ - #ifdef WIN32 - SwapBuffers(dc); - #else - glXSwapBuffers(dpy, window); - #endif /* WIN32 */ + drawframe(); return true; } @@ -187,13 +183,8 @@ bool stage_input(void) /* actions */ /* d - display box */ if (key & KEY_D) box_display = true; /* w - wipe box */ if (key & KEY_W) box_display = false; - + #ifndef NDEBUG - /* r - windowed */ if (key & KEY_R) { setwindowed(640, 480); key &= ~KEY_R; } - /* f - fullscreen */ if (key & KEY_F) { setfullscreen(); key &= ~KEY_F; } - /* q - quit */ if (key & KEY_Q) quit = true; - /* v - uncapture mouse */ if (key & KEY_V) { mouse_captured = false; debug_cursor_changed = true; } - /* c - uncapture mouse */ if (key & KEY_C) { mouse_captured = true; debug_cursor_changed = true; } /* hot mode switching for debugging */ if (KEY_ISNUM(key) && !(key & KEY_4)) { stage_free(); @@ -214,11 +205,17 @@ bool stage_input(void) scene_test_init(); game_mode = GM_SCENE_TEST; break; + case KEY_6: + actor_test_init(); + game_mode = GM_ACTOR_TEST; + break; default: quit = true; break; } } + + debug_pollkeys(key); #endif /* NDEBUG */ return true; @@ -268,10 +265,12 @@ bool stage_free(void) printf("stage: free\n"); #endif /* NDEBUG */ - glDeleteTextures(1, &stage_menu_texture); - texture_free(menu_texture); glDeleteTextures(1, &stage_font_texture); + glDeleteTextures(1, &stage_menu_texture); + texture_free(font); + texture_free(menu_texture); + return true; } diff --git a/src/util/macros.h b/src/util/macros.h index 4a11d6c..e8e9819 100644 --- a/src/util/macros.h +++ b/src/util/macros.h @@ -8,8 +8,61 @@ extern "C" { #endif /* __cplusplus */ +#ifdef _WIN32 +#define _USE_MATH_DEFINES +#endif /* _WIN32 */ + +#include + /* if there were macros you would see them here */ -#define degtorad(x) (x / 360) * 2 * 3.14 +#define degtorad(x) (x / 360.0) * 2.0 * M_PI +#define radtodeg(x) (x * 180.0) / M_PI + +/* debugging functionality */ + +#ifndef NDEBUG + +/* + * drop in debug inspector, pulls errors sitting on the stack at insertion point + * using standard C streams, pipeable + */ +#define INSPECT_GL while ((gl_errno = glGetError()) != GL_NO_ERROR) { \ + if (gl_errno | GL_INVALID_ENUM) \ + fputs("OpenGL: Invalid enum\n", stderr); \ + else if (gl_errno | GL_INVALID_VALUE) \ + fputs("OpenGL: Invalid value\n", stderr); \ + else if (gl_errno | GL_INVALID_OPERATION) \ + fputs("OpenGL: Invalid operation\n", stderr); \ + else if (gl_errno | GL_OUT_OF_MEMORY) \ + fputs("OpenGL: Out of memory\n", stderr); \ + else \ + fprintf(stderr, "OpenGL: Undefined error %d\n", gl_errno); \ + } \ + printf("OpenGL: Error inspection complete.\n"); \ + + +/* drop in gdb interrupt */ +#define GDB_INTERRUPT raise(SIGINT); + +/* debugging key handlers, hold t + key */ +#define debug_pollkeys(key) \ + if (key & KEY_T) { \ +/* q - quit */ if (key & KEY_Q) quit = true; /* must be after modeswitch or free will happen twice */ \ +/* r - windowed */ if (key & KEY_R) { setwindowed(640, 480); key &= ~KEY_R; } \ +/* f - fullscreen */ if (key & KEY_F) { setfullscreen(); key &= ~KEY_F; } \ +/* v - uncapture mouse */ if (key & KEY_V) { mouse_captured = false; debug_cursor_changed = true; } \ +/* c - uncapture mouse */ if (key & KEY_C) { mouse_captured = true; debug_cursor_changed = true; } \ +/* b - break (gdb) */ if (key & KEY_B) GDB_INTERRUPT \ + } + +#define debug_init \ + mouse_captured = true; /* debugging can uncapture pointer */ \ + debug_cursor_changed = false; /* so it needs state variables */ \ + isfullscreen = false; /* debug in a window */ + +#else +#define debug_init +#endif /* NDEBUG */ #ifdef __cplusplus }; diff --git a/src/util/veccomp.c b/src/util/veccomp.c new file mode 100644 index 0000000..f6c40b8 --- /dev/null +++ b/src/util/veccomp.c @@ -0,0 +1,98 @@ +/* + * veccomp - vector components + */ +#include "macros.h" +#include "veccomp.h" + +/* + * veccomp2d_calc - calculate the components of a 2D vector with given magnitude and angle + */ +void veccomp2d_calc(double magnitude, double angle, veccomp2d *new) +{ + if (angle <= -270) { + new->x = -sin(degtorad(fmod(angle, 90))); + new->y = cos(degtorad(fmod(angle, 90))); + } else if (angle <= -180) { + new->x = -cos(degtorad(fmod(angle, 90))); + new->y = -sin(degtorad(fmod(angle, 90))); + } else if (angle <= -90) { + new->x = sin(degtorad(fmod(angle, 90))); + new->y = -cos(degtorad(fmod(angle, 90))); + } else if (angle < 0) { + new->x = cos(degtorad(fmod(angle, 90))); + new->y = sin(degtorad(fmod(angle, 90))); + } else if (angle < 90) { + new->x = cos(degtorad(fmod(angle, 90))); + new->y = sin(degtorad(fmod(angle, 90))); + } else if (angle < 180) { + new->x = -sin(degtorad(fmod(angle, 90))); + new->y = cos(degtorad(fmod(angle, 90))); + } else if (angle < 270) { + new->x = -cos(degtorad(fmod(angle, 90))); + new->y = -sin(degtorad(fmod(angle, 90))); + } else { + new->x = sin(degtorad(fmod(angle, 90))); + new->y = -cos(degtorad(fmod(angle, 90))); + } + + new->x *= magnitude; + new->y *= magnitude; + + return; +} + +/* + * vecang2d_calc - calculate the angle from normal for a displacement using arctangent + */ +double vecang2d_calc(double x_comp, double y_comp) +{ + double angle; + double abs_x_comp = fabs(x_comp); + double abs_y_comp = fabs(y_comp); + + if (x_comp == 0 && y_comp == 0) + return 0.0; + else if (x_comp == 0) { + if (y_comp > 0) + return 0.0; + else + return 180.0; + } else if (y_comp == 0) { + if (x_comp > 0) + return 90.0; + else + return -90.0; + } + + if (x_comp > 0 && y_comp > 0) { + if (abs_y_comp > abs_x_comp) + return radtodeg(atan(abs_x_comp / abs_y_comp)); + else if (abs_y_comp < abs_x_comp) + return 90.0 - radtodeg(atan(abs_y_comp / abs_x_comp)); + else + return 45.0; + } else if (x_comp > 0 && y_comp < 0) { + if (abs_x_comp > abs_y_comp) + return radtodeg(atan(abs_y_comp / abs_x_comp)) + 90.0; + else if (abs_x_comp < abs_y_comp) + return 180.0 - radtodeg(atan(abs_x_comp / abs_y_comp)); + else + return 135.0; + } else if (x_comp < 0 && y_comp < 0) { + if (abs_y_comp > abs_x_comp) + return -180.0 + radtodeg(atan(abs_x_comp / abs_y_comp)); + else if (abs_y_comp < abs_x_comp) + return -90.0 - radtodeg(atan(abs_y_comp / abs_x_comp)); + else + return -135.0; + } else { + if (abs_x_comp > abs_y_comp) + return -90.0 + radtodeg(atan(abs_y_comp / abs_x_comp)); + else if (abs_x_comp < abs_y_comp) + return -radtodeg(atan(abs_x_comp / abs_y_comp)); + else + return -45.0; + } + + return angle; +} diff --git a/src/util/veccomp.h b/src/util/veccomp.h new file mode 100644 index 0000000..07f973a --- /dev/null +++ b/src/util/veccomp.h @@ -0,0 +1,23 @@ +/* + * veccomp - vector components + */ +#ifndef __VECCOMP_H__ +#define __VECCOMP_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef struct veccomp2d { + double x; + double y; +} veccomp2d; + +void veccomp2d_calc(double magnitude, double angle, veccomp2d *new); +double vecang2d_calc(double x_comp, double y_comp); + +#ifdef __cplusplus +}; +#endif /* __cplusplus */ + +#endif /* __VECCOMP_H__ */