From 0f5ff5a5de58668b5cc6044a9b7c61b44ef9357e Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 25 Nov 2017 10:21:15 +0200 Subject: [PATCH 01/12] Removed obsolete files after timer code refactoring --- src/CMakeLists.txt | 2 -- src/posix/cocoa/i_system.mm | 6 ---- src/posix/cocoa/i_timer.cpp | 51 -------------------------------- src/posix/sdl/i_system.cpp | 6 ---- src/posix/sdl/i_timer.cpp | 59 ------------------------------------- 5 files changed, 124 deletions(-) delete mode 100644 src/posix/cocoa/i_timer.cpp delete mode 100644 src/posix/sdl/i_timer.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fc6545ea3..c88d50b15 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -507,7 +507,6 @@ set( PLAT_SDL_SOURCES posix/sdl/i_joystick.cpp posix/sdl/i_main.cpp posix/sdl/i_system.cpp - posix/sdl/i_timer.cpp posix/sdl/sdlvideo.cpp posix/sdl/sdlglvideo.cpp posix/sdl/st_start.cpp ) @@ -525,7 +524,6 @@ set( PLAT_COCOA_SOURCES posix/cocoa/i_main.mm posix/cocoa/i_main_except.cpp posix/cocoa/i_system.mm - posix/cocoa/i_timer.cpp posix/cocoa/i_video.mm posix/cocoa/st_console.mm posix/cocoa/st_start.mm ) diff --git a/src/posix/cocoa/i_system.mm b/src/posix/cocoa/i_system.mm index cc9dc613a..bb1ea2e1b 100644 --- a/src/posix/cocoa/i_system.mm +++ b/src/posix/cocoa/i_system.mm @@ -84,9 +84,6 @@ void SetLanguageIDs() } -void I_InitTimer(); -void I_ShutdownTimer(); - double PerfToSec, PerfToMillisec; static void CalculateCPUSpeed() @@ -114,7 +111,6 @@ void I_Init(void) atterm(I_ShutdownSound); I_InitSound(); - I_InitTimer(); } static int has_exited; @@ -129,8 +125,6 @@ void I_Quit() } C_DeinitConsole(); - - I_ShutdownTimer(); } diff --git a/src/posix/cocoa/i_timer.cpp b/src/posix/cocoa/i_timer.cpp deleted file mode 100644 index 503fa64ec..000000000 --- a/src/posix/cocoa/i_timer.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - ** i_timer.cpp - ** - **--------------------------------------------------------------------------- - ** Copyright 2012-2015 Alexey Lysiuk - ** All rights reserved. - ** - ** Redistribution and use in source and binary forms, with or without - ** modification, are permitted provided that the following conditions - ** are met: - ** - ** 1. Redistributions of source code must retain the above copyright - ** notice, this list of conditions and the following disclaimer. - ** 2. Redistributions in binary form must reproduce the above copyright - ** notice, this list of conditions and the following disclaimer in the - ** documentation and/or other materials provided with the distribution. - ** 3. The name of the author may not be used to endorse or promote products - ** derived from this software without specific prior written permission. - ** - ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - **--------------------------------------------------------------------------- - ** - */ - -#include -#include -#include -#include - -#include "doomdef.h" -#include "i_system.h" -#include "templates.h" - -// To do: this file is obviously not needed anymore. It needs to be removed. - -void I_InitTimer() -{ -} - -void I_ShutdownTimer() -{ -} diff --git a/src/posix/sdl/i_system.cpp b/src/posix/sdl/i_system.cpp index 903563da0..7bf23af11 100644 --- a/src/posix/sdl/i_system.cpp +++ b/src/posix/sdl/i_system.cpp @@ -119,9 +119,6 @@ void SetLanguageIDs () LanguageIDs[3] = LanguageIDs[2] = LanguageIDs[1] = LanguageIDs[0] = lang; } -void I_InitTimer (); -void I_ShutdownTimer (); - // // I_Init // @@ -132,7 +129,6 @@ void I_Init (void) atterm (I_ShutdownSound); I_InitSound (); - I_InitTimer (); } // @@ -148,8 +144,6 @@ void I_Quit (void) G_CheckDemoStatus(); C_DeinitConsole(); - - I_ShutdownTimer(); } diff --git a/src/posix/sdl/i_timer.cpp b/src/posix/sdl/i_timer.cpp deleted file mode 100644 index dab7c30ac..000000000 --- a/src/posix/sdl/i_timer.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* -** i_timer.cpp -** -**--------------------------------------------------------------------------- -** Copyright 2005-2016 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -// Moved from sdl/i_system.cpp - -#include -#include -#include - -#include - -#include "m_fixed.h" -#include "hardware.h" -#include "i_system.h" -#include "templates.h" - -void I_InitTimer () -{ - if(SDL_InitSubSystem(SDL_INIT_TIMER) < 0) - I_FatalError("Could not initialize SDL timers:\n%s\n", SDL_GetError()); - - // Maybe this file isn't needed at all anymore. - // Someone with Linux should test if the timer subsystem is used elsewhere.. -} - -void I_ShutdownTimer () -{ - SDL_QuitSubSystem(SDL_INIT_TIMER); -} From 074a8e4895d6cbbfba5bbc5e5226304566d5ac5c Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 25 Nov 2017 11:03:37 +0200 Subject: [PATCH 02/12] Fixed issue with endless waiting for next tic https://forum.zdoom.org/viewtopic.php?t=58426&p=1028622#p1028547 --- src/i_time.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/i_time.cpp b/src/i_time.cpp index 516ecfad1..bea027243 100644 --- a/src/i_time.cpp +++ b/src/i_time.cpp @@ -130,11 +130,22 @@ int I_WaitForTic(int prevtic) int time; while ((time = I_GetTime()) <= prevtic) { + // Windows-specific note: // The minimum amount of time a thread can sleep is controlled by timeBeginPeriod. // We set this to 1 ms in DoMain. - uint64_t sleepTime = NSToMS(FirstFrameStartTime + TicToNS(prevtic + 1) - I_nsTime()); - if (sleepTime > 2) - std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime - 2)); + + const uint64_t next = FirstFrameStartTime + TicToNS(prevtic + 1); + const uint64_t now = I_nsTime(); + + if (next > now) + { + const uint64_t sleepTime = NSToMS(next - now); + + if (sleepTime > 2) + { + std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime - 2)); + } + } I_SetFrameTime(); } From 87816f811f0a415688b46cb2a504ded87c9ec68f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 25 Nov 2017 10:58:33 +0100 Subject: [PATCH 03/12] - removed windows.h include from a few files which do not need it anymore. --- src/sound/mpg123_decoder.cpp | 4 ---- src/sound/oalsound.cpp | 7 ------- src/sound/sndfile_decoder.cpp | 5 ----- src/win32/win32video.cpp | 2 +- 4 files changed, 1 insertion(+), 17 deletions(-) diff --git a/src/sound/mpg123_decoder.cpp b/src/sound/mpg123_decoder.cpp index 27a26c747..f8d946429 100644 --- a/src/sound/mpg123_decoder.cpp +++ b/src/sound/mpg123_decoder.cpp @@ -30,10 +30,6 @@ **--------------------------------------------------------------------------- ** */ -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#endif #include "mpg123_decoder.h" #include "files.h" diff --git a/src/sound/oalsound.cpp b/src/sound/oalsound.cpp index c2867804d..f0cf6342f 100644 --- a/src/sound/oalsound.cpp +++ b/src/sound/oalsound.cpp @@ -32,13 +32,6 @@ ** */ -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#else -#include -#endif - #include #include #include diff --git a/src/sound/sndfile_decoder.cpp b/src/sound/sndfile_decoder.cpp index a46f0146b..6fa5c5c07 100644 --- a/src/sound/sndfile_decoder.cpp +++ b/src/sound/sndfile_decoder.cpp @@ -30,11 +30,6 @@ **--------------------------------------------------------------------------- ** */ -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#endif - #include "sndfile_decoder.h" #include "templates.h" #include "files.h" diff --git a/src/win32/win32video.cpp b/src/win32/win32video.cpp index 5a26a876b..3ef45e6de 100644 --- a/src/win32/win32video.cpp +++ b/src/win32/win32video.cpp @@ -820,7 +820,7 @@ void I_SetFPSLimit(int limit) { CloseHandle(FPSLimitEvent); FPSLimitEvent = NULL; - Printf("Failed to create FPS limitter timer\n"); + Printf("Failed to create FPS limiter timer\n"); return; } DPrintf(DMSG_NOTIFY, "FPS timer set to %u ms\n", period); From b25f191e853895f9209ab401f620a6083f7ec163 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sat, 25 Nov 2017 12:11:57 +0100 Subject: [PATCH 04/12] - Move shared model code out of the GL renderer --- src/CMakeLists.txt | 9 +- src/gl/data/gl_vertexbuffer.h | 47 +- src/gl/models/gl_models.cpp | 847 +---------------- src/gl/models/gl_models.h | 429 +-------- src/models/models.cpp | 877 ++++++++++++++++++ src/models/models.h | 497 ++++++++++ .../models_md2.cpp} | 14 +- .../models_md3.cpp} | 11 +- src/{gl => }/models/tab_anorms.h | 0 .../gl_voxels.cpp => models/voxels.cpp} | 15 +- 10 files changed, 1395 insertions(+), 1351 deletions(-) create mode 100644 src/models/models.cpp create mode 100644 src/models/models.h rename src/{gl/models/gl_models_md2.cpp => models/models_md2.cpp} (98%) rename src/{gl/models/gl_models_md3.cpp => models/models_md3.cpp} (97%) rename src/{gl => }/models/tab_anorms.h (100%) rename src/{gl/models/gl_voxels.cpp => models/voxels.cpp} (96%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c88d50b15..c54372e0e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -645,6 +645,7 @@ file( GLOB HEADER_FILES g_inventory/*.h intermission/*.h menu/*.h + models/*.h sound/oplsynth/*.h sound/oplsynth/dosbox/*.h posix/*.h @@ -824,6 +825,7 @@ set( FASTMATH_SOURCES gl/dynlights/gl_dynlight1.cpp gl/system/gl_load.c gl/models/gl_models.cpp + models/models.cpp ) set (PCH_SOURCES @@ -997,9 +999,6 @@ set (PCH_SOURCES gl/dynlights/gl_lightbuffer.cpp gl/dynlights/gl_aabbtree.cpp gl/dynlights/gl_shadowmap.cpp - gl/models/gl_models_md3.cpp - gl/models/gl_models_md2.cpp - gl/models/gl_voxels.cpp gl/renderer/gl_quaddrawer.cpp gl/renderer/gl_renderer.cpp gl/renderer/gl_renderstate.cpp @@ -1084,6 +1083,9 @@ set (PCH_SOURCES textures/tgatexture.cpp textures/warptexture.cpp textures/skyboxtexture.cpp + models/models_md3.cpp + models/models_md2.cpp + models/voxels.cpp xlat/parse_xlat.cpp fragglescript/t_func.cpp fragglescript/t_load.cpp @@ -1331,6 +1333,7 @@ source_group("FraggleScript" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/fr source_group("Intermission" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/intermission/.+") source_group("Inventory" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_inventory/.+") source_group("Menu" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/menu/.+") +source_group("Models" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/models/.+") source_group("OpenGL Renderer" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/.+") source_group("OpenGL Renderer\\Data" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/data/.+") source_group("OpenGL Renderer\\Dynamic Lights" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/dynlights/.+") diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index 8f4b22550..2fab5b8fc 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -26,6 +26,7 @@ #include "tarray.h" #include "gl/utility/gl_clock.h" #include "gl/system/gl_interface.h" +#include "models/models.h" struct vertex_t; struct secplane_t; @@ -266,49 +267,6 @@ public: }; -#define VSO ((FSkyVertex*)NULL) - -struct FModelVertex -{ - float x, y, z; // world position - float u, v; // texture coordinates - unsigned packedNormal; // normal vector as GL_INT_2_10_10_10_REV. - - void Set(float xx, float yy, float zz, float uu, float vv) - { - x = xx; - y = yy; - z = zz; - u = uu; - v = vv; - } - - void SetNormal(float nx, float ny, float nz) - { - int inx = clamp(int(nx * 512), -512, 511); - int iny = clamp(int(ny * 512), -512, 511); - int inz = clamp(int(nz * 512), -512, 511); - int inw = 0; - packedNormal = (inw << 30) | ((inz & 1023) << 20) | ((iny & 1023) << 10) | (inx & 1023); - } -}; - -class FModelRenderer; - -class IModelVertexBuffer -{ -public: - virtual ~IModelVertexBuffer() { } - - virtual FModelVertex *LockVertexBuffer(unsigned int size) = 0; - virtual void UnlockVertexBuffer() = 0; - - virtual unsigned int *LockIndexBuffer(unsigned int size) = 0; - virtual void UnlockIndexBuffer() = 0; - - virtual void SetupFrame(FModelRenderer *renderer, unsigned int frame1, unsigned int frame2, unsigned int size) = 0; -}; - class FModelVertexBuffer : public FVertexBuffer, public IModelVertexBuffer { int mIndexFrame[2]; @@ -330,7 +288,6 @@ public: void BindVBO() override; }; -#define VMO ((FModelVertex*)NULL) - +#define VSO ((FSkyVertex*)NULL) #endif \ No newline at end of file diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp index c64f05854..4b2f1d7d8 100644 --- a/src/gl/models/gl_models.cpp +++ b/src/gl/models/gl_models.cpp @@ -22,7 +22,7 @@ /* ** gl_models.cpp ** -** General model handling code +** OpenGL renderer model handling code ** **/ @@ -53,233 +53,7 @@ #include "gl/renderer/gl_renderstate.h" #include "gl/shaders/gl_shader.h" -CVAR(Bool, gl_interpolate_model_frames, true, CVAR_ARCHIVE) CVAR(Bool, gl_light_models, true, CVAR_ARCHIVE) -EXTERN_CVAR(Int, gl_fogmode) - -extern TDeletingArray Voxels; -extern TDeletingArray VoxelDefs; - -DeletingModelArray Models; - -void FModelRenderer::RenderModel(float x, float y, float z, FSpriteModelFrame *smf, AActor *actor) -{ - // Setup transformation. - - int translation = 0; - if (!(smf->flags & MDL_IGNORETRANSLATION)) - translation = actor->Translation; - - // y scale for a sprite means height, i.e. z in the world! - float scaleFactorX = actor->Scale.X * smf->xscale; - float scaleFactorY = actor->Scale.X * smf->yscale; - float scaleFactorZ = actor->Scale.Y * smf->zscale; - float pitch = 0; - float roll = 0; - double rotateOffset = 0; - float angle = actor->Angles.Yaw.Degrees; - - // [BB] Workaround for the missing pitch information. - if ((smf->flags & MDL_PITCHFROMMOMENTUM)) - { - const double x = actor->Vel.X; - const double y = actor->Vel.Y; - const double z = actor->Vel.Z; - - if (actor->Vel.LengthSquared() > EQUAL_EPSILON) - { - // [BB] Calculate the pitch using spherical coordinates. - if (z || x || y) pitch = float(atan(z / sqrt(x*x + y*y)) / M_PI * 180); - - // Correcting pitch if model is moving backwards - if (fabs(x) > EQUAL_EPSILON || fabs(y) > EQUAL_EPSILON) - { - if ((x * cos(angle * M_PI / 180) + y * sin(angle * M_PI / 180)) / sqrt(x * x + y * y) < 0) pitch *= -1; - } - else pitch = fabs(pitch); - } - } - - if (smf->flags & MDL_ROTATING) - { - const double time = smf->rotationSpeed*GetTimeFloat() / 200.; - rotateOffset = double((time - xs_FloorToInt(time)) *360.); - } - - // Added MDL_USEACTORPITCH and MDL_USEACTORROLL flags processing. - // If both flags MDL_USEACTORPITCH and MDL_PITCHFROMMOMENTUM are set, the pitch sums up the actor pitch and the velocity vector pitch. - if (smf->flags & MDL_USEACTORPITCH) - { - double d = actor->Angles.Pitch.Degrees; - if (smf->flags & MDL_BADROTATION) pitch += d; - else pitch -= d; - } - if (smf->flags & MDL_USEACTORROLL) roll += actor->Angles.Roll.Degrees; - - VSMatrix objectToWorldMatrix; - objectToWorldMatrix.loadIdentity(); - - // Model space => World space - objectToWorldMatrix.translate(x, z, y); - - // [Nash] take SpriteRotation into account - angle += actor->SpriteRotation.Degrees; - - if (actor->renderflags & RF_INTERPOLATEANGLES) - { - // [Nash] use interpolated angles - DRotator Angles = actor->InterpolatedAngles(r_viewpoint.TicFrac); - angle = Angles.Yaw.Degrees; - } - - // Applying model transformations: - // 1) Applying actor angle, pitch and roll to the model - objectToWorldMatrix.rotate(-angle, 0, 1, 0); - objectToWorldMatrix.rotate(pitch, 0, 0, 1); - objectToWorldMatrix.rotate(-roll, 1, 0, 0); - - // 2) Applying Doomsday like rotation of the weapon pickup models - // The rotation angle is based on the elapsed time. - - if (smf->flags & MDL_ROTATING) - { - objectToWorldMatrix.translate(smf->rotationCenterX, smf->rotationCenterY, smf->rotationCenterZ); - objectToWorldMatrix.rotate(rotateOffset, smf->xrotate, smf->yrotate, smf->zrotate); - objectToWorldMatrix.translate(-smf->rotationCenterX, -smf->rotationCenterY, -smf->rotationCenterZ); - } - - // 3) Scaling model. - objectToWorldMatrix.scale(scaleFactorX, scaleFactorZ, scaleFactorY); - - // 4) Aplying model offsets (model offsets do not depend on model scalings). - objectToWorldMatrix.translate(smf->xoffset / smf->xscale, smf->zoffset / smf->zscale, smf->yoffset / smf->yscale); - - // 5) Applying model rotations. - objectToWorldMatrix.rotate(-smf->angleoffset, 0, 1, 0); - objectToWorldMatrix.rotate(smf->pitchoffset, 0, 0, 1); - objectToWorldMatrix.rotate(-smf->rolloffset, 1, 0, 0); - - // consider the pixel stretching. For non-voxels this must be factored out here - float stretch = (smf->modelIDs[0] != -1 ? Models[smf->modelIDs[0]]->getAspectFactor() : 1.f) / level.info->pixelstretch; - objectToWorldMatrix.scale(1, stretch, 1); - - BeginDrawModel(actor, smf, objectToWorldMatrix); - RenderFrameModels(smf, actor->state, actor->tics, actor->GetClass(), nullptr, translation); - EndDrawModel(actor, smf); -} - -void FModelRenderer::RenderHUDModel(DPSprite *psp, float ofsX, float ofsY) -{ - AActor * playermo = players[consoleplayer].camera; - FSpriteModelFrame *smf = gl_FindModelFrame(playermo->player->ReadyWeapon->GetClass(), psp->GetState()->sprite, psp->GetState()->GetFrame(), false); - - // [BB] No model found for this sprite, so we can't render anything. - if (smf == nullptr) - return; - - // The model position and orientation has to be drawn independently from the position of the player, - // but we need to position it correctly in the world for light to work properly. - VSMatrix objectToWorldMatrix = GetViewToWorldMatrix(); - - // Scaling model (y scale for a sprite means height, i.e. z in the world!). - objectToWorldMatrix.scale(smf->xscale, smf->zscale, smf->yscale); - - // Aplying model offsets (model offsets do not depend on model scalings). - objectToWorldMatrix.translate(smf->xoffset / smf->xscale, smf->zoffset / smf->zscale, smf->yoffset / smf->yscale); - - // [BB] Weapon bob, very similar to the normal Doom weapon bob. - objectToWorldMatrix.rotate(ofsX / 4, 0, 1, 0); - objectToWorldMatrix.rotate((ofsY - WEAPONTOP) / -4., 1, 0, 0); - - // [BB] For some reason the jDoom models need to be rotated. - objectToWorldMatrix.rotate(90.f, 0, 1, 0); - - // Applying angleoffset, pitchoffset, rolloffset. - objectToWorldMatrix.rotate(-smf->angleoffset, 0, 1, 0); - objectToWorldMatrix.rotate(smf->pitchoffset, 0, 0, 1); - objectToWorldMatrix.rotate(-smf->rolloffset, 1, 0, 0); - - BeginDrawHUDModel(playermo, objectToWorldMatrix); - RenderFrameModels(smf, psp->GetState(), psp->GetTics(), playermo->player->ReadyWeapon->GetClass(), nullptr, 0); - EndDrawHUDModel(playermo); -} - -void FModelRenderer::RenderFrameModels(const FSpriteModelFrame *smf, - const FState *curState, - const int curTics, - const PClass *ti, - Matrix3x4 *normaltransform, - int translation) -{ - // [BB] Frame interpolation: Find the FSpriteModelFrame smfNext which follows after smf in the animation - // and the scalar value inter ( element of [0,1) ), both necessary to determine the interpolated frame. - FSpriteModelFrame * smfNext = nullptr; - double inter = 0.; - if (gl_interpolate_model_frames && !(smf->flags & MDL_NOINTERPOLATION)) - { - FState *nextState = curState->GetNextState(); - if (curState != nextState && nextState) - { - // [BB] To interpolate at more than 35 fps we take tic fractions into account. - float ticFraction = 0.; - // [BB] In case the tic counter is frozen we have to leave ticFraction at zero. - if (ConsoleState == c_up && menuactive != MENU_On && !(level.flags2 & LEVEL2_FROZEN)) - { - double time = GetTimeFloat(); - ticFraction = (time - static_cast(time)); - } - inter = static_cast(curState->Tics - curTics - ticFraction) / static_cast(curState->Tics); - - // [BB] For some actors (e.g. ZPoisonShroom) spr->actor->tics can be bigger than curState->Tics. - // In this case inter is negative and we need to set it to zero. - if (inter < 0.) - inter = 0.; - else - { - // [BB] Workaround for actors that use the same frame twice in a row. - // Most of the standard Doom monsters do this in their see state. - if ((smf->flags & MDL_INTERPOLATEDOUBLEDFRAMES)) - { - const FState *prevState = curState - 1; - if ((curState->sprite == prevState->sprite) && (curState->Frame == prevState->Frame)) - { - inter /= 2.; - inter += 0.5; - } - if ((curState->sprite == nextState->sprite) && (curState->Frame == nextState->Frame)) - { - inter /= 2.; - nextState = nextState->GetNextState(); - } - } - if (inter != 0.0) - smfNext = gl_FindModelFrame(ti, nextState->sprite, nextState->Frame, false); - } - } - } - - for (int i = 0; imodelIDs[i] != -1) - { - FModel * mdl = Models[smf->modelIDs[i]]; - FTexture *tex = smf->skinIDs[i].isValid() ? TexMan(smf->skinIDs[i]) : nullptr; - mdl->BuildVertexBuffer(this); - SetVertexBuffer(mdl->mVBuf); - - mdl->PushSpriteMDLFrame(smf, i); - - if (smfNext && smf->modelframes[i] != smfNext->modelframes[i]) - mdl->RenderFrame(this, tex, smf->modelframes[i], smfNext->modelframes[i], inter, translation); - else - mdl->RenderFrame(this, tex, smf->modelframes[i], smf->modelframes[i], 0.f, translation); - - ResetVertexBuffer(); - } - } -} - -///////////////////////////////////////////////////////////////////////////// extern int modellightindex; @@ -387,26 +161,6 @@ double FGLModelRenderer::GetTimeFloat() return (float)I_msTime() * (float)TICRATE / 1000.0f; } -///////////////////////////////////////////////////////////////////////////// - -void gl_LoadModels() -{ - /* - for (int i = Models.Size() - 1; i >= 0; i--) - { - Models[i]->BuildVertexBuffer(); - } - */ -} - -void gl_FlushModels() -{ - for (int i = Models.Size() - 1; i >= 0; i--) - { - Models[i]->DestroyVertexBuffer(); - } -} - //=========================================================================== // // Uses a hardware buffer if either single frame (i.e. no interpolation needed) @@ -600,583 +354,6 @@ void FModelVertexBuffer::SetupFrame(FModelRenderer *renderer, unsigned int frame } } -//=========================================================================== -// -// FModel::~FModel -// -//=========================================================================== - -FModel::~FModel() -{ - if (mVBuf != nullptr) delete mVBuf; -} - - - - -static TArray SpriteModelFrames; -static int * SpriteModelHash; -//TArray StateModelFrames; - -static void DeleteModelHash() -{ - if (SpriteModelHash != nullptr) delete [] SpriteModelHash; - SpriteModelHash = nullptr; -} - -//=========================================================================== -// -// FindGFXFile -// -//=========================================================================== - -static int FindGFXFile(FString & fn) -{ - int lump = Wads.CheckNumForFullName(fn); // if we find something that matches the name plus the extension, return it and do not enter the substitution logic below. - if (lump != -1) return lump; - - int best = -1; - int dot = fn.LastIndexOf('.'); - int slash = fn.LastIndexOf('/'); - if (dot > slash) fn.Truncate(dot); - - static const char * extensions[] = { ".png", ".jpg", ".tga", ".pcx", nullptr }; - - for (const char ** extp=extensions; *extp; extp++) - { - int lump = Wads.CheckNumForFullName(fn + *extp); - if (lump >= best) best = lump; - } - return best; -} - - -//=========================================================================== -// -// LoadSkin -// -//=========================================================================== - -FTextureID LoadSkin(const char * path, const char * fn) -{ - FString buffer; - - buffer.Format("%s%s", path, fn); - - int texlump = FindGFXFile(buffer); - const char * const texname = texlump < 0 ? fn : Wads.GetLumpFullName(texlump); - return TexMan.CheckForTexture(texname, FTexture::TEX_Any, FTextureManager::TEXMAN_TryAny); -} - -//=========================================================================== -// -// ModelFrameHash -// -//=========================================================================== - -static int ModelFrameHash(FSpriteModelFrame * smf) -{ - const uint32_t *table = GetCRCTable (); - uint32_t hash = 0xffffffff; - - const char * s = (const char *)(&smf->type); // this uses type, sprite and frame for hashing - const char * se= (const char *)(&smf->hashnext); - - for (; smFileName.CompareNoCase(fullname)) return i; - } - - int len = Wads.LumpLength(lump); - FMemLump lumpd = Wads.ReadLump(lump); - char * buffer = (char*)lumpd.GetMem(); - - if (!memcmp(buffer, "DMDM", 4)) - { - model = new FDMDModel; - } - else if (!memcmp(buffer, "IDP2", 4)) - { - model = new FMD2Model; - } - else if (!memcmp(buffer, "IDP3", 4)) - { - model = new FMD3Model; - } - - if (model != nullptr) - { - if (!model->Load(path, lump, buffer, len)) - { - delete model; - return -1; - } - } - else - { - // try loading as a voxel - FVoxel *voxel = R_LoadKVX(lump); - if (voxel != nullptr) - { - model = new FVoxelModel(voxel, true); - } - else - { - Printf("LoadModel: Unknown model format in '%s'\n", fullname.GetChars()); - return -1; - } - } - // The vertex buffer cannot be initialized here because this gets called before OpenGL is initialized - model->mFileName = fullname; - return Models.Push(model); -} - -//=========================================================================== -// -// gl_InitModels -// -//=========================================================================== - -void gl_InitModels() -{ - int Lump, lastLump; - FString path; - int index, surface; - int i; - - FSpriteModelFrame smf; - - lastLump = 0; - - for(unsigned i=0;iVoxelIndex = Models.Push(md); - } - // now create GL model frames for the voxeldefs - for (unsigned i = 0; i < VoxelDefs.Size(); i++) - { - FVoxelModel *md = (FVoxelModel*)Models[VoxelDefs[i]->Voxel->VoxelIndex]; - memset(&smf, 0, sizeof(smf)); - smf.modelIDs[1] = smf.modelIDs[2] = smf.modelIDs[3] = -1; - smf.modelIDs[0] = VoxelDefs[i]->Voxel->VoxelIndex; - smf.skinIDs[0] = md->GetPaletteTexture(); - smf.xscale = smf.yscale = smf.zscale = VoxelDefs[i]->Scale; - smf.angleoffset = VoxelDefs[i]->AngleOffset.Degrees; - if (VoxelDefs[i]->PlacedSpin != 0) - { - smf.yrotate = 1.f; - smf.rotationSpeed = VoxelDefs[i]->PlacedSpin / 55.55f; - smf.flags |= MDL_ROTATING; - } - VoxelDefs[i]->VoxeldefIndex = SpriteModelFrames.Push(smf); - if (VoxelDefs[i]->PlacedSpin != VoxelDefs[i]->DroppedSpin) - { - if (VoxelDefs[i]->DroppedSpin != 0) - { - smf.yrotate = 1.f; - smf.rotationSpeed = VoxelDefs[i]->DroppedSpin / 55.55f; - smf.flags |= MDL_ROTATING; - } - else - { - smf.yrotate = 0; - smf.rotationSpeed = 0; - smf.flags &= ~MDL_ROTATING; - } - SpriteModelFrames.Push(smf); - } - } - - memset(&smf, 0, sizeof(smf)); - smf.modelIDs[0] = smf.modelIDs[1] = smf.modelIDs[2] = smf.modelIDs[3] = -1; - while ((Lump = Wads.FindLump("MODELDEF", &lastLump)) != -1) - { - FScanner sc(Lump); - while (sc.GetString()) - { - if (sc.Compare("model")) - { - path = ""; - sc.MustGetString(); - memset(&smf, 0, sizeof(smf)); - smf.modelIDs[0] = smf.modelIDs[1] = smf.modelIDs[2] = smf.modelIDs[3] = -1; - smf.xscale=smf.yscale=smf.zscale=1.f; - - smf.type = PClass::FindClass(sc.String); - if (!smf.type || smf.type->Defaults == nullptr) - { - sc.ScriptError("MODELDEF: Unknown actor type '%s'\n", sc.String); - } - sc.MustGetStringName("{"); - while (!sc.CheckString("}")) - { - sc.MustGetString(); - if (sc.Compare("path")) - { - sc.MustGetString(); - FixPathSeperator(sc.String); - path = sc.String; - if (path[(int)path.Len()-1]!='/') path+='/'; - } - else if (sc.Compare("model")) - { - sc.MustGetNumber(); - index = sc.Number; - if (index < 0 || index >= MAX_MODELS_PER_FRAME) - { - sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars()); - } - sc.MustGetString(); - FixPathSeperator(sc.String); - smf.modelIDs[index] = FindModel(path.GetChars(), sc.String); - if (smf.modelIDs[index] == -1) - { - Printf("%s: model not found in %s\n", sc.String, path.GetChars()); - } - } - else if (sc.Compare("scale")) - { - sc.MustGetFloat(); - smf.xscale = sc.Float; - sc.MustGetFloat(); - smf.yscale = sc.Float; - sc.MustGetFloat(); - smf.zscale = sc.Float; - } - // [BB] Added zoffset reading. - // Now it must be considered deprecated. - else if (sc.Compare("zoffset")) - { - sc.MustGetFloat(); - smf.zoffset=sc.Float; - } - // Offset reading. - else if (sc.Compare("offset")) - { - sc.MustGetFloat(); - smf.xoffset = sc.Float; - sc.MustGetFloat(); - smf.yoffset = sc.Float; - sc.MustGetFloat(); - smf.zoffset = sc.Float; - } - // angleoffset, pitchoffset and rolloffset reading. - else if (sc.Compare("angleoffset")) - { - sc.MustGetFloat(); - smf.angleoffset = sc.Float; - } - else if (sc.Compare("pitchoffset")) - { - sc.MustGetFloat(); - smf.pitchoffset = sc.Float; - } - else if (sc.Compare("rolloffset")) - { - sc.MustGetFloat(); - smf.rolloffset = sc.Float; - } - // [BB] Added model flags reading. - else if (sc.Compare("ignoretranslation")) - { - smf.flags |= MDL_IGNORETRANSLATION; - } - else if (sc.Compare("pitchfrommomentum")) - { - smf.flags |= MDL_PITCHFROMMOMENTUM; - } - else if (sc.Compare("inheritactorpitch")) - { - smf.flags |= MDL_USEACTORPITCH | MDL_BADROTATION; - } - else if (sc.Compare("inheritactorroll")) - { - smf.flags |= MDL_USEACTORROLL; - } - else if (sc.Compare("useactorpitch")) - { - smf.flags |= MDL_USEACTORPITCH; - } - else if (sc.Compare("useactorroll")) - { - smf.flags |= MDL_USEACTORROLL; - } - else if (sc.Compare("rotating")) - { - smf.flags |= MDL_ROTATING; - smf.xrotate = 0.; - smf.yrotate = 1.; - smf.zrotate = 0.; - smf.rotationCenterX = 0.; - smf.rotationCenterY = 0.; - smf.rotationCenterZ = 0.; - smf.rotationSpeed = 1.; - } - else if (sc.Compare("rotation-speed")) - { - sc.MustGetFloat(); - smf.rotationSpeed = sc.Float; - } - else if (sc.Compare("rotation-vector")) - { - sc.MustGetFloat(); - smf.xrotate = sc.Float; - sc.MustGetFloat(); - smf.yrotate = sc.Float; - sc.MustGetFloat(); - smf.zrotate = sc.Float; - } - else if (sc.Compare("rotation-center")) - { - sc.MustGetFloat(); - smf.rotationCenterX = sc.Float; - sc.MustGetFloat(); - smf.rotationCenterY = sc.Float; - sc.MustGetFloat(); - smf.rotationCenterZ = sc.Float; - } - else if (sc.Compare("interpolatedoubledframes")) - { - smf.flags |= MDL_INTERPOLATEDOUBLEDFRAMES; - } - else if (sc.Compare("nointerpolation")) - { - smf.flags |= MDL_NOINTERPOLATION; - } - else if (sc.Compare("skin")) - { - sc.MustGetNumber(); - index=sc.Number; - if (index<0 || index>=MAX_MODELS_PER_FRAME) - { - sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars()); - } - sc.MustGetString(); - FixPathSeperator(sc.String); - if (sc.Compare("")) - { - smf.skinIDs[index]=FNullTextureID(); - } - else - { - smf.skinIDs[index] = LoadSkin(path.GetChars(), sc.String); - if (!smf.skinIDs[index].isValid()) - { - Printf("Skin '%s' not found in '%s'\n", - sc.String, smf.type->TypeName.GetChars()); - } - } - } - else if (sc.Compare("surfaceskin")) - { - sc.MustGetNumber(); - index = sc.Number; - sc.MustGetNumber(); - surface = sc.Number; - - if (index<0 || index >= MAX_MODELS_PER_FRAME) - { - sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars()); - } - - if (surface<0 || surface >= MD3_MAX_SURFACES) - { - sc.ScriptError("Invalid MD3 Surface %d in %s", MD3_MAX_SURFACES, smf.type->TypeName.GetChars()); - } - - sc.MustGetString(); - FixPathSeperator(sc.String); - if (sc.Compare("")) - { - smf.surfaceskinIDs[index][surface] = FNullTextureID(); - } - else - { - smf.surfaceskinIDs[index][surface] = LoadSkin(path.GetChars(), sc.String); - if (!smf.surfaceskinIDs[index][surface].isValid()) - { - Printf("Surface Skin '%s' not found in '%s'\n", - sc.String, smf.type->TypeName.GetChars()); - } - } - } - else if (sc.Compare("frameindex") || sc.Compare("frame")) - { - bool isframe=!!sc.Compare("frame"); - - sc.MustGetString(); - smf.sprite = -1; - for (i = 0; i < (int)sprites.Size (); ++i) - { - if (strnicmp (sprites[i].name, sc.String, 4) == 0) - { - if (sprites[i].numframes==0) - { - //sc.ScriptError("Sprite %s has no frames", sc.String); - } - smf.sprite = i; - break; - } - } - if (smf.sprite==-1) - { - sc.ScriptError("Unknown sprite %s in model definition for %s", sc.String, smf.type->TypeName.GetChars()); - } - - sc.MustGetString(); - FString framechars = sc.String; - - sc.MustGetNumber(); - index=sc.Number; - if (index<0 || index>=MAX_MODELS_PER_FRAME) - { - sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars()); - } - if (isframe) - { - sc.MustGetString(); - if (smf.modelIDs[index] != -1) - { - FModel *model = Models[smf.modelIDs[index]]; - smf.modelframes[index] = model->FindFrame(sc.String); - if (smf.modelframes[index]==-1) sc.ScriptError("Unknown frame '%s' in %s", sc.String, smf.type->TypeName.GetChars()); - } - else smf.modelframes[index] = -1; - } - else - { - sc.MustGetNumber(); - smf.modelframes[index] = sc.Number; - } - - for(i=0; framechars[i]>0; i++) - { - char map[29]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - int c = toupper(framechars[i])-'A'; - - if (c<0 || c>=29) - { - sc.ScriptError("Invalid frame character %c found", c+'A'); - } - if (map[c]) continue; - smf.frame=c; - SpriteModelFrames.Push(smf); - GetDefaultByType(smf.type)->hasmodel = true; - map[c]=1; - } - } - else if (sc.Compare("dontcullbackfaces")) - { - smf.flags |= MDL_DONTCULLBACKFACES; - } - else - { - sc.ScriptMessage("Unrecognized string \"%s\"", sc.String); - } - } - } - } - } - - // create a hash table for quick access - SpriteModelHash = new int[SpriteModelFrames.Size ()]; - atterm(DeleteModelHash); - memset(SpriteModelHash, 0xff, SpriteModelFrames.Size () * sizeof(int)); - - for (i = 0; i < (int)SpriteModelFrames.Size (); i++) - { - int j = ModelFrameHash(&SpriteModelFrames[i]) % SpriteModelFrames.Size (); - - SpriteModelFrames[i].hashnext = SpriteModelHash[j]; - SpriteModelHash[j]=i; - } -} - - -//=========================================================================== -// -// gl_FindModelFrame -// -//=========================================================================== -EXTERN_CVAR (Bool, r_drawvoxels) - -FSpriteModelFrame * gl_FindModelFrame(const PClass * ti, int sprite, int frame, bool dropped) -{ - if (GetDefaultByType(ti)->hasmodel) - { - FSpriteModelFrame smf; - - memset(&smf, 0, sizeof(smf)); - smf.type=ti; - smf.sprite=sprite; - smf.frame=frame; - - int hash = SpriteModelHash[ModelFrameHash(&smf) % SpriteModelFrames.Size()]; - - while (hash>=0) - { - FSpriteModelFrame * smff = &SpriteModelFrames[hash]; - if (smff->type==ti && smff->sprite==sprite && smff->frame==frame) return smff; - hash=smff->hashnext; - } - } - - // Check for voxel replacements - if (r_drawvoxels) - { - spritedef_t *sprdef = &sprites[sprite]; - if (frame < sprdef->numframes) - { - spriteframe_t *sprframe = &SpriteFrames[sprdef->spriteframes + frame]; - if (sprframe->Voxel != nullptr) - { - int index = sprframe->Voxel->VoxeldefIndex; - if (dropped && sprframe->Voxel->DroppedSpin !=sprframe->Voxel->PlacedSpin) index++; - return &SpriteModelFrames[index]; - } - } - } - return nullptr; -} - - //=========================================================================== // // gl_RenderModel @@ -1200,25 +377,3 @@ void gl_RenderHUDModel(DPSprite *psp, float ofsX, float ofsY) FGLModelRenderer renderer; renderer.RenderHUDModel(psp, ofsX, ofsY); } - -//=========================================================================== -// -// gl_IsHUDModelForPlayerAvailable -// -//=========================================================================== - -bool gl_IsHUDModelForPlayerAvailable (player_t * player) -{ - if (player == nullptr || player->ReadyWeapon == nullptr) - return false; - - DPSprite *psp = player->FindPSprite(PSP_WEAPON); - - if (psp == nullptr || psp->GetState() == nullptr) - return false; - - FState* state = psp->GetState(); - FSpriteModelFrame *smf = gl_FindModelFrame(player->ReadyWeapon->GetClass(), state->sprite, state->GetFrame(), false); - return ( smf != nullptr ); -} - diff --git a/src/gl/models/gl_models.h b/src/gl/models/gl_models.h index cc41466db..aa4d44939 100644 --- a/src/gl/models/gl_models.h +++ b/src/gl/models/gl_models.h @@ -20,62 +20,14 @@ //-------------------------------------------------------------------------- // -#ifndef __GL_MODELS_H_ -#define __GL_MODELS_H_ +#pragma once #include "tarray.h" #include "gl/utility/gl_geometric.h" #include "gl/data/gl_vertexbuffer.h" #include "p_pspr.h" #include "r_data/voxels.h" - - -#define MAX_LODS 4 - -enum { VX, VZ, VY }; - -#define MD2_MAGIC 0x32504449 -#define DMD_MAGIC 0x4D444D44 -#define MD3_MAGIC 0x33504449 -#define NUMVERTEXNORMALS 162 -#define MD3_MAX_SURFACES 32 - -FTextureID LoadSkin(const char * path, const char * fn); - -// [JM] Necessary forward declaration -typedef struct FSpriteModelFrame FSpriteModelFrame; - -class FModelRenderer -{ -public: - virtual ~FModelRenderer() { } - - void RenderModel(float x, float y, float z, FSpriteModelFrame *modelframe, AActor *actor); - void RenderHUDModel(DPSprite *psp, float ofsx, float ofsy); - - virtual void BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix) = 0; - virtual void EndDrawModel(AActor *actor, FSpriteModelFrame *smf) = 0; - - virtual IModelVertexBuffer *CreateVertexBuffer(bool needindex, bool singleframe) = 0; - - virtual void SetVertexBuffer(IModelVertexBuffer *buffer) = 0; - virtual void ResetVertexBuffer() = 0; - - virtual VSMatrix GetViewToWorldMatrix() = 0; - - virtual void BeginDrawHUDModel(AActor *actor, const VSMatrix &objectToWorldMatrix) = 0; - virtual void EndDrawHUDModel(AActor *actor) = 0; - - virtual void SetInterpolation(double interpolation) = 0; - virtual void SetMaterial(FTexture *skin, int clampmode, int translation) = 0; - virtual void DrawArrays(int primitiveType, int start, int count) = 0; - virtual void DrawElements(int primitiveType, int numIndices, int elementType, size_t offset) = 0; - - virtual double GetTimeFloat() = 0; - -private: - void RenderFrameModels(const FSpriteModelFrame *smf, const FState *curState, const int curTics, const PClass *ti, Matrix3x4 *normaltransform, int translation); -}; +#include "models/models.h" class FGLModelRenderer : public FModelRenderer { @@ -95,382 +47,5 @@ public: double GetTimeFloat() override; }; -class FModel -{ -public: - - FModel() - { - mVBuf = NULL; - } - virtual ~FModel(); - - virtual bool Load(const char * fn, int lumpnum, const char * buffer, int length) = 0; - virtual int FindFrame(const char * name) = 0; - virtual void RenderFrame(FModelRenderer *renderer, FTexture * skin, int frame, int frame2, double inter, int translation=0) = 0; - virtual void BuildVertexBuffer(FModelRenderer *renderer) = 0; - virtual void AddSkins(uint8_t *hitlist) = 0; - void DestroyVertexBuffer() - { - delete mVBuf; - mVBuf = NULL; - } - virtual float getAspectFactor() { return 1.f; } - - const FSpriteModelFrame *curSpriteMDLFrame; - int curMDLIndex; - void PushSpriteMDLFrame(const FSpriteModelFrame *smf, int index) { curSpriteMDLFrame = smf; curMDLIndex = index; }; - - IModelVertexBuffer *mVBuf; - FString mFileName; -}; - -class FDMDModel : public FModel -{ -protected: - - struct FTriangle - { - unsigned short vertexIndices[3]; - unsigned short textureIndices[3]; - }; - - - struct DMDHeader - { - int magic; - int version; - int flags; - }; - - struct DMDModelVertex - { - float xyz[3]; - }; - - struct FTexCoord - { - short s, t; - }; - - struct FGLCommandVertex - { - float s, t; - int index; - }; - - struct DMDInfo - { - int skinWidth; - int skinHeight; - int frameSize; - int numSkins; - int numVertices; - int numTexCoords; - int numFrames; - int numLODs; - int offsetSkins; - int offsetTexCoords; - int offsetFrames; - int offsetLODs; - int offsetEnd; - }; - - struct ModelFrame - { - char name[16]; - unsigned int vindex; - }; - - struct ModelFrameVertexData - { - DMDModelVertex *vertices; - DMDModelVertex *normals; - }; - - struct DMDLoDInfo - { - int numTriangles; - int numGlCommands; - int offsetTriangles; - int offsetGlCommands; - }; - - struct DMDLoD - { - FTriangle * triangles; - }; - - - int mLumpNum; - DMDHeader header; - DMDInfo info; - FTextureID * skins; - ModelFrame * frames; - bool allowTexComp; // Allow texture compression with this. - - // Temp data only needed for buffer construction - FTexCoord * texCoords; - ModelFrameVertexData *framevtx; - DMDLoDInfo lodInfo[MAX_LODS]; - DMDLoD lods[MAX_LODS]; - -public: - FDMDModel() - { - mLumpNum = -1; - frames = NULL; - skins = NULL; - for (int i = 0; i < MAX_LODS; i++) - { - lods[i].triangles = NULL; - } - info.numLODs = 0; - texCoords = NULL; - framevtx = NULL; - } - virtual ~FDMDModel(); - - virtual bool Load(const char * fn, int lumpnum, const char * buffer, int length); - virtual int FindFrame(const char * name); - virtual void RenderFrame(FModelRenderer *renderer, FTexture * skin, int frame, int frame2, double inter, int translation=0); - virtual void LoadGeometry(); - virtual void AddSkins(uint8_t *hitlist); - - void UnloadGeometry(); - void BuildVertexBuffer(FModelRenderer *renderer); - -}; - -// This uses the same internal representation as DMD -class FMD2Model : public FDMDModel -{ -public: - FMD2Model() {} - virtual ~FMD2Model(); - - virtual bool Load(const char * fn, int lumpnum, const char * buffer, int length); - virtual void LoadGeometry(); - -}; - - -class FMD3Model : public FModel -{ - struct MD3Tag - { - // Currently I have no use for this - }; - - struct MD3TexCoord - { - float s,t; - }; - - struct MD3Vertex - { - float x,y,z; - float nx,ny,nz; - }; - - struct MD3Triangle - { - int VertIndex[3]; - }; - - struct MD3Surface - { - int numVertices; - int numTriangles; - int numSkins; - - FTextureID * skins; - MD3Triangle * tris; - MD3TexCoord * texcoords; - MD3Vertex * vertices; - - unsigned int vindex; // contains numframes arrays of vertices - unsigned int iindex; - - MD3Surface() - { - tris=NULL; - vertices=NULL; - texcoords=NULL; - vindex = iindex = UINT_MAX; - } - - ~MD3Surface() - { - if (skins) delete [] skins; - UnloadGeometry(); - } - - void UnloadGeometry() - { - if (tris) delete [] tris; - if (vertices) delete [] vertices; - if (texcoords) delete [] texcoords; - tris = NULL; - vertices = NULL; - texcoords = NULL; - } - }; - - struct MD3Frame - { - // The bounding box information is of no use in the Doom engine - // That will still be done with the actor's size information. - char Name[16]; - float origin[3]; - }; - - int numFrames; - int numTags; - int numSurfaces; - int mLumpNum; - - MD3Frame * frames; - MD3Surface * surfaces; - -public: - FMD3Model() { } - virtual ~FMD3Model(); - - virtual bool Load(const char * fn, int lumpnum, const char * buffer, int length); - virtual int FindFrame(const char * name); - virtual void RenderFrame(FModelRenderer *renderer, FTexture * skin, int frame, int frame2, double inter, int translation=0); - void LoadGeometry(); - void BuildVertexBuffer(FModelRenderer *renderer); - virtual void AddSkins(uint8_t *hitlist); -}; - -struct FVoxelVertexHash -{ - // Returns the hash value for a key. - hash_t Hash(const FModelVertex &key) - { - int ix = xs_RoundToInt(key.x); - int iy = xs_RoundToInt(key.y); - int iz = xs_RoundToInt(key.z); - return (hash_t)(ix + (iy<<9) + (iz<<18)); - } - - // Compares two keys, returning zero if they are the same. - int Compare(const FModelVertex &left, const FModelVertex &right) - { - return left.x != right.x || left.y != right.y || left.z != right.z || left.u != right.u || left.v != right.v; - } -}; - -struct FIndexInit -{ - void Init(unsigned int &value) - { - value = 0xffffffff; - } -}; - -typedef TMap FVoxelMap; - - -class FVoxelModel : public FModel -{ -protected: - FVoxel *mVoxel; - bool mOwningVoxel; // if created through MODELDEF deleting this object must also delete the voxel object - FTextureID mPalette; - unsigned int mNumIndices; - TArray mVertices; - TArray mIndices; - - void MakeSlabPolys(int x, int y, kvxslab_t *voxptr, FVoxelMap &check); - void AddFace(int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3, int x4, int y4, int z4, uint8_t color, FVoxelMap &check); - unsigned int AddVertex(FModelVertex &vert, FVoxelMap &check); - -public: - FVoxelModel(FVoxel *voxel, bool owned); - ~FVoxelModel(); - bool Load(const char * fn, int lumpnum, const char * buffer, int length); - void Initialize(); - virtual int FindFrame(const char * name); - virtual void RenderFrame(FModelRenderer *renderer, FTexture * skin, int frame, int frame2, double inter, int translation=0); - virtual void AddSkins(uint8_t *hitlist); - FTextureID GetPaletteTexture() const { return mPalette; } - void BuildVertexBuffer(FModelRenderer *renderer); - float getAspectFactor(); -}; - - - -#define MAX_MODELS_PER_FRAME 4 - -// -// [BB] Model rendering flags. -// -enum -{ - // [BB] Color translations for the model skin are ignored. This is - // useful if the skin texture is not using the game palette. - MDL_IGNORETRANSLATION = 1, - MDL_PITCHFROMMOMENTUM = 2, - MDL_ROTATING = 4, - MDL_INTERPOLATEDOUBLEDFRAMES = 8, - MDL_NOINTERPOLATION = 16, - MDL_USEACTORPITCH = 32, - MDL_USEACTORROLL = 64, - MDL_BADROTATION = 128, - MDL_DONTCULLBACKFACES = 256, -}; - -struct FSpriteModelFrame -{ - int modelIDs[MAX_MODELS_PER_FRAME]; - FTextureID skinIDs[MAX_MODELS_PER_FRAME]; - FTextureID surfaceskinIDs[MAX_MODELS_PER_FRAME][MD3_MAX_SURFACES]; - int modelframes[MAX_MODELS_PER_FRAME]; - float xscale, yscale, zscale; - // [BB] Added zoffset, rotation parameters and flags. - // Added xoffset, yoffset - float xoffset, yoffset, zoffset; - float xrotate, yrotate, zrotate; - float rotationCenterX, rotationCenterY, rotationCenterZ; - float rotationSpeed; - unsigned int flags; - const PClass * type; - short sprite; - short frame; - FState * state; // for later! - int hashnext; - float angleoffset; - // added pithoffset, rolloffset. - float pitchoffset, rolloffset; // I don't want to bother with type transformations, so I made this variables float. -}; - -class GLSprite; - -FSpriteModelFrame * gl_FindModelFrame(const PClass * ti, int sprite, int frame, bool dropped); - void gl_RenderModel(GLSprite * spr); -// [BB] HUD weapon model rendering functions. void gl_RenderHUDModel(DPSprite *psp, float ofsx, float ofsy); -bool gl_IsHUDModelForPlayerAvailable (player_t * player); - - -class DeletingModelArray : public TArray -{ -public: - - ~DeletingModelArray() - { - for (unsigned i = 0; i Voxels; +extern TDeletingArray VoxelDefs; + +DeletingModelArray Models; + +void FModelRenderer::RenderModel(float x, float y, float z, FSpriteModelFrame *smf, AActor *actor) +{ + // Setup transformation. + + int translation = 0; + if (!(smf->flags & MDL_IGNORETRANSLATION)) + translation = actor->Translation; + + // y scale for a sprite means height, i.e. z in the world! + float scaleFactorX = actor->Scale.X * smf->xscale; + float scaleFactorY = actor->Scale.X * smf->yscale; + float scaleFactorZ = actor->Scale.Y * smf->zscale; + float pitch = 0; + float roll = 0; + double rotateOffset = 0; + float angle = actor->Angles.Yaw.Degrees; + + // [BB] Workaround for the missing pitch information. + if ((smf->flags & MDL_PITCHFROMMOMENTUM)) + { + const double x = actor->Vel.X; + const double y = actor->Vel.Y; + const double z = actor->Vel.Z; + + if (actor->Vel.LengthSquared() > EQUAL_EPSILON) + { + // [BB] Calculate the pitch using spherical coordinates. + if (z || x || y) pitch = float(atan(z / sqrt(x*x + y*y)) / M_PI * 180); + + // Correcting pitch if model is moving backwards + if (fabs(x) > EQUAL_EPSILON || fabs(y) > EQUAL_EPSILON) + { + if ((x * cos(angle * M_PI / 180) + y * sin(angle * M_PI / 180)) / sqrt(x * x + y * y) < 0) pitch *= -1; + } + else pitch = fabs(pitch); + } + } + + if (smf->flags & MDL_ROTATING) + { + const double time = smf->rotationSpeed*GetTimeFloat() / 200.; + rotateOffset = double((time - xs_FloorToInt(time)) *360.); + } + + // Added MDL_USEACTORPITCH and MDL_USEACTORROLL flags processing. + // If both flags MDL_USEACTORPITCH and MDL_PITCHFROMMOMENTUM are set, the pitch sums up the actor pitch and the velocity vector pitch. + if (smf->flags & MDL_USEACTORPITCH) + { + double d = actor->Angles.Pitch.Degrees; + if (smf->flags & MDL_BADROTATION) pitch += d; + else pitch -= d; + } + if (smf->flags & MDL_USEACTORROLL) roll += actor->Angles.Roll.Degrees; + + VSMatrix objectToWorldMatrix; + objectToWorldMatrix.loadIdentity(); + + // Model space => World space + objectToWorldMatrix.translate(x, z, y); + + // [Nash] take SpriteRotation into account + angle += actor->SpriteRotation.Degrees; + + if (actor->renderflags & RF_INTERPOLATEANGLES) + { + // [Nash] use interpolated angles + DRotator Angles = actor->InterpolatedAngles(r_viewpoint.TicFrac); + angle = Angles.Yaw.Degrees; + } + + // Applying model transformations: + // 1) Applying actor angle, pitch and roll to the model + objectToWorldMatrix.rotate(-angle, 0, 1, 0); + objectToWorldMatrix.rotate(pitch, 0, 0, 1); + objectToWorldMatrix.rotate(-roll, 1, 0, 0); + + // 2) Applying Doomsday like rotation of the weapon pickup models + // The rotation angle is based on the elapsed time. + + if (smf->flags & MDL_ROTATING) + { + objectToWorldMatrix.translate(smf->rotationCenterX, smf->rotationCenterY, smf->rotationCenterZ); + objectToWorldMatrix.rotate(rotateOffset, smf->xrotate, smf->yrotate, smf->zrotate); + objectToWorldMatrix.translate(-smf->rotationCenterX, -smf->rotationCenterY, -smf->rotationCenterZ); + } + + // 3) Scaling model. + objectToWorldMatrix.scale(scaleFactorX, scaleFactorZ, scaleFactorY); + + // 4) Aplying model offsets (model offsets do not depend on model scalings). + objectToWorldMatrix.translate(smf->xoffset / smf->xscale, smf->zoffset / smf->zscale, smf->yoffset / smf->yscale); + + // 5) Applying model rotations. + objectToWorldMatrix.rotate(-smf->angleoffset, 0, 1, 0); + objectToWorldMatrix.rotate(smf->pitchoffset, 0, 0, 1); + objectToWorldMatrix.rotate(-smf->rolloffset, 1, 0, 0); + + // consider the pixel stretching. For non-voxels this must be factored out here + float stretch = (smf->modelIDs[0] != -1 ? Models[smf->modelIDs[0]]->getAspectFactor() : 1.f) / level.info->pixelstretch; + objectToWorldMatrix.scale(1, stretch, 1); + + BeginDrawModel(actor, smf, objectToWorldMatrix); + RenderFrameModels(smf, actor->state, actor->tics, actor->GetClass(), nullptr, translation); + EndDrawModel(actor, smf); +} + +void FModelRenderer::RenderHUDModel(DPSprite *psp, float ofsX, float ofsY) +{ + AActor * playermo = players[consoleplayer].camera; + FSpriteModelFrame *smf = gl_FindModelFrame(playermo->player->ReadyWeapon->GetClass(), psp->GetState()->sprite, psp->GetState()->GetFrame(), false); + + // [BB] No model found for this sprite, so we can't render anything. + if (smf == nullptr) + return; + + // The model position and orientation has to be drawn independently from the position of the player, + // but we need to position it correctly in the world for light to work properly. + VSMatrix objectToWorldMatrix = GetViewToWorldMatrix(); + + // Scaling model (y scale for a sprite means height, i.e. z in the world!). + objectToWorldMatrix.scale(smf->xscale, smf->zscale, smf->yscale); + + // Aplying model offsets (model offsets do not depend on model scalings). + objectToWorldMatrix.translate(smf->xoffset / smf->xscale, smf->zoffset / smf->zscale, smf->yoffset / smf->yscale); + + // [BB] Weapon bob, very similar to the normal Doom weapon bob. + objectToWorldMatrix.rotate(ofsX / 4, 0, 1, 0); + objectToWorldMatrix.rotate((ofsY - WEAPONTOP) / -4., 1, 0, 0); + + // [BB] For some reason the jDoom models need to be rotated. + objectToWorldMatrix.rotate(90.f, 0, 1, 0); + + // Applying angleoffset, pitchoffset, rolloffset. + objectToWorldMatrix.rotate(-smf->angleoffset, 0, 1, 0); + objectToWorldMatrix.rotate(smf->pitchoffset, 0, 0, 1); + objectToWorldMatrix.rotate(-smf->rolloffset, 1, 0, 0); + + BeginDrawHUDModel(playermo, objectToWorldMatrix); + RenderFrameModels(smf, psp->GetState(), psp->GetTics(), playermo->player->ReadyWeapon->GetClass(), nullptr, 0); + EndDrawHUDModel(playermo); +} + +void FModelRenderer::RenderFrameModels(const FSpriteModelFrame *smf, + const FState *curState, + const int curTics, + const PClass *ti, + Matrix3x4 *normaltransform, + int translation) +{ + // [BB] Frame interpolation: Find the FSpriteModelFrame smfNext which follows after smf in the animation + // and the scalar value inter ( element of [0,1) ), both necessary to determine the interpolated frame. + FSpriteModelFrame * smfNext = nullptr; + double inter = 0.; + if (gl_interpolate_model_frames && !(smf->flags & MDL_NOINTERPOLATION)) + { + FState *nextState = curState->GetNextState(); + if (curState != nextState && nextState) + { + // [BB] To interpolate at more than 35 fps we take tic fractions into account. + float ticFraction = 0.; + // [BB] In case the tic counter is frozen we have to leave ticFraction at zero. + if (ConsoleState == c_up && menuactive != MENU_On && !(level.flags2 & LEVEL2_FROZEN)) + { + double time = GetTimeFloat(); + ticFraction = (time - static_cast(time)); + } + inter = static_cast(curState->Tics - curTics - ticFraction) / static_cast(curState->Tics); + + // [BB] For some actors (e.g. ZPoisonShroom) spr->actor->tics can be bigger than curState->Tics. + // In this case inter is negative and we need to set it to zero. + if (inter < 0.) + inter = 0.; + else + { + // [BB] Workaround for actors that use the same frame twice in a row. + // Most of the standard Doom monsters do this in their see state. + if ((smf->flags & MDL_INTERPOLATEDOUBLEDFRAMES)) + { + const FState *prevState = curState - 1; + if ((curState->sprite == prevState->sprite) && (curState->Frame == prevState->Frame)) + { + inter /= 2.; + inter += 0.5; + } + if ((curState->sprite == nextState->sprite) && (curState->Frame == nextState->Frame)) + { + inter /= 2.; + nextState = nextState->GetNextState(); + } + } + if (inter != 0.0) + smfNext = gl_FindModelFrame(ti, nextState->sprite, nextState->Frame, false); + } + } + } + + for (int i = 0; imodelIDs[i] != -1) + { + FModel * mdl = Models[smf->modelIDs[i]]; + FTexture *tex = smf->skinIDs[i].isValid() ? TexMan(smf->skinIDs[i]) : nullptr; + mdl->BuildVertexBuffer(this); + SetVertexBuffer(mdl->mVBuf); + + mdl->PushSpriteMDLFrame(smf, i); + + if (smfNext && smf->modelframes[i] != smfNext->modelframes[i]) + mdl->RenderFrame(this, tex, smf->modelframes[i], smfNext->modelframes[i], inter, translation); + else + mdl->RenderFrame(this, tex, smf->modelframes[i], smf->modelframes[i], 0.f, translation); + + ResetVertexBuffer(); + } + } +} + +///////////////////////////////////////////////////////////////////////////// + +void gl_LoadModels() +{ + /* + for (int i = Models.Size() - 1; i >= 0; i--) + { + Models[i]->BuildVertexBuffer(); + } + */ +} + +void gl_FlushModels() +{ + for (int i = Models.Size() - 1; i >= 0; i--) + { + Models[i]->DestroyVertexBuffer(); + } +} + +///////////////////////////////////////////////////////////////////////////// + +FModel::~FModel() +{ + if (mVBuf != nullptr) delete mVBuf; +} + +static TArray SpriteModelFrames; +static int * SpriteModelHash; +//TArray StateModelFrames; + +static void DeleteModelHash() +{ + if (SpriteModelHash != nullptr) delete [] SpriteModelHash; + SpriteModelHash = nullptr; +} + +//=========================================================================== +// +// FindGFXFile +// +//=========================================================================== + +static int FindGFXFile(FString & fn) +{ + int lump = Wads.CheckNumForFullName(fn); // if we find something that matches the name plus the extension, return it and do not enter the substitution logic below. + if (lump != -1) return lump; + + int best = -1; + int dot = fn.LastIndexOf('.'); + int slash = fn.LastIndexOf('/'); + if (dot > slash) fn.Truncate(dot); + + static const char * extensions[] = { ".png", ".jpg", ".tga", ".pcx", nullptr }; + + for (const char ** extp=extensions; *extp; extp++) + { + int lump = Wads.CheckNumForFullName(fn + *extp); + if (lump >= best) best = lump; + } + return best; +} + + +//=========================================================================== +// +// LoadSkin +// +//=========================================================================== + +FTextureID LoadSkin(const char * path, const char * fn) +{ + FString buffer; + + buffer.Format("%s%s", path, fn); + + int texlump = FindGFXFile(buffer); + const char * const texname = texlump < 0 ? fn : Wads.GetLumpFullName(texlump); + return TexMan.CheckForTexture(texname, FTexture::TEX_Any, FTextureManager::TEXMAN_TryAny); +} + +//=========================================================================== +// +// ModelFrameHash +// +//=========================================================================== + +static int ModelFrameHash(FSpriteModelFrame * smf) +{ + const uint32_t *table = GetCRCTable (); + uint32_t hash = 0xffffffff; + + const char * s = (const char *)(&smf->type); // this uses type, sprite and frame for hashing + const char * se= (const char *)(&smf->hashnext); + + for (; smFileName.CompareNoCase(fullname)) return i; + } + + int len = Wads.LumpLength(lump); + FMemLump lumpd = Wads.ReadLump(lump); + char * buffer = (char*)lumpd.GetMem(); + + if (!memcmp(buffer, "DMDM", 4)) + { + model = new FDMDModel; + } + else if (!memcmp(buffer, "IDP2", 4)) + { + model = new FMD2Model; + } + else if (!memcmp(buffer, "IDP3", 4)) + { + model = new FMD3Model; + } + + if (model != nullptr) + { + if (!model->Load(path, lump, buffer, len)) + { + delete model; + return -1; + } + } + else + { + // try loading as a voxel + FVoxel *voxel = R_LoadKVX(lump); + if (voxel != nullptr) + { + model = new FVoxelModel(voxel, true); + } + else + { + Printf("LoadModel: Unknown model format in '%s'\n", fullname.GetChars()); + return -1; + } + } + // The vertex buffer cannot be initialized here because this gets called before OpenGL is initialized + model->mFileName = fullname; + return Models.Push(model); +} + +//=========================================================================== +// +// gl_InitModels +// +//=========================================================================== + +void gl_InitModels() +{ + int Lump, lastLump; + FString path; + int index, surface; + int i; + + FSpriteModelFrame smf; + + lastLump = 0; + + for(unsigned i=0;iVoxelIndex = Models.Push(md); + } + // now create GL model frames for the voxeldefs + for (unsigned i = 0; i < VoxelDefs.Size(); i++) + { + FVoxelModel *md = (FVoxelModel*)Models[VoxelDefs[i]->Voxel->VoxelIndex]; + memset(&smf, 0, sizeof(smf)); + smf.modelIDs[1] = smf.modelIDs[2] = smf.modelIDs[3] = -1; + smf.modelIDs[0] = VoxelDefs[i]->Voxel->VoxelIndex; + smf.skinIDs[0] = md->GetPaletteTexture(); + smf.xscale = smf.yscale = smf.zscale = VoxelDefs[i]->Scale; + smf.angleoffset = VoxelDefs[i]->AngleOffset.Degrees; + if (VoxelDefs[i]->PlacedSpin != 0) + { + smf.yrotate = 1.f; + smf.rotationSpeed = VoxelDefs[i]->PlacedSpin / 55.55f; + smf.flags |= MDL_ROTATING; + } + VoxelDefs[i]->VoxeldefIndex = SpriteModelFrames.Push(smf); + if (VoxelDefs[i]->PlacedSpin != VoxelDefs[i]->DroppedSpin) + { + if (VoxelDefs[i]->DroppedSpin != 0) + { + smf.yrotate = 1.f; + smf.rotationSpeed = VoxelDefs[i]->DroppedSpin / 55.55f; + smf.flags |= MDL_ROTATING; + } + else + { + smf.yrotate = 0; + smf.rotationSpeed = 0; + smf.flags &= ~MDL_ROTATING; + } + SpriteModelFrames.Push(smf); + } + } + + memset(&smf, 0, sizeof(smf)); + smf.modelIDs[0] = smf.modelIDs[1] = smf.modelIDs[2] = smf.modelIDs[3] = -1; + while ((Lump = Wads.FindLump("MODELDEF", &lastLump)) != -1) + { + FScanner sc(Lump); + while (sc.GetString()) + { + if (sc.Compare("model")) + { + path = ""; + sc.MustGetString(); + memset(&smf, 0, sizeof(smf)); + smf.modelIDs[0] = smf.modelIDs[1] = smf.modelIDs[2] = smf.modelIDs[3] = -1; + smf.xscale=smf.yscale=smf.zscale=1.f; + + smf.type = PClass::FindClass(sc.String); + if (!smf.type || smf.type->Defaults == nullptr) + { + sc.ScriptError("MODELDEF: Unknown actor type '%s'\n", sc.String); + } + sc.MustGetStringName("{"); + while (!sc.CheckString("}")) + { + sc.MustGetString(); + if (sc.Compare("path")) + { + sc.MustGetString(); + FixPathSeperator(sc.String); + path = sc.String; + if (path[(int)path.Len()-1]!='/') path+='/'; + } + else if (sc.Compare("model")) + { + sc.MustGetNumber(); + index = sc.Number; + if (index < 0 || index >= MAX_MODELS_PER_FRAME) + { + sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars()); + } + sc.MustGetString(); + FixPathSeperator(sc.String); + smf.modelIDs[index] = FindModel(path.GetChars(), sc.String); + if (smf.modelIDs[index] == -1) + { + Printf("%s: model not found in %s\n", sc.String, path.GetChars()); + } + } + else if (sc.Compare("scale")) + { + sc.MustGetFloat(); + smf.xscale = sc.Float; + sc.MustGetFloat(); + smf.yscale = sc.Float; + sc.MustGetFloat(); + smf.zscale = sc.Float; + } + // [BB] Added zoffset reading. + // Now it must be considered deprecated. + else if (sc.Compare("zoffset")) + { + sc.MustGetFloat(); + smf.zoffset=sc.Float; + } + // Offset reading. + else if (sc.Compare("offset")) + { + sc.MustGetFloat(); + smf.xoffset = sc.Float; + sc.MustGetFloat(); + smf.yoffset = sc.Float; + sc.MustGetFloat(); + smf.zoffset = sc.Float; + } + // angleoffset, pitchoffset and rolloffset reading. + else if (sc.Compare("angleoffset")) + { + sc.MustGetFloat(); + smf.angleoffset = sc.Float; + } + else if (sc.Compare("pitchoffset")) + { + sc.MustGetFloat(); + smf.pitchoffset = sc.Float; + } + else if (sc.Compare("rolloffset")) + { + sc.MustGetFloat(); + smf.rolloffset = sc.Float; + } + // [BB] Added model flags reading. + else if (sc.Compare("ignoretranslation")) + { + smf.flags |= MDL_IGNORETRANSLATION; + } + else if (sc.Compare("pitchfrommomentum")) + { + smf.flags |= MDL_PITCHFROMMOMENTUM; + } + else if (sc.Compare("inheritactorpitch")) + { + smf.flags |= MDL_USEACTORPITCH | MDL_BADROTATION; + } + else if (sc.Compare("inheritactorroll")) + { + smf.flags |= MDL_USEACTORROLL; + } + else if (sc.Compare("useactorpitch")) + { + smf.flags |= MDL_USEACTORPITCH; + } + else if (sc.Compare("useactorroll")) + { + smf.flags |= MDL_USEACTORROLL; + } + else if (sc.Compare("rotating")) + { + smf.flags |= MDL_ROTATING; + smf.xrotate = 0.; + smf.yrotate = 1.; + smf.zrotate = 0.; + smf.rotationCenterX = 0.; + smf.rotationCenterY = 0.; + smf.rotationCenterZ = 0.; + smf.rotationSpeed = 1.; + } + else if (sc.Compare("rotation-speed")) + { + sc.MustGetFloat(); + smf.rotationSpeed = sc.Float; + } + else if (sc.Compare("rotation-vector")) + { + sc.MustGetFloat(); + smf.xrotate = sc.Float; + sc.MustGetFloat(); + smf.yrotate = sc.Float; + sc.MustGetFloat(); + smf.zrotate = sc.Float; + } + else if (sc.Compare("rotation-center")) + { + sc.MustGetFloat(); + smf.rotationCenterX = sc.Float; + sc.MustGetFloat(); + smf.rotationCenterY = sc.Float; + sc.MustGetFloat(); + smf.rotationCenterZ = sc.Float; + } + else if (sc.Compare("interpolatedoubledframes")) + { + smf.flags |= MDL_INTERPOLATEDOUBLEDFRAMES; + } + else if (sc.Compare("nointerpolation")) + { + smf.flags |= MDL_NOINTERPOLATION; + } + else if (sc.Compare("skin")) + { + sc.MustGetNumber(); + index=sc.Number; + if (index<0 || index>=MAX_MODELS_PER_FRAME) + { + sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars()); + } + sc.MustGetString(); + FixPathSeperator(sc.String); + if (sc.Compare("")) + { + smf.skinIDs[index]=FNullTextureID(); + } + else + { + smf.skinIDs[index] = LoadSkin(path.GetChars(), sc.String); + if (!smf.skinIDs[index].isValid()) + { + Printf("Skin '%s' not found in '%s'\n", + sc.String, smf.type->TypeName.GetChars()); + } + } + } + else if (sc.Compare("surfaceskin")) + { + sc.MustGetNumber(); + index = sc.Number; + sc.MustGetNumber(); + surface = sc.Number; + + if (index<0 || index >= MAX_MODELS_PER_FRAME) + { + sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars()); + } + + if (surface<0 || surface >= MD3_MAX_SURFACES) + { + sc.ScriptError("Invalid MD3 Surface %d in %s", MD3_MAX_SURFACES, smf.type->TypeName.GetChars()); + } + + sc.MustGetString(); + FixPathSeperator(sc.String); + if (sc.Compare("")) + { + smf.surfaceskinIDs[index][surface] = FNullTextureID(); + } + else + { + smf.surfaceskinIDs[index][surface] = LoadSkin(path.GetChars(), sc.String); + if (!smf.surfaceskinIDs[index][surface].isValid()) + { + Printf("Surface Skin '%s' not found in '%s'\n", + sc.String, smf.type->TypeName.GetChars()); + } + } + } + else if (sc.Compare("frameindex") || sc.Compare("frame")) + { + bool isframe=!!sc.Compare("frame"); + + sc.MustGetString(); + smf.sprite = -1; + for (i = 0; i < (int)sprites.Size (); ++i) + { + if (strnicmp (sprites[i].name, sc.String, 4) == 0) + { + if (sprites[i].numframes==0) + { + //sc.ScriptError("Sprite %s has no frames", sc.String); + } + smf.sprite = i; + break; + } + } + if (smf.sprite==-1) + { + sc.ScriptError("Unknown sprite %s in model definition for %s", sc.String, smf.type->TypeName.GetChars()); + } + + sc.MustGetString(); + FString framechars = sc.String; + + sc.MustGetNumber(); + index=sc.Number; + if (index<0 || index>=MAX_MODELS_PER_FRAME) + { + sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars()); + } + if (isframe) + { + sc.MustGetString(); + if (smf.modelIDs[index] != -1) + { + FModel *model = Models[smf.modelIDs[index]]; + smf.modelframes[index] = model->FindFrame(sc.String); + if (smf.modelframes[index]==-1) sc.ScriptError("Unknown frame '%s' in %s", sc.String, smf.type->TypeName.GetChars()); + } + else smf.modelframes[index] = -1; + } + else + { + sc.MustGetNumber(); + smf.modelframes[index] = sc.Number; + } + + for(i=0; framechars[i]>0; i++) + { + char map[29]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + int c = toupper(framechars[i])-'A'; + + if (c<0 || c>=29) + { + sc.ScriptError("Invalid frame character %c found", c+'A'); + } + if (map[c]) continue; + smf.frame=c; + SpriteModelFrames.Push(smf); + GetDefaultByType(smf.type)->hasmodel = true; + map[c]=1; + } + } + else if (sc.Compare("dontcullbackfaces")) + { + smf.flags |= MDL_DONTCULLBACKFACES; + } + else + { + sc.ScriptMessage("Unrecognized string \"%s\"", sc.String); + } + } + } + } + } + + // create a hash table for quick access + SpriteModelHash = new int[SpriteModelFrames.Size ()]; + atterm(DeleteModelHash); + memset(SpriteModelHash, 0xff, SpriteModelFrames.Size () * sizeof(int)); + + for (i = 0; i < (int)SpriteModelFrames.Size (); i++) + { + int j = ModelFrameHash(&SpriteModelFrames[i]) % SpriteModelFrames.Size (); + + SpriteModelFrames[i].hashnext = SpriteModelHash[j]; + SpriteModelHash[j]=i; + } +} + +//=========================================================================== +// +// gl_FindModelFrame +// +//=========================================================================== + +FSpriteModelFrame * gl_FindModelFrame(const PClass * ti, int sprite, int frame, bool dropped) +{ + if (GetDefaultByType(ti)->hasmodel) + { + FSpriteModelFrame smf; + + memset(&smf, 0, sizeof(smf)); + smf.type=ti; + smf.sprite=sprite; + smf.frame=frame; + + int hash = SpriteModelHash[ModelFrameHash(&smf) % SpriteModelFrames.Size()]; + + while (hash>=0) + { + FSpriteModelFrame * smff = &SpriteModelFrames[hash]; + if (smff->type==ti && smff->sprite==sprite && smff->frame==frame) return smff; + hash=smff->hashnext; + } + } + + // Check for voxel replacements + if (r_drawvoxels) + { + spritedef_t *sprdef = &sprites[sprite]; + if (frame < sprdef->numframes) + { + spriteframe_t *sprframe = &SpriteFrames[sprdef->spriteframes + frame]; + if (sprframe->Voxel != nullptr) + { + int index = sprframe->Voxel->VoxeldefIndex; + if (dropped && sprframe->Voxel->DroppedSpin !=sprframe->Voxel->PlacedSpin) index++; + return &SpriteModelFrames[index]; + } + } + } + return nullptr; +} + +//=========================================================================== +// +// gl_IsHUDModelForPlayerAvailable +// +//=========================================================================== + +bool gl_IsHUDModelForPlayerAvailable (player_t * player) +{ + if (player == nullptr || player->ReadyWeapon == nullptr) + return false; + + DPSprite *psp = player->FindPSprite(PSP_WEAPON); + + if (psp == nullptr || psp->GetState() == nullptr) + return false; + + FState* state = psp->GetState(); + FSpriteModelFrame *smf = gl_FindModelFrame(player->ReadyWeapon->GetClass(), state->sprite, state->GetFrame(), false); + return ( smf != nullptr ); +} + diff --git a/src/models/models.h b/src/models/models.h new file mode 100644 index 000000000..d7172323d --- /dev/null +++ b/src/models/models.h @@ -0,0 +1,497 @@ +// +//--------------------------------------------------------------------------- +// +// Copyright(C) 2005-2016 Christoph Oelckers +// All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see http://www.gnu.org/licenses/ +// +//-------------------------------------------------------------------------- +// + +#ifndef __GL_MODELS_H_ +#define __GL_MODELS_H_ + +#include "tarray.h" +#include "gl/utility/gl_geometric.h" +#include "gl/data/gl_matrix.h" +#include "actor.h" +#include "dobject.h" +#include "p_pspr.h" +#include "r_data/voxels.h" +#include "info.h" + +#define MAX_LODS 4 + +enum { VX, VZ, VY }; + +#define MD2_MAGIC 0x32504449 +#define DMD_MAGIC 0x4D444D44 +#define MD3_MAGIC 0x33504449 +#define NUMVERTEXNORMALS 162 +#define MD3_MAX_SURFACES 32 + +FTextureID LoadSkin(const char * path, const char * fn); + +struct FSpriteModelFrame; +class IModelVertexBuffer; + +class FModelRenderer +{ +public: + virtual ~FModelRenderer() { } + + void RenderModel(float x, float y, float z, FSpriteModelFrame *modelframe, AActor *actor); + void RenderHUDModel(DPSprite *psp, float ofsx, float ofsy); + + virtual void BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix) = 0; + virtual void EndDrawModel(AActor *actor, FSpriteModelFrame *smf) = 0; + + virtual IModelVertexBuffer *CreateVertexBuffer(bool needindex, bool singleframe) = 0; + + virtual void SetVertexBuffer(IModelVertexBuffer *buffer) = 0; + virtual void ResetVertexBuffer() = 0; + + virtual VSMatrix GetViewToWorldMatrix() = 0; + + virtual void BeginDrawHUDModel(AActor *actor, const VSMatrix &objectToWorldMatrix) = 0; + virtual void EndDrawHUDModel(AActor *actor) = 0; + + virtual void SetInterpolation(double interpolation) = 0; + virtual void SetMaterial(FTexture *skin, int clampmode, int translation) = 0; + virtual void DrawArrays(int primitiveType, int start, int count) = 0; + virtual void DrawElements(int primitiveType, int numIndices, int elementType, size_t offset) = 0; + + virtual double GetTimeFloat() = 0; + +private: + void RenderFrameModels(const FSpriteModelFrame *smf, const FState *curState, const int curTics, const PClass *ti, Matrix3x4 *normaltransform, int translation); +}; + +struct FModelVertex +{ + float x, y, z; // world position + float u, v; // texture coordinates + unsigned packedNormal; // normal vector as GL_INT_2_10_10_10_REV. + + void Set(float xx, float yy, float zz, float uu, float vv) + { + x = xx; + y = yy; + z = zz; + u = uu; + v = vv; + } + + void SetNormal(float nx, float ny, float nz) + { + int inx = clamp(int(nx * 512), -512, 511); + int iny = clamp(int(ny * 512), -512, 511); + int inz = clamp(int(nz * 512), -512, 511); + int inw = 0; + packedNormal = (inw << 30) | ((inz & 1023) << 20) | ((iny & 1023) << 10) | (inx & 1023); + } +}; + +#define VMO ((FModelVertex*)NULL) + +class FModelRenderer; + +class IModelVertexBuffer +{ +public: + virtual ~IModelVertexBuffer() { } + + virtual FModelVertex *LockVertexBuffer(unsigned int size) = 0; + virtual void UnlockVertexBuffer() = 0; + + virtual unsigned int *LockIndexBuffer(unsigned int size) = 0; + virtual void UnlockIndexBuffer() = 0; + + virtual void SetupFrame(FModelRenderer *renderer, unsigned int frame1, unsigned int frame2, unsigned int size) = 0; +}; + +class FModel +{ +public: + + FModel() + { + mVBuf = NULL; + } + virtual ~FModel(); + + virtual bool Load(const char * fn, int lumpnum, const char * buffer, int length) = 0; + virtual int FindFrame(const char * name) = 0; + virtual void RenderFrame(FModelRenderer *renderer, FTexture * skin, int frame, int frame2, double inter, int translation=0) = 0; + virtual void BuildVertexBuffer(FModelRenderer *renderer) = 0; + virtual void AddSkins(uint8_t *hitlist) = 0; + void DestroyVertexBuffer() + { + delete mVBuf; + mVBuf = NULL; + } + virtual float getAspectFactor() { return 1.f; } + + const FSpriteModelFrame *curSpriteMDLFrame; + int curMDLIndex; + void PushSpriteMDLFrame(const FSpriteModelFrame *smf, int index) { curSpriteMDLFrame = smf; curMDLIndex = index; }; + + IModelVertexBuffer *mVBuf; + FString mFileName; +}; + +class FDMDModel : public FModel +{ +protected: + + struct FTriangle + { + unsigned short vertexIndices[3]; + unsigned short textureIndices[3]; + }; + + + struct DMDHeader + { + int magic; + int version; + int flags; + }; + + struct DMDModelVertex + { + float xyz[3]; + }; + + struct FTexCoord + { + short s, t; + }; + + struct FGLCommandVertex + { + float s, t; + int index; + }; + + struct DMDInfo + { + int skinWidth; + int skinHeight; + int frameSize; + int numSkins; + int numVertices; + int numTexCoords; + int numFrames; + int numLODs; + int offsetSkins; + int offsetTexCoords; + int offsetFrames; + int offsetLODs; + int offsetEnd; + }; + + struct ModelFrame + { + char name[16]; + unsigned int vindex; + }; + + struct ModelFrameVertexData + { + DMDModelVertex *vertices; + DMDModelVertex *normals; + }; + + struct DMDLoDInfo + { + int numTriangles; + int numGlCommands; + int offsetTriangles; + int offsetGlCommands; + }; + + struct DMDLoD + { + FTriangle * triangles; + }; + + + int mLumpNum; + DMDHeader header; + DMDInfo info; + FTextureID * skins; + ModelFrame * frames; + bool allowTexComp; // Allow texture compression with this. + + // Temp data only needed for buffer construction + FTexCoord * texCoords; + ModelFrameVertexData *framevtx; + DMDLoDInfo lodInfo[MAX_LODS]; + DMDLoD lods[MAX_LODS]; + +public: + FDMDModel() + { + mLumpNum = -1; + frames = NULL; + skins = NULL; + for (int i = 0; i < MAX_LODS; i++) + { + lods[i].triangles = NULL; + } + info.numLODs = 0; + texCoords = NULL; + framevtx = NULL; + } + virtual ~FDMDModel(); + + virtual bool Load(const char * fn, int lumpnum, const char * buffer, int length); + virtual int FindFrame(const char * name); + virtual void RenderFrame(FModelRenderer *renderer, FTexture * skin, int frame, int frame2, double inter, int translation=0); + virtual void LoadGeometry(); + virtual void AddSkins(uint8_t *hitlist); + + void UnloadGeometry(); + void BuildVertexBuffer(FModelRenderer *renderer); + +}; + +// This uses the same internal representation as DMD +class FMD2Model : public FDMDModel +{ +public: + FMD2Model() {} + virtual ~FMD2Model(); + + virtual bool Load(const char * fn, int lumpnum, const char * buffer, int length); + virtual void LoadGeometry(); + +}; + + +class FMD3Model : public FModel +{ + struct MD3Tag + { + // Currently I have no use for this + }; + + struct MD3TexCoord + { + float s,t; + }; + + struct MD3Vertex + { + float x,y,z; + float nx,ny,nz; + }; + + struct MD3Triangle + { + int VertIndex[3]; + }; + + struct MD3Surface + { + int numVertices; + int numTriangles; + int numSkins; + + FTextureID * skins; + MD3Triangle * tris; + MD3TexCoord * texcoords; + MD3Vertex * vertices; + + unsigned int vindex; // contains numframes arrays of vertices + unsigned int iindex; + + MD3Surface() + { + tris=NULL; + vertices=NULL; + texcoords=NULL; + vindex = iindex = UINT_MAX; + } + + ~MD3Surface() + { + if (skins) delete [] skins; + UnloadGeometry(); + } + + void UnloadGeometry() + { + if (tris) delete [] tris; + if (vertices) delete [] vertices; + if (texcoords) delete [] texcoords; + tris = NULL; + vertices = NULL; + texcoords = NULL; + } + }; + + struct MD3Frame + { + // The bounding box information is of no use in the Doom engine + // That will still be done with the actor's size information. + char Name[16]; + float origin[3]; + }; + + int numFrames; + int numTags; + int numSurfaces; + int mLumpNum; + + MD3Frame * frames; + MD3Surface * surfaces; + +public: + FMD3Model() { } + virtual ~FMD3Model(); + + virtual bool Load(const char * fn, int lumpnum, const char * buffer, int length); + virtual int FindFrame(const char * name); + virtual void RenderFrame(FModelRenderer *renderer, FTexture * skin, int frame, int frame2, double inter, int translation=0); + void LoadGeometry(); + void BuildVertexBuffer(FModelRenderer *renderer); + virtual void AddSkins(uint8_t *hitlist); +}; + +struct FVoxelVertexHash +{ + // Returns the hash value for a key. + hash_t Hash(const FModelVertex &key) + { + int ix = xs_RoundToInt(key.x); + int iy = xs_RoundToInt(key.y); + int iz = xs_RoundToInt(key.z); + return (hash_t)(ix + (iy<<9) + (iz<<18)); + } + + // Compares two keys, returning zero if they are the same. + int Compare(const FModelVertex &left, const FModelVertex &right) + { + return left.x != right.x || left.y != right.y || left.z != right.z || left.u != right.u || left.v != right.v; + } +}; + +struct FIndexInit +{ + void Init(unsigned int &value) + { + value = 0xffffffff; + } +}; + +typedef TMap FVoxelMap; + + +class FVoxelModel : public FModel +{ +protected: + FVoxel *mVoxel; + bool mOwningVoxel; // if created through MODELDEF deleting this object must also delete the voxel object + FTextureID mPalette; + unsigned int mNumIndices; + TArray mVertices; + TArray mIndices; + + void MakeSlabPolys(int x, int y, kvxslab_t *voxptr, FVoxelMap &check); + void AddFace(int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3, int x4, int y4, int z4, uint8_t color, FVoxelMap &check); + unsigned int AddVertex(FModelVertex &vert, FVoxelMap &check); + +public: + FVoxelModel(FVoxel *voxel, bool owned); + ~FVoxelModel(); + bool Load(const char * fn, int lumpnum, const char * buffer, int length); + void Initialize(); + virtual int FindFrame(const char * name); + virtual void RenderFrame(FModelRenderer *renderer, FTexture * skin, int frame, int frame2, double inter, int translation=0); + virtual void AddSkins(uint8_t *hitlist); + FTextureID GetPaletteTexture() const { return mPalette; } + void BuildVertexBuffer(FModelRenderer *renderer); + float getAspectFactor(); +}; + + + +#define MAX_MODELS_PER_FRAME 4 + +// +// [BB] Model rendering flags. +// +enum +{ + // [BB] Color translations for the model skin are ignored. This is + // useful if the skin texture is not using the game palette. + MDL_IGNORETRANSLATION = 1, + MDL_PITCHFROMMOMENTUM = 2, + MDL_ROTATING = 4, + MDL_INTERPOLATEDOUBLEDFRAMES = 8, + MDL_NOINTERPOLATION = 16, + MDL_USEACTORPITCH = 32, + MDL_USEACTORROLL = 64, + MDL_BADROTATION = 128, + MDL_DONTCULLBACKFACES = 256, +}; + +struct FSpriteModelFrame +{ + int modelIDs[MAX_MODELS_PER_FRAME]; + FTextureID skinIDs[MAX_MODELS_PER_FRAME]; + FTextureID surfaceskinIDs[MAX_MODELS_PER_FRAME][MD3_MAX_SURFACES]; + int modelframes[MAX_MODELS_PER_FRAME]; + float xscale, yscale, zscale; + // [BB] Added zoffset, rotation parameters and flags. + // Added xoffset, yoffset + float xoffset, yoffset, zoffset; + float xrotate, yrotate, zrotate; + float rotationCenterX, rotationCenterY, rotationCenterZ; + float rotationSpeed; + unsigned int flags; + const PClass * type; + short sprite; + short frame; + FState * state; // for later! + int hashnext; + float angleoffset; + // added pithoffset, rolloffset. + float pitchoffset, rolloffset; // I don't want to bother with type transformations, so I made this variables float. +}; + +FSpriteModelFrame * gl_FindModelFrame(const PClass * ti, int sprite, int frame, bool dropped); + +bool gl_IsHUDModelForPlayerAvailable (player_t * player); + +class DeletingModelArray : public TArray +{ +public: + + ~DeletingModelArray() + { + for (unsigned i = 0; i Date: Sat, 25 Nov 2017 12:20:00 +0100 Subject: [PATCH 05/12] - Fix 'Requested invalid render buffer sizes' when executing the reverbedit command from fullscreen --- src/win32/eaxedit.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/win32/eaxedit.cpp b/src/win32/eaxedit.cpp index 509f95322..a5a4b8116 100644 --- a/src/win32/eaxedit.cpp +++ b/src/win32/eaxedit.cpp @@ -49,6 +49,7 @@ #include "c_dispatch.h" #include "c_cvars.h" #include "doomstat.h" +#include "v_video.h" #ifdef _MSC_VER #pragma warning(disable:4244) @@ -1384,6 +1385,8 @@ void ShowEAXEditor () EAXEditWindow = CreateDialog (g_hInst, MAKEINTRESOURCE(IDD_EAXEDIT), Window, EAXProc); } +extern int NewWidth, NewHeight, NewBits, DisplayBits; + CCMD (reverbedit) { if (EAXEditWindow != 0) @@ -1395,6 +1398,9 @@ CCMD (reverbedit) ForceWindowed = true; if (fullscreen) { + NewWidth = screen->VideoWidth; + NewHeight = screen->VideoHeight; + NewBits = DisplayBits; setmodeneeded = true; SpawnEAXWindow = true; } From 679f42db78baee18f932df56941e79d8016f831e Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sat, 25 Nov 2017 13:00:44 +0100 Subject: [PATCH 06/12] - Remove model GL dependencies except for the matrix classes --- src/gl/models/gl_models.cpp | 12 ++++++------ src/gl/models/gl_models.h | 6 +++--- src/models/models.h | 6 +++--- src/models/models_md2.cpp | 10 ++++++---- src/models/models_md3.cpp | 10 ++++++---- src/models/voxels.cpp | 10 ++++++---- src/polyrenderer/scene/poly_model.cpp | 9 +++++---- src/polyrenderer/scene/poly_model.h | 6 +++--- 8 files changed, 38 insertions(+), 31 deletions(-) diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp index 4b2f1d7d8..0e051a402 100644 --- a/src/gl/models/gl_models.cpp +++ b/src/gl/models/gl_models.cpp @@ -137,23 +137,23 @@ void FGLModelRenderer::SetInterpolation(double inter) gl_RenderState.SetInterpolationFactor((float)inter); } -void FGLModelRenderer::SetMaterial(FTexture *skin, int clampmode, int translation) +void FGLModelRenderer::SetMaterial(FTexture *skin, bool clampNoFilter, int translation) { FMaterial * tex = FMaterial::ValidateTexture(skin, false); - gl_RenderState.SetMaterial(tex, clampmode, translation, -1, false); + gl_RenderState.SetMaterial(tex, clampNoFilter ? CLAMP_NOFILTER : CLAMP_NONE, translation, -1, false); gl_RenderState.Apply(); if (modellightindex != -1) gl_RenderState.ApplyLightIndex(modellightindex); } -void FGLModelRenderer::DrawArrays(int primitiveType, int start, int count) +void FGLModelRenderer::DrawArrays(int start, int count) { - glDrawArrays(primitiveType, start, count); + glDrawArrays(GL_TRIANGLES, start, count); } -void FGLModelRenderer::DrawElements(int primitiveType, int numIndices, int elementType, size_t offset) +void FGLModelRenderer::DrawElements(int numIndices, size_t offset) { - glDrawElements(primitiveType, numIndices, elementType, (void*)(intptr_t)offset); + glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_INT, (void*)(intptr_t)offset); } double FGLModelRenderer::GetTimeFloat() diff --git a/src/gl/models/gl_models.h b/src/gl/models/gl_models.h index aa4d44939..fc22644f6 100644 --- a/src/gl/models/gl_models.h +++ b/src/gl/models/gl_models.h @@ -41,9 +41,9 @@ public: void BeginDrawHUDModel(AActor *actor, const VSMatrix &objectToWorldMatrix) override; void EndDrawHUDModel(AActor *actor) override; void SetInterpolation(double interpolation) override; - void SetMaterial(FTexture *skin, int clampmode, int translation) override; - void DrawArrays(int primitiveType, int start, int count) override; - void DrawElements(int primitiveType, int numIndices, int elementType, size_t offset) override; + void SetMaterial(FTexture *skin, bool clampNoFilter, int translation) override; + void DrawArrays(int start, int count) override; + void DrawElements(int numIndices, size_t offset) override; double GetTimeFloat() override; }; diff --git a/src/models/models.h b/src/models/models.h index d7172323d..7e9dabf82 100644 --- a/src/models/models.h +++ b/src/models/models.h @@ -69,9 +69,9 @@ public: virtual void EndDrawHUDModel(AActor *actor) = 0; virtual void SetInterpolation(double interpolation) = 0; - virtual void SetMaterial(FTexture *skin, int clampmode, int translation) = 0; - virtual void DrawArrays(int primitiveType, int start, int count) = 0; - virtual void DrawElements(int primitiveType, int numIndices, int elementType, size_t offset) = 0; + virtual void SetMaterial(FTexture *skin, bool clampNoFilter, int translation) = 0; + virtual void DrawArrays(int start, int count) = 0; + virtual void DrawElements(int numIndices, size_t offset) = 0; virtual double GetTimeFloat() = 0; diff --git a/src/models/models_md2.cpp b/src/models/models_md2.cpp index 18b7349e7..d43a0826b 100644 --- a/src/models/models_md2.cpp +++ b/src/models/models_md2.cpp @@ -26,13 +26,15 @@ ** **/ -#include "gl/system/gl_system.h" // for GL_TRIANGLES #include "w_wad.h" #include "cmdlib.h" #include "sc_man.h" #include "m_crc32.h" #include "models/models.h" -#include "gl/textures/gl_material.h" // for CLAMP_NONE + +#ifdef _MSC_VER +#pragma warning(disable:4244) // warning C4244: conversion from 'double' to 'float', possible loss of data +#endif static float avertexnormals[NUMVERTEXNORMALS][3] = { #include "tab_anorms.h" @@ -368,9 +370,9 @@ void FDMDModel::RenderFrame(FModelRenderer *renderer, FTexture * skin, int frame } renderer->SetInterpolation(inter); - renderer->SetMaterial(skin, CLAMP_NONE, translation); + renderer->SetMaterial(skin, false, translation); mVBuf->SetupFrame(renderer, frames[frameno].vindex, frames[frameno2].vindex, lodInfo[0].numTriangles * 3); - renderer->DrawArrays(GL_TRIANGLES, 0, lodInfo[0].numTriangles * 3); + renderer->DrawArrays(0, lodInfo[0].numTriangles * 3); renderer->SetInterpolation(0.f); } diff --git a/src/models/models_md3.cpp b/src/models/models_md3.cpp index 000c43bd4..5c4bf045a 100644 --- a/src/models/models_md3.cpp +++ b/src/models/models_md3.cpp @@ -20,16 +20,18 @@ //-------------------------------------------------------------------------- // -#include "gl/system/gl_system.h" // for GL_TRIANGLES #include "w_wad.h" #include "cmdlib.h" #include "sc_man.h" #include "m_crc32.h" #include "models/models.h" -#include "gl/textures/gl_material.h" // for CLAMP_NONE #define MAX_QPATH 64 +#ifdef _MSC_VER +#pragma warning(disable:4244) // warning C4244: conversion from 'double' to 'float', possible loss of data +#endif + //=========================================================================== // // decode the lat/lng normal to a 3 float normal @@ -362,9 +364,9 @@ void FMD3Model::RenderFrame(FModelRenderer *renderer, FTexture * skin, int frame if (!surfaceSkin) return; } - renderer->SetMaterial(surfaceSkin, CLAMP_NONE, translation); + renderer->SetMaterial(surfaceSkin, false, translation); mVBuf->SetupFrame(renderer, surf->vindex + frameno * surf->numVertices, surf->vindex + frameno2 * surf->numVertices, surf->numVertices); - renderer->DrawElements(GL_TRIANGLES, surf->numTriangles * 3, GL_UNSIGNED_INT, surf->iindex * sizeof(unsigned int)); + renderer->DrawElements(surf->numTriangles * 3, surf->iindex * sizeof(unsigned int)); } renderer->SetInterpolation(0.f); } diff --git a/src/models/voxels.cpp b/src/models/voxels.cpp index 0c87561ca..6e96d7e7b 100644 --- a/src/models/voxels.cpp +++ b/src/models/voxels.cpp @@ -26,7 +26,6 @@ ** **/ -#include "gl/system/gl_system.h" // for GL_TRIANGLES #include "w_wad.h" #include "cmdlib.h" #include "sc_man.h" @@ -39,7 +38,10 @@ #include "textures/bitmap.h" #include "g_levellocals.h" #include "models.h" -#include "gl/textures/gl_material.h" // for CLAMP_NONE + +#ifdef _MSC_VER +#pragma warning(disable:4244) // warning C4244: conversion from 'double' to 'float', possible loss of data +#endif //=========================================================================== // @@ -431,8 +433,8 @@ float FVoxelModel::getAspectFactor() void FVoxelModel::RenderFrame(FModelRenderer *renderer, FTexture * skin, int frame, int frame2, double inter, int translation) { - renderer->SetMaterial(skin, CLAMP_NOFILTER, translation); + renderer->SetMaterial(skin, true, translation); mVBuf->SetupFrame(renderer, 0, 0, 0); - renderer->DrawElements(GL_TRIANGLES, mNumIndices, GL_UNSIGNED_INT, 0); + renderer->DrawElements(mNumIndices, 0); } diff --git a/src/polyrenderer/scene/poly_model.cpp b/src/polyrenderer/scene/poly_model.cpp index f9d7b4887..285d19e16 100644 --- a/src/polyrenderer/scene/poly_model.cpp +++ b/src/polyrenderer/scene/poly_model.cpp @@ -31,6 +31,7 @@ #include "polyrenderer/poly_renderthread.h" #include "r_data/r_vanillatrans.h" #include "actorinlines.h" +#include "i_time.h" void PolyRenderModel(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, uint32_t stencilValue, float x, float y, float z, FSpriteModelFrame *smf, AActor *actor) { @@ -102,12 +103,12 @@ void PolyModelRenderer::SetInterpolation(double interpolation) InterpolationFactor = (float)interpolation; } -void PolyModelRenderer::SetMaterial(FTexture *skin, int clampmode, int translation) +void PolyModelRenderer::SetMaterial(FTexture *skin, bool clampNoFilter, int translation) { SkinTexture = skin; } -void PolyModelRenderer::DrawArrays(int primitiveType, int start, int count) +void PolyModelRenderer::DrawArrays(int start, int count) { const auto &viewpoint = PolyRenderer::Instance()->Viewpoint; @@ -141,7 +142,7 @@ void PolyModelRenderer::DrawArrays(int primitiveType, int start, int count) args.DrawArray(Thread, VertexBuffer + start, count); } -void PolyModelRenderer::DrawElements(int primitiveType, int numIndices, int elementType, size_t offset) +void PolyModelRenderer::DrawElements(int numIndices, size_t offset) { const auto &viewpoint = PolyRenderer::Instance()->Viewpoint; @@ -177,7 +178,7 @@ void PolyModelRenderer::DrawElements(int primitiveType, int numIndices, int elem double PolyModelRenderer::GetTimeFloat() { - return 0.0f; // (float)gl_frameMS * (float)TICRATE / 1000.0f; + return (float)I_msTime() * (float)TICRATE / 1000.0f; } ///////////////////////////////////////////////////////////////////////////// diff --git a/src/polyrenderer/scene/poly_model.h b/src/polyrenderer/scene/poly_model.h index d80bed45f..a3907edc0 100644 --- a/src/polyrenderer/scene/poly_model.h +++ b/src/polyrenderer/scene/poly_model.h @@ -43,9 +43,9 @@ public: void BeginDrawHUDModel(AActor *actor, const VSMatrix &objectToWorldMatrix) override; void EndDrawHUDModel(AActor *actor) override; void SetInterpolation(double interpolation) override; - void SetMaterial(FTexture *skin, int clampmode, int translation) override; - void DrawArrays(int primitiveType, int start, int count) override; - void DrawElements(int primitiveType, int numIndices, int elementType, size_t offset) override; + void SetMaterial(FTexture *skin, bool clampNoFilter, int translation) override; + void DrawArrays(int start, int count) override; + void DrawElements(int numIndices, size_t offset) override; double GetTimeFloat() override; PolyRenderThread *Thread = nullptr; From 7bb92812b8db10b82170bc460e420b53a9844a4f Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sat, 25 Nov 2017 13:19:00 +0100 Subject: [PATCH 07/12] - Move models into r_data --- src/CMakeLists.txt | 15 +++++++-------- src/gl/data/gl_vertexbuffer.h | 2 +- src/gl/models/gl_models.h | 2 +- src/{ => r_data}/models/models.cpp | 2 +- src/{ => r_data}/models/models.h | 0 src/{ => r_data}/models/models_md2.cpp | 2 +- src/{ => r_data}/models/models_md3.cpp | 2 +- src/{ => r_data}/models/tab_anorms.h | 0 src/{ => r_data}/models/voxels.cpp | 0 9 files changed, 12 insertions(+), 13 deletions(-) rename src/{ => r_data}/models/models.cpp (99%) rename src/{ => r_data}/models/models.h (100%) rename src/{ => r_data}/models/models_md2.cpp (99%) rename src/{ => r_data}/models/models_md3.cpp (99%) rename src/{ => r_data}/models/tab_anorms.h (100%) rename src/{ => r_data}/models/voxels.cpp (100%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c54372e0e..15504c65d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -645,13 +645,13 @@ file( GLOB HEADER_FILES g_inventory/*.h intermission/*.h menu/*.h - models/*.h sound/oplsynth/*.h sound/oplsynth/dosbox/*.h posix/*.h posix/cocoa/*.h posix/sdl/*.h r_data/*.h + r_data/models/*.h rapidjson/*.h resourcefiles/*.h sfmt/*.h @@ -825,7 +825,7 @@ set( FASTMATH_SOURCES gl/dynlights/gl_dynlight1.cpp gl/system/gl_load.c gl/models/gl_models.cpp - models/models.cpp + r_data/models/models.cpp ) set (PCH_SOURCES @@ -1083,9 +1083,6 @@ set (PCH_SOURCES textures/tgatexture.cpp textures/warptexture.cpp textures/skyboxtexture.cpp - models/models_md3.cpp - models/models_md2.cpp - models/voxels.cpp xlat/parse_xlat.cpp fragglescript/t_func.cpp fragglescript/t_load.cpp @@ -1105,6 +1102,9 @@ set (PCH_SOURCES r_data/renderstyle.cpp r_data/r_interpolate.cpp r_data/r_vanillatrans.cpp + r_data/models/models_md3.cpp + r_data/models/models_md2.cpp + r_data/models/voxels.cpp scripting/symbols.cpp scripting/types.cpp scripting/thingdef.cpp @@ -1333,7 +1333,6 @@ source_group("FraggleScript" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/fr source_group("Intermission" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/intermission/.+") source_group("Inventory" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_inventory/.+") source_group("Menu" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/menu/.+") -source_group("Models" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/models/.+") source_group("OpenGL Renderer" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/.+") source_group("OpenGL Renderer\\Data" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/data/.+") source_group("OpenGL Renderer\\Dynamic Lights" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/dynlights/.+") @@ -1360,9 +1359,9 @@ source_group("Poly Renderer" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/po source_group("Poly Renderer\\Math" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/polyrenderer/math/.+") source_group("Poly Renderer\\Drawers" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/polyrenderer/drawers/.+") source_group("Poly Renderer\\Scene" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/polyrenderer/scene/.+") -source_group("Render Data\\Resource Headers" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/r_data/.+\\.h$") -source_group("Render Data\\Resource Sources" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/r_data/.+\\.cpp$") +source_group("Render Data" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/r_data/.+") source_group("Render Data\\Textures" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/textures/.+") +source_group("Render Data\\Models" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/r_data/models/.+") source_group("Render Interface" FILES r_defs.h r_renderer.h r_sky.cpp r_sky.h r_state.h r_utility.cpp r_utility.h) source_group("Resource Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/resourcefiles/.+") source_group("Platforms\\POSIX Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/posix/.+") diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index 2fab5b8fc..ea4c3481f 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -26,7 +26,7 @@ #include "tarray.h" #include "gl/utility/gl_clock.h" #include "gl/system/gl_interface.h" -#include "models/models.h" +#include "r_data/models/models.h" struct vertex_t; struct secplane_t; diff --git a/src/gl/models/gl_models.h b/src/gl/models/gl_models.h index fc22644f6..b60fabea6 100644 --- a/src/gl/models/gl_models.h +++ b/src/gl/models/gl_models.h @@ -27,7 +27,7 @@ #include "gl/data/gl_vertexbuffer.h" #include "p_pspr.h" #include "r_data/voxels.h" -#include "models/models.h" +#include "r_data/models/models.h" class FGLModelRenderer : public FModelRenderer { diff --git a/src/models/models.cpp b/src/r_data/models/models.cpp similarity index 99% rename from src/models/models.cpp rename to src/r_data/models/models.cpp index 30e194e74..46db0deeb 100644 --- a/src/models/models.cpp +++ b/src/r_data/models/models.cpp @@ -40,7 +40,7 @@ #include "g_levellocals.h" #include "r_utility.h" #include "i_time.h" -#include "models/models.h" +#include "r_data/models/models.h" CVAR(Bool, gl_interpolate_model_frames, true, CVAR_ARCHIVE) EXTERN_CVAR(Bool, r_drawvoxels) diff --git a/src/models/models.h b/src/r_data/models/models.h similarity index 100% rename from src/models/models.h rename to src/r_data/models/models.h diff --git a/src/models/models_md2.cpp b/src/r_data/models/models_md2.cpp similarity index 99% rename from src/models/models_md2.cpp rename to src/r_data/models/models_md2.cpp index d43a0826b..11cc8783d 100644 --- a/src/models/models_md2.cpp +++ b/src/r_data/models/models_md2.cpp @@ -30,7 +30,7 @@ #include "cmdlib.h" #include "sc_man.h" #include "m_crc32.h" -#include "models/models.h" +#include "r_data/models/models.h" #ifdef _MSC_VER #pragma warning(disable:4244) // warning C4244: conversion from 'double' to 'float', possible loss of data diff --git a/src/models/models_md3.cpp b/src/r_data/models/models_md3.cpp similarity index 99% rename from src/models/models_md3.cpp rename to src/r_data/models/models_md3.cpp index 5c4bf045a..e504b252a 100644 --- a/src/models/models_md3.cpp +++ b/src/r_data/models/models_md3.cpp @@ -24,7 +24,7 @@ #include "cmdlib.h" #include "sc_man.h" #include "m_crc32.h" -#include "models/models.h" +#include "r_data/models/models.h" #define MAX_QPATH 64 diff --git a/src/models/tab_anorms.h b/src/r_data/models/tab_anorms.h similarity index 100% rename from src/models/tab_anorms.h rename to src/r_data/models/tab_anorms.h diff --git a/src/models/voxels.cpp b/src/r_data/models/voxels.cpp similarity index 100% rename from src/models/voxels.cpp rename to src/r_data/models/voxels.cpp From 637a9dff9be9b65d0cb3e0cf9d54a723c86c8136 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sat, 25 Nov 2017 13:22:59 +0100 Subject: [PATCH 08/12] - Rename voxels.cpp to models_voxel.cpp to avoid having two source files with the same name (confuses debuggers and some build tools) --- src/CMakeLists.txt | 2 +- src/r_data/models/{voxels.cpp => models_voxel.cpp} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/r_data/models/{voxels.cpp => models_voxel.cpp} (100%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 15504c65d..17fca731c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1104,7 +1104,7 @@ set (PCH_SOURCES r_data/r_vanillatrans.cpp r_data/models/models_md3.cpp r_data/models/models_md2.cpp - r_data/models/voxels.cpp + r_data/models/models_voxel.cpp scripting/symbols.cpp scripting/types.cpp scripting/thingdef.cpp diff --git a/src/r_data/models/voxels.cpp b/src/r_data/models/models_voxel.cpp similarity index 100% rename from src/r_data/models/voxels.cpp rename to src/r_data/models/models_voxel.cpp From 836970f012f1f00dbe455abc22c66833e0e10718 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 25 Nov 2017 13:51:09 +0100 Subject: [PATCH 09/12] - moved the matrix code out of 'gl' because the model code also needs it. --- src/CMakeLists.txt | 2 +- src/gl/models/gl_models.cpp | 1 - src/gl/models/gl_models.h | 3 +- src/gl/renderer/gl_postprocessstate.h | 2 +- src/gl/renderer/gl_quaddrawer.cpp | 2 +- src/gl/renderer/gl_renderer.h | 2 +- src/gl/renderer/gl_renderstate.cpp | 17 +-- src/gl/renderer/gl_renderstate.h | 2 +- src/gl/scene/gl_portal.cpp | 1 - src/gl/scene/gl_walls.cpp | 1 - src/gl/shaders/gl_shader.cpp | 2 +- src/gl/stereo3d/gl_stereo3d.h | 2 +- src/gl/utility/gl_geometric.h | 99 ----------------- src/polyrenderer/scene/poly_model.h | 2 +- .../data/gl_matrix.cpp => r_data/matrix.cpp} | 23 +--- src/{gl/data/gl_matrix.h => r_data/matrix.h} | 102 +++++++++++++++++- src/r_data/models/models.h | 3 +- src/r_data/models/models_voxel.cpp | 1 + 18 files changed, 129 insertions(+), 138 deletions(-) rename src/{gl/data/gl_matrix.cpp => r_data/matrix.cpp} (98%) rename src/{gl/data/gl_matrix.h => r_data/matrix.h} (50%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 17fca731c..39bd0933e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -796,7 +796,6 @@ set( FASTMATH_SOURCES sound/oalsound.cpp sound/sndfile_decoder.cpp sound/mididevices/music_timiditypp_mididevice.cpp - gl/data/gl_matrix.cpp gl/utility/gl_clock.cpp gl/renderer/gl_2ddrawer.cpp gl/hqnx/init.cpp @@ -826,6 +825,7 @@ set( FASTMATH_SOURCES gl/system/gl_load.c gl/models/gl_models.cpp r_data/models/models.cpp + r_data/matrix.cpp ) set (PCH_SOURCES diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp index 0e051a402..0d3754b7f 100644 --- a/src/gl/models/gl_models.cpp +++ b/src/gl/models/gl_models.cpp @@ -48,7 +48,6 @@ #include "gl/scene/gl_drawinfo.h" #include "gl/models/gl_models.h" #include "gl/textures/gl_material.h" -#include "gl/utility/gl_geometric.h" #include "gl/utility/gl_convert.h" #include "gl/renderer/gl_renderstate.h" #include "gl/shaders/gl_shader.h" diff --git a/src/gl/models/gl_models.h b/src/gl/models/gl_models.h index b60fabea6..636c1944c 100644 --- a/src/gl/models/gl_models.h +++ b/src/gl/models/gl_models.h @@ -23,12 +23,13 @@ #pragma once #include "tarray.h" -#include "gl/utility/gl_geometric.h" #include "gl/data/gl_vertexbuffer.h" #include "p_pspr.h" #include "r_data/voxels.h" #include "r_data/models/models.h" +class GLSprite; + class FGLModelRenderer : public FModelRenderer { public: diff --git a/src/gl/renderer/gl_postprocessstate.h b/src/gl/renderer/gl_postprocessstate.h index 795a7d4ba..cd45915aa 100644 --- a/src/gl/renderer/gl_postprocessstate.h +++ b/src/gl/renderer/gl_postprocessstate.h @@ -4,7 +4,7 @@ #include #include "gl/system/gl_interface.h" #include "gl/data/gl_data.h" -#include "gl/data/gl_matrix.h" +#include "r_data/matrix.h" #include "c_cvars.h" #include "r_defs.h" diff --git a/src/gl/renderer/gl_quaddrawer.cpp b/src/gl/renderer/gl_quaddrawer.cpp index d6a4f98a8..3a31fe62b 100644 --- a/src/gl/renderer/gl_quaddrawer.cpp +++ b/src/gl/renderer/gl_quaddrawer.cpp @@ -25,7 +25,7 @@ #include "gl/renderer/gl_renderer.h" #include "gl/renderer/gl_renderstate.h" #include "gl/renderer/gl_quaddrawer.h" -#include "gl/data/gl_matrix.h" +#include "r_data/matrix.h" /* ** For handling of dynamically created quads when no persistently mapped diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index e3924ad40..8b6ba46df 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -5,7 +5,7 @@ #include "v_video.h" #include "vectors.h" #include "r_renderer.h" -#include "gl/data/gl_matrix.h" +#include "r_data/matrix.h" #include "gl/dynlights/gl_shadowmap.h" struct particle_t; diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index c37ccbb99..6dd78d593 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -50,6 +50,11 @@ CVAR(Bool, gl_bandedswlight, false, CVAR_ARCHIVE) static VSMatrix identityMatrix(1); TArray gl_MatrixStack; +static void matrixToGL(const VSMatrix &mat, int loc) +{ + glUniformMatrix4fv(loc, 1, false, (float*)&mat); +} + //========================================================================== // // @@ -273,28 +278,28 @@ bool FRenderState::ApplyShader() } if (mTextureMatrixEnabled) { - mTextureMatrix.matrixToGL(activeShader->texturematrix_index); + matrixToGL(mTextureMatrix, activeShader->texturematrix_index); activeShader->currentTextureMatrixState = true; } else if (activeShader->currentTextureMatrixState) { activeShader->currentTextureMatrixState = false; - identityMatrix.matrixToGL(activeShader->texturematrix_index); + matrixToGL(identityMatrix, activeShader->texturematrix_index); } if (mModelMatrixEnabled) { - mModelMatrix.matrixToGL(activeShader->modelmatrix_index); + matrixToGL(mModelMatrix, activeShader->modelmatrix_index); VSMatrix norm; norm.computeNormalMatrix(mModelMatrix); - norm.matrixToGL(activeShader->normalmodelmatrix_index); + matrixToGL(norm, activeShader->normalmodelmatrix_index); activeShader->currentModelMatrixState = true; } else if (activeShader->currentModelMatrixState) { activeShader->currentModelMatrixState = false; - identityMatrix.matrixToGL(activeShader->modelmatrix_index); - identityMatrix.matrixToGL(activeShader->normalmodelmatrix_index); + matrixToGL(identityMatrix, activeShader->modelmatrix_index); + matrixToGL(identityMatrix, activeShader->normalmodelmatrix_index); } return true; } diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index 241461e13..92de96e9a 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -26,7 +26,7 @@ #include #include "gl/system/gl_interface.h" #include "gl/data/gl_data.h" -#include "gl/data/gl_matrix.h" +#include "r_data/matrix.h" #include "gl/textures/gl_material.h" #include "c_cvars.h" #include "r_defs.h" diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index b5671923f..2e5df1da9 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -57,7 +57,6 @@ #include "gl/textures/gl_material.h" #include "gl/utility/gl_clock.h" #include "gl/utility/gl_templates.h" -#include "gl/utility/gl_geometric.h" //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index 2ce769575..018f8ab67 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -45,7 +45,6 @@ #include "gl/scene/gl_scenedrawer.h" #include "gl/textures/gl_material.h" #include "gl/utility/gl_clock.h" -#include "gl/utility/gl_geometric.h" #include "gl/utility/gl_templates.h" #include "gl/shaders/gl_shader.h" diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 6c9ee416d..d551106a4 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -42,7 +42,7 @@ #include "gl/system/gl_interface.h" #include "gl/system/gl_debug.h" #include "gl/data/gl_data.h" -#include "gl/data/gl_matrix.h" +#include "r_data/matrix.h" #include "gl/renderer/gl_renderer.h" #include "gl/renderer/gl_renderstate.h" #include "gl/system/gl_cvars.h" diff --git a/src/gl/stereo3d/gl_stereo3d.h b/src/gl/stereo3d/gl_stereo3d.h index 81a72874f..ee632b31c 100644 --- a/src/gl/stereo3d/gl_stereo3d.h +++ b/src/gl/stereo3d/gl_stereo3d.h @@ -30,7 +30,7 @@ #include // needed for memcpy on linux, which is needed by VSMatrix copy ctor #include "tarray.h" -#include "gl/data/gl_matrix.h" +#include "r_data/matrix.h" #include "gl/renderer/gl_renderer.h" diff --git a/src/gl/utility/gl_geometric.h b/src/gl/utility/gl_geometric.h index 30c3e2dea..5f5fad8e5 100644 --- a/src/gl/utility/gl_geometric.h +++ b/src/gl/utility/gl_geometric.h @@ -83,103 +83,4 @@ protected: float m_d; }; - -class Matrix3x4 // used like a 4x4 matrix with the last row always being (0,0,0,1) -{ - float m[3][4]; - -public: - - void MakeIdentity() - { - memset(m, 0, sizeof(m)); - m[0][0] = m[1][1] = m[2][2] = 1.f; - } - - void Translate(float x, float y, float z) - { - m[0][3] = m[0][0]*x + m[0][1]*y + m[0][2]*z + m[0][3]; - m[1][3] = m[1][0]*x + m[1][1]*y + m[1][2]*z + m[1][3]; - m[2][3] = m[2][0]*x + m[2][1]*y + m[2][2]*z + m[2][3]; - } - - void Scale(float x, float y, float z) - { - m[0][0] *=x; - m[1][0] *=x; - m[2][0] *=x; - - m[0][1] *=y; - m[1][1] *=y; - m[2][1] *=y; - - m[0][2] *=z; - m[1][2] *=z; - m[2][2] *=z; - } - - void Rotate(float ax, float ay, float az, float angle) - { - Matrix3x4 m1; - - FVector3 axis(ax, ay, az); - axis.MakeUnit(); - double c = cos(angle * M_PI/180.), s = sin(angle * M_PI/180.), t = 1 - c; - double sx = s*axis.X, sy = s*axis.Y, sz = s*axis.Z; - double tx, ty, txx, tyy, u, v; - - tx = t*axis.X; - m1.m[0][0] = float( (txx=tx*axis.X) + c ); - m1.m[0][1] = float( (u=tx*axis.Y) - sz); - m1.m[0][2] = float( (v=tx*axis.Z) + sy); - - ty = t*axis.Y; - m1.m[1][0] = float( u + sz); - m1.m[1][1] = float( (tyy=ty*axis.Y) + c ); - m1.m[1][2] = float( (u=ty*axis.Z) - sx); - - m1.m[2][0] = float( v - sy); - m1.m[2][1] = float( u + sx); - m1.m[2][2] = float( (t-txx-tyy) + c ); - - m1.m[0][3] = 0.f; - m1.m[1][3] = 0.f; - m1.m[2][3] = 0.f; - - *this = (*this) * m1; - } - - Matrix3x4 operator *(const Matrix3x4 &other) - { - Matrix3x4 result; - - result.m[0][0] = m[0][0]*other.m[0][0] + m[0][1]*other.m[1][0] + m[0][2]*other.m[2][0]; - result.m[0][1] = m[0][0]*other.m[0][1] + m[0][1]*other.m[1][1] + m[0][2]*other.m[2][1]; - result.m[0][2] = m[0][0]*other.m[0][2] + m[0][1]*other.m[1][2] + m[0][2]*other.m[2][2]; - result.m[0][3] = m[0][0]*other.m[0][3] + m[0][1]*other.m[1][3] + m[0][2]*other.m[2][3] + m[0][3]; - - result.m[1][0] = m[1][0]*other.m[0][0] + m[1][1]*other.m[1][0] + m[1][2]*other.m[2][0]; - result.m[1][1] = m[1][0]*other.m[0][1] + m[1][1]*other.m[1][1] + m[1][2]*other.m[2][1]; - result.m[1][2] = m[1][0]*other.m[0][2] + m[1][1]*other.m[1][2] + m[1][2]*other.m[2][2]; - result.m[1][3] = m[1][0]*other.m[0][3] + m[1][1]*other.m[1][3] + m[1][2]*other.m[2][3] + m[1][3]; - - result.m[2][0] = m[2][0]*other.m[0][0] + m[2][1]*other.m[1][0] + m[2][2]*other.m[2][0]; - result.m[2][1] = m[2][0]*other.m[0][1] + m[2][1]*other.m[1][1] + m[2][2]*other.m[2][1]; - result.m[2][2] = m[2][0]*other.m[0][2] + m[2][1]*other.m[1][2] + m[2][2]*other.m[2][2]; - result.m[2][3] = m[2][0]*other.m[0][3] + m[2][1]*other.m[1][3] + m[2][2]*other.m[2][3] + m[2][3]; - - return result; - } - - FVector3 operator *(const FVector3 &vec) - { - FVector3 result; - - result.X = vec.X*m[0][0] + vec.Y*m[0][1] + vec.Z*m[0][2] + m[0][3]; - result.Y = vec.X*m[1][0] + vec.Y*m[1][1] + vec.Z*m[1][2] + m[1][3]; - result.Z = vec.X*m[2][0] + vec.Y*m[2][1] + vec.Z*m[2][2] + m[2][3]; - return result; - } -}; - #endif diff --git a/src/polyrenderer/scene/poly_model.h b/src/polyrenderer/scene/poly_model.h index a3907edc0..b4896b7d8 100644 --- a/src/polyrenderer/scene/poly_model.h +++ b/src/polyrenderer/scene/poly_model.h @@ -23,7 +23,7 @@ #pragma once #include "polyrenderer/drawers/poly_triangle.h" -#include "gl/data/gl_matrix.h" +#include "r_data/matrix.h" #include "gl/models/gl_models.h" void PolyRenderModel(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, uint32_t stencilValue, float x, float y, float z, FSpriteModelFrame *smf, AActor *actor); diff --git a/src/gl/data/gl_matrix.cpp b/src/r_data/matrix.cpp similarity index 98% rename from src/gl/data/gl_matrix.cpp rename to src/r_data/matrix.cpp index 9063fc59b..edc26e833 100644 --- a/src/gl/data/gl_matrix.cpp +++ b/src/r_data/matrix.cpp @@ -11,13 +11,16 @@ This is a simplified version of VSMatrix that has been adjusted for GZDoom's nee ----------------------------------------------------*/ #include -#include "gl/system/gl_system.h" #include #include #include #include #include "doomtype.h" -#include "gl/data/gl_matrix.h" +#include "matrix.h" + +#ifdef _MSC_VER +#pragma warning(disable : 4244) // truncate from double to float +#endif static inline FLOATTYPE DegToRad(FLOATTYPE degrees) @@ -310,22 +313,6 @@ VSMatrix::get(MatrixTypes aType) SEND MATRICES TO OPENGL ------------------------------------------------------*/ - - - -// universal -void -VSMatrix::matrixToGL(int loc) -{ -#ifdef USE_DOUBLE - float copyto[16]; - copy(copyto); - glUniformMatrix4fv(loc, 1, false, copyto); -#else - glUniformMatrix4fv(loc, 1, false, mMatrix); -#endif -} - // ----------------------------------------------------- // AUX functions // ----------------------------------------------------- diff --git a/src/gl/data/gl_matrix.h b/src/r_data/matrix.h similarity index 50% rename from src/gl/data/gl_matrix.h rename to src/r_data/matrix.h index 3ec1f5ff4..22774845a 100644 --- a/src/gl/data/gl_matrix.h +++ b/src/r_data/matrix.h @@ -21,6 +21,8 @@ #define __VSMatrix__ #include +#include "vectors.h" +#include "doomtype.h" #ifdef USE_DOUBLE typedef double FLOATTYPE; @@ -82,7 +84,6 @@ class VSMatrix { return mMatrix; } - void matrixToGL(int location); void multMatrixPoint(const FLOATTYPE *point, FLOATTYPE *res); #ifdef USE_DOUBLE @@ -112,4 +113,103 @@ class VSMatrix { }; + +class Matrix3x4 // used like a 4x4 matrix with the last row always being (0,0,0,1) +{ + float m[3][4]; + +public: + + void MakeIdentity() + { + memset(m, 0, sizeof(m)); + m[0][0] = m[1][1] = m[2][2] = 1.f; + } + + void Translate(float x, float y, float z) + { + m[0][3] = m[0][0]*x + m[0][1]*y + m[0][2]*z + m[0][3]; + m[1][3] = m[1][0]*x + m[1][1]*y + m[1][2]*z + m[1][3]; + m[2][3] = m[2][0]*x + m[2][1]*y + m[2][2]*z + m[2][3]; + } + + void Scale(float x, float y, float z) + { + m[0][0] *=x; + m[1][0] *=x; + m[2][0] *=x; + + m[0][1] *=y; + m[1][1] *=y; + m[2][1] *=y; + + m[0][2] *=z; + m[1][2] *=z; + m[2][2] *=z; + } + + void Rotate(float ax, float ay, float az, float angle) + { + Matrix3x4 m1; + + FVector3 axis(ax, ay, az); + axis.MakeUnit(); + double c = cos(angle * M_PI/180.), s = sin(angle * M_PI/180.), t = 1 - c; + double sx = s*axis.X, sy = s*axis.Y, sz = s*axis.Z; + double tx, ty, txx, tyy, u, v; + + tx = t*axis.X; + m1.m[0][0] = float( (txx=tx*axis.X) + c ); + m1.m[0][1] = float( (u=tx*axis.Y) - sz); + m1.m[0][2] = float( (v=tx*axis.Z) + sy); + + ty = t*axis.Y; + m1.m[1][0] = float( u + sz); + m1.m[1][1] = float( (tyy=ty*axis.Y) + c ); + m1.m[1][2] = float( (u=ty*axis.Z) - sx); + + m1.m[2][0] = float( v - sy); + m1.m[2][1] = float( u + sx); + m1.m[2][2] = float( (t-txx-tyy) + c ); + + m1.m[0][3] = 0.f; + m1.m[1][3] = 0.f; + m1.m[2][3] = 0.f; + + *this = (*this) * m1; + } + + Matrix3x4 operator *(const Matrix3x4 &other) + { + Matrix3x4 result; + + result.m[0][0] = m[0][0]*other.m[0][0] + m[0][1]*other.m[1][0] + m[0][2]*other.m[2][0]; + result.m[0][1] = m[0][0]*other.m[0][1] + m[0][1]*other.m[1][1] + m[0][2]*other.m[2][1]; + result.m[0][2] = m[0][0]*other.m[0][2] + m[0][1]*other.m[1][2] + m[0][2]*other.m[2][2]; + result.m[0][3] = m[0][0]*other.m[0][3] + m[0][1]*other.m[1][3] + m[0][2]*other.m[2][3] + m[0][3]; + + result.m[1][0] = m[1][0]*other.m[0][0] + m[1][1]*other.m[1][0] + m[1][2]*other.m[2][0]; + result.m[1][1] = m[1][0]*other.m[0][1] + m[1][1]*other.m[1][1] + m[1][2]*other.m[2][1]; + result.m[1][2] = m[1][0]*other.m[0][2] + m[1][1]*other.m[1][2] + m[1][2]*other.m[2][2]; + result.m[1][3] = m[1][0]*other.m[0][3] + m[1][1]*other.m[1][3] + m[1][2]*other.m[2][3] + m[1][3]; + + result.m[2][0] = m[2][0]*other.m[0][0] + m[2][1]*other.m[1][0] + m[2][2]*other.m[2][0]; + result.m[2][1] = m[2][0]*other.m[0][1] + m[2][1]*other.m[1][1] + m[2][2]*other.m[2][1]; + result.m[2][2] = m[2][0]*other.m[0][2] + m[2][1]*other.m[1][2] + m[2][2]*other.m[2][2]; + result.m[2][3] = m[2][0]*other.m[0][3] + m[2][1]*other.m[1][3] + m[2][2]*other.m[2][3] + m[2][3]; + + return result; + } + + FVector3 operator *(const FVector3 &vec) + { + FVector3 result; + + result.X = vec.X*m[0][0] + vec.Y*m[0][1] + vec.Z*m[0][2] + m[0][3]; + result.Y = vec.X*m[1][0] + vec.Y*m[1][1] + vec.Z*m[1][2] + m[1][3]; + result.Z = vec.X*m[2][0] + vec.Y*m[2][1] + vec.Z*m[2][2] + m[2][3]; + return result; + } +}; + #endif \ No newline at end of file diff --git a/src/r_data/models/models.h b/src/r_data/models/models.h index 7e9dabf82..4a8678fa6 100644 --- a/src/r_data/models/models.h +++ b/src/r_data/models/models.h @@ -24,8 +24,7 @@ #define __GL_MODELS_H_ #include "tarray.h" -#include "gl/utility/gl_geometric.h" -#include "gl/data/gl_matrix.h" +#include "r_data/matrix.h" #include "actor.h" #include "dobject.h" #include "p_pspr.h" diff --git a/src/r_data/models/models_voxel.cpp b/src/r_data/models/models_voxel.cpp index 6e96d7e7b..848f5a54d 100644 --- a/src/r_data/models/models_voxel.cpp +++ b/src/r_data/models/models_voxel.cpp @@ -38,6 +38,7 @@ #include "textures/bitmap.h" #include "g_levellocals.h" #include "models.h" +#include "v_palette.h" #ifdef _MSC_VER #pragma warning(disable:4244) // warning C4244: conversion from 'double' to 'float', possible loss of data From e43a9aa5b56013d91abd39f480b7c66d71c0eaac Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 25 Nov 2017 13:56:17 +0100 Subject: [PATCH 10/12] - don't let models.cpp include gl_system.h. --- src/r_data/models/models.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/r_data/models/models.cpp b/src/r_data/models/models.cpp index 46db0deeb..ff799b14d 100644 --- a/src/r_data/models/models.cpp +++ b/src/r_data/models/models.cpp @@ -26,7 +26,6 @@ ** **/ -#include "gl/system/gl_system.h" #include "w_wad.h" #include "cmdlib.h" #include "sc_man.h" @@ -42,6 +41,10 @@ #include "i_time.h" #include "r_data/models/models.h" +#ifdef _MSC_VER +#pragma warning(disable:4244) // warning C4244: conversion from 'double' to 'float', possible loss of data +#endif + CVAR(Bool, gl_interpolate_model_frames, true, CVAR_ARCHIVE) EXTERN_CVAR(Bool, r_drawvoxels) From 700aeaf192bea7b865736dfd2309939ff301579c Mon Sep 17 00:00:00 2001 From: Henk Roos Date: Sat, 25 Nov 2017 14:54:48 +0100 Subject: [PATCH 11/12] Added 'static' to CreateCeiling (base.txt) Keyword 'static'was missing in CreateCeiling. --- wadsrc/static/zscript/base.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 89dd0ab7d..e38517142 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -796,7 +796,7 @@ class Ceiling : MovingCeiling native crushSlowdown = 2 } - native bool CreateCeiling(sector sec, int type, line ln, double speed, double speed2, double height = 0, int crush = -1, int silent = 0, int change = 0, int crushmode = crushDoom); + native static bool CreateCeiling(sector sec, int type, line ln, double speed, double speed2, double height = 0, int crush = -1, int silent = 0, int change = 0, int crushmode = crushDoom); } From eeba7a7cdfe5838116716e2d6fe750ddf6dcfc27 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 25 Nov 2017 16:32:53 +0200 Subject: [PATCH 12/12] Fixed tics to seconds conversion Correct time values are now displayed in HUD --- src/cmdlib.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cmdlib.h b/src/cmdlib.h index f8fdfc496..e2119ed8a 100644 --- a/src/cmdlib.h +++ b/src/cmdlib.h @@ -67,7 +67,7 @@ void ScanDirectory(TArray &list, const char *dirpath); inline int Tics2Seconds(int tics) { - return tics * TICRATE; + return tics / TICRATE; }