diff --git a/Makefile b/Makefile index 3dc4d57a..bfa98f54 100755 --- a/Makefile +++ b/Makefile @@ -163,7 +163,7 @@ CFLAGS += $(OSX_ARCH) else #CFLAGS := -O2 -fno-strict-aliasing -fomit-frame-pointer \ -Wall -pipe -g -ggdb -MMD -fwrapv -CFLAGS := -O0 -fno-strict-aliasing \ +CFLAGS := -O2 -fno-strict-aliasing \ -Wall -pipe -g -ggdb -MMD -fwrapv endif @@ -849,6 +849,7 @@ REFGL3_OBJS_ := \ src/client/refresh/gl3/gl3_misc.o \ src/client/refresh/gl3/gl3_model.o \ src/client/refresh/gl3/gl3_sdl.o \ + src/client/refresh/gl3/gl3_warp.o \ src/client/refresh/files/pcx.o \ src/client/refresh/files/stb.o \ src/client/refresh/files/wal.o \ @@ -862,6 +863,7 @@ REFGL3_TODO_ := \ src/client/refresh/files/pcx.o \ src/client/refresh/files/sp2.o + # TODO: glad_dbg support REFGL3_OBJS_ += \ src/client/refresh/gl3/glad/src/glad.o diff --git a/src/client/header/ref.h b/src/client/header/ref.h index 193f42ef..8b3cabbc 100644 --- a/src/client/header/ref.h +++ b/src/client/header/ref.h @@ -142,7 +142,7 @@ typedef struct // called by GLimp_InitGraphics() *after* creating window, // passing the SDL_Window* (void* so we don't spill SDL.h here) // returns true (1) on success - int (EXPORT *InitContext)(void* window); + int (EXPORT *InitContext)(void* sdl_window); // shuts down rendering (OpenGL) context, calls // VID_ShutdownWindow() to shut down window as well, if !contextOnly diff --git a/src/client/refresh/gl/header/model.h b/src/client/refresh/gl/header/model.h index 8664eced..9c3b2726 100644 --- a/src/client/refresh/gl/header/model.h +++ b/src/client/refresh/gl/header/model.h @@ -147,7 +147,6 @@ typedef struct mleaf_s } mleaf_t; /* Whole model */ -typedef enum {mod_bad, mod_brush, mod_sprite, mod_alias} modtype_t; typedef struct model_s { diff --git a/src/client/refresh/gl/r_main.c b/src/client/refresh/gl/r_main.c index ffb71ad0..b4aac33f 100644 --- a/src/client/refresh/gl/r_main.c +++ b/src/client/refresh/gl/r_main.c @@ -1114,6 +1114,8 @@ R_RenderView(refdef_t *fd) } switch (gl_state.stereo_mode) { + case STEREO_MODE_NONE: + break; case STEREO_MODE_ANAGLYPH: glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); break; @@ -1127,7 +1129,8 @@ R_RenderView(refdef_t *fd) } } -enum opengl_special_buffer_modes GL_GetSpecialBufferModeForStereoMode(enum stereo_modes stereo_mode) { +enum opengl_special_buffer_modes +GL_GetSpecialBufferModeForStereoMode(enum stereo_modes stereo_mode) { switch (stereo_mode) { case STEREO_MODE_NONE: case STEREO_SPLIT_HORIZONTAL: diff --git a/src/client/refresh/gl3/gl3_draw.c b/src/client/refresh/gl3/gl3_draw.c index 2d1aac5c..95ce1efc 100644 --- a/src/client/refresh/gl3/gl3_draw.c +++ b/src/client/refresh/gl3/gl3_draw.c @@ -1,6 +1,6 @@ /* * Copyright (C) 1997-2001 Id Software, Inc. - * Copyright (C) 2016 Daniel Gibson + * Copyright (C) 2016-2017 Daniel Gibson * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -38,6 +38,42 @@ GL3_Draw_InitLocal(void) draw_chars = GL3_FindImage("pics/conchars.pcx", it_pic); } +gl3image_t * +GL3_Draw_FindPic(char *name) +{ + gl3image_t *gl; + char fullname[MAX_QPATH]; + + if ((name[0] != '/') && (name[0] != '\\')) + { + Com_sprintf(fullname, sizeof(fullname), "pics/%s.pcx", name); + gl = GL3_FindImage(fullname, it_pic); + } + else + { + gl = GL3_FindImage(name + 1, it_pic); + } + + return gl; +} + +void +GL3_Draw_GetPicSize(int *w, int *h, char *pic) +{ + gl3image_t *gl; + + gl = GL3Draw_FindPic(pic); + + if (!gl) + { + *w = *h = -1; + return; + } + + *w = gl->width; + *h = gl->height; +} + int GL3_Draw_GetPalette(void) { @@ -72,5 +108,3 @@ GL3_Draw_GetPalette(void) return 0; } - - diff --git a/src/client/refresh/gl3/gl3_image.c b/src/client/refresh/gl3/gl3_image.c index a27bedea..83440d65 100644 --- a/src/client/refresh/gl3/gl3_image.c +++ b/src/client/refresh/gl3/gl3_image.c @@ -1,6 +1,6 @@ /* * Copyright (C) 1997-2001 Id Software, Inc. - * Copyright (C) 2016 Daniel Gibson + * Copyright (C) 2016-2017 Daniel Gibson * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -318,6 +318,8 @@ GL3_LoadPic(char *name, byte *pic, int width, int realwidth, glGenTextures(1, &texNum); image->texnum = texNum; + + // glActiveTexture(GL_TEXTURE0); TODO: useful if we need >1 texture in the fragment shader GL3_Bind(texNum); if (bits == 8) @@ -681,32 +683,109 @@ GL3_RegisterSkin(char *name) return GL3_FindImage(name, it_skin); } +/* + * Any image that was not touched on + * this registration sequence + * will be freed. + */ +void +GL3_FreeUnusedImages(void) +{ + int i; + gl3image_t *image; + /* never free r_notexture or particle texture */ + gl3_notexture->registration_sequence = registration_sequence; + gl3_particletexture->registration_sequence = registration_sequence; + + for (i = 0, image = gl3textures; i < numgl3textures; i++, image++) + { + if (image->registration_sequence == registration_sequence) + { + continue; /* used this sequence */ + } + + if (!image->registration_sequence) + { + continue; /* free image_t slot */ + } + + if (image->type == it_pic) + { + continue; /* don't free pics */ + } + + /* free it */ + glDeleteTextures(1, &image->texnum); + memset(image, 0, sizeof(*image)); + } +} + +void +GL3_ShutdownImages(void) +{ + int i; + gl3image_t *image; + + for (i = 0, image = gl3textures; i < numgl3textures; i++, image++) + { + if (!image->registration_sequence) + { + continue; /* free image_t slot */ + } + + /* free it */ + glDeleteTextures(1, &image->texnum); + memset(image, 0, sizeof(*image)); + } +} + +static qboolean IsNPOT(int v) +{ + unsigned int uv = v; + // just try all the power of two values between 1 and 1 << 15 (32k) + for(unsigned int i=0; i<16; ++i) + { + unsigned int pot = (1u << i); + if(uv & pot) + { + return uv != pot; + } + } + + return true; +} void GL3_ImageList_f(void) { - R_Printf(PRINT_ALL, "TODO: Implement R_ImageList_f()\n"); - - int i; + int i, texels=0; gl3image_t *image; - int texels; const char *formatstrings[2] = { "RGB ", "RGBA" }; + const char* potstrings[2] = { + " POT", "NPOT" + }; + R_Printf(PRINT_ALL, "------------------\n"); - texels = 0; for (i = 0, image = gl3textures; i < numgl3textures; i++, image++) { + int w, h; + qboolean isNPOT = false; if (image->texnum == 0) { continue; } + w = image->upload_width; + h = image->upload_height; - texels += image->upload_width * image->upload_height; + isNPOT = IsNPOT(w) || IsNPOT(h); + + texels += w*h; switch (image->type) { @@ -727,9 +806,8 @@ GL3_ImageList_f(void) break; } - R_Printf(PRINT_ALL, " %3i %3i %s: %s\n", - image->upload_width, image->upload_height, - formatstrings[image->has_alpha], image->name); + R_Printf(PRINT_ALL, " %3i %3i %s %s: %s\n", w, h, + formatstrings[image->has_alpha], potstrings[isNPOT], image->name); } R_Printf(PRINT_ALL, "Total texel count (not counting mipmaps): %i\n", texels); diff --git a/src/client/refresh/gl3/gl3_main.c b/src/client/refresh/gl3/gl3_main.c index 726bbd38..4c772619 100644 --- a/src/client/refresh/gl3/gl3_main.c +++ b/src/client/refresh/gl3/gl3_main.c @@ -1,6 +1,6 @@ /* * Copyright (C) 1997-2001 Id Software, Inc. - * Copyright (C) 2016 Daniel Gibson + * Copyright (C) 2016-2017 Daniel Gibson * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,6 +25,9 @@ * ======================================================================= */ +#define HANDMADE_MATH_IMPLEMENTATION +#include "header/HandmadeMath.h" + #include "../../header/ref.h" #include "header/local.h" @@ -36,8 +39,13 @@ refimport_t ri; gl3config_t gl3config; gl3state_t gl3state; +/* screen size info */ +refdef_t gl3_newrefdef; + viddef_t vid; +int gl3_viewcluster, gl3_viewcluster2, gl3_oldviewcluster, gl3_oldviewcluster2; + cvar_t *gl_msaa_samples; cvar_t *gl_swapinterval; cvar_t *gl_retexturing; @@ -378,10 +386,8 @@ GL3_Init(void) STUB("TODO: Some intensity and gamma stuff that was in R_InitImages()"); registration_sequence = 1; // also from R_InitImages() -#if 0 //R_InitImages(); - most of the things in R_InitImages() shouldn't be needed anymore - Mod_Init(); -#endif // 0 + GL3_Mod_Init(); GL3_InitParticleTexture(); @@ -389,28 +395,326 @@ GL3_Init(void) R_Printf(PRINT_ALL, "\n"); return true; - } void GL3_Shutdown(void) { - ri.Cmd_RemoveCommand("modellist"); ri.Cmd_RemoveCommand("screenshot"); ri.Cmd_RemoveCommand("imagelist"); ri.Cmd_RemoveCommand("gl_strings"); -#if 0 // TODO! - Mod_FreeAll(); - R_ShutdownImages(); -#endif // 0 + GL3_Mod_FreeAll(); + GL3_ShutdownImages(); /* shutdown OS specific OpenGL stuff like contexts, etc. */ GL3_ShutdownWindow(false); } +static void +GL3_SetGL2D(void) +{ + int x, w, y, h; +#if 0 // TODO: stereo + /* set 2D virtual screen size */ + qboolean drawing_left_eye = gl_state.camera_separation < 0; + qboolean stereo_split_tb = ((gl_state.stereo_mode == STEREO_SPLIT_VERTICAL) && gl_state.camera_separation); + qboolean stereo_split_lr = ((gl_state.stereo_mode == STEREO_SPLIT_HORIZONTAL) && gl_state.camera_separation); +#endif // 0 + x = 0; + w = vid.width; + y = 0; + h = vid.height; + +#if 0 // TODO: stereo + if(stereo_split_lr) { + w = w / 2; + x = drawing_left_eye ? 0 : w; + } + + if(stereo_split_tb) { + h = h / 2; + y = drawing_left_eye ? h : 0; + } +#endif // 0 + + // FIXME: change to GL3 code! + glViewport(x, y, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, vid.width, vid.height, 0, -99999, 99999); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + glDisable(GL_BLEND); + glEnable(GL_ALPHA_TEST); + glColor4f(1, 1, 1, 1); +} + +/* + * r_newrefdef must be set before the first call + */ +static void +GL3_RenderView(refdef_t *fd) +{ +#if 0 // TODO: keep stereo stuff? + if ((gl_state.stereo_mode != STEREO_MODE_NONE) && gl_state.camera_separation) { + + qboolean drawing_left_eye = gl_state.camera_separation < 0; + switch (gl_state.stereo_mode) { + case STEREO_MODE_ANAGLYPH: + { + + // Work out the colour for each eye. + int anaglyph_colours[] = { 0x4, 0x3 }; // Left = red, right = cyan. + + if (strlen(gl_stereo_anaglyph_colors->string) == 2) { + int eye, colour, missing_bits; + // Decode the colour name from its character. + for (eye = 0; eye < 2; ++eye) { + colour = 0; + switch (toupper(gl_stereo_anaglyph_colors->string[eye])) { + case 'B': ++colour; // 001 Blue + case 'G': ++colour; // 010 Green + case 'C': ++colour; // 011 Cyan + case 'R': ++colour; // 100 Red + case 'M': ++colour; // 101 Magenta + case 'Y': ++colour; // 110 Yellow + anaglyph_colours[eye] = colour; + break; + } + } + // Fill in any missing bits. + missing_bits = ~(anaglyph_colours[0] | anaglyph_colours[1]) & 0x3; + for (eye = 0; eye < 2; ++eye) { + anaglyph_colours[eye] |= missing_bits; + } + } + + // Set the current colour. + glColorMask( + !!(anaglyph_colours[drawing_left_eye] & 0x4), + !!(anaglyph_colours[drawing_left_eye] & 0x2), + !!(anaglyph_colours[drawing_left_eye] & 0x1), + GL_TRUE + ); + } + break; + case STEREO_MODE_ROW_INTERLEAVED: + case STEREO_MODE_COLUMN_INTERLEAVED: + case STEREO_MODE_PIXEL_INTERLEAVED: + { + qboolean flip_eyes = true; + int client_x, client_y; + + //GLimp_GetClientAreaOffset(&client_x, &client_y); + client_x = 0; + client_y = 0; + + GL3_SetGL2D(); + + glEnable(GL_STENCIL_TEST); + glStencilMask(GL_TRUE); + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + + glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP); + glStencilFunc(GL_NEVER, 0, 1); + + glBegin(GL_QUADS); + { + glVertex2i(0, 0); + glVertex2i(vid.width, 0); + glVertex2i(vid.width, vid.height); + glVertex2i(0, vid.height); + } + glEnd(); + + glStencilOp(GL_INVERT, GL_KEEP, GL_KEEP); + glStencilFunc(GL_NEVER, 1, 1); + + glBegin(GL_LINES); + { + if (gl_state.stereo_mode == STEREO_MODE_ROW_INTERLEAVED || gl_state.stereo_mode == STEREO_MODE_PIXEL_INTERLEAVED) { + int y; + for (y = 0; y <= vid.height; y += 2) { + glVertex2f(0, y - 0.5f); + glVertex2f(vid.width, y - 0.5f); + } + flip_eyes ^= (client_y & 1); + } + + if (gl_state.stereo_mode == STEREO_MODE_COLUMN_INTERLEAVED || gl_state.stereo_mode == STEREO_MODE_PIXEL_INTERLEAVED) { + int x; + for (x = 0; x <= vid.width; x += 2) { + glVertex2f(x - 0.5f, 0); + glVertex2f(x - 0.5f, vid.height); + } + flip_eyes ^= (client_x & 1); + } + } + glEnd(); + + glStencilMask(GL_FALSE); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + + glStencilFunc(GL_EQUAL, drawing_left_eye ^ flip_eyes, 1); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + } + break; + default: + break; + } + } +#endif // 0 (stereo stuff) + + if (gl_norefresh->value) + { + return; + } + + gl3_newrefdef = *fd; + + STUB_ONCE("TODO: Implement!"); + +#if 0 // TODO !! + if (!r_worldmodel && !(gl3_newrefdef.rdflags & RDF_NOWORLDMODEL)) + { + ri.Sys_Error(ERR_DROP, "R_RenderView: NULL worldmodel"); + } + + if (gl_speeds->value) + { + c_brush_polys = 0; + c_alias_polys = 0; + } + + R_PushDlights(); + + if (gl_finish->value) + { + glFinish(); + } + + R_SetupFrame(); + + R_SetFrustum(); + + R_SetupGL(); + + R_MarkLeaves(); /* done here so we know if we're in water */ + + R_DrawWorld(); + + R_DrawEntitiesOnList(); + + R_RenderDlights(); + + R_DrawParticles(); + + R_DrawAlphaSurfaces(); + + R_Flash(); + + if (gl_speeds->value) + { + R_Printf(PRINT_ALL, "%4i wpoly %4i epoly %i tex %i lmaps\n", + c_brush_polys, c_alias_polys, c_visible_textures, + c_visible_lightmaps); + } + +#endif // 0 + +#if 0 // TODO: stereo stuff + switch (gl_state.stereo_mode) { + case STEREO_MODE_NONE: + break; + case STEREO_MODE_ANAGLYPH: + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + break; + case STEREO_MODE_ROW_INTERLEAVED: + case STEREO_MODE_COLUMN_INTERLEAVED: + case STEREO_MODE_PIXEL_INTERLEAVED: + glDisable(GL_STENCIL_TEST); + break; + default: + break; + } +#endif // 0 +} + +#if 0 // TODO: stereo +enum opengl_special_buffer_modes +GL3_GetSpecialBufferModeForStereoMode(enum stereo_modes stereo_mode) { + switch (stereo_mode) { + case STEREO_MODE_NONE: + case STEREO_SPLIT_HORIZONTAL: + case STEREO_SPLIT_VERTICAL: + case STEREO_MODE_ANAGLYPH: + return OPENGL_SPECIAL_BUFFER_MODE_NONE; + case STEREO_MODE_OPENGL: + return OPENGL_SPECIAL_BUFFER_MODE_STEREO; + case STEREO_MODE_ROW_INTERLEAVED: + case STEREO_MODE_COLUMN_INTERLEAVED: + case STEREO_MODE_PIXEL_INTERLEAVED: + return OPENGL_SPECIAL_BUFFER_MODE_STENCIL; + } + return OPENGL_SPECIAL_BUFFER_MODE_NONE; +} +#endif // 0 + +static void +GL3_SetLightLevel(void) +{ + vec3_t shadelight = {0}; + + if (r_newrefdef.rdflags & RDF_NOWORLDMODEL) + { + return; + } + + STUB_ONCE("TODO: IMPLEMENT!"); + +#if 0 // TODO! + /* save off light value for server to look at */ + R_LightPoint(r_newrefdef.vieworg, shadelight); + + /* pick the greatest component, which should be the + * same as the mono value returned by software */ + if (shadelight[0] > shadelight[1]) + { + if (shadelight[0] > shadelight[2]) + { + gl_lightlevel->value = 150 * shadelight[0]; + } + else + { + gl_lightlevel->value = 150 * shadelight[2]; + } + } + else + { + if (shadelight[1] > shadelight[2]) + { + gl_lightlevel->value = 150 * shadelight[1]; + } + else + { + gl_lightlevel->value = 150 * shadelight[2]; + } + } +#endif // 0 +} + +static void +GL3_RenderFrame(refdef_t *fd) +{ + GL3_RenderView(fd); + GL3_SetLightLevel(); + GL3_SetGL2D(); +} Q2_DLL_EXPORTED refexport_t GetRefAPI(refimport_t imp) @@ -427,20 +731,19 @@ GetRefAPI(refimport_t imp) re.InitContext = GL3_InitContext; re.ShutdownWindow = GL3_ShutdownWindow; -#if 0 // TODO! - re.BeginRegistration = RI_BeginRegistration; - re.RegisterModel = RI_RegisterModel; + re.BeginRegistration = GL3_BeginRegistration; + re.RegisterModel = GL3_RegisterModel; re.RegisterSkin = GL3_RegisterSkin; - re.SetSky = RI_SetSky; - re.EndRegistration = RI_EndRegistration; + re.SetSky = GL3_SetSky; + re.EndRegistration = GL3_EndRegistration; - re.RenderFrame = RI_RenderFrame; + re.RenderFrame = GL3_RenderFrame; - re.DrawFindPic = RDraw_FindPic; - - re.DrawGetPicSize = RDraw_GetPicSize; + re.DrawFindPic = GL3_Draw_FindPic; + re.DrawGetPicSize = GL3_Draw_GetPicSize; +#if 0 // TODO! re.DrawPicScaled = RDraw_PicScaled; re.DrawStretchPic = RDraw_StretchPic; @@ -450,8 +753,8 @@ GetRefAPI(refimport_t imp) re.DrawFadeScreen = RDraw_FadeScreen; re.DrawStretchRaw = RDraw_StretchRaw; - re.SetPalette = RI_SetPalette; + re.BeginFrame = RI_BeginFrame; #endif // 0 re.EndFrame = GL3_EndFrame; diff --git a/src/client/refresh/gl3/gl3_misc.c b/src/client/refresh/gl3/gl3_misc.c index b02d0e68..1f0f7b67 100644 --- a/src/client/refresh/gl3/gl3_misc.c +++ b/src/client/refresh/gl3/gl3_misc.c @@ -1,6 +1,6 @@ /* * Copyright (C) 1997-2001 Id Software, Inc. - * Copyright (C) 2016 Daniel Gibson + * Copyright (C) 2016-2017 Daniel Gibson * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/client/refresh/gl3/gl3_model.c b/src/client/refresh/gl3/gl3_model.c index f217b90c..dba47304 100644 --- a/src/client/refresh/gl3/gl3_model.c +++ b/src/client/refresh/gl3/gl3_model.c @@ -1,5 +1,6 @@ /* * Copyright (C) 1997-2001 Id Software, Inc. + * Copyright (C) 2016-2017 Daniel Gibson * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,8 +27,13 @@ #include "header/local.h" +enum { MAX_MOD_KNOWN = 512 }; + int registration_sequence; +gl3model_t mod_known[MAX_MOD_KNOWN]; +int mod_numknown; + void GL3_Mod_Modellist_f(void) { @@ -53,3 +59,140 @@ GL3_Mod_Modellist_f(void) R_Printf(PRINT_ALL, "Total resident: %i\n", total); #endif } + +void +GL3_Mod_Init(void) +{ + STUB("TODO: Implement!"); + // memset(mod_novis, 0xff, sizeof(mod_novis)); +} + + +static void +Mod_Free(gl3model_t *mod) +{ + Hunk_Free(mod->extradata); + memset(mod, 0, sizeof(*mod)); +} + +void +GL3_Mod_FreeAll(void) +{ + int i; + + for (i = 0; i < mod_numknown; i++) + { + if (mod_known[i].extradatasize) + { + Mod_Free(&mod_known[i]); + } + } +} + + +/* + * Specifies the model that will be used as the world + */ +void +GL3_BeginRegistration(char *model) +{ + char fullname[MAX_QPATH]; + cvar_t *flushmap; + + registration_sequence++; + gl3_oldviewcluster = -1; /* force markleafs */ + + Com_sprintf(fullname, sizeof(fullname), "maps/%s.bsp", model); + + /* explicitly free the old map if different + this guarantees that mod_known[0] is the + world map */ + flushmap = ri.Cvar_Get("flushmap", "0", 0); + + if (strcmp(mod_known[0].name, fullname) || flushmap->value) + { + Mod_Free(&mod_known[0]); + } + + STUB_ONCE("TODO: Implement Mod_ForName()!"); +#if 0 // TODO! + r_worldmodel = Mod_ForName(fullname, true); +#endif // 0 + gl3_viewcluster = -1; +} + +struct model_s * +GL3_RegisterModel(char *name) +{ + STUB_ONCE("TODO: Implement!"); + return NULL; +#if 0 + model_t *mod; + int i; + dsprite_t *sprout; + dmdl_t *pheader; + + mod = Mod_ForName(name, false); + + if (mod) + { + mod->registration_sequence = registration_sequence; + + /* register any images used by the models */ + if (mod->type == mod_sprite) + { + sprout = (dsprite_t *)mod->extradata; + + for (i = 0; i < sprout->numframes; i++) + { + mod->skins[i] = R_FindImage(sprout->frames[i].name, it_sprite); + } + } + else if (mod->type == mod_alias) + { + pheader = (dmdl_t *)mod->extradata; + + for (i = 0; i < pheader->num_skins; i++) + { + mod->skins[i] = R_FindImage((char *)pheader + pheader->ofs_skins + + i * MAX_SKINNAME, it_skin); + } + + mod->numframes = pheader->num_frames; + } + else if (mod->type == mod_brush) + { + for (i = 0; i < mod->numtexinfo; i++) + { + mod->texinfo[i].image->registration_sequence = + registration_sequence; + } + } + } + + return mod; +#endif // 0 +} + +void +GL3_EndRegistration(void) +{ + int i; + gl3model_t *mod; + + for (i = 0, mod = mod_known; i < mod_numknown; i++, mod++) + { + if (!mod->name[0]) + { + continue; + } + + if (mod->registration_sequence != registration_sequence) + { + /* don't need this model */ + Mod_Free(mod); + } + } + + GL3_FreeUnusedImages(); +} diff --git a/src/client/refresh/gl3/gl3_sdl.c b/src/client/refresh/gl3/gl3_sdl.c index e753d6a8..e3a7786c 100644 --- a/src/client/refresh/gl3/gl3_sdl.c +++ b/src/client/refresh/gl3/gl3_sdl.c @@ -1,6 +1,6 @@ /* * Copyright (C) 1997-2001 Id Software, Inc. - * Copyright (C) 2016 Daniel Gibson + * Copyright (C) 2016-2017 Daniel Gibson * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/client/refresh/gl3/gl3_warp.c b/src/client/refresh/gl3/gl3_warp.c new file mode 100644 index 00000000..8e269e17 --- /dev/null +++ b/src/client/refresh/gl3/gl3_warp.c @@ -0,0 +1,66 @@ +/* + * Copyright (C) 1997-2001 Id Software, Inc. + * Copyright (C) 2016-2017 Daniel Gibson + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * ======================================================================= + * + * Warps. Used on water surfaces und for skybox rotation. + * + * ======================================================================= + */ + +#include "header/local.h" + +static float skyrotate; +static vec3_t skyaxis; +static gl3image_t* sky_images[6]; +static float sky_min, sky_max; + +/* 3dstudio environment map names */ +static const char* suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"}; + +void +GL3_SetSky(char *name, float rotate, vec3_t axis) +{ + int i; + char pathname[MAX_QPATH]; + char skyname[MAX_QPATH]; + + Q_strlcpy(skyname, name, sizeof(skyname)); + skyrotate = rotate; + VectorCopy(axis, skyaxis); + + for (i = 0; i < 6; i++) + { + + // NOTE: there might be a paletted .pcx version, which was only used + // if gl_config.palettedtexture + Com_sprintf(pathname, sizeof(pathname), "env/%s%s.tga", skyname, suf[i]); + + sky_images[i] = GL3_FindImage(pathname, it_sky); + + if (!sky_images[i]) + { + sky_images[i] = gl3_notexture; + } + + sky_min = 1.0 / 512; + sky_max = 511.0 / 512; + } +} diff --git a/src/client/refresh/gl3/header/HandmadeMath.h b/src/client/refresh/gl3/header/HandmadeMath.h new file mode 100644 index 00000000..d2abbc75 --- /dev/null +++ b/src/client/refresh/gl3/header/HandmadeMath.h @@ -0,0 +1,2141 @@ +/* + HandmadeMath.h v1.0 + + This is a single header file with a bunch of useful functions for + basic game math operations. + + ========================================================================== + + You MUST + + #define HANDMADE_MATH_IMPLEMENTATION + + in EXACTLY one C or C++ file that includes this header, BEFORE the + include, like this: + + #define HANDMADE_MATH_IMPLEMENTATION + #include "HandmadeMath.h" + + All other files should just #include "HandmadeMath.h" without the #define. + + ========================================================================== + + For overloaded and operator overloaded versions of the base C functions, + you MUST + + #define HANDMADE_MATH_CPP_MODE + + in EXACTLY one C or C++ file that includes this header, BEFORE the + include, like this: + + #define HANDMADE_MATH_IMPLEMENTATION + #define HANDMADE_MATH_CPP_MODE + #include "HandmadeMath.h" + + All other files should just #include "HandmadeMath.h" without the #define. + + ========================================================================== + + To disable SSE intrinsics, you MUST + + #define HANDMADE_MATH_NO_SSE + + in EXACTLY one C or C++ file that includes this header, BEFORE the + include, like this: + + #define HANDMADE_MATH_IMPLEMENTATION + #define HANDMADE_MATH_CPP_MODE + #define HANDMADE_MATH_NO_SSE + #include "HandmadeMath.h" + + or + + #define HANDMADE_MATH_IMPLEMENTATION + #define HANDMADE_MATH_NO_SSE + #include "HandmadeMath.h" + + ========================================================================== + + To disable inlining functions, you MUST + + #define HANDMADE_MATH_NO_INLINE + + in EXACTLY one C or C++ file that includes this header, BEFORE the + include, like this: + + #define HANDMADE_MATH_IMPLEMENTATION + #define HANDMADE_MATH_CPP_MODE + #define HANDMADE_MATH_NO_INLINE + #include "HandmadeMath.h" + + All other files should just #include "HandmadeMath.h" without the #define. + + ========================================================================== + + To Disable the CRT, you MUST + + #define HMM_SINF MySinF + #define HMM_COSF MyCosF + #define HMM_TANF MyTanF + #define HMM_EXPF MyExpF + #define HMM_LOGF MyLogF + + Provide your own implementations of SinF, CosF, TanF, ExpF and LogF + in EXACTLY one C or C++ file that includes this header, BEFORE the + include, like this: + + #define HMM_SINF MySinF + #define HMM_COSF MyCosF + #define HMM_TANF MyTanF + #define HMM_EXPF MyExpF + #define HMM_LOGF MyLogF + #define HANDMADE_MATH_IMPLEMENTATION + #define HANDMADE_MATH_CPP_MODE + #include "HandmadeMath.h" + + If you do not define all five of these, HandmadeMath.h will use the + versions of these functions that are provided by the CRT. + + ========================================================================== + + Version History: + 0.2 (*) Updated documentation + (*) Better C compliance + (*) Prefix all handmade math functions + (*) Better operator overloading + 0.2a + (*) Prefixed Macros + 0.2b + (*) Disabled warning 4201 on MSVC as it is legal is C11 + (*) Removed the f at the end of HMM_PI to get 64bit precision + 0.3 + (*) Added +=, -=, *=, /= for hmm_vec2, hmm_vec3, hmm_vec4 + 0.4 + (*) SSE Optimized HMM_SqrtF + (*) SSE Optimized HMM_RSqrtF + (*) Removed CRT + 0.5 + (*) Added scalar multiplication and division for vectors + and matrices + (*) Added matrix subtraction and += for hmm_mat4 + (*) Reconciled all headers and implementations + (*) Tidied up, and filled in a few missing operators + 0.5.1 + (*) Ensured column-major order for matrices throughout + (*) Fixed HMM_Translate producing row-major matrices + 0.5.2 + (*) Fixed SSE code in HMM_SqrtF + (*) Fixed SSE code in HMM_RSqrtF + 0.6 + (*) Added Unit testing + (*) Made HMM_Power faster + (*) Fixed possible efficiency problem with HMM_Normalize + (*) RENAMED HMM_LengthSquareRoot to HMM_LengthSquared + (*) RENAMED HMM_RSqrtF to HMM_RSquareRootF + (*) RENAMED HMM_SqrtF to HMM_SquareRootF + (*) REMOVED Inner function (user should use Dot now) + (*) REMOVED HMM_FastInverseSquareRoot function declaration + 0.7 + (*) REMOVED HMM_LengthSquared in HANDMADE_MATH_IMPLEMENTATION (should use HMM_LengthSquaredVec3, or HANDMADE_MATH_CPP_MODE for function overloaded version) + (*) REMOVED HMM_Length in HANDMADE_MATH_IMPLEMENTATION (should use HMM_LengthVec3, HANDMADE_MATH_CPP_MODE for function overloaded version) + (*) REMOVED HMM_Normalize in HANDMADE_MATH_IMPLEMENTATION (should use HMM_NormalizeVec3, or HANDMADE_MATH_CPP_MODE for function overloaded version) + (*) Added HMM_LengthSquaredVec2 + (*) Added HMM_LengthSquaredVec4 + (*) Addd HMM_LengthVec2 + (*) Added HMM_LengthVec4 + (*) Added HMM_NormalizeVec2 + (*) Added HMM_NormalizeVec4 + 1.0 + (*) Lots of testing! + + LICENSE + + This software is in the public domain. Where that dedication is not + recognized, you are granted a perpetual, irrevocable license to copy, + distribute, and modify this file as you see fit. + + CREDITS + + Written by Zakary Strange (zak@handmade.network && @strangezak) + + Functionality: + Matt Mascarenhas (@miblo_) + Aleph + FieryDrake (@fierydrake) + Gingerbill (@TheGingerBill) + Ben Visness (@bvisness) + + Fixes: + Jeroen van Rijn (@J_vanRijn) + Kiljacken (@Kiljacken) + Insofaras (@insofaras) +*/ + +#include + +#ifndef HANDMADE_MATH_H +#define HANDMADE_MATH_H + +#ifdef _MSC_VER +#pragma warning(disable:4201) +#endif + +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-Wgnu-anonymous-struct" +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifdef HANDMADEMATH_STATIC +#define HMMDEF static +#else +#define HMMDEF extern +#endif + +#ifdef HANDMADE_MATH_NO_INLINE +#define HINLINE +#elif _MSC_VER && !__INTEL_COMPILER +#define HINLINE __inline +#else +#define HINLINE inline +#endif + +#if !defined(HMM_SINF) || !defined(HMM_COSF) || !defined(HMM_TANF) || \ + !defined(HMM_EXPF) || !defined(HMM_LOGF) +#include +#endif + +#ifndef HMM_SINF +#define HMM_SINF sinf +#endif + +#ifndef HMM_COSF +#define HMM_COSF cosf +#endif + +#ifndef HMM_TANF +#define HMM_TANF tanf +#endif + +#ifndef HMM_EXPF +#define HMM_EXPF expf +#endif + +#ifndef HMM_LOGF +#define HMM_LOGF logf +#endif + +#define HMM_PI32 3.14159265359f +#define HMM_PI 3.14159265358979323846 + +#define HMM_MIN(a, b) (a) > (b) ? (b) : (a) +#define HMM_MAX(a, b) (a) < (b) ? (b) : (a) +#define HMN_ABS(a) (a) < 0 ? -(a) : (a) +#define HMM_MOD(a, m) ((a) % (m)) >= 0 ? ((a) % (m)) : (((a) % (m)) + (m)) +#define HMM_SQUARE(x) ((x) * (x)) + +typedef union hmm_vec2 +{ + struct + { + float X, Y; + }; + + struct + { + float U, V; + }; + + struct + { + float Left, Right; + }; + + float Elements[2]; +} hmm_vec2; + +typedef union hmm_vec3 +{ + struct + { + float X, Y, Z; + }; + + struct + { + float U, V, W; + }; + + struct + { + float R, G, B; + }; + + struct + { + hmm_vec2 XY; + float Ignored0_; + }; + + struct + { + float Ignored1_; + hmm_vec2 YZ; + }; + + struct + { + hmm_vec2 UV; + float Ignored2_; + }; + + struct + { + float Ignored3_; + hmm_vec2 VW; + }; + + float Elements[3]; +} hmm_vec3; + +typedef union hmm_vec4 +{ + struct + { + union + { + hmm_vec3 XYZ; + struct + { + float X, Y, Z; + }; + }; + + float W; + }; + struct + { + union + { + hmm_vec3 RGB; + struct + { + float R, G, B; + }; + }; + + float A; + }; + + struct + { + hmm_vec2 XY; + float Ignored0_; + float Ignored1_; + }; + + struct + { + float Ignored2_; + hmm_vec2 YZ; + float Ignored3_; + }; + + struct + { + float Ignored4_; + float Ignored5_; + hmm_vec2 ZW; + }; + + float Elements[4]; +} hmm_vec4; + +typedef union hmm_mat4 +{ + float Elements[4][4]; +} hmm_mat4; + +typedef hmm_vec2 hmm_v2; +typedef hmm_vec3 hmm_v3; +typedef hmm_vec4 hmm_v4; +typedef hmm_mat4 hmm_m4; + +HMMDEF float HMM_SinF(float Angle); +HMMDEF float HMM_TanF(float Angle); +HMMDEF float HMM_CosF(float Angle); +HMMDEF float HMM_ExpF(float Float); +HMMDEF float HMM_LogF(float Float); + +HMMDEF float HMM_ToRadians(float Degrees); +HMMDEF float HMM_SquareRootF(float Float); +HMMDEF float HMM_RSquareRootF(float Float); + +HMMDEF float HMM_LengthSquaredVec2(hmm_vec2 A); +HMMDEF float HMM_LengthSquaredVec3(hmm_vec3 A); +HMMDEF float HMM_LengthSquaredVec4(hmm_vec4 A); + +HMMDEF float HMM_LengthVec2(hmm_vec2 A); +HMMDEF float HMM_LengthVec3(hmm_vec3 A); +HMMDEF float HMM_LengthVec4(hmm_vec4 A); + +HMMDEF float HMM_Power(float Base, int Exponent); +HMMDEF float HMM_PowerF(float Base, float Exponent); +HMMDEF float HMM_Lerp(float A, float Time, float B); +HMMDEF float HMM_Clamp(float Min, float Value, float Max); + +HMMDEF hmm_vec2 HMM_NormalizeVec2(hmm_vec2 A); +HMMDEF hmm_vec3 HMM_NormalizeVec3(hmm_vec3 A); +HMMDEF hmm_vec4 HMM_NormalizeVec4(hmm_vec4 A); + +HMMDEF float HMM_DotVec2(hmm_vec2 VecOne, hmm_vec2 VecTwo); +HMMDEF float HMM_DotVec3(hmm_vec3 VecOne, hmm_vec3 VecTwo); +HMMDEF float HMM_DotVec4(hmm_vec4 VecOne, hmm_vec4 VecTwo); + +HMMDEF hmm_vec3 HMM_Cross(hmm_vec3 VecOne, hmm_vec3 VecTwo); + +HMMDEF hmm_vec2 HMM_Vec2i(int X, int Y); +HMMDEF hmm_vec2 HMM_Vec2(float X, float Y); +HMMDEF hmm_vec3 HMM_Vec3(float X, float Y, float Z); +HMMDEF hmm_vec3 HMM_Vec3i(int X, int Y, int Z); +HMMDEF hmm_vec4 HMM_Vec4(float X, float Y, float Z, float W); +HMMDEF hmm_vec4 HMM_Vec4i(int X, int Y, int Z, int W); +HMMDEF hmm_vec4 HMM_Vec4v(hmm_vec3 Vector, float W); + +HMMDEF hmm_vec2 HMM_AddVec2(hmm_vec2 Left, hmm_vec2 Right); +HMMDEF hmm_vec3 HMM_AddVec3(hmm_vec3 Left, hmm_vec3 Right); +HMMDEF hmm_vec4 HMM_AddVec4(hmm_vec4 Left, hmm_vec4 Right); + +HMMDEF hmm_vec2 HMM_SubtractVec2(hmm_vec2 Left, hmm_vec2 Right); +HMMDEF hmm_vec3 HMM_SubtractVec3(hmm_vec3 Left, hmm_vec3 Right); +HMMDEF hmm_vec4 HMM_SubtractVec4(hmm_vec4 Left, hmm_vec4 Right); + +HMMDEF hmm_vec2 HMM_MultiplyVec2(hmm_vec2 Left, hmm_vec2 Right); +HMMDEF hmm_vec2 HMM_MultiplyVec2f(hmm_vec2 Left, float Right); +HMMDEF hmm_vec3 HMM_MultiplyVec3(hmm_vec3 Left, hmm_vec3 Right); +HMMDEF hmm_vec3 HMM_MultiplyVec3f(hmm_vec3 Left, float Right); +HMMDEF hmm_vec4 HMM_MultiplyVec4(hmm_vec4 Left, hmm_vec4 Right); +HMMDEF hmm_vec4 HMM_MultiplyVec4f(hmm_vec4 Left, float Right); + +HMMDEF hmm_vec2 HMM_DivideVec2(hmm_vec2 Left, hmm_vec2 Right); +HMMDEF hmm_vec2 HMM_DivideVec2f(hmm_vec2 Left, float Right); +HMMDEF hmm_vec3 HMM_DivideVec3(hmm_vec3 Left, hmm_vec3 Right); +HMMDEF hmm_vec3 HMM_DivideVec3f(hmm_vec3 Left, float Right); +HMMDEF hmm_vec4 HMM_DivideVec4(hmm_vec4 Left, hmm_vec4 Right); +HMMDEF hmm_vec4 HMM_DivideVec4f(hmm_vec4 Left, float Right); + +HMMDEF hmm_mat4 HMM_Mat4(void); +HMMDEF hmm_mat4 HMM_Mat4d(float Diagonal); +HMMDEF hmm_mat4 HMM_AddMat4(hmm_mat4 Left, hmm_mat4 Right); +HMMDEF hmm_mat4 HMM_SubtractMat4(hmm_mat4 Left, hmm_mat4 Right); +HMMDEF hmm_mat4 HMM_MultiplyMat4(hmm_mat4 Left, hmm_mat4 Right); +HMMDEF hmm_mat4 HMM_MultiplyMat4f(hmm_mat4 Matrix, float Scalar); +HMMDEF hmm_vec4 HMM_MultiplyMat4ByVec4(hmm_mat4 Matrix, hmm_vec4 Vector); +HMMDEF hmm_mat4 HMM_DivideMat4f(hmm_mat4 Matrix, float Scalar); + +HMMDEF hmm_mat4 HMM_Transpose(hmm_mat4 Matrix); + +HMMDEF hmm_mat4 HMM_Orthographic(float Left, float Right, float Bottom, float Top, float Near, float Far); +HMMDEF hmm_mat4 HMM_Perspective(float FOV, float AspectRatio, float Near, float Far); + +HMMDEF hmm_mat4 HMM_Translate(hmm_vec3 Translation); +HMMDEF hmm_mat4 HMM_Rotate(float Angle, hmm_vec3 Axis); +HMMDEF hmm_mat4 HMM_Scale(hmm_vec3 Scale); + +HMMDEF hmm_mat4 HMM_LookAt(hmm_vec3 Eye, hmm_vec3 Center, hmm_vec3 Up); + +#ifdef __cplusplus +} +#endif + +#ifdef HANDMADE_MATH_CPP_MODE + +HMMDEF float HMM_Length(hmm_vec2 A); +HMMDEF float HMM_Length(hmm_vec3 A); +HMMDEF float HMM_Length(hmm_vec4 A); + +HMMDEF float HMM_LengthSquared(hmm_vec2 A); +HMMDEF float HMM_LengthSquared(hmm_vec3 A); +HMMDEF float HMM_LengthSquared(hmm_vec4 A); + +HMMDEF hmm_vec2 HMM_Normalize(hmm_vec2 A); +HMMDEF hmm_vec3 HMM_Normalize(hmm_vec3 A); +HMMDEF hmm_vec4 HMM_Normalize(hmm_vec4 A); + +HMMDEF float HMM_Dot(hmm_vec2 VecOne, hmm_vec2 VecTwo); +HMMDEF float HMM_Dot(hmm_vec3 VecOne, hmm_vec3 VecTwo); +HMMDEF float HMM_Dot(hmm_vec4 VecOne, hmm_vec4 VecTwo); + +HMMDEF hmm_vec2 HMM_Add(hmm_vec2 Left, hmm_vec2 Right); +HMMDEF hmm_vec3 HMM_Add(hmm_vec3 Left, hmm_vec3 Right); +HMMDEF hmm_vec4 HMM_Add(hmm_vec4 Left, hmm_vec4 Right); +HMMDEF hmm_mat4 HMM_Add(hmm_mat4 Left, hmm_mat4 Right); + +HMMDEF hmm_vec2 HMM_Subtract(hmm_vec2 Left, hmm_vec2 Right); +HMMDEF hmm_vec3 HMM_Subtract(hmm_vec3 Left, hmm_vec3 Right); +HMMDEF hmm_vec4 HMM_Subtract(hmm_vec4 Left, hmm_vec4 Right); +HMMDEF hmm_mat4 HMM_Subtract(hmm_mat4 Left, hmm_mat4 Right); + +HMMDEF hmm_vec2 HMM_Multiply(hmm_vec2 Left, hmm_vec2 Right); +HMMDEF hmm_vec2 HMM_Multiply(hmm_vec2 Left, float Right); +HMMDEF hmm_vec3 HMM_Multiply(hmm_vec3 Left, hmm_vec3 Right); +HMMDEF hmm_vec3 HMM_Multiply(hmm_vec3 Left, float Right); +HMMDEF hmm_vec4 HMM_Multiply(hmm_vec4 Left, hmm_vec4 Right); +HMMDEF hmm_vec4 HMM_Multiply(hmm_vec4 Left, float Right); +HMMDEF hmm_mat4 HMM_Multiply(hmm_mat4 Left, hmm_mat4 Right); +HMMDEF hmm_mat4 HMM_Multiply(hmm_mat4 Left, float Right); +HMMDEF hmm_vec4 HMM_Multiply(hmm_mat4 Matrix, hmm_vec4 Vector); + +HMMDEF hmm_vec2 HMM_Divide(hmm_vec2 Left, hmm_vec2 Right); +HMMDEF hmm_vec2 HMM_Divide(hmm_vec2 Left, float Right); +HMMDEF hmm_vec3 HMM_Divide(hmm_vec3 Left, hmm_vec3 Right); +HMMDEF hmm_vec3 HMM_Divide(hmm_vec3 Left, float Right); +HMMDEF hmm_vec4 HMM_Divide(hmm_vec4 Left, hmm_vec4 Right); +HMMDEF hmm_vec4 HMM_Divide(hmm_vec4 Left, float Right); +HMMDEF hmm_mat4 HMM_Divide(hmm_mat4 Left, float Right); + +HMMDEF hmm_vec2 operator+(hmm_vec2 Left, hmm_vec2 Right); +HMMDEF hmm_vec3 operator+(hmm_vec3 Left, hmm_vec3 Right); +HMMDEF hmm_vec4 operator+(hmm_vec4 Left, hmm_vec4 Right); +HMMDEF hmm_mat4 operator+(hmm_mat4 Left, hmm_mat4 Right); + +HMMDEF hmm_vec2 operator-(hmm_vec2 Left, hmm_vec2 Right); +HMMDEF hmm_vec3 operator-(hmm_vec3 Left, hmm_vec3 Right); +HMMDEF hmm_vec4 operator-(hmm_vec4 Left, hmm_vec4 Right); +HMMDEF hmm_mat4 operator-(hmm_mat4 Left, hmm_mat4 Right); + +HMMDEF hmm_vec2 operator*(hmm_vec2 Left, hmm_vec2 Right); +HMMDEF hmm_vec3 operator*(hmm_vec3 Left, hmm_vec3 Right); +HMMDEF hmm_vec4 operator*(hmm_vec4 Left, hmm_vec4 Right); +HMMDEF hmm_mat4 operator*(hmm_mat4 Left, hmm_mat4 Right); + +HMMDEF hmm_vec2 operator*(hmm_vec2 Left, float Right); +HMMDEF hmm_vec3 operator*(hmm_vec3 Left, float Right); +HMMDEF hmm_vec4 operator*(hmm_vec4 Left, float Right); +HMMDEF hmm_mat4 operator*(hmm_mat4 Left, float Right); + +HMMDEF hmm_vec2 operator*(float Left, hmm_vec2 Right); +HMMDEF hmm_vec3 operator*(float Left, hmm_vec3 Right); +HMMDEF hmm_vec4 operator*(float Left, hmm_vec4 Right); +HMMDEF hmm_mat4 operator*(float Left, hmm_mat4 Right); + +HMMDEF hmm_vec4 operator*(hmm_mat4 Matrix, hmm_vec4 Vector); + +HMMDEF hmm_vec2 operator/(hmm_vec2 Left, hmm_vec2 Right); +HMMDEF hmm_vec3 operator/(hmm_vec3 Left, hmm_vec3 Right); +HMMDEF hmm_vec4 operator/(hmm_vec4 Left, hmm_vec4 Right); + +HMMDEF hmm_vec2 operator/(hmm_vec2 Left, float Right); +HMMDEF hmm_vec3 operator/(hmm_vec3 Left, float Right); +HMMDEF hmm_vec4 operator/(hmm_vec4 Left, float Right); +HMMDEF hmm_mat4 operator/(hmm_mat4 Left, float Right); + +HMMDEF hmm_vec2 &operator+=(hmm_vec2 &Left, hmm_vec2 Right); +HMMDEF hmm_vec3 &operator+=(hmm_vec3 &Left, hmm_vec3 Right); +HMMDEF hmm_vec4 &operator+=(hmm_vec4 &Left, hmm_vec4 Right); +HMMDEF hmm_mat4 &operator+=(hmm_mat4 &Left, hmm_mat4 Right); + +HMMDEF hmm_vec2 &operator-=(hmm_vec2 &Left, hmm_vec2 Right); +HMMDEF hmm_vec3 &operator-=(hmm_vec3 &Left, hmm_vec3 Right); +HMMDEF hmm_vec4 &operator-=(hmm_vec4 &Left, hmm_vec4 Right); +HMMDEF hmm_mat4 &operator-=(hmm_mat4 &Left, hmm_mat4 Right); + +HMMDEF hmm_vec2 &operator*=(hmm_vec2 &Left, hmm_vec2 Right); +HMMDEF hmm_vec3 &operator*=(hmm_vec3 &Left, hmm_vec3 Right); +HMMDEF hmm_vec4 &operator*=(hmm_vec4 &Left, hmm_vec4 Right); + +HMMDEF hmm_vec2 &operator*=(hmm_vec2 &Left, float Right); +HMMDEF hmm_vec3 &operator*=(hmm_vec3 &Left, float Right); +HMMDEF hmm_vec4 &operator*=(hmm_vec4 &Left, float Right); +HMMDEF hmm_mat4 &operator*=(hmm_mat4 &Left, float Right); + +HMMDEF hmm_vec2 &operator/=(hmm_vec2 &Left, hmm_vec2 Right); +HMMDEF hmm_vec3 &operator/=(hmm_vec3 &Left, hmm_vec3 Right); +HMMDEF hmm_vec4 &operator/=(hmm_vec4 &Left, hmm_vec4 Right); + +HMMDEF hmm_vec2 &operator/=(hmm_vec2 &Left, float Right); +HMMDEF hmm_vec3 &operator/=(hmm_vec3 &Left, float Right); +HMMDEF hmm_vec4 &operator/=(hmm_vec4 &Left, float Right); +HMMDEF hmm_mat4 &operator/=(hmm_mat4 &Left, float Right); + +#endif /* HANDMADE_MATH_CPP */ + +#endif /* HANDMADE_MATH_H */ + +#ifdef HANDMADE_MATH_IMPLEMENTATION + +HINLINE float +HMM_SinF(float Angle) +{ + float Result = 0.0f; + + Result = HMM_SINF(Angle); + return (Result); +} + +HINLINE float +HMM_CosF(float Angle) +{ + float Result = 0.0f; + + Result = HMM_COSF(Angle); + return (Result); +} + +HINLINE float +HMM_TanF(float Radians) +{ + float Result = 0.0f; + + Result = HMM_TANF(Radians); + return (Result); +} + +HINLINE float +HMM_ExpF(float Float) +{ + float Result = 0.0f; + + Result = HMM_EXPF(Float); + return (Result); +} + +HINLINE float +HMM_LogF(float Float) +{ + float Result = 0.0f; + + Result = HMM_LOGF(Float); + return (Result); +} + +HINLINE float +HMM_ToRadians(float Degrees) +{ + float Result = 0.0f; + + Result = Degrees * (HMM_PI32 / 180.0f); + return (Result); +} + +HINLINE float +HMM_SquareRootF(float Value) +{ + float Result = 0.0f; + +#ifdef HANDMADE_MATH_NO_SSE + Result = sqrtf(Value); +#else + __m128 In = _mm_set_ss(Value); + __m128 Out = _mm_sqrt_ss(In); + Result = _mm_cvtss_f32(Out); +#endif + + return(Result); +} + +HINLINE float +HMM_RSquareRootF(float Value) +{ + float Result = 0.0f; + +#ifdef HANDMADE_MATH_NO_SSE + Result = 1.0f/HMM_SqrtF(Value); +#else + __m128 In = _mm_set_ss(Value); + __m128 Out = _mm_rsqrt_ss(In); + Result = _mm_cvtss_f32(Out); +#endif + + return(Result); +} + +HINLINE float +HMM_LengthSquaredVec2(hmm_vec2 A) +{ + float Result = 0.0f; + + Result = HMM_DotVec2(A, A); + + return(Result); +} + +HINLINE float +HMM_LengthSquaredVec3(hmm_vec3 A) +{ + float Result = 0.0f; + + Result = HMM_DotVec3(A, A); + + return (Result); +} + +HINLINE float +HMM_LengthSquaredVec4(hmm_vec4 A) +{ + float Result = 0.0f; + + Result = HMM_DotVec4(A, A); + + return(Result); +} + +HINLINE float +HMM_LengthVec2(hmm_vec2 A) +{ + float Result = 0.0f; + + Result = HMM_SquareRootF(HMM_LengthSquaredVec2(A)); + + return(Result); +} + +HINLINE float +HMM_LengthVec3(hmm_vec3 A) +{ + float Result = 0.0f; + + Result = HMM_SquareRootF(HMM_LengthSquaredVec3(A)); + + return (Result); +} + +HINLINE float +HMM_LengthVec4(hmm_vec4 A) +{ + float Result = 0.0f; + + Result = HMM_SquareRootF(HMM_LengthSquaredVec4(A)); + + return(Result); +} + +HINLINE float +HMM_Power(float Base, int Exponent) +{ + float Result = 1.0f; + float Mul = Exponent < 0 ? 1.f / Base : Base; + unsigned int X = Exponent < 0 ? -Exponent : Exponent; + while (X) + { + if (X & 1) + { + Result *= Mul; + } + + Mul *= Mul; + X >>= 1; + } + + return (Result); +} + +HINLINE float +HMM_PowerF(float Base, float Exponent) +{ + return HMM_EXPF(Exponent * HMM_LOGF(Base)); +} + +HINLINE float +HMM_Lerp(float A, float Time, float B) +{ + float Result = 0; + + Result = (1.0f - Time) * A + Time * B; + return (Result); +} + +HINLINE float +HMM_Clamp(float Min, float Value, float Max) +{ + float Result = Value; + + if(Result < Min) + { + Result = Min; + } + else if(Result > Max) + { + Result = Max; + } + + return (Result); +} + +HINLINE hmm_vec2 +HMM_NormalizeVec2(hmm_vec2 A) +{ + hmm_vec2 Result = {0}; + + float VectorLength = HMM_LengthVec2(A); + + Result.X = A.X * (1.0f / VectorLength); + Result.Y = A.Y * (1.0f / VectorLength); + + return (Result); +} + +HINLINE hmm_vec3 +HMM_NormalizeVec3(hmm_vec3 A) +{ + hmm_vec3 Result = {0}; + + float VectorLength = HMM_LengthVec3(A); + + Result.X = A.X * (1.0f / VectorLength); + Result.Y = A.Y * (1.0f / VectorLength); + Result.Z = A.Z * (1.0f / VectorLength); + + return (Result); +} + +HINLINE hmm_vec4 +HMM_NormalizeVec4(hmm_vec4 A) +{ + hmm_vec4 Result = {0}; + + float VectorLength = HMM_LengthVec4(A); + + Result.X = A.X * (1.0f / VectorLength); + Result.Y = A.Y * (1.0f / VectorLength); + Result.Z = A.Z * (1.0f / VectorLength); + Result.W = A.W * (1.0f / VectorLength); + + return (Result); +} + +HINLINE float +HMM_DotVec2(hmm_vec2 VecOne, hmm_vec2 VecTwo) +{ + float Result = 0.0f; + + Result = (VecOne.X * VecTwo.X) + (VecOne.Y * VecTwo.Y); + + return (Result); +} + +HINLINE float +HMM_DotVec3(hmm_vec3 VecOne, hmm_vec3 VecTwo) +{ + float Result = 0.0f; + + Result = (VecOne.X * VecTwo.X) + (VecOne.Y * VecTwo.Y) + (VecOne.Z * VecTwo.Z); + + return (Result); +} + +HINLINE float +HMM_DotVec4(hmm_vec4 VecOne, hmm_vec4 VecTwo) +{ + float Result = 0.0f; + + Result = (VecOne.X * VecTwo.X) + (VecOne.Y * VecTwo.Y) + (VecOne.Z * VecTwo.Z) + (VecOne.W * VecTwo.W); + + return (Result); +} + +HINLINE hmm_vec3 +HMM_Cross(hmm_vec3 VecOne, hmm_vec3 VecTwo) +{ + hmm_vec3 Result = {0}; + + Result.X = (VecOne.Y * VecTwo.Z) - (VecOne.Z * VecTwo.Y); + Result.Y = (VecOne.Z * VecTwo.X) - (VecOne.X * VecTwo.Z); + Result.Z = (VecOne.X * VecTwo.Y) - (VecOne.Y * VecTwo.X); + + return (Result); +} + +HINLINE hmm_vec2 +HMM_Vec2(float X, float Y) +{ + hmm_vec2 Result = {0}; + + Result.X = X; + Result.Y = Y; + + return (Result); +} + +HINLINE hmm_vec2 +HMM_Vec2i(int X, int Y) +{ + hmm_vec2 Result = {0}; + + Result.X = (float)X; + Result.Y = (float)Y; + + return (Result); +} + +HINLINE hmm_vec3 +HMM_Vec3(float X, float Y, float Z) +{ + hmm_vec3 Result = {0}; + + Result.X = X; + Result.Y = Y; + Result.Z = Z; + + return (Result); +} + +HINLINE hmm_vec3 +HMM_Vec3i(int X, int Y, int Z) +{ + hmm_vec3 Result = {0}; + + Result.X = (float)X; + Result.Y = (float)Y; + Result.Z = (float)Z; + + return (Result); +} + +HINLINE hmm_vec4 +HMM_Vec4(float X, float Y, float Z, float W) +{ + hmm_vec4 Result = {0}; + + Result.X = X; + Result.Y = Y; + Result.Z = Z; + Result.W = W; + + return (Result); +} + +HINLINE hmm_vec4 +HMM_Vec4i(int X, int Y, int Z, int W) +{ + hmm_vec4 Result = {0}; + + Result.X = (float)X; + Result.Y = (float)Y; + Result.Z = (float)Z; + Result.W = (float)W; + + return (Result); +} + +HINLINE hmm_vec4 +HMM_Vec4v(hmm_vec3 Vector, float W) +{ + hmm_vec4 Result = {0}; + + Result.XYZ = Vector; + Result.W = W; + + return (Result); +} + +HINLINE hmm_vec2 +HMM_AddVec2(hmm_vec2 Left, hmm_vec2 Right) +{ + hmm_vec2 Result = {0}; + + Result.X = Left.X + Right.X; + Result.Y = Left.Y + Right.Y; + + return (Result); +} + +HINLINE hmm_vec3 +HMM_AddVec3(hmm_vec3 Left, hmm_vec3 Right) +{ + hmm_vec3 Result = {0}; + + Result.X = Left.X + Right.X; + Result.Y = Left.Y + Right.Y; + Result.Z = Left.Z + Right.Z; + + return (Result); +} + +HINLINE hmm_vec4 +HMM_AddVec4(hmm_vec4 Left, hmm_vec4 Right) +{ + hmm_vec4 Result = {0}; + + Result.X = Left.X + Right.X; + Result.Y = Left.Y + Right.Y; + Result.Z = Left.Z + Right.Z; + Result.W = Left.W + Right.W; + + return (Result); +} + +HINLINE hmm_vec2 +HMM_SubtractVec2(hmm_vec2 Left, hmm_vec2 Right) +{ + hmm_vec2 Result = {0}; + + Result.X = Left.X - Right.X; + Result.Y = Left.Y - Right.Y; + + return (Result); +} + +HINLINE hmm_vec3 +HMM_SubtractVec3(hmm_vec3 Left, hmm_vec3 Right) +{ + hmm_vec3 Result = {0}; + + Result.X = Left.X - Right.X; + Result.Y = Left.Y - Right.Y; + Result.Z = Left.Z - Right.Z; + + return (Result); +} + +HINLINE hmm_vec4 +HMM_SubtractVec4(hmm_vec4 Left, hmm_vec4 Right) +{ + hmm_vec4 Result = {0}; + + Result.X = Left.X - Right.X; + Result.Y = Left.Y - Right.Y; + Result.Z = Left.Z - Right.Z; + Result.W = Left.W - Right.W; + + return (Result); +} + +HINLINE hmm_vec2 +HMM_MultiplyVec2(hmm_vec2 Left, hmm_vec2 Right) +{ + hmm_vec2 Result = {0}; + + Result.X = Left.X * Right.X; + Result.Y = Left.Y * Right.Y; + + return (Result); +} + +HINLINE hmm_vec2 +HMM_MultiplyVec2f(hmm_vec2 Left, float Right) +{ + hmm_vec2 Result = {0}; + + Result.X = Left.X * Right; + Result.Y = Left.Y * Right; + + return (Result); +} + +HINLINE hmm_vec3 +HMM_MultiplyVec3(hmm_vec3 Left, hmm_vec3 Right) +{ + hmm_vec3 Result = {0}; + + Result.X = Left.X * Right.X; + Result.Y = Left.Y * Right.Y; + Result.Z = Left.Z * Right.Z; + + return (Result); +} + +HINLINE hmm_vec3 +HMM_MultiplyVec3f(hmm_vec3 Left, float Right) +{ + hmm_vec3 Result = {0}; + + Result.X = Left.X * Right; + Result.Y = Left.Y * Right; + Result.Z = Left.Z * Right; + + return (Result); +} + +HINLINE hmm_vec4 +HMM_MultiplyVec4(hmm_vec4 Left, hmm_vec4 Right) +{ + hmm_vec4 Result = {0}; + + Result.X = Left.X * Right.X; + Result.Y = Left.Y * Right.Y; + Result.Z = Left.Z * Right.Z; + Result.W = Left.W * Right.W; + + return (Result); +} + +HINLINE hmm_vec4 +HMM_MultiplyVec4f(hmm_vec4 Left, float Right) +{ + hmm_vec4 Result = {0}; + + Result.X = Left.X * Right; + Result.Y = Left.Y * Right; + Result.Z = Left.Z * Right; + Result.W = Left.W * Right; + + return (Result); +} + +HINLINE hmm_vec2 +HMM_DivideVec2(hmm_vec2 Left, hmm_vec2 Right) +{ + hmm_vec2 Result = {0}; + + Result.X = Left.X / Right.X; + Result.Y = Left.Y / Right.Y; + + return (Result); +} + +HINLINE hmm_vec2 +HMM_DivideVec2f(hmm_vec2 Left, float Right) +{ + hmm_vec2 Result = {0}; + + Result.X = Left.X / Right; + Result.Y = Left.Y / Right; + + return (Result); +} + +HINLINE hmm_vec3 +HMM_DivideVec3(hmm_vec3 Left, hmm_vec3 Right) +{ + hmm_vec3 Result = {0}; + + Result.X = Left.X / Right.X; + Result.Y = Left.Y / Right.Y; + Result.Z = Left.Z / Right.Z; + + return (Result); +} + +HINLINE hmm_vec3 +HMM_DivideVec3f(hmm_vec3 Left, float Right) +{ + hmm_vec3 Result = {0}; + + Result.X = Left.X / Right; + Result.Y = Left.Y / Right; + Result.Z = Left.Z / Right; + + return (Result); +} + +HINLINE hmm_vec4 +HMM_DivideVec4(hmm_vec4 Left, hmm_vec4 Right) +{ + hmm_vec4 Result = {0}; + + Result.X = Left.X / Right.X; + Result.Y = Left.Y / Right.Y; + Result.Z = Left.Z / Right.Z; + Result.W = Left.W / Right.W; + + return (Result); +} + +HINLINE hmm_vec4 +HMM_DivideVec4f(hmm_vec4 Left, float Right) +{ + hmm_vec4 Result = {0}; + + Result.X = Left.X / Right; + Result.Y = Left.Y / Right; + Result.Z = Left.Z / Right; + Result.W = Left.W / Right; + + return (Result); +} + +HINLINE hmm_mat4 +HMM_Mat4(void) +{ + hmm_mat4 Result = {0}; + + return (Result); +} + +HINLINE hmm_mat4 +HMM_Mat4d(float Diagonal) +{ + hmm_mat4 Result = HMM_Mat4(); + + Result.Elements[0][0] = Diagonal; + Result.Elements[1][1] = Diagonal; + Result.Elements[2][2] = Diagonal; + Result.Elements[3][3] = Diagonal; + + return (Result); +} + +HINLINE hmm_mat4 +HMM_AddMat4(hmm_mat4 Left, hmm_mat4 Right) +{ + hmm_mat4 Result = HMM_Mat4(); + + int Columns; + for(Columns = 0; Columns < 4; ++Columns) + { + int Rows; + for(Rows = 0; Rows < 4; ++Rows) + { + Result.Elements[Columns][Rows] = Left.Elements[Columns][Rows] + Right.Elements[Columns][Rows]; + } + } + + return (Result); +} + +HINLINE hmm_mat4 +HMM_SubtractMat4(hmm_mat4 Left, hmm_mat4 Right) +{ + hmm_mat4 Result = HMM_Mat4(); + + int Columns; + for(Columns = 0; Columns < 4; ++Columns) + { + int Rows; + for(Rows = 0; Rows < 4; ++Rows) + { + Result.Elements[Columns][Rows] = Left.Elements[Columns][Rows] - Right.Elements[Columns][Rows]; + } + } + + return (Result); +} + +hmm_mat4 +HMM_MultiplyMat4(hmm_mat4 Left, hmm_mat4 Right) +{ + hmm_mat4 Result = HMM_Mat4(); + + int Columns; + for(Columns = 0; Columns < 4; ++Columns) + { + int Rows; + for(Rows = 0; Rows < 4; ++Rows) + { + float Sum = 0; + int CurrentMatrice; + for(CurrentMatrice = 0; CurrentMatrice < 4; ++CurrentMatrice) + { + Sum += Left.Elements[CurrentMatrice][Rows] * Right.Elements[Columns][CurrentMatrice]; + } + + Result.Elements[Columns][Rows] = Sum; + } + } + + return (Result); +} + +hmm_mat4 +HMM_MultiplyMat4f(hmm_mat4 Matrix, float Scalar) +{ + hmm_mat4 Result = HMM_Mat4(); + + int Columns; + for(Columns = 0; Columns < 4; ++Columns) + { + int Rows; + for(Rows = 0; Rows < 4; ++Rows) + { + Result.Elements[Columns][Rows] = Matrix.Elements[Columns][Rows] * Scalar; + } + } + + return (Result); +} + +hmm_vec4 +HMM_MultiplyMat4ByVec4(hmm_mat4 Matrix, hmm_vec4 Vector) +{ + hmm_vec4 Result = {0}; + + int Columns, Rows; + for(Rows = 0; Rows < 4; ++Rows) + { + float Sum = 0; + for(Columns = 0; Columns < 4; ++Columns) + { + Sum += Matrix.Elements[Columns][Rows] * Vector.Elements[Columns]; + } + + Result.Elements[Rows] = Sum; + } + + return (Result); +} + +hmm_mat4 +HMM_DivideMat4f(hmm_mat4 Matrix, float Scalar) +{ + hmm_mat4 Result = HMM_Mat4(); + + int Columns; + for(Columns = 0; Columns < 4; ++Columns) + { + int Rows; + for(Rows = 0; Rows < 4; ++Rows) + { + Result.Elements[Columns][Rows] = Matrix.Elements[Columns][Rows] / Scalar; + } + } + + return (Result); +} + +hmm_mat4 +HMM_Transpose(hmm_mat4 Matrix) +{ + hmm_mat4 Result = HMM_Mat4(); + + int Columns; + for(Columns = 0; Columns < 4; ++Columns) + { + int Rows; + for(Rows = 0; Rows < 4; ++Rows) + { + Result.Elements[Rows][Columns] = Matrix.Elements[Columns][Rows]; + } + } + + return (Result); +} + +hmm_mat4 +HMM_Orthographic(float Left, float Right, float Bottom, float Top, float Near, float Far) +{ + hmm_mat4 Result = HMM_Mat4d(1.0f); + + Result.Elements[0][0] = 2.0f / (Right - Left); + Result.Elements[1][1] = 2.0f / (Top - Bottom); + Result.Elements[2][2] = 2.0f / (Near - Far); + + Result.Elements[3][0] = (Left + Right) / (Left - Right); + Result.Elements[3][1] = (Bottom + Top) / (Bottom - Top); + Result.Elements[3][2] = (Far + Near) / (Near - Far); + + return (Result); +} + +hmm_mat4 +HMM_Perspective(float FOV, float AspectRatio, float Near, float Far) +{ + hmm_mat4 Result = HMM_Mat4d(1.0f); + + float TanThetaOver2 = HMM_TanF(FOV * (HMM_PI32 / 360.0f)); + + Result.Elements[0][0] = 1.0f / TanThetaOver2; + Result.Elements[1][1] = AspectRatio / TanThetaOver2; + Result.Elements[2][3] = -1.0f; + Result.Elements[2][2] = (Near + Far) / (Near - Far); + Result.Elements[3][2] = (2.0f * Near * Far) / (Near - Far); + Result.Elements[3][3] = 0.0f; + + return (Result); +} + +hmm_mat4 +HMM_Translate(hmm_vec3 Translation) +{ + hmm_mat4 Result = HMM_Mat4d(1.0f); + + Result.Elements[3][0] = Translation.X; + Result.Elements[3][1] = Translation.Y; + Result.Elements[3][2] = Translation.Z; + + return (Result); +} + +hmm_mat4 +HMM_Rotate(float Angle, hmm_vec3 Axis) +{ + hmm_mat4 Result = HMM_Mat4d(1.0f); + + Axis = HMM_NormalizeVec3(Axis); + + float SinTheta = HMM_SinF(HMM_ToRadians(Angle)); + float CosTheta = HMM_CosF(HMM_ToRadians(Angle)); + float CosValue = 1.0f - CosTheta; + + Result.Elements[0][0] = (Axis.X * Axis.X * CosValue) + CosTheta; + Result.Elements[0][1] = (Axis.X * Axis.Y * CosValue) + (Axis.Z * SinTheta); + Result.Elements[0][2] = (Axis.X * Axis.Z * CosValue) - (Axis.Y * SinTheta); + + Result.Elements[1][0] = (Axis.Y * Axis.X * CosValue) - (Axis.Z * SinTheta); + Result.Elements[1][1] = (Axis.Y * Axis.Y * CosValue) + CosTheta; + Result.Elements[1][2] = (Axis.Y * Axis.Z * CosValue) + (Axis.X * SinTheta); + + Result.Elements[2][0] = (Axis.Z * Axis.X * CosValue) + (Axis.Y * SinTheta); + Result.Elements[2][1] = (Axis.Z * Axis.Y * CosValue) - (Axis.X * SinTheta); + Result.Elements[2][2] = (Axis.Z * Axis.Z * CosValue) + CosTheta; + + return (Result); +} + +hmm_mat4 +HMM_Scale(hmm_vec3 Scale) +{ + hmm_mat4 Result = HMM_Mat4d(1.0f); + + Result.Elements[0][0] = Scale.X; + Result.Elements[1][1] = Scale.Y; + Result.Elements[2][2] = Scale.Z; + + return (Result); +} + +hmm_mat4 +HMM_LookAt(hmm_vec3 Eye, hmm_vec3 Center, hmm_vec3 Up) +{ + hmm_mat4 Result = {0}; + + hmm_vec3 F = HMM_NormalizeVec3(HMM_SubtractVec3(Center, Eye)); + hmm_vec3 S = HMM_NormalizeVec3(HMM_Cross(F, Up)); + hmm_vec3 U = HMM_Cross(S, F); + + Result.Elements[0][0] = S.X; + Result.Elements[0][1] = U.X; + Result.Elements[0][2] = -F.X; + + Result.Elements[1][0] = S.Y; + Result.Elements[1][1] = U.Y; + Result.Elements[1][2] = -F.Y; + + Result.Elements[2][0] = S.Z; + Result.Elements[2][1] = U.Z; + Result.Elements[2][2] = -F.Z; + + Result.Elements[3][0] = -HMM_DotVec3(S, Eye); + Result.Elements[3][1] = -HMM_DotVec3(U, Eye); + Result.Elements[3][2] = HMM_DotVec3(F, Eye); + Result.Elements[3][3] = 1.0f; + + return (Result); +} + +#ifdef HANDMADE_MATH_CPP_MODE + +HMMDEF float +HMM_Length(hmm_vec2 A) +{ + float Result = 0.0f; + + Result = HMM_LengthVec2(A); + + return(Result); +} + +HMMDEF float +HMM_Length(hmm_vec3 A) +{ + float Result = 0.0f; + + Result = HMM_LengthVec3(A); + + return(Result); +} + +HMMDEF float +HMM_Length(hmm_vec4 A) +{ + float Result = 0.0f; + + Result = HMM_LengthVec4(A); + + return(Result); +} + +HINLINE float +HMM_LengthSquared(hmm_vec2 A) +{ + float Result = 0.0f; + + Result = HMM_LengthSquaredVec2(A); + + return(Result); +} + +HINLINE float +HMM_LengthSquared(hmm_vec3 A) +{ + float Result = 0.0f; + + Result = HMM_LengthSquaredVec3(A); + + return(Result); +} + +HINLINE float +HMM_LengthSquared(hmm_vec4 A) +{ + float Result = 0.0f; + + Result = HMM_LengthSquaredVec4(A); + + return(Result); +} + +HINLINE hmm_vec2 +HMM_Normalize(hmm_vec2 A) +{ + hmm_vec2 Result = {0}; + + Result = HMM_NormalizeVec2(A); + + return(Result); +} + +HINLINE hmm_vec3 +HMM_Normalize(hmm_vec3 A) +{ + hmm_vec3 Result = {0}; + + Result = HMM_NormalizeVec3(A); + + return(Result); +} + +HINLINE hmm_vec4 +HMM_Normalize(hmm_vec4 A) +{ + hmm_vec4 Result = {0}; + + Result = HMM_NormalizeVec4(A); + + return(Result); +} + +HINLINE float +HMM_Dot(hmm_vec2 VecOne, hmm_vec2 VecTwo) +{ + float Result = 0; + + Result = HMM_DotVec2(VecOne, VecTwo); + + return(Result); +} + +HINLINE float +HMM_Dot(hmm_vec3 VecOne, hmm_vec3 VecTwo) +{ + float Result = 0; + + Result = HMM_DotVec3(VecOne, VecTwo); + + return(Result); +} + +HINLINE float +HMM_Dot(hmm_vec4 VecOne, hmm_vec4 VecTwo) +{ + float Result = 0; + + Result = HMM_DotVec4(VecOne, VecTwo); + + return(Result); +} + +HINLINE hmm_vec2 +HMM_Add(hmm_vec2 Left, hmm_vec2 Right) +{ + hmm_vec2 Result = {0}; + + Result = HMM_AddVec2(Left, Right); + return (Result); +} + +HINLINE hmm_vec3 +HMM_Add(hmm_vec3 Left, hmm_vec3 Right) +{ + hmm_vec3 Result = {0}; + + Result = HMM_AddVec3(Left, Right); + return (Result); +} + +HMMDEF HINLINE hmm_vec4 +HMM_Add(hmm_vec4 Left, hmm_vec4 Right) +{ + hmm_vec4 Result = {0}; + + Result = HMM_AddVec4(Left, Right); + return (Result); +} + +HINLINE hmm_mat4 +HMM_Add(hmm_mat4 Left, hmm_mat4 Right) +{ + hmm_mat4 Result = {0}; + + Result = HMM_AddMat4(Left, Right); + return (Result); +} + +HINLINE hmm_vec2 +HMM_Subtract(hmm_vec2 Left, hmm_vec2 Right) +{ + hmm_vec2 Result = {0}; + + Result = HMM_SubtractVec2(Left, Right); + return (Result); +} + +HINLINE hmm_vec3 +HMM_Subtract(hmm_vec3 Left, hmm_vec3 Right) +{ + hmm_vec3 Result = {0}; + + Result = HMM_SubtractVec3(Left, Right); + return (Result); +} + +HINLINE hmm_vec4 +HMM_Subtract(hmm_vec4 Left, hmm_vec4 Right) +{ + hmm_vec4 Result = {0}; + + Result = HMM_SubtractVec4(Left, Right); + return (Result); +} + +HINLINE hmm_mat4 +HMM_Subtract(hmm_mat4 Left, hmm_mat4 Right) +{ + hmm_mat4 Result = {0}; + + Result = HMM_SubtractMat4(Left, Right); + return (Result); +} + +HINLINE hmm_vec2 +HMM_Multiply(hmm_vec2 Left, hmm_vec2 Right) +{ + hmm_vec2 Result = {0}; + + Result = HMM_MultiplyVec2(Left, Right); + return (Result); +} + +HINLINE hmm_vec2 +HMM_Multiply(hmm_vec2 Left, float Right) +{ + hmm_vec2 Result = {0}; + + Result = HMM_MultiplyVec2f(Left, Right); + return (Result); +} + +HINLINE hmm_vec3 +HMM_Multiply(hmm_vec3 Left, hmm_vec3 Right) +{ + hmm_vec3 Result = {0}; + + Result = HMM_MultiplyVec3(Left, Right); + return (Result); +} + +HINLINE hmm_vec3 +HMM_Multiply(hmm_vec3 Left, float Right) +{ + hmm_vec3 Result = {0}; + + Result = HMM_MultiplyVec3f(Left, Right); + return (Result); +} + +HINLINE hmm_vec4 +HMM_Multiply(hmm_vec4 Left, hmm_vec4 Right) +{ + hmm_vec4 Result = {0}; + + Result = HMM_MultiplyVec4(Left, Right); + return (Result); +} + +HINLINE hmm_vec4 +HMM_Multiply(hmm_vec4 Left, float Right) +{ + hmm_vec4 Result = {0}; + + Result = HMM_MultiplyVec4f(Left, Right); + return (Result); +} + +HINLINE hmm_mat4 +HMM_Multiply(hmm_mat4 Left, hmm_mat4 Right) +{ + hmm_mat4 Result = {0}; + + Result = HMM_MultiplyMat4(Left, Right); + return (Result); +} + +HINLINE hmm_mat4 +HMM_Multiply(hmm_mat4 Left, float Right) +{ + hmm_mat4 Result = {0}; + + Result = HMM_MultiplyMat4f(Left, Right); + return (Result); +} + +HINLINE hmm_vec4 +HMM_Multiply(hmm_mat4 Matrix, hmm_vec4 Vector) +{ + hmm_vec4 Result = {0}; + + Result = HMM_MultiplyMat4ByVec4(Matrix, Vector); + return (Result); +} + +HINLINE hmm_vec2 +HMM_Divide(hmm_vec2 Left, hmm_vec2 Right) +{ + hmm_vec2 Result = {0}; + + Result = HMM_DivideVec2(Left, Right); + return (Result); +} + +HINLINE hmm_vec2 +HMM_Divide(hmm_vec2 Left, float Right) +{ + hmm_vec2 Result = {0}; + + Result = HMM_DivideVec2f(Left, Right); + return (Result); +} + +HINLINE hmm_vec3 +HMM_Divide(hmm_vec3 Left, hmm_vec3 Right) +{ + hmm_vec3 Result = {0}; + + Result = HMM_DivideVec3(Left, Right); + return (Result); +} + +HINLINE hmm_vec3 +HMM_Divide(hmm_vec3 Left, float Right) +{ + hmm_vec3 Result = {0}; + + Result = HMM_DivideVec3f(Left, Right); + return (Result); +} + +HINLINE hmm_vec4 +HMM_Divide(hmm_vec4 Left, hmm_vec4 Right) +{ + hmm_vec4 Result = {0}; + + Result = HMM_DivideVec4(Left, Right); + return (Result); +} + +HINLINE hmm_vec4 +HMM_Divide(hmm_vec4 Left, float Right) +{ + hmm_vec4 Result = {0}; + + Result = HMM_DivideVec4f(Left, Right); + return (Result); +} + +HINLINE hmm_mat4 +HMM_Divide(hmm_mat4 Left, float Right) +{ + hmm_mat4 Result = {0}; + + Result = HMM_DivideMat4f(Left, Right); + return (Result); +} + +HINLINE hmm_vec2 +operator+(hmm_vec2 Left, hmm_vec2 Right) +{ + hmm_vec2 Result = {0}; + + Result = HMM_Add(Left, Right); + return (Result); +} + +HINLINE hmm_vec3 +operator+(hmm_vec3 Left, hmm_vec3 Right) +{ + hmm_vec3 Result = {0}; + + Result = HMM_Add(Left, Right); + return (Result); +} + +HINLINE hmm_vec4 +operator+(hmm_vec4 Left, hmm_vec4 Right) +{ + hmm_vec4 Result = {0}; + + Result = HMM_Add(Left, Right); + return (Result); +} + +HINLINE hmm_mat4 +operator+(hmm_mat4 Left, hmm_mat4 Right) +{ + hmm_mat4 Result = {0}; + + Result = HMM_Add(Left, Right); + return (Result); +} + +HINLINE hmm_vec2 +operator-(hmm_vec2 Left, hmm_vec2 Right) +{ + hmm_vec2 Result = {0}; + + Result = HMM_Subtract(Left, Right); + return (Result); +} + +HINLINE hmm_vec3 +operator-(hmm_vec3 Left, hmm_vec3 Right) +{ + hmm_vec3 Result = {0}; + + Result = HMM_Subtract(Left, Right); + return (Result); +} + +HINLINE hmm_vec4 +operator-(hmm_vec4 Left, hmm_vec4 Right) +{ + hmm_vec4 Result = {0}; + + Result = HMM_Subtract(Left, Right); + return (Result); +} + +HINLINE hmm_mat4 +operator-(hmm_mat4 Left, hmm_mat4 Right) +{ + hmm_mat4 Result = {0}; + + Result = HMM_Subtract(Left, Right); + return (Result); +} + +HINLINE hmm_vec2 +operator*(hmm_vec2 Left, hmm_vec2 Right) +{ + hmm_vec2 Result = {0}; + + Result = HMM_Multiply(Left, Right); + return (Result); +} + +HINLINE hmm_vec3 +operator*(hmm_vec3 Left, hmm_vec3 Right) +{ + hmm_vec3 Result = {0}; + + Result = HMM_Multiply(Left, Right); + return (Result); +} + +HINLINE hmm_vec4 +operator*(hmm_vec4 Left, hmm_vec4 Right) +{ + hmm_vec4 Result = HMM_Multiply(Left, Right); + + return (Result); +} + +HINLINE hmm_vec2 +operator*(hmm_vec2 Left, float Right) +{ + hmm_vec2 Result = {0}; + + Result = HMM_Multiply(Left, Right); + return (Result); +} + +HINLINE hmm_vec3 +operator*(hmm_vec3 Left, float Right) +{ + hmm_vec3 Result = {0}; + + Result = HMM_Multiply(Left, Right); + return (Result); +} + +HINLINE hmm_vec4 +operator*(hmm_vec4 Left, float Right) +{ + hmm_vec4 Result = {0}; + + Result = HMM_Multiply(Left, Right); + return (Result); +} + +HINLINE hmm_mat4 +operator*(hmm_mat4 Left, float Right) +{ + hmm_mat4 Result = {0}; + + Result = HMM_Multiply(Left, Right); + return (Result); +} + +HINLINE hmm_vec2 +operator*(float Left, hmm_vec2 Right) +{ + hmm_vec2 Result = {0}; + + Result = HMM_Multiply(Right, Left); + return (Result); +} + +HINLINE hmm_vec3 +operator*(float Left, hmm_vec3 Right) +{ + hmm_vec3 Result = {0}; + + Result = HMM_Multiply(Right, Left); + return (Result); +} + +HINLINE hmm_vec4 +operator*(float Left, hmm_vec4 Right) +{ + hmm_vec4 Result = {0}; + + Result = HMM_Multiply(Right, Left); + return (Result); +} + +HINLINE hmm_mat4 +operator*(float Left, hmm_mat4 Right) +{ + hmm_mat4 Result = {0}; + + Result = HMM_Multiply(Right, Left); + return (Result); +} + +HINLINE hmm_mat4 +operator*(hmm_mat4 Left, hmm_mat4 Right) +{ + hmm_mat4 Result = {0}; + + Result = HMM_Multiply(Left, Right); + return (Result); +} + +HINLINE hmm_vec4 +operator*(hmm_mat4 Matrix, hmm_vec4 Vector) +{ + hmm_vec4 Result = {0}; + + Result = HMM_Multiply(Matrix, Vector); + return (Result); +} + +HINLINE hmm_vec2 +operator/(hmm_vec2 Left, hmm_vec2 Right) +{ + hmm_vec2 Result = {0}; + + Result = HMM_Divide(Left, Right); + return (Result); +} + +HINLINE hmm_vec3 +operator/(hmm_vec3 Left, hmm_vec3 Right) +{ + hmm_vec3 Result = HMM_Divide(Left, Right); + + return (Result); +} + +HINLINE hmm_vec4 +operator/(hmm_vec4 Left, hmm_vec4 Right) +{ + hmm_vec4 Result = {0}; + + Result = HMM_Divide(Left, Right); + return (Result); +} + +HINLINE hmm_vec2 +operator/(hmm_vec2 Left, float Right) +{ + hmm_vec2 Result = {0}; + + Result = HMM_Divide(Left, Right); + return (Result); +} + +HINLINE hmm_vec3 +operator/(hmm_vec3 Left, float Right) +{ + hmm_vec3 Result = {0}; + + Result = HMM_Divide(Left, Right); + return (Result); +} + +HINLINE hmm_vec4 +operator/(hmm_vec4 Left, float Right) +{ + hmm_vec4 Result = {0}; + + Result = HMM_Divide(Left, Right); + return (Result); +} + +HINLINE hmm_mat4 +operator/(hmm_mat4 Left, float Right) +{ + hmm_mat4 Result = {0}; + + Result = HMM_Divide(Left, Right); + return (Result); +} + +HINLINE hmm_vec2 & +operator+=(hmm_vec2 &Left, hmm_vec2 Right) +{ + return (Left = Left + Right); +} + +HINLINE hmm_vec3 & +operator+=(hmm_vec3 &Left, hmm_vec3 Right) +{ + return (Left = Left + Right); +} + +HINLINE hmm_vec4 & +operator+=(hmm_vec4 &Left, hmm_vec4 Right) +{ + return (Left = Left + Right); +} + +HINLINE hmm_mat4 & +operator+=(hmm_mat4 &Left, hmm_mat4 Right) +{ + return (Left = Left + Right); +} + +HINLINE hmm_vec2 & +operator-=(hmm_vec2 &Left, hmm_vec2 Right) +{ + return (Left = Left - Right); +} + +HINLINE hmm_vec3 & +operator-=(hmm_vec3 &Left, hmm_vec3 Right) +{ + return (Left = Left - Right); +} + +HINLINE hmm_vec4 & +operator-=(hmm_vec4 &Left, hmm_vec4 Right) +{ + return (Left = Left - Right); +} + +HINLINE hmm_mat4 & +operator-=(hmm_mat4 &Left, hmm_mat4 Right) +{ + return (Left = Left - Right); +} + +HINLINE hmm_vec2 & +operator/=(hmm_vec2 &Left, hmm_vec2 Right) +{ + return (Left = Left / Right); +} + +HINLINE hmm_vec3 & +operator/=(hmm_vec3 &Left, hmm_vec3 Right) +{ + return (Left = Left / Right); +} + +HINLINE hmm_vec4 & +operator/=(hmm_vec4 &Left, hmm_vec4 Right) +{ + return (Left = Left / Right); +} + +HINLINE hmm_vec2 & +operator/=(hmm_vec2 &Left, float Right) +{ + return (Left = Left / Right); +} + +HINLINE hmm_vec3 & +operator/=(hmm_vec3 &Left, float Right) +{ + return (Left = Left / Right); +} + +HINLINE hmm_vec4 & +operator/=(hmm_vec4 &Left, float Right) +{ + return (Left = Left / Right); +} + +HINLINE hmm_mat4 & +operator/=(hmm_mat4 &Left, float Right) +{ + return (Left = Left / Right); +} + +HINLINE hmm_vec2 & +operator*=(hmm_vec2 &Left, hmm_vec2 Right) +{ + return (Left = Left * Right); +} + +HINLINE hmm_vec3 & +operator*=(hmm_vec3 &Left, hmm_vec3 Right) +{ + return (Left = Left * Right); +} + +HINLINE hmm_vec4 & +operator*=(hmm_vec4 &Left, hmm_vec4 Right) +{ + return (Left = Left * Right); +} + +HINLINE hmm_vec2 & +operator*=(hmm_vec2 &Left, float Right) +{ + return (Left = Left * Right); +} + +HINLINE hmm_vec3 & +operator*=(hmm_vec3 &Left, float Right) +{ + return (Left = Left * Right); +} + +HINLINE hmm_vec4 & +operator*=(hmm_vec4 &Left, float Right) +{ + return (Left = Left * Right); +} + +HINLINE hmm_mat4 & +operator*=(hmm_mat4 &Left, float Right) +{ + return (Left = Left * Right); +} + +#endif /* HANDMADE_MATH_CPP_MODE */ + +#endif /* HANDMADE_MATH_IMPLEMENTATION */ \ No newline at end of file diff --git a/src/client/refresh/gl3/header/local.h b/src/client/refresh/gl3/header/local.h index b5676722..c0046027 100644 --- a/src/client/refresh/gl3/header/local.h +++ b/src/client/refresh/gl3/header/local.h @@ -1,6 +1,6 @@ /* * Copyright (C) 1997-2001 Id Software, Inc. - * Copyright (C) 2016 Daniel Gibson + * Copyright (C) 2016-2017 Daniel Gibson * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -44,16 +44,24 @@ #include "../../ref_shared.h" #define STUB(msg) \ - R_Printf(PRINT_ALL, "STUB: %s() %s\n", __FUNCTION__, msg ) + R_Printf(PRINT_ALL, "STUB: %s() %s\n", __FUNCTION__, msg) -#define STUB_ONCE(msg) do {\ +#define STUB_ONCE(msg) do { \ static int show=1; \ if(show) { \ show = 0; \ - R_Printf(PRINT_ALL, "STUB: %s() %s\n", __FUNCTION__, msg ); \ + R_Printf(PRINT_ALL, "STUB: %s() %s\n", __FUNCTION__, msg); \ } \ } while(0); +// a wrapper around glVertexAttribPointer() to stay sane +// (caller doesn't have to cast to GLintptr and then void*) +static inline void +qglVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset) +{ + glVertexAttribPointer(index, size, type, normalized, stride, (const void*)offset); +} + typedef struct { const char *renderer_string; @@ -103,6 +111,8 @@ extern gl3state_t gl3state; extern viddef_t vid; +extern int gl3_viewcluster, gl3_viewcluster2, gl3_oldviewcluster, gl3_oldviewcluster2; + /* NOTE: struct image_s* is what re.RegisterSkin() etc return so no gl3image_s! * (I think the client only passes the pointer around and doesn't know the * definition of this struct, so this being different from struct image_s @@ -127,36 +137,54 @@ typedef struct image_s enum {MAX_GL3TEXTURES = 1024}; +// include this down here so it can use gl3image_t +#include "model.h" + extern gl3image_t *gl3_notexture; /* use for bad textures */ extern gl3image_t *gl3_particletexture; /* little dot for particles */ - extern int gl_filter_min; extern int gl_filter_max; +// gl3_sdl.c extern int GL3_PrepareForWindow(void); extern int GL3_InitContext(void* win); extern void GL3_EndFrame(void); extern void GL3_ShutdownWindow(qboolean contextOnly); +// gl3_misc.c extern void GL3_InitParticleTexture(void); extern void GL3_ScreenShot(void); extern void GL3_SetDefaultState(void); +// gl3_model.c extern int registration_sequence; +extern void GL3_Mod_Init(void); +extern void GL3_Mod_FreeAll(void); +extern void GL3_BeginRegistration(char *model); +extern struct model_s * GL3_RegisterModel(char *name); +extern void GL3_EndRegistration(void); extern void GL3_Mod_Modellist_f(void); +// gl3_draw.c extern void GL3_Draw_InitLocal(void); +extern gl3image_t * GL3_Draw_FindPic(char *name); +extern void GL3_Draw_GetPicSize(int *w, int *h, char *pic); extern int GL3_Draw_GetPalette(void); +// gl3_image.c +extern void GL3_TextureMode(char *string); extern void GL3_Bind(int texnum); extern gl3image_t *GL3_LoadPic(char *name, byte *pic, int width, int realwidth, int height, int realheight, imagetype_t type, int bits); extern gl3image_t *GL3_FindImage(char *name, imagetype_t type); extern gl3image_t *GL3_RegisterSkin(char *name); -extern void GL3_TextureMode(char *string); +extern void GL3_FreeUnusedImages(void); extern void GL3_ImageList_f(void); +// gl3_warp.c +extern void GL3_SetSky(char *name, float rotate, vec3_t axis); + extern cvar_t *gl_msaa_samples; extern cvar_t *gl_swapinterval; extern cvar_t *gl_retexturing; diff --git a/src/client/refresh/gl3/header/model.h b/src/client/refresh/gl3/header/model.h new file mode 100644 index 00000000..33408db5 --- /dev/null +++ b/src/client/refresh/gl3/header/model.h @@ -0,0 +1,226 @@ +/* + * Copyright (C) 1997-2001 Id Software, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * ======================================================================= + * + * Header for the model stuff. + * + * ======================================================================= + */ + +#ifndef SRC_CLIENT_REFRESH_GL3_HEADER_MODEL_H_ +#define SRC_CLIENT_REFRESH_GL3_HEADER_MODEL_H_ + +// TODO: maybe lots of these things should get a gl3_ prefix and might +// need to be adapted and so on + +enum { + SIDE_FRONT = 0, + SIDE_BACK = 1, + SIDE_ON = 2 +}; + +enum { + SURF_PLANEBACK = 2, + SURF_DRAWSKY = 4, + SURF_DRAWTURB = 0x10, + SURF_DRAWBACKGROUND = 0x40, + SURF_UNDERWATER = 0x80, + + VERTEXSIZE = 7 +}; + +/* in memory representation */ +typedef struct +{ + vec3_t position; +} mvertex_t; + +typedef struct +{ + vec3_t mins, maxs; + vec3_t origin; /* for sounds or lights */ + float radius; + int headnode; + int visleafs; /* not including the solid leaf 0 */ + int firstface, numfaces; +} mmodel_t; + +typedef struct +{ + unsigned short v[2]; + unsigned int cachededgeoffset; +} medge_t; + +typedef struct mtexinfo_s +{ + float vecs[2][4]; + int flags; + int numframes; + struct mtexinfo_s *next; /* animation chain */ + gl3image_t *image; +} mtexinfo_t; + +typedef struct glpoly_s +{ + struct glpoly_s *next; + struct glpoly_s *chain; + int numverts; + int flags; /* for SURF_UNDERWATER (not needed anymore?) */ + float verts[4][VERTEXSIZE]; /* variable sized (xyz s1t1 s2t2) */ +} glpoly_t; + +typedef struct msurface_s +{ + int visframe; /* should be drawn when node is crossed */ + + cplane_t *plane; + int flags; + + int firstedge; /* look up in model->surfedges[], negative numbers */ + int numedges; /* are backwards edges */ + + short texturemins[2]; + short extents[2]; + + int light_s, light_t; /* gl lightmap coordinates */ + int dlight_s, dlight_t; /* gl lightmap coordinates for dynamic lightmaps */ + + glpoly_t *polys; /* multiple if warped */ + struct msurface_s *texturechain; + struct msurface_s *lightmapchain; + + mtexinfo_t *texinfo; + + /* lighting info */ + int dlightframe; + int dlightbits; + + int lightmaptexturenum; + byte styles[MAXLIGHTMAPS]; + float cached_light[MAXLIGHTMAPS]; /* values currently used in lightmap */ + byte *samples; /* [numstyles*surfsize] */ +} msurface_t; + +typedef struct mnode_s +{ + /* common with leaf */ + int contents; /* -1, to differentiate from leafs */ + int visframe; /* node needs to be traversed if current */ + + float minmaxs[6]; /* for bounding box culling */ + + struct mnode_s *parent; + + /* node specific */ + cplane_t *plane; + struct mnode_s *children[2]; + + unsigned short firstsurface; + unsigned short numsurfaces; +} mnode_t; + +typedef struct mleaf_s +{ + /* common with node */ + int contents; /* wil be a negative contents number */ + int visframe; /* node needs to be traversed if current */ + + float minmaxs[6]; /* for bounding box culling */ + + struct mnode_s *parent; + + /* leaf specific */ + int cluster; + int area; + + msurface_t **firstmarksurface; + int nummarksurfaces; +} mleaf_t; + +/* Whole model */ + +// this, must be struct model_s, not gl3model_s, +// because struct model_s* is returned by re.RegisterModel() +typedef struct model_s +{ + char name[MAX_QPATH]; + + int registration_sequence; + + modtype_t type; + int numframes; + + int flags; + + /* volume occupied by the model graphics */ + vec3_t mins, maxs; + float radius; + + /* solid volume for clipping */ + qboolean clipbox; + vec3_t clipmins, clipmaxs; + + /* brush model */ + int firstmodelsurface, nummodelsurfaces; + int lightmap; /* only for submodels */ + + int numsubmodels; + mmodel_t *submodels; + + int numplanes; + cplane_t *planes; + + int numleafs; /* number of visible leafs, not counting 0 */ + mleaf_t *leafs; + + int numvertexes; + mvertex_t *vertexes; + + int numedges; + medge_t *edges; + + int numnodes; + int firstnode; + mnode_t *nodes; + + int numtexinfo; + mtexinfo_t *texinfo; + + int numsurfaces; + msurface_t *surfaces; + + int numsurfedges; + int *surfedges; + + int nummarksurfaces; + msurface_t **marksurfaces; + + dvis_t *vis; + + byte *lightdata; + + /* for alias models and skins */ + gl3image_t *skins[MAX_MD2SKINS]; + + int extradatasize; + void *extradata; +} gl3model_t; + +#endif /* SRC_CLIENT_REFRESH_GL3_HEADER_MODEL_H_ */ diff --git a/src/client/refresh/ref_shared.h b/src/client/refresh/ref_shared.h index b7da8161..2d2266c1 100644 --- a/src/client/refresh/ref_shared.h +++ b/src/client/refresh/ref_shared.h @@ -48,6 +48,14 @@ typedef enum it_sky } imagetype_t; +typedef enum +{ + mod_bad, + mod_brush, + mod_sprite, + mod_alias +} modtype_t; + extern void R_Printf(int level, const char* msg, ...) __attribute__ ((format (printf, 2, 3))); extern void LoadPCX(char *origname, byte **pic, byte **palette, int *width, int *height);