mirror of
https://github.com/openmoh/openmohaa.git
synced 2025-04-28 13:47:58 +03:00
Add minimal renderergl2 implementation
This implementation should just let the game run without crashing, the renderer doesn't show anything yet
This commit is contained in:
parent
fe16f999d8
commit
3d950764a2
45 changed files with 12269 additions and 3355 deletions
|
@ -10,6 +10,8 @@ set(SOURCES_RENDERER_COMMON ${SOURCES_RENDERER_COMMON}
|
|||
|
||||
add_library(omohrenderer_common STATIC ${SOURCES_RENDERER_COMMON})
|
||||
target_include_directories(omohrenderer_common PUBLIC "../sdl" "./")
|
||||
target_compile_features(omohrenderer_common PUBLIC cxx_nullptr)
|
||||
target_compile_features(omohrenderer_common PUBLIC c_variadic_macros)
|
||||
target_link_libraries(omohrenderer_common PUBLIC qcommon_shared)
|
||||
target_link_libraries(omohrenderer_common PUBLIC omohsdl_gl)
|
||||
target_compile_definitions(omohrenderer_common PRIVATE USE_INTERNAL_JPEG=1)
|
||||
|
|
|
@ -27,7 +27,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#define MAX_DLIGHTS 32 // can't be increased, because bit flags are used on surfaces
|
||||
#define MAX_REAL_LIGHTS 32
|
||||
|
||||
#define REFENTITYNUM_BITS 10 // can't be increased without changing drawsurf bit packing
|
||||
#define REFENTITYNUM_BITS 12 // can't be increased without changing drawsurf bit packing
|
||||
#define REFENTITYNUM_MASK ((1<<REFENTITYNUM_BITS) - 1)
|
||||
// the last N-bit number (2^REFENTITYNUM_BITS - 1) is reserved for the special world refentity,
|
||||
// and this is reflected by the value of MAX_REFENTITIES (which therefore is not a power-of-2)
|
||||
|
|
|
@ -2,7 +2,10 @@ cmake_minimum_required(VERSION 3.12)
|
|||
|
||||
project(omohrenderergl2)
|
||||
|
||||
file(GLOB SOURCES_RENDERER "./*.c" "./*.cpp" "../renderercommon/tr_*.c")
|
||||
file(GLOB SOURCES_RENDERER "*.c" "*.cpp" "../renderercommon/tr_*.c")
|
||||
# Remove Quake III old model source
|
||||
list(REMOVE_ITEM SOURCES_RENDERER "${CMAKE_CURRENT_SOURCE_DIR}/tr_model.c")
|
||||
|
||||
include("glsl/shaders.cmake")
|
||||
|
||||
if (${USE_RENDERER_DLOPEN})
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../tr_local.h"
|
||||
|
||||
int RE_MapVersion(void)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RE_PrintBSPFileSizes(void)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../tr_local.h"
|
||||
|
||||
static backEndCounters_t pc_save;
|
||||
|
||||
/*
|
||||
=====================
|
||||
R_PerformanceCounters
|
||||
=====================
|
||||
*/
|
||||
void R_SavePerformanceCounters(void) {
|
||||
memcpy(&pc_save, &backEnd.pc, sizeof(pc_save));
|
||||
}
|
||||
|
||||
void R_SyncRenderThread() {
|
||||
R_IssuePendingRenderCommands();
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../tr_local.h"
|
|
@ -1,175 +0,0 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../tr_local.h"
|
||||
|
||||
cvar_t* r_reset_tc_array;
|
||||
cvar_t* r_numdebuglines;
|
||||
|
||||
|
||||
cvar_t* r_staticlod;
|
||||
cvar_t* r_lodscale;
|
||||
cvar_t* r_lodcap;
|
||||
cvar_t* r_lodviewmodelcap;
|
||||
|
||||
cvar_t* r_uselod;
|
||||
cvar_t* lod_LOD;
|
||||
cvar_t* lod_minLOD;
|
||||
cvar_t* lod_maxLOD;
|
||||
cvar_t* lod_LOD_slider;
|
||||
cvar_t* lod_curve_0_val;
|
||||
cvar_t* lod_curve_1_val;
|
||||
cvar_t* lod_curve_2_val;
|
||||
cvar_t* lod_curve_3_val;
|
||||
cvar_t* lod_curve_4_val;
|
||||
cvar_t* lod_edit_0;
|
||||
cvar_t* lod_edit_1;
|
||||
cvar_t* lod_edit_2;
|
||||
cvar_t* lod_edit_3;
|
||||
cvar_t* lod_edit_4;
|
||||
cvar_t* lod_curve_0_slider;
|
||||
cvar_t* lod_curve_1_slider;
|
||||
cvar_t* lod_curve_2_slider;
|
||||
cvar_t* lod_curve_3_slider;
|
||||
cvar_t* lod_curve_4_slider;
|
||||
cvar_t* lod_pitch_val;
|
||||
cvar_t* lod_zee_val;
|
||||
cvar_t* lod_mesh;
|
||||
cvar_t* lod_meshname;
|
||||
cvar_t* lod_tikiname;
|
||||
cvar_t* lod_metric;
|
||||
cvar_t* lod_tris;
|
||||
cvar_t* lod_position;
|
||||
cvar_t* lod_save;
|
||||
cvar_t* lod_tool;
|
||||
|
||||
cvar_t* r_showSkeleton;
|
||||
|
||||
int r_sequencenumber;
|
||||
|
||||
//=============================================================================
|
||||
|
||||
/*
|
||||
** RE_BeginRegistration
|
||||
*/
|
||||
void RE_BeginRegistration(glconfig_t* glconfigOut) {
|
||||
int i;
|
||||
|
||||
R_Init();
|
||||
|
||||
*glconfigOut = glConfig;
|
||||
|
||||
R_IssuePendingRenderCommands();
|
||||
|
||||
tr.visIndex = 0;
|
||||
// force markleafs to regenerate
|
||||
for (i = 0; i < MAX_VISCOUNTS; i++) {
|
||||
tr.visClusters[i] = -2;
|
||||
}
|
||||
|
||||
R_ClearFlares();
|
||||
RE_ClearScene();
|
||||
|
||||
tr.registered = qtrue;
|
||||
}
|
||||
|
||||
const char* RE_GetGraphicsInfo() {
|
||||
// FIXME: unimplemented
|
||||
return NULL;
|
||||
}
|
||||
|
||||
qboolean R_SetMode(int mode, const glconfig_t* glConfig) {
|
||||
// FIXME: unimplemented
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
void R_SetFullscreen(qboolean fullscreen) {
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void RE_SetRenderTime(int t) {
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void GetRefAPI_new(refimport_t* ri, refexport_t* re)
|
||||
{
|
||||
re->FreeModels = RE_FreeModels;
|
||||
re->SpawnEffectModel = RE_SpawnEffectModel;
|
||||
re->RegisterServerModel = RE_RegisterServerModel;
|
||||
re->UnregisterServerModel = RE_UnregisterServerModel;
|
||||
re->RefreshShaderNoMip = RE_RefreshShaderNoMip;
|
||||
re->PrintBSPFileSizes = RE_PrintBSPFileSizes;
|
||||
re->MapVersion = RE_MapVersion;
|
||||
re->LoadFont = R_LoadFont;
|
||||
|
||||
re->BeginFrame = RE_BeginFrame;
|
||||
|
||||
re->MarkFragments = R_MarkFragments_New;
|
||||
re->MarkFragmentsForInlineModel = R_MarkFragmentsForInlineModel;
|
||||
re->GetInlineModelBounds = R_GetInlineModelBounds;
|
||||
re->GetLightingForDecal = R_GetLightingForDecal;
|
||||
re->GetLightingForSmoke = R_GetLightingForSmoke;
|
||||
re->R_GatherLightSources = R_GatherLightSources;
|
||||
re->ModelBounds = R_ModelBounds;
|
||||
re->ModelRadius = R_ModelRadius;
|
||||
|
||||
re->AddRefEntityToScene = RE_AddRefEntityToScene;
|
||||
re->AddRefSpriteToScene = RE_AddRefSpriteToScene;
|
||||
re->AddPolyToScene = RE_AddPolyToScene;
|
||||
re->AddTerrainMarkToScene = RE_AddTerrainMarkToScene;
|
||||
re->AddLightToScene = RE_AddLightToScene;
|
||||
re->RenderScene = RE_RenderScene;
|
||||
re->GetRenderEntity = RE_GetRenderEntity;
|
||||
|
||||
re->SavePerformanceCounters = R_SavePerformanceCounters;
|
||||
|
||||
re->R_Model_GetHandle = R_Model_GetHandle;
|
||||
re->DrawStretchRaw = RE_StretchRaw;
|
||||
re->DebugLine = R_DebugLine;
|
||||
re->DrawStretchPic = Draw_StretchPic;
|
||||
re->DrawTilePic = Draw_TilePic;
|
||||
re->DrawTilePicOffset = Draw_TilePicOffset;
|
||||
re->DrawTrianglePic = Draw_TrianglePic;
|
||||
re->DrawBox = DrawBox;
|
||||
re->AddBox = AddBox;
|
||||
re->Set2DWindow = Set2DWindow;
|
||||
re->Scissor = RE_Scissor;
|
||||
re->DrawLineLoop = DrawLineLoop;
|
||||
re->DrawString = R_DrawString;
|
||||
re->GetFontHeight = R_GetFontHeight;
|
||||
re->GetFontStringWidth = R_GetFontStringWidth;
|
||||
re->SwipeBegin = RE_SwipeBegin;
|
||||
re->SwipeEnd = RE_SwipeEnd;
|
||||
re->SetRenderTime = RE_SetRenderTime;
|
||||
re->Noise = R_NoiseGet4f;
|
||||
|
||||
re->SetMode = R_SetMode;
|
||||
re->SetFullscreen = R_SetFullscreen;
|
||||
|
||||
re->GetShaderHeight = RE_GetShaderHeight;
|
||||
re->GetShaderWidth = RE_GetShaderWidth;
|
||||
re->GetGraphicsInfo = RE_GetGraphicsInfo;
|
||||
re->ForceUpdatePose = RE_ForceUpdatePose;
|
||||
re->TIKI_Orientation = RE_TIKI_Orientation;
|
||||
re->TIKI_IsOnGround = RE_TIKI_IsOnGround;
|
||||
re->SetFrameNumber = RE_SetFrameNumber;
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../tr_local.h"
|
||||
|
||||
void R_GetLightingForDecal(vec3_t vLight, vec3_t vFacing, vec3_t vOrigin)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void R_GetLightingForSmoke(vec3_t vLight, vec3_t vOrigin)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
|
@ -1,465 +0,0 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
extern int r_sequencenumber;
|
||||
|
||||
void GetRefAPI_new(refimport_t* ri, refexport_t* re);
|
||||
|
||||
extern cvar_t* r_reset_tc_array;
|
||||
extern cvar_t* r_numdebuglines;
|
||||
|
||||
extern cvar_t* r_staticlod;
|
||||
extern cvar_t* r_lodscale;
|
||||
extern cvar_t* r_lodcap;
|
||||
extern cvar_t* r_lodviewmodelcap;
|
||||
|
||||
extern cvar_t* r_uselod;
|
||||
extern cvar_t* lod_LOD;
|
||||
extern cvar_t* lod_minLOD;
|
||||
extern cvar_t* lod_maxLOD;
|
||||
extern cvar_t* lod_LOD_slider;
|
||||
extern cvar_t* lod_curve_0_val;
|
||||
extern cvar_t* lod_curve_1_val;
|
||||
extern cvar_t* lod_curve_2_val;
|
||||
extern cvar_t* lod_curve_3_val;
|
||||
extern cvar_t* lod_curve_4_val;
|
||||
extern cvar_t* lod_edit_0;
|
||||
extern cvar_t* lod_edit_1;
|
||||
extern cvar_t* lod_edit_2;
|
||||
extern cvar_t* lod_edit_3;
|
||||
extern cvar_t* lod_edit_4;
|
||||
extern cvar_t* lod_curve_0_slider;
|
||||
extern cvar_t* lod_curve_1_slider;
|
||||
extern cvar_t* lod_curve_2_slider;
|
||||
extern cvar_t* lod_curve_3_slider;
|
||||
extern cvar_t* lod_curve_4_slider;
|
||||
extern cvar_t* lod_pitch_val;
|
||||
extern cvar_t* lod_zee_val;
|
||||
extern cvar_t* lod_mesh;
|
||||
extern cvar_t* lod_meshname;
|
||||
extern cvar_t* lod_tikiname;
|
||||
extern cvar_t* lod_metric;
|
||||
extern cvar_t* lod_tris;
|
||||
extern cvar_t* lod_position;
|
||||
extern cvar_t* lod_save;
|
||||
extern cvar_t* lod_tool;
|
||||
extern cvar_t* r_showSkeleton;
|
||||
|
||||
typedef union varnodeUnpacked_u {
|
||||
float fVariance;
|
||||
struct {
|
||||
byte flags;
|
||||
unsigned char unused[3];
|
||||
} s;
|
||||
} varnodeUnpacked_t;
|
||||
|
||||
typedef unsigned short terraInt;
|
||||
|
||||
typedef struct terrainVert_s {
|
||||
vec3_t xyz;
|
||||
vec2_t texCoords[2];
|
||||
float fVariance;
|
||||
float fHgtAvg;
|
||||
float fHgtAdd;
|
||||
unsigned int uiDistRecalc;
|
||||
terraInt nRef;
|
||||
terraInt iVertArray;
|
||||
byte* pHgt;
|
||||
terraInt iNext;
|
||||
terraInt iPrev;
|
||||
} terrainVert_t;
|
||||
|
||||
typedef struct terraTri_s {
|
||||
unsigned short iPt[3];
|
||||
terraInt nSplit;
|
||||
unsigned int uiDistRecalc;
|
||||
struct cTerraPatchUnpacked_s* patch;
|
||||
varnodeUnpacked_t* varnode;
|
||||
terraInt index;
|
||||
byte lod;
|
||||
byte byConstChecks;
|
||||
terraInt iLeft;
|
||||
terraInt iRight;
|
||||
terraInt iBase;
|
||||
terraInt iLeftChild;
|
||||
terraInt iRightChild;
|
||||
terraInt iParent;
|
||||
terraInt iPrev;
|
||||
terraInt iNext;
|
||||
} terraTri_t;
|
||||
|
||||
typedef struct srfTerrain_s {
|
||||
surfaceType_t surfaceType;
|
||||
terraInt iVertHead;
|
||||
terraInt iTriHead;
|
||||
terraInt iTriTail;
|
||||
terraInt iMergeHead;
|
||||
int nVerts;
|
||||
int nTris;
|
||||
int lmapSize;
|
||||
int dlightBits[2];
|
||||
float lmapStep;
|
||||
int dlightMap[2];
|
||||
byte* lmData;
|
||||
float lmapX;
|
||||
float lmapY;
|
||||
} srfTerrain_t;
|
||||
|
||||
typedef struct cTerraPatchUnpacked_s {
|
||||
srfTerrain_t drawinfo;
|
||||
int viewCount;
|
||||
int visCountCheck;
|
||||
int visCountDraw;
|
||||
int frameCount;
|
||||
unsigned int uiDistRecalc;
|
||||
float s;
|
||||
float t;
|
||||
vec2_t texCoord[2][2];
|
||||
float x0;
|
||||
float y0;
|
||||
float z0;
|
||||
float zmax;
|
||||
shader_t* shader;
|
||||
short int iNorth;
|
||||
short int iEast;
|
||||
short int iSouth;
|
||||
short int iWest;
|
||||
struct cTerraPatchUnpacked_s* pNextActive;
|
||||
varnodeUnpacked_t varTree[2][63];
|
||||
unsigned char heightmap[81];
|
||||
byte flags;
|
||||
byte byDirty;
|
||||
} cTerraPatchUnpacked_t;
|
||||
|
||||
typedef struct srfStaticModel_s {
|
||||
surfaceType_t surfaceType;
|
||||
struct cStaticModelUnpacked_s* parent;
|
||||
} srfStaticModel_t;
|
||||
|
||||
typedef struct cStaticModelUnpacked_s {
|
||||
qboolean useSpecialLighting;
|
||||
qboolean bLightGridCalculated;
|
||||
qboolean bRendered;
|
||||
char model[128];
|
||||
vec3_t origin;
|
||||
vec3_t angles;
|
||||
vec3_t axis[3];
|
||||
float scale;
|
||||
int firstVertexData;
|
||||
int numVertexData;
|
||||
int visCount;
|
||||
dtiki_t* tiki;
|
||||
sphere_dlight_t dlights[32];
|
||||
int numdlights;
|
||||
float radius;
|
||||
float cull_radius;
|
||||
int iGridLighting;
|
||||
float lodpercentage[2];
|
||||
} cStaticModelUnpacked_t;
|
||||
|
||||
typedef struct refSprite_s {
|
||||
surfaceType_t surftype;
|
||||
int hModel;
|
||||
int shaderNum;
|
||||
float origin[3];
|
||||
float scale;
|
||||
float axis[3][3];
|
||||
unsigned char shaderRGBA[4];
|
||||
int renderfx;
|
||||
float shaderTime;
|
||||
} refSprite_t;
|
||||
|
||||
//
|
||||
// tr_shader.c
|
||||
//
|
||||
qhandle_t RE_RefreshShaderNoMip(const char* name);
|
||||
|
||||
//
|
||||
// tr_bsp.c
|
||||
//
|
||||
void RE_PrintBSPFileSizes(void);
|
||||
int RE_MapVersion(void);
|
||||
|
||||
typedef struct skelSurfaceGame_s skelSurfaceGame_t;
|
||||
typedef struct staticSurface_s staticSurface_t;
|
||||
|
||||
/*
|
||||
============================================================
|
||||
|
||||
DRAWING
|
||||
|
||||
============================================================
|
||||
*/
|
||||
void Draw_StretchPic(float x, float y, float w, float h, float s1, float t1, float s2, float t2, qhandle_t hShader);
|
||||
void Draw_TilePic(float x, float y, float w, float h, qhandle_t hShader);
|
||||
void Draw_TilePicOffset(float x, float y, float w, float h, qhandle_t hShader, int offsetX, int offsetY);
|
||||
void Draw_TrianglePic(const vec2_t vPoints[3], const vec2_t vTexCoords[3], qhandle_t hShader);
|
||||
void DrawBox(float x, float y, float w, float h);
|
||||
void AddBox(float x, float y, float w, float h);
|
||||
void Set2DWindow(int x, int y, int w, int h, float left, float right, float bottom, float top, float n, float f);
|
||||
void RE_Scissor(int x, int y, int width, int height);
|
||||
void DrawLineLoop(const vec2_t* points, int count, int stipple_factor, int stipple_mask);
|
||||
|
||||
/*
|
||||
============================================================
|
||||
|
||||
FLARES
|
||||
|
||||
============================================================
|
||||
*/
|
||||
|
||||
void R_ClearFlares(void);
|
||||
|
||||
void RB_AddFlare(void* surface, int fogNum, vec3_t point, vec3_t color, vec3_t normal);
|
||||
void RB_AddDlightFlares(void);
|
||||
void RB_RenderFlares(void);
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
||||
FONT
|
||||
|
||||
=============================================================
|
||||
*/
|
||||
fontheader_t* R_LoadFont(const char* name);
|
||||
void R_LoadFontShader(fontheader_t* font);
|
||||
void R_DrawString(fontheader_t* font, const char* text, float x, float y, int maxlen, qboolean bVirtualScreen);
|
||||
float R_GetFontHeight(const fontheader_t* font);
|
||||
float R_GetFontStringWidth(const fontheader_t* font, const char* s);
|
||||
|
||||
/*
|
||||
============================================================
|
||||
|
||||
LIGHTS
|
||||
|
||||
============================================================
|
||||
*/
|
||||
|
||||
void R_DlightBmodel(bmodel_t* bmodel);
|
||||
void R_GetLightingGridValue(const vec3_t vPos, vec3_t vLight);
|
||||
void R_GetLightingForDecal(vec3_t vLight, vec3_t vFacing, vec3_t vOrigin);
|
||||
void R_GetLightingForSmoke(vec3_t vLight, vec3_t vOrigin);
|
||||
void R_SetupEntityLighting(const trRefdef_t* refdef, trRefEntity_t* ent);
|
||||
void RB_SetupEntityGridLighting();
|
||||
void RB_SetupStaticModelGridLighting(trRefdef_t* refdef, cStaticModelUnpacked_t* ent, const vec3_t lightOrigin);
|
||||
void R_TransformDlights(int count, dlight_t* dl, orientationr_t* ori);
|
||||
void RB_Light_Real(unsigned char* colors);
|
||||
void RB_Sphere_BuildDLights();
|
||||
void RB_Sphere_SetupEntity();
|
||||
void RB_Grid_SetupEntity();
|
||||
void RB_Grid_SetupStaticModel();
|
||||
void RB_Light_Fullbright(unsigned char* colors);
|
||||
void R_Sphere_InitLights();
|
||||
int R_GatherLightSources(const vec3_t vPos, vec3_t* pvLightPos, vec3_t* pvLightIntensity, int iMaxLights);
|
||||
void R_UploadDlights();
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
||||
MARKS
|
||||
|
||||
=============================================================
|
||||
*/
|
||||
void R_LevelMarksLoad(const char* szBSPName);
|
||||
void R_LevelMarksInit();
|
||||
void R_LevelMarksFree();
|
||||
void R_UpdateLevelMarksSystem();
|
||||
void R_AddPermanentMarkFragmentSurfaces(void** pFirstMarkFragment, int iNumMarkFragment);
|
||||
|
||||
int R_MarkFragments_New(int numPoints, const vec3_t* points, const vec3_t projection,
|
||||
int maxPoints, vec3_t pointBuffer, int maxFragments, markFragment_t* fragmentBuffer, float fRadiusSquared);
|
||||
|
||||
int R_MarkFragmentsForInlineModel(clipHandle_t bmodel, const vec3_t angles, const vec3_t origin, int numPoints,
|
||||
const vec3_t* points, const vec3_t projection, int maxPoints, vec3_t pointBuffer,
|
||||
int maxFragments, markFragment_t* fragmentBuffer, float radiusSquared);
|
||||
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
||||
SHADE
|
||||
|
||||
=============================================================
|
||||
*/
|
||||
void RB_CalcColorFromConstant(unsigned char* dstColors, unsigned char* constantColor);
|
||||
void RB_CalcRGBFromDot(unsigned char* colors, float alphaMin, float alphaMax);
|
||||
void RB_CalcRGBFromOneMinusDot(unsigned char* colors, float alphaMin, float alphaMax);
|
||||
void RB_CalcAlphaFromConstant(unsigned char* dstColors, int constantAlpha);
|
||||
void RB_CalcAlphaFromDot(unsigned char* colors, float alphaMin, float alphaMax);
|
||||
void RB_CalcAlphaFromOneMinusDot(unsigned char* colors, float alphaMin, float alphaMax);
|
||||
void RB_CalcAlphaFromTexCoords(unsigned char* colors, float alphaMin, float alphaMax, int alphaMinCap, int alphaCap, float sWeight, float tWeight, float* st);
|
||||
void RB_CalcRGBFromTexCoords(unsigned char* colors, float alphaMin, float alphaMax, int alphaMinCap, int alphaCap, float sWeight, float tWeight, float* st);
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
||||
SKY PORTALS
|
||||
|
||||
=============================================================
|
||||
*/
|
||||
void R_Sky_Init();
|
||||
void R_Sky_Reset();
|
||||
void R_Sky_AddSurf(msurface_t* surf);
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
||||
SPRITE
|
||||
|
||||
=============================================================
|
||||
*/
|
||||
sprite_t* SPR_RegisterSprite(const char* name);
|
||||
void RB_DrawSprite(const refSprite_t* spr);
|
||||
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
||||
SUN FLARE
|
||||
|
||||
=============================================================
|
||||
*/
|
||||
void R_InitLensFlare();
|
||||
void R_DrawLensFlares();
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
||||
SWIPE
|
||||
|
||||
=============================================================
|
||||
*/
|
||||
void RB_DrawSwipeSurface(surfaceType_t* pswipe);
|
||||
void RE_SwipeBegin(float thistime, float life, qhandle_t shader);
|
||||
void RE_SwipeEnd();
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
||||
TERRAIN
|
||||
|
||||
=============================================================
|
||||
*/
|
||||
void R_MarkTerrainPatch(cTerraPatchUnpacked_t* pPatch);
|
||||
void R_AddTerrainSurfaces();
|
||||
void R_InitTerrain();
|
||||
void R_TerrainPrepareFrame();
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
||||
SCENE GENERATION
|
||||
|
||||
=============================================================
|
||||
*/
|
||||
void RE_AddRefSpriteToScene(const refEntity_t* ent);
|
||||
void RE_AddTerrainMarkToScene(int iTerrainIndex, qhandle_t hShader, int numVerts, const polyVert_t* verts, int renderfx);
|
||||
refEntity_t* RE_GetRenderEntity(int entityNumber);
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
||||
TIKI
|
||||
|
||||
=============================================================
|
||||
*/
|
||||
void R_InitStaticModels(void);
|
||||
void RE_FreeModels(void);
|
||||
qhandle_t RE_SpawnEffectModel(const char* szModel, vec3_t vPos, vec3_t* axis);
|
||||
qhandle_t RE_RegisterServerModel(const char* name);
|
||||
void RE_UnregisterServerModel(qhandle_t hModel);
|
||||
orientation_t RE_TIKI_Orientation(refEntity_t* model, int tagnum);
|
||||
qboolean RE_TIKI_IsOnGround(refEntity_t* model, int tagnum, float threshold);
|
||||
float R_ModelRadius(qhandle_t handle);
|
||||
void R_ModelBounds(qhandle_t handle, vec3_t mins, vec3_t maxs);
|
||||
dtiki_t* R_Model_GetHandle(qhandle_t handle);
|
||||
|
||||
float R_GetRadius(refEntity_t* model);
|
||||
void R_GetFrame(refEntity_t* model, struct skelAnimFrame_s* newFrame);
|
||||
void RE_ForceUpdatePose(refEntity_t* model);
|
||||
void RE_SetFrameNumber(int frameNumber);
|
||||
void R_UpdatePoseInternal(refEntity_t* model);
|
||||
void RB_SkelMesh(skelSurfaceGame_t* sf);
|
||||
void RB_StaticMesh(staticSurface_t* staticSurf);
|
||||
void RB_Static_BuildDLights();
|
||||
void R_PrintInfoStaticModels();
|
||||
void R_AddSkelSurfaces(trRefEntity_t* ent);
|
||||
void R_AddStaticModelSurfaces(void);
|
||||
float R_CalcLod(const vec3_t origin, float radius);
|
||||
int R_LerpTag(orientation_t* tag, qhandle_t handle, int startFrame, int endFrame,
|
||||
float frac, const char* tagName);
|
||||
void R_PrintInfoWorldtris(void);
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
||||
UTIL
|
||||
|
||||
=============================================================
|
||||
*/
|
||||
int RE_GetShaderHeight(qhandle_t hShader);
|
||||
int RE_GetShaderWidth(qhandle_t hShader);
|
||||
void RB_StreamBegin(shader_t* shader);
|
||||
void RB_StreamEnd(void);
|
||||
void RB_StreamBeginDrawSurf(void);
|
||||
void RB_StreamEndDrawSurf(void);
|
||||
static void addTriangle(void);
|
||||
void RB_Vertex3fv(vec3_t v);
|
||||
void RB_Vertex3f(vec_t x, vec_t y, vec_t z);
|
||||
void RB_Vertex2f(vec_t x, vec_t y);
|
||||
void RB_Color4f(vec_t r, vec_t g, vec_t b, vec_t a);
|
||||
void RB_Color3f(vec_t r, vec_t g, vec_t b);
|
||||
void RB_Color3fv(vec3_t col);
|
||||
void RB_Color4bv(unsigned char* colors);
|
||||
void RB_Texcoord2f(float s, float t);
|
||||
void RB_Texcoord2fv(vec2_t st);
|
||||
void R_DrawDebugNumber(const vec3_t org, float number, float scale, float r, float g, float b, int precision);
|
||||
void R_DebugRotatedBBox(const vec3_t org, vec3_t ang, vec3_t mins, vec3_t maxs, float r, float g, float b, float alpha);
|
||||
const char* RE_GetGraphicsInfo();
|
||||
|
||||
/*
|
||||
=============================================================
|
||||
|
||||
WORLD MAP
|
||||
|
||||
=============================================================
|
||||
*/
|
||||
void R_GetInlineModelBounds(int iIndex, vec3_t vMins, vec3_t vMaxs);
|
||||
|
||||
extern int g_nStaticSurfaces;
|
||||
extern qboolean g_bInfostaticmodels;
|
||||
extern qboolean g_bInfoworldtris;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
void R_DebugCircle(const vec3_t org, float radius, float r, float g, float b, float alpha, qboolean horizontal);
|
||||
void R_DebugLine(const vec3_t start, const vec3_t end, float r, float g, float b, float alpha);
|
||||
|
||||
void RE_SetRenderTime(int t);
|
||||
qboolean R_SetMode(int mode, const glconfig_t* glConfig);
|
||||
void R_SetFullscreen(qboolean fullscreen);
|
||||
void R_SavePerformanceCounters(void);
|
||||
void R_SyncRenderThread(void);
|
|
@ -1,107 +0,0 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef struct suninfo_s {
|
||||
vec3_t color;
|
||||
vec3_t direction;
|
||||
vec3_t flaredirection;
|
||||
char szFlareName[64];
|
||||
qboolean exists;
|
||||
} suninfo_t;
|
||||
|
||||
typedef struct {
|
||||
vec3_t transformed;
|
||||
int index;
|
||||
} sphere_dlight_t;
|
||||
|
||||
typedef enum {
|
||||
LIGHT_POINT,
|
||||
LIGHT_DIRECTIONAL,
|
||||
LIGHT_SPOT,
|
||||
LIGHT_SPOT_FAST
|
||||
} lighttype_t;
|
||||
|
||||
typedef struct reallightinfo_s {
|
||||
vec3_t color;
|
||||
lighttype_t eType;
|
||||
float fIntensity;
|
||||
float fDist;
|
||||
float fSpotSlope;
|
||||
float fSpotConst;
|
||||
float fSpotScale;
|
||||
vec3_t vOrigin;
|
||||
vec3_t vDirection;
|
||||
} reallightinfo_t;
|
||||
|
||||
typedef float cube_entry_t[3][4];
|
||||
|
||||
typedef struct {
|
||||
vec3_t origin;
|
||||
vec3_t worldOrigin;
|
||||
vec3_t traceOrigin;
|
||||
float radius;
|
||||
struct mnode_s* leaves[8];
|
||||
void(*TessFunction) (unsigned char* dstColors);
|
||||
union {
|
||||
unsigned char level[4];
|
||||
int value;
|
||||
} ambient;
|
||||
int numRealLights;
|
||||
reallightinfo_t light[32];
|
||||
int bUsesCubeMap;
|
||||
float cubemap[24][3][4];
|
||||
} sphereor_t;
|
||||
|
||||
typedef struct spherel_s {
|
||||
vec3_t origin;
|
||||
vec3_t color;
|
||||
float intensity;
|
||||
struct mnode_s* leaf;
|
||||
int needs_trace;
|
||||
int spot_light;
|
||||
float spot_radiusbydistance;
|
||||
vec3_t spot_dir;
|
||||
int reference_count;
|
||||
} spherel_t;
|
||||
|
||||
typedef enum {
|
||||
SPRITE_PARALLEL,
|
||||
SPRITE_PARALLEL_ORIENTED,
|
||||
SPRITE_ORIENTED,
|
||||
SPRITE_PARALLEL_UPRIGHT
|
||||
} spriteType_t;
|
||||
|
||||
typedef struct {
|
||||
spriteType_t type;
|
||||
float scale;
|
||||
} spriteParms_t;
|
||||
|
||||
typedef struct {
|
||||
float width;
|
||||
float height;
|
||||
float origin_x;
|
||||
float origin_y;
|
||||
float scale;
|
||||
struct shader_s* shader;
|
||||
} sprite_t;
|
|
@ -1,122 +0,0 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../tr_local.h"
|
||||
|
||||
#define CIRCLE_LENGTH 25
|
||||
|
||||
/*
|
||||
================
|
||||
R_DebugCircle
|
||||
================
|
||||
*/
|
||||
void R_DebugCircle(const vec3_t org, float radius, float r, float g, float b, float alpha, qboolean horizontal) {
|
||||
int i;
|
||||
float ang;
|
||||
debugline_t* line;
|
||||
vec3_t forward, right;
|
||||
vec3_t pos, lastpos;
|
||||
|
||||
if (!ri.DebugLines || !ri.numDebugLines) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (horizontal)
|
||||
{
|
||||
VectorSet(forward, 1, 0, 0);
|
||||
VectorSet(right, 0, 1, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorCopy(tr.refdef.viewaxis[1], right);
|
||||
VectorCopy(tr.refdef.viewaxis[2], forward);
|
||||
}
|
||||
|
||||
VectorClear(pos);
|
||||
VectorClear(lastpos);
|
||||
|
||||
for (i = 0; i < CIRCLE_LENGTH; i++) {
|
||||
VectorCopy(pos, lastpos);
|
||||
|
||||
ang = (float)i * 0.0174532925199433f;
|
||||
pos[0] = (org[0] + sin(ang) * radius * forward[0]) +
|
||||
cos(ang) * radius * right[0];
|
||||
pos[1] = (org[1] + sin(ang) * radius * forward[1]) +
|
||||
cos(ang) * radius * right[1];
|
||||
pos[2] = (org[2] + sin(ang) * radius * forward[2]) +
|
||||
cos(ang) * radius * right[2];
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
if (*ri.numDebugLines >= r_numdebuglines->integer) {
|
||||
ri.Printf(PRINT_ALL, "R_DebugCircle: Exceeded MAX_DEBUG_LINES\n");
|
||||
return;
|
||||
}
|
||||
|
||||
line = &(*ri.DebugLines)[*ri.numDebugLines];
|
||||
(*ri.numDebugLines)++;
|
||||
VectorCopy(lastpos, line->start);
|
||||
VectorCopy(pos, line->end);
|
||||
VectorSet(line->color, r, g, b);
|
||||
line->alpha = alpha;
|
||||
line->width = 1.0;
|
||||
line->factor = 1;
|
||||
line->pattern = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
R_DebugLine
|
||||
================
|
||||
*/
|
||||
void R_DebugLine(const vec3_t start, const vec3_t end, float r, float g, float b, float alpha) {
|
||||
debugline_t* line;
|
||||
|
||||
if (!ri.DebugLines || !ri.numDebugLines) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (*ri.numDebugLines >= r_numdebuglines->integer) {
|
||||
ri.Printf(PRINT_ALL, "R_DebugLine: Exceeded MAX_DEBUG_LINES\n");
|
||||
}
|
||||
|
||||
line = &(*ri.DebugLines)[*ri.numDebugLines];
|
||||
(*ri.numDebugLines)++;
|
||||
VectorCopy(start, line->start);
|
||||
VectorCopy(end, line->end);
|
||||
VectorSet(line->color, r, g, b);
|
||||
line->alpha = alpha;
|
||||
line->width = 1.0;
|
||||
line->factor = 1;
|
||||
line->pattern = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
R_DrawDebugLines
|
||||
================
|
||||
*/
|
||||
void R_DrawDebugLines(void) {
|
||||
// FIXME: stub
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../tr_local.h"
|
||||
int R_MarkFragments_New(int numPoints, const vec3_t* points, const vec3_t projection,
|
||||
int maxPoints, vec3_t pointBuffer, int maxFragments, markFragment_t* fragmentBuffer, float fRadiusSquared) {
|
||||
return R_MarkFragments(numPoints, points, projection, maxPoints, pointBuffer, maxFragments, fragmentBuffer);
|
||||
}
|
||||
|
||||
int R_MarkFragmentsForInlineModel(clipHandle_t bmodel, const vec3_t angles, const vec3_t origin, int numPoints,
|
||||
const vec3_t* points, const vec3_t projection, int maxPoints, vec3_t pointBuffer,
|
||||
int maxFragments, markFragment_t* fragmentBuffer, float radiusSquared)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return 0;
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,77 +0,0 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../tr_local.h"
|
||||
|
||||
extern int r_firstSceneDrawSurf;
|
||||
|
||||
extern int r_numdlights;
|
||||
extern int r_firstSceneDlight;
|
||||
|
||||
extern int r_numentities;
|
||||
extern int r_firstSceneEntity;
|
||||
|
||||
extern int r_numpolys;
|
||||
extern int r_firstScenePoly;
|
||||
|
||||
extern int r_numpolyverts;
|
||||
|
||||
void RE_AddRefSpriteToScene(const refEntity_t* ent) {
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
R_AddTerrainMarkSurfaces
|
||||
=====================
|
||||
*/
|
||||
void R_AddTerrainMarkSurfaces(void) {
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
RE_AddTerrainMarkToScene
|
||||
=====================
|
||||
*/
|
||||
void RE_AddTerrainMarkToScene(int iTerrainIndex, qhandle_t hShader, int numVerts, const polyVert_t* verts, int renderfx) {
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
//=================================================================================
|
||||
|
||||
/*
|
||||
=====================
|
||||
RE_GetRenderEntity
|
||||
=====================
|
||||
*/
|
||||
refEntity_t* RE_GetRenderEntity(int entityNumber) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < r_numentities; i++) {
|
||||
if (backEndData->entities[i].e.entityNumber == entityNumber) {
|
||||
return &backEndData->entities[i].e;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../tr_local.h"
|
||||
|
||||
/*
|
||||
** RB_CalcColorFromConstant
|
||||
*/
|
||||
void RB_CalcColorFromConstant(unsigned char* dstColors, unsigned char* constantColor)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < tess.numVertexes; i++) {
|
||||
dstColors[i * 4] = constantColor[0];
|
||||
dstColors[i * 4 + 1] = constantColor[1];
|
||||
dstColors[i * 4 + 2] = constantColor[2];
|
||||
dstColors[i * 4 + 3] = constantColor[3];
|
||||
}
|
||||
}
|
||||
|
||||
void RB_CalcRGBFromDot(unsigned char* colors, float alphaMin, float alphaMax)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void RB_CalcRGBFromOneMinusDot(unsigned char* colors, float alphaMin, float alphaMax)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void RB_CalcAlphaFromConstant(unsigned char* dstColors, int constantAlpha)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < tess.numVertexes; i++) {
|
||||
dstColors[i * 4 + 3] = constantAlpha;
|
||||
}
|
||||
}
|
||||
|
||||
void RB_CalcAlphaFromDot(unsigned char* colors, float alphaMin, float alphaMax)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void RB_CalcAlphaFromOneMinusDot(unsigned char* colors, float alphaMin, float alphaMax)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void RB_CalcAlphaFromTexCoords(unsigned char* colors, float alphaMin, float alphaMax, int alphaMinCap, int alphaCap, float sWeight, float tWeight, float* st)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void RB_CalcRGBFromTexCoords(unsigned char* colors, float alphaMin, float alphaMax, int alphaMinCap, int alphaCap, float sWeight, float tWeight, float* st)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../tr_local.h"
|
||||
|
||||
qhandle_t RE_RefreshShaderNoMip(const char* name) {
|
||||
// FIXME: unimplemented
|
||||
// Workaround
|
||||
return RE_RegisterShaderNoMip(name);
|
||||
}
|
|
@ -1,129 +0,0 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// tr_sphere_shade.cpp -- sphere shade
|
||||
|
||||
#include "../tr_local.h"
|
||||
|
||||
vec3_t spheredef[6];
|
||||
suninfo_t s_sun;
|
||||
static vec3_t ambientlight;
|
||||
static qboolean bEntityOverbright;
|
||||
static int iEntityLightingMax;
|
||||
static int light_reference_count = 0;
|
||||
|
||||
int compare_light_intensities(const void* p1, const void* p2)
|
||||
{
|
||||
return ((const reallightinfo_t*)p2)->fIntensity - ((const reallightinfo_t*)p1)->fIntensity;
|
||||
}
|
||||
|
||||
static void RB_OptimizeLights()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
static void RB_Light_CubeMap(const color4ub_t colors)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void RB_Light_Real(unsigned char* colors)
|
||||
{
|
||||
int i, j;
|
||||
float* normal;
|
||||
float* xyz;
|
||||
unsigned char* color;
|
||||
vec3_t v;
|
||||
vec3_t colorout;
|
||||
float fDot;
|
||||
reallightinfo_t* pLight;
|
||||
|
||||
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
static void RB_Sphere_Light_Sun()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
static qboolean RB_Sphere_CalculateSphereOrigin()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
static void RB_Sphere_DrawDebugLine(const spherel_t* thislight, float falloff, const vec3_t origin)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
static void RB_Sphere_AddSpotLight(const spherel_t* thislight)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
static void RB_Sphere_AddLight(const spherel_t* thislight)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
static void RB_Sphere_BuildStaticLights()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void RB_Sphere_BuildDLights()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void RB_Sphere_SetupEntity()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void RB_Grid_SetupEntity()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void RB_Grid_SetupStaticModel()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void RB_Light_Fullbright(unsigned char* colors)
|
||||
{
|
||||
memset((void*)colors, 0xFF, tess.numVertexes);
|
||||
}
|
||||
|
||||
void R_Sphere_InitLights()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
int R_GatherLightSources(const vec3_t vPos, vec3_t* pvLightPos, vec3_t* pvLightIntensity, int iMaxLights)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
return 0;
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2010 su44
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
// tr_sprite.c - MoHAA sprite system
|
||||
|
||||
#include "../tr_local.h"
|
||||
|
||||
/*
|
||||
=====================
|
||||
SPR_RegisterSprite
|
||||
=====================
|
||||
*/
|
||||
sprite_t *SPR_RegisterSprite(const char *name)
|
||||
{
|
||||
image_t *spriteImage;
|
||||
shader_t *shader;
|
||||
sprite_t *spr;
|
||||
char shadername[256];
|
||||
COM_StripExtension(name,shadername,sizeof(shadername));
|
||||
shader = R_FindShader(shadername,-1,qfalse,qfalse,qfalse,qfalse);
|
||||
if(shader) {
|
||||
spriteImage = 0;
|
||||
if(shader->stages[0])
|
||||
spriteImage = shader->stages[0]->bundle[0].image[0];
|
||||
if ( !spriteImage ) {
|
||||
ri.Printf(1, "Could not find image for sprite in shader %s\n", name);
|
||||
return 0;
|
||||
}
|
||||
spr = ri.Hunk_Alloc(sizeof(sprite_t), h_dontcare);
|
||||
spr->height = spriteImage->height;
|
||||
spr->width = spriteImage->width;
|
||||
spr->origin_x = spr->width * 0.5;
|
||||
spr->origin_y = spr->height * 0.5;
|
||||
spr->shader = shader;
|
||||
spr->scale = spr->shader->sprite.scale;
|
||||
return spr;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
RB_DrawSprite
|
||||
=====================
|
||||
*/
|
||||
void RB_DrawSprite( const refSprite_t *spr ) {
|
||||
// FIXME: stub
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// tr_swipe.cpp -- swipe rendering
|
||||
|
||||
#include "../tr_local.h"
|
||||
|
||||
void RB_DrawSwipeSurface(surfaceType_t* pswipe) {
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void RE_SwipeBegin(float thistime, float life, qhandle_t shader)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void RE_SwipePoint(vec3_t point1, vec3_t point2, float time)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
void RE_SwipeEnd()
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
|
@ -1,260 +0,0 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
// tr_util.c -- renderer utility
|
||||
|
||||
#include "../tr_local.h"
|
||||
|
||||
static const size_t colorSize = (1 << (sizeof(uint16_t) * 8)) - 1;
|
||||
static uint16_t cntColor[4];
|
||||
static float cntSt[ 2 ];
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_StreamBegin
|
||||
===============
|
||||
*/
|
||||
void RB_StreamBegin( shader_t *shader ) {
|
||||
RB_BeginSurface( shader, 0, 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_StreamEnd
|
||||
===============
|
||||
*/
|
||||
void RB_StreamEnd( void ) {
|
||||
int i;
|
||||
|
||||
if( tess.numVertexes <= 2 ) {
|
||||
RB_EndSurface();
|
||||
return;
|
||||
}
|
||||
|
||||
tess.indexes[ 0 ] = 0;
|
||||
tess.indexes[ 1 ] = 1;
|
||||
tess.indexes[ 2 ] = 2;
|
||||
|
||||
for( i = 0; i < tess.numVertexes - 2; i++ ) {
|
||||
tess.indexes[ i * 3 + 0 ] = ( i & 1 ) + i;
|
||||
tess.indexes[ i * 3 + 1 ] = i - ( ( i & 1 ) - 1 );
|
||||
tess.indexes[ i * 3 + 2 ] = i + 2;
|
||||
tess.numIndexes += 3;
|
||||
}
|
||||
|
||||
RB_EndSurface();
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_StreamBeginDrawSurf
|
||||
===============
|
||||
*/
|
||||
void RB_StreamBeginDrawSurf( void ) {
|
||||
backEnd.dsStreamVert = tess.numVertexes;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_StreamEndDrawSurf
|
||||
===============
|
||||
*/
|
||||
void RB_StreamEndDrawSurf( void ) {
|
||||
int numverts;
|
||||
int i;
|
||||
|
||||
if( tess.numVertexes - backEnd.dsStreamVert <= 2 ) {
|
||||
tess.numVertexes = backEnd.dsStreamVert;
|
||||
return;
|
||||
}
|
||||
|
||||
numverts = tess.numVertexes - backEnd.dsStreamVert - 2;
|
||||
for( i = 0; i < numverts; i++ ) {
|
||||
tess.indexes[ i + tess.numIndexes ] = ( i & 1 ) + i + backEnd.dsStreamVert;
|
||||
tess.indexes[ i + tess.numIndexes + 1 ] = i + backEnd.dsStreamVert - ( ( i & 1 ) - 1 );
|
||||
tess.indexes[ i + tess.numIndexes + 2 ] = i + backEnd.dsStreamVert + 2;
|
||||
tess.numIndexes += 3;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
addTriangle
|
||||
===============
|
||||
*/
|
||||
static void addTriangle(void) {
|
||||
tess.texCoords[tess.numVertexes][0] = cntSt[0];
|
||||
tess.texCoords[tess.numVertexes][1] = cntSt[1];
|
||||
tess.color[tess.numVertexes][0] = cntColor[0];
|
||||
tess.color[tess.numVertexes][1] = cntColor[1];
|
||||
tess.color[tess.numVertexes][2] = cntColor[2];
|
||||
tess.color[tess.numVertexes][3] = cntColor[3];
|
||||
tess.numVertexes++;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_Vertex3fv
|
||||
===============
|
||||
*/
|
||||
void RB_Vertex3fv( vec3_t v ) {
|
||||
VectorCopy( v, tess.xyz[ tess.numVertexes ] );
|
||||
addTriangle();
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_Vertex3f
|
||||
===============
|
||||
*/
|
||||
void RB_Vertex3f( vec_t x, vec_t y, vec_t z ) {
|
||||
tess.xyz[ tess.numVertexes ][ 0 ] = x;
|
||||
tess.xyz[ tess.numVertexes ][ 1 ] = y;
|
||||
tess.xyz[ tess.numVertexes ][ 2 ] = z;
|
||||
addTriangle();
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_Vertex2f
|
||||
===============
|
||||
*/
|
||||
void RB_Vertex2f( vec_t x, vec_t y ) {
|
||||
RB_Vertex3f( x, y, 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_Color4f
|
||||
===============
|
||||
*/
|
||||
void RB_Color4f( vec_t r, vec_t g, vec_t b, vec_t a ) {
|
||||
cntColor[ 0 ] = r * tr.identityLightByte;
|
||||
cntColor[ 1 ] = g * tr.identityLightByte;
|
||||
cntColor[ 2 ] = b * tr.identityLightByte;
|
||||
cntColor[ 3 ] = a * 255.0;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_Color3f
|
||||
===============
|
||||
*/
|
||||
void RB_Color3f( vec_t r, vec_t g, vec_t b ) {
|
||||
RB_Color4f( r, g, b, 1.0 );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_Color3fv
|
||||
===============
|
||||
*/
|
||||
void RB_Color3fv( vec3_t col ) {
|
||||
RB_Color3f( col[ 0 ], col[ 1 ], col[ 2 ] );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_Color4bv
|
||||
===============
|
||||
*/
|
||||
void RB_Color4bv( unsigned char *colors ) {
|
||||
cntColor[ 0 ] = colors[ 0 ];
|
||||
cntColor[ 1 ] = colors[ 1 ];
|
||||
cntColor[ 2 ] = colors[ 2 ];
|
||||
cntColor[ 3 ] = colors[ 3 ];
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_Texcoord2f
|
||||
===============
|
||||
*/
|
||||
void RB_Texcoord2f( float s, float t ) {
|
||||
cntSt[ 0 ] = s;
|
||||
cntSt[ 1 ] = t;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_Texcoord2fv
|
||||
===============
|
||||
*/
|
||||
void RB_Texcoord2fv( vec2_t st ) {
|
||||
cntSt[ 0 ] = st[ 0 ];
|
||||
cntSt[ 1 ] = st[ 1 ];
|
||||
}
|
||||
|
||||
static int Numbers[ 12 ][ 8 ];
|
||||
static float Lines[ 13 ][ 4 ];
|
||||
|
||||
/*
|
||||
===============
|
||||
R_DrawDebugNumber
|
||||
===============
|
||||
*/
|
||||
void R_DrawDebugNumber( const vec3_t org, float number, float scale, float r, float g, float b, int precision ) {
|
||||
// FIXME: unimplemented
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_DebugRotatedBBox
|
||||
===============
|
||||
*/
|
||||
void R_DebugRotatedBBox( const vec3_t org, vec3_t ang, vec3_t mins, vec3_t maxs, float r, float g, float b, float alpha ) {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RE_GetShaderWidth
|
||||
===============
|
||||
*/
|
||||
int RE_GetShaderWidth( qhandle_t hShader ) {
|
||||
shader_t *shader;
|
||||
|
||||
if( hShader ) {
|
||||
shader = R_GetShaderByHandle( hShader );
|
||||
} else {
|
||||
shader = tr.defaultShader;
|
||||
}
|
||||
|
||||
return shader->stages[ 0 ]->bundle[ 0 ].image[ 0 ]->uploadWidth;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RE_GetShaderHeight
|
||||
===============
|
||||
*/
|
||||
int RE_GetShaderHeight( qhandle_t hShader ) {
|
||||
shader_t *shader;
|
||||
|
||||
if( hShader ) {
|
||||
shader = R_GetShaderByHandle( hShader );
|
||||
}
|
||||
else {
|
||||
shader = tr.defaultShader;
|
||||
}
|
||||
|
||||
return shader->stages[ 0 ]->bundle[ 0 ].image[ 0 ]->uploadHeight;
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../tr_local.h"
|
||||
|
||||
void R_GetInlineModelBounds(int iIndex, vec3_t vMins, vec3_t vMaxs)
|
||||
{
|
||||
// FIXME: unimplemented
|
||||
}
|
|
@ -43,6 +43,42 @@ static byte *fileBase;
|
|||
int c_subdivisions;
|
||||
int c_gridVerts;
|
||||
|
||||
//
|
||||
// OPENMOHAA-specific stuff
|
||||
//=========================
|
||||
|
||||
static int map_length;
|
||||
static int nummodels;
|
||||
static int numShaders;
|
||||
static int numbrushes;
|
||||
static int numbrushsides;
|
||||
static int numFogs;
|
||||
static int numplanes;
|
||||
static int num_entities;
|
||||
static int numnodes;
|
||||
static int numleafs;
|
||||
static int numleafsurfaces;
|
||||
static int numDrawVerts;
|
||||
static int numDrawIndexes;
|
||||
static int numDrawSurfaces;
|
||||
static int numLightDefs;
|
||||
static int numLightBytes;
|
||||
static int numVisBytes;
|
||||
static int numSLights;
|
||||
static int entLightVisSize;
|
||||
static int g_iGridArraySize;
|
||||
static int g_iGridDataSize;
|
||||
static int g_iGridPaletteBytes;
|
||||
static int g_iGridOffsets;
|
||||
static int g_nStaticModelData;
|
||||
static int map_version;
|
||||
static int g_nStaticModelIndices;
|
||||
static int g_nStaticModels;
|
||||
static int g_nTerPatchIndices;
|
||||
static int g_nTerraPatches;
|
||||
|
||||
//=========================
|
||||
|
||||
//===============================================================================
|
||||
|
||||
static void HSVtoRGB( float h, float s, float v, float rgb[3] )
|
||||
|
@ -3016,3 +3052,66 @@ void RE_LoadWorldMap( const char *name ) {
|
|||
|
||||
ri.FS_FreeFile( buffer.v );
|
||||
}
|
||||
|
||||
//
|
||||
// OPENMOHAA-specific stuff
|
||||
//
|
||||
|
||||
/*
|
||||
=================
|
||||
RE_MapVersion
|
||||
|
||||
=================
|
||||
*/
|
||||
int RE_MapVersion(void)
|
||||
{
|
||||
return map_version;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
RE_PrintBSPFileSizes
|
||||
|
||||
=================
|
||||
*/
|
||||
void RE_PrintBSPFileSizes(void)
|
||||
{
|
||||
ri.Printf(PRINT_ALL, "%s: %i\n", s_worldData.name, map_length);
|
||||
ri.Printf(PRINT_ALL, "%6i models %7i\n", nummodels, 40 * nummodels);
|
||||
ri.Printf(PRINT_ALL, "%6i shaders %7i\n", numShaders, 140 * numShaders);
|
||||
ri.Printf(PRINT_ALL, "%6i brushes %7i\n", numbrushes, 12 * numbrushes);
|
||||
ri.Printf(PRINT_ALL, "%6i brushsides %7i\n", numbrushsides, 12 * numbrushsides);
|
||||
ri.Printf(PRINT_ALL, "%6i fogs %7i\n", numFogs, 72 * numFogs);
|
||||
ri.Printf(PRINT_ALL, "%6i planes %7i\n", numplanes, 16 * numplanes);
|
||||
ri.Printf(PRINT_ALL, "%6i nodes %7i\n", numnodes, 36 * numnodes);
|
||||
ri.Printf(PRINT_ALL, "%6i leafs %7i\n", numleafs, numleafs << 6);
|
||||
ri.Printf(PRINT_ALL, "%6i leafsurfaces %7i\n", numleafsurfaces, 4 * numleafsurfaces);
|
||||
ri.Printf(PRINT_ALL, "%6i drawverts %7i\n", numDrawVerts, 44 * numDrawVerts);
|
||||
ri.Printf(PRINT_ALL, "%6i drawindexes %7i\n", numDrawIndexes, 4 * numDrawIndexes);
|
||||
ri.Printf(PRINT_ALL, "%6i drawsurfaces %7i\n", numDrawSurfaces, 108 * numDrawSurfaces);
|
||||
ri.Printf(PRINT_ALL, "%6i lightdefs %7i\n", numLightDefs, 52 * numLightDefs);
|
||||
ri.Printf(PRINT_ALL, "%6i lightmaps %7i\n", numLightBytes / 49152, numLightBytes);
|
||||
ri.Printf(PRINT_ALL, " visibility %7i\n", numVisBytes);
|
||||
ri.Printf(PRINT_ALL, "%6i entitylights %7i\n", numSLights, 56 * numSLights);
|
||||
ri.Printf(PRINT_ALL, " entitylightvis %7i\n", entLightVisSize);
|
||||
ri.Printf(PRINT_ALL, " light grid palette %7i\n", g_iGridPaletteBytes);
|
||||
ri.Printf(PRINT_ALL, "%6i light grid offsets %7i\n", g_iGridOffsets, 2 * g_iGridOffsets);
|
||||
ri.Printf(PRINT_ALL, " light grid data %7i\n", g_iGridDataSize);
|
||||
ri.Printf(PRINT_ALL, "%6i terrain %7i\n", g_nTerraPatches, 388 * g_nTerraPatches);
|
||||
ri.Printf(PRINT_ALL, "%6i terrain indexes %7i\n", g_nTerPatchIndices, 2 * g_nTerPatchIndices);
|
||||
ri.Printf(PRINT_ALL, " static model data %7i\n", g_nStaticModelData);
|
||||
ri.Printf(PRINT_ALL, "%6i static models defs %7i\n", g_nStaticModels, 164 * g_nStaticModels);
|
||||
ri.Printf(PRINT_ALL, " static model indexes %7i\n", g_nStaticModelIndices);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_ClearWorld
|
||||
|
||||
Set the world to NULL to prevent anyone from accessing
|
||||
freed world data
|
||||
=================
|
||||
*/
|
||||
void R_ClearWorld(void) {
|
||||
tr.world = NULL;
|
||||
}
|
||||
|
|
|
@ -21,12 +21,34 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
*/
|
||||
#include "tr_local.h"
|
||||
|
||||
static backEndCounters_t pc_save;
|
||||
|
||||
/*
|
||||
=====================
|
||||
R_SavePerformanceCounters
|
||||
=====================
|
||||
*/
|
||||
void R_SavePerformanceCounters(void) {
|
||||
memcpy(&pc_save, &backEnd.pc, sizeof(pc_save));
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
R_PerformanceCounters
|
||||
=====================
|
||||
*/
|
||||
void R_PerformanceCounters( void ) {
|
||||
if (r_fps->integer) {
|
||||
ri.SetPerformanceCounters(
|
||||
backEnd.pc.c_totalIndexes / 3,
|
||||
backEnd.pc.c_vertexes,
|
||||
R_SumOfUsedImages(),
|
||||
pc_save.c_totalIndexes / 3,
|
||||
pc_save.c_vertexes,
|
||||
backEnd.pc.c_characterlights
|
||||
);
|
||||
}
|
||||
|
||||
if ( !r_speeds->integer ) {
|
||||
// clear the counters even if we aren't printing
|
||||
Com_Memset( &tr.pc, 0, sizeof( tr.pc ) );
|
||||
|
|
|
@ -21,7 +21,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
*/
|
||||
// tr_draw.c -- drawing
|
||||
|
||||
#include "../tr_local.h"
|
||||
#include "tr_local.h"
|
||||
|
||||
vec4_t r_colorWhite = { 1.0, 1.0, 1.0, 1.0 };
|
||||
|
||||
|
@ -40,6 +40,7 @@ void Draw_SetColor(const vec4_t rgba) {
|
|||
backEnd.color2D[1] = (byte)(rgba[1] * tr.identityLightByte);
|
||||
backEnd.color2D[2] = (byte)(rgba[2] * tr.identityLightByte);
|
||||
backEnd.color2D[3] = (byte)(rgba[3] * 255.0);
|
||||
//qglColor4ubv(backEnd.color2D);
|
||||
#else
|
||||
RE_SetColor(rgba);
|
||||
#endif
|
||||
|
@ -54,7 +55,7 @@ void Draw_StretchPic(float x, float y, float w, float h, float s1, float t1, flo
|
|||
#if 1
|
||||
shader_t* shader;
|
||||
|
||||
R_SyncRenderThread();
|
||||
R_IssuePendingRenderCommands();
|
||||
|
||||
if (hShader) {
|
||||
shader = R_GetShaderByHandle(hShader);
|
||||
|
@ -90,6 +91,58 @@ void Draw_StretchPic(float x, float y, float w, float h, float s1, float t1, flo
|
|||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Draw_StretchPic2
|
||||
================
|
||||
*/
|
||||
void Draw_StretchPic2(float x, float y, float w, float h, float s1, float t1, float s2, float t2, float sx, float sy, qhandle_t hShader) {
|
||||
shader_t* shader;
|
||||
float halfWidth, halfHeight;
|
||||
float scaledWidth1, scaledHeight1;
|
||||
float scaledWidth2, scaledHeight2;
|
||||
|
||||
R_IssuePendingRenderCommands();
|
||||
|
||||
if (hShader) {
|
||||
shader = R_GetShaderByHandle(hShader);
|
||||
}
|
||||
else {
|
||||
shader = tr.defaultShader;
|
||||
}
|
||||
|
||||
if (w <= 0) {
|
||||
w = shader->stages[0]->bundle[0].image[0]->width;
|
||||
h = shader->stages[0]->bundle[0].image[0]->height;
|
||||
}
|
||||
|
||||
halfWidth = w * 0.5f;
|
||||
halfHeight = h * 0.5f;
|
||||
scaledWidth1 = halfWidth * sy;
|
||||
scaledHeight1 = halfHeight * sx;
|
||||
scaledWidth2 = halfWidth * sx;
|
||||
scaledHeight2 = halfHeight * sy;
|
||||
|
||||
// draw the pic
|
||||
RB_Color4f(backEnd.color2D[0], backEnd.color2D[1], backEnd.color2D[2], backEnd.color2D[3]);
|
||||
RB_BeginSurface(shader, 0, 0);
|
||||
|
||||
RB_Texcoord2f(s1, t1);
|
||||
RB_Vertex3f(x + halfWidth - (scaledWidth2 + -scaledHeight2), y + halfWidth - scaledHeight1 - scaledWidth1, 0);
|
||||
|
||||
RB_Texcoord2f(t2, t1);
|
||||
RB_Vertex3f(scaledWidth2 - -scaledHeight2 + x + halfWidth, scaledWidth1 - scaledHeight1 + y + halfWidth, 0);
|
||||
|
||||
RB_Texcoord2f(s1, s2);
|
||||
RB_Vertex3f(x+ halfWidth - (scaledWidth2 + scaledHeight2), scaledHeight1 - scaledWidth1 + y + halfWidth, 0);
|
||||
|
||||
RB_Texcoord2f(t2, s2);
|
||||
RB_Vertex3f(scaledWidth2 - scaledHeight2 + x + halfWidth, scaledWidth1 + scaledHeight1 + y + halfWidth, 0);
|
||||
|
||||
RB_StreamEnd();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
Draw_TilePic
|
||||
|
@ -99,7 +152,7 @@ void Draw_TilePic(float x, float y, float w, float h, qhandle_t hShader) {
|
|||
shader_t* shader;
|
||||
float picw, pich;
|
||||
|
||||
R_SyncRenderThread();
|
||||
R_IssuePendingRenderCommands();
|
||||
|
||||
if (hShader) {
|
||||
shader = R_GetShaderByHandle(hShader);
|
||||
|
@ -145,7 +198,7 @@ void Draw_TilePicOffset(float x, float y, float w, float h, qhandle_t hShader, i
|
|||
shader_t* shader;
|
||||
float picw, pich;
|
||||
|
||||
R_SyncRenderThread();
|
||||
R_IssuePendingRenderCommands();
|
||||
|
||||
if (hShader) {
|
||||
shader = R_GetShaderByHandle(hShader);
|
||||
|
@ -191,7 +244,7 @@ void Draw_TrianglePic(const vec2_t vPoints[3], const vec2_t vTexCoords[3], qhand
|
|||
int i;
|
||||
shader_t* shader;
|
||||
|
||||
R_SyncRenderThread();
|
||||
R_IssuePendingRenderCommands();
|
||||
|
||||
if (hShader) {
|
||||
shader = R_GetShaderByHandle(hShader);
|
||||
|
@ -219,15 +272,15 @@ RE_DrawBackground_TexSubImage
|
|||
================
|
||||
*/
|
||||
void RE_DrawBackground_TexSubImage(int cols, int rows, int bgr, byte* data) {
|
||||
// FIXME: unimplemented (GL2)
|
||||
#if 0
|
||||
GLenum format;
|
||||
int w, h;
|
||||
vec4_t quadVerts[4];
|
||||
vec2_t texCoords[4];
|
||||
int w, h;
|
||||
|
||||
w = glConfig.vidWidth;
|
||||
h = glConfig.vidHeight;
|
||||
|
||||
R_SyncRenderThread();
|
||||
R_IssuePendingRenderCommands();
|
||||
qglFinish();
|
||||
|
||||
if (bgr) {
|
||||
|
@ -237,17 +290,17 @@ void RE_DrawBackground_TexSubImage(int cols, int rows, int bgr, byte* data) {
|
|||
format = GL_RGB;
|
||||
}
|
||||
|
||||
GL_BindToTMU(tr.scratchImage[0], TB_COLORMAP);
|
||||
GL_Bind(tr.scratchImage);
|
||||
|
||||
if (cols == tr.scratchImage[0]->width && rows == tr.scratchImage[0]->height && format == tr.scratchImage[0]->internalFormat)
|
||||
if (cols == tr.scratchImage->width && rows == tr.scratchImage->height && format == tr.scratchImage->internalFormat)
|
||||
{
|
||||
qglTexSubImage2D(3553, 0, 0, 0, cols, rows, format, 5121, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
tr.scratchImage[0]->uploadWidth = cols;
|
||||
tr.scratchImage[0]->uploadHeight = rows;
|
||||
tr.scratchImage[0]->internalFormat = format;
|
||||
tr.scratchImage->uploadWidth = cols;
|
||||
tr.scratchImage->uploadHeight = rows;
|
||||
tr.scratchImage->internalFormat = format;
|
||||
qglTexImage2D(GL_TEXTURE_2D, 0, 3, cols, rows, 0, format, 5121, data);
|
||||
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 9729.0);
|
||||
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, 9729.0);
|
||||
|
@ -257,22 +310,22 @@ void RE_DrawBackground_TexSubImage(int cols, int rows, int bgr, byte* data) {
|
|||
qglDisable(GL_DEPTH_TEST);
|
||||
qglEnable(GL_TEXTURE_2D);
|
||||
|
||||
VectorSet4(quadVerts[0], 0.0f, 0.0f, 0.0f, 1.0f);
|
||||
VectorSet4(quadVerts[1], w, 0.0f, 0.0f, 1.0f);
|
||||
VectorSet4(quadVerts[2], w, h, 0.0f, 1.0f);
|
||||
VectorSet4(quadVerts[3], 0.0f, h, 0.0f, 1.0f);
|
||||
qglBegin(GL_QUADS);
|
||||
|
||||
VectorSet2(texCoords[0], 0.5f / cols, (rows - 0.5f) / rows);
|
||||
VectorSet2(texCoords[1], (cols - 0.5f) / cols, (rows - 0.5f) / rows);
|
||||
VectorSet2(texCoords[2], (cols - 0.5f) / cols, 0.5f / rows);
|
||||
VectorSet2(texCoords[3], 0.5f / cols, 0.5f / rows);
|
||||
qglTexCoord2f(0.5 / (GLfloat)cols, ((GLfloat)rows - 0.5) / rows);
|
||||
qglVertex2f(0, 0);
|
||||
|
||||
GLSL_BindProgram(&tr.textureColorShader);
|
||||
qglTexCoord2f(((GLfloat)cols - 0.5) / cols, ((GLfloat)rows - 0.5) / rows);
|
||||
qglVertex2f(w, 0);
|
||||
|
||||
GLSL_SetUniformMat4(&tr.textureColorShader, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
GLSL_SetUniformVec4(&tr.textureColorShader, UNIFORM_COLOR, colorWhite);
|
||||
qglTexCoord2f(((GLfloat)cols - 0.5) / cols, 0.5 / (GLfloat)rows);
|
||||
qglVertex2f(w, h);
|
||||
|
||||
RB_InstantQuad2(quadVerts, texCoords);
|
||||
qglTexCoord2f(0.5 / (GLfloat)rows, 0.5 / (GLfloat)rows);
|
||||
qglVertex2f(0, h);
|
||||
|
||||
qglEnd();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -281,7 +334,25 @@ RE_DrawBackground_DrawPixels
|
|||
================
|
||||
*/
|
||||
void RE_DrawBackground_DrawPixels(int cols, int rows, int bgr, byte* data) {
|
||||
// FIXME: stub
|
||||
// FIXME: unimplemented (GL2)
|
||||
#if 0
|
||||
R_IssuePendingRenderCommands();
|
||||
|
||||
GL_State(0);
|
||||
qglDisable(GL_TEXTURE_2D);
|
||||
|
||||
qglPixelZoom(glConfig.vidWidth / rows, glConfig.vidHeight / cols);
|
||||
|
||||
if (bgr) {
|
||||
qglDrawPixels(cols, rows, GL_BGR, GL_UNSIGNED_BYTE, data);
|
||||
} else {
|
||||
qglDrawPixels(cols, rows, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||
}
|
||||
|
||||
qglPixelZoom(1.0, 1.0);
|
||||
|
||||
qglEnable(GL_TEXTURE_2D);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -290,36 +361,25 @@ AddBox
|
|||
================
|
||||
*/
|
||||
void AddBox(float x, float y, float w, float h) {
|
||||
R_SyncRenderThread();
|
||||
// FIXME: unimplemented (GL2)
|
||||
#if 0
|
||||
R_IssuePendingRenderCommands();
|
||||
|
||||
qglColor4ubv(backEnd.color2D);
|
||||
qglDisable(GL_TEXTURE_2D);
|
||||
GL_State(GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE);
|
||||
|
||||
{
|
||||
shaderProgram_t* sp = &tr.textureColorShader;
|
||||
vec4_t color = { backEnd.color2D[0] / 255.0f, backEnd.color2D[1] / 255.0f, backEnd.color2D[2] / 255.0f, backEnd.color2D[3] / 255.0f };
|
||||
vec4_t quadVerts[4];
|
||||
vec2_t texCoords[4];
|
||||
qglBegin(GL_QUADS);
|
||||
|
||||
VectorSet4(quadVerts[0], x, y, 0.0f, 1.0f);
|
||||
VectorSet4(quadVerts[1], x + w, y, 0.0f, 1.0f);
|
||||
VectorSet4(quadVerts[2], x + w, y + h, 0.0f, 1.0f);
|
||||
VectorSet4(quadVerts[3], x, y + h, 0.0f, 1.0f);
|
||||
qglVertex2f(x, y);
|
||||
qglVertex2f(x + w, y);
|
||||
qglVertex2f(x + w, y + h);
|
||||
qglVertex2f(x, y + h);
|
||||
|
||||
VectorSet2(texCoords[0], 0.0f, 0.0f);
|
||||
VectorSet2(texCoords[1], 1.0f, 0.0f);
|
||||
VectorSet2(texCoords[2], 1.0f, 1.0f);
|
||||
VectorSet2(texCoords[3], 0.0f, 1.0f);
|
||||
|
||||
GLSL_BindProgram(sp);
|
||||
|
||||
GLSL_SetUniformMat4(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
GLSL_SetUniformVec4(sp, UNIFORM_COLOR, color);
|
||||
|
||||
RB_InstantQuad2(quadVerts, texCoords);
|
||||
}
|
||||
qglEnd();
|
||||
|
||||
qglEnable(GL_TEXTURE_2D);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -328,36 +388,25 @@ DrawBox
|
|||
================
|
||||
*/
|
||||
void DrawBox(float x, float y, float w, float h) {
|
||||
R_SyncRenderThread();
|
||||
// FIXME: unimplemented (GL2)
|
||||
#if 0
|
||||
R_IssuePendingRenderCommands();
|
||||
|
||||
qglColor4ubv(backEnd.color2D);
|
||||
qglDisable(GL_TEXTURE_2D);
|
||||
GL_State(GLS_DEPTHTEST_DISABLE | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_SRCBLEND_SRC_ALPHA);
|
||||
|
||||
{
|
||||
shaderProgram_t* sp = &tr.textureColorShader;
|
||||
vec4_t color = { backEnd.color2D[0] / 255.0f, backEnd.color2D[1] / 255.0f, backEnd.color2D[2] / 255.0f, backEnd.color2D[3] / 255.0f };
|
||||
vec4_t quadVerts[4];
|
||||
vec2_t texCoords[4];
|
||||
qglBegin(GL_QUADS);
|
||||
|
||||
VectorSet4(quadVerts[0], x, y, 0.0f, 1.0f);
|
||||
VectorSet4(quadVerts[1], x + w, y, 0.0f, 1.0f);
|
||||
VectorSet4(quadVerts[2], x + w, y + h, 0.0f, 1.0f);
|
||||
VectorSet4(quadVerts[3], x, y + h, 0.0f, 1.0f);
|
||||
qglVertex2f(x, y);
|
||||
qglVertex2f(x + w, y);
|
||||
qglVertex2f(x + w, y + h);
|
||||
qglVertex2f(x, y + h);
|
||||
|
||||
VectorSet2(texCoords[0], 0.0f, 0.0f);
|
||||
VectorSet2(texCoords[1], 1.0f, 0.0f);
|
||||
VectorSet2(texCoords[2], 1.0f, 1.0f);
|
||||
VectorSet2(texCoords[3], 0.0f, 1.0f);
|
||||
|
||||
GLSL_BindProgram(sp);
|
||||
|
||||
GLSL_SetUniformMat4(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
|
||||
GLSL_SetUniformVec4(sp, UNIFORM_COLOR, color);
|
||||
|
||||
RB_InstantQuad2(quadVerts, texCoords);
|
||||
}
|
||||
qglEnd();
|
||||
|
||||
qglEnable(GL_TEXTURE_2D);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -366,19 +415,19 @@ DrawLineLoop
|
|||
================
|
||||
*/
|
||||
void DrawLineLoop(const vec2_t* points, int count, int stipple_factor, int stipple_mask) {
|
||||
// FIXME: unimplemented (GL2)
|
||||
#if 0
|
||||
int i;
|
||||
|
||||
R_SyncRenderThread();
|
||||
R_IssuePendingRenderCommands();
|
||||
|
||||
qglDisable(GL_TEXTURE_2D);
|
||||
|
||||
if (stipple_factor) {
|
||||
qglEnable(GL_LINE_STIPPLE);
|
||||
glLineStipple(stipple_factor, stipple_mask);
|
||||
qglLineStipple(stipple_factor, stipple_mask);
|
||||
}
|
||||
|
||||
// FIXME: unimplemented
|
||||
/*
|
||||
qglBegin(GL_LINE_LOOP);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
|
@ -386,13 +435,13 @@ void DrawLineLoop(const vec2_t* points, int count, int stipple_factor, int stipp
|
|||
}
|
||||
|
||||
qglEnd();
|
||||
*/
|
||||
|
||||
qglEnable(GL_TEXTURE_2D);
|
||||
|
||||
if (stipple_factor) {
|
||||
qglDisable(GL_LINE_STIPPLE);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -401,32 +450,36 @@ Set2DWindow
|
|||
================
|
||||
*/
|
||||
void Set2DWindow(int x, int y, int w, int h, float left, float right, float bottom, float top, float n, float f) {
|
||||
mat4_t matrix;
|
||||
|
||||
R_SyncRenderThread();
|
||||
// FIXME: unimplemented (GL2)
|
||||
#if 0
|
||||
R_IssuePendingRenderCommands();
|
||||
qglViewport(x, y, w, h);
|
||||
qglScissor(x, y, w, h);
|
||||
qglMatrixMode(GL_PROJECTION);
|
||||
qglLoadIdentity();
|
||||
qglOrtho(left, right, bottom, top, n, f);
|
||||
qglMatrixMode(GL_MODELVIEW);
|
||||
|
||||
Mat4Ortho(left, right, bottom, top, n, f, matrix);
|
||||
GL_SetProjectionMatrix(matrix);
|
||||
Mat4Identity(matrix);
|
||||
GL_SetModelviewMatrix(matrix);
|
||||
|
||||
qglLoadIdentity();
|
||||
GL_State(GLS_DEPTHTEST_DISABLE | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_SRCBLEND_SRC_ALPHA);
|
||||
qglEnable(GL_BLEND);
|
||||
qglDisable(GL_CULL_FACE);
|
||||
qglDisable(GL_CLIP_PLANE0);
|
||||
// Make sure to disable the fog to avoid messing up with the UI
|
||||
qglDisable(GL_FOG);
|
||||
qglFogf(GL_FOG_START, 0);
|
||||
|
||||
//if (r_reset_tc_array->integer) {
|
||||
// qglDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
//}
|
||||
if (r_reset_tc_array->integer) {
|
||||
qglDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
|
||||
if (!backEnd.projection2D)
|
||||
if (!backEnd.in2D)
|
||||
{
|
||||
backEnd.refdef.time = ri.Milliseconds();
|
||||
backEnd.projection2D = qtrue;
|
||||
backEnd.in2D = qtrue;
|
||||
backEnd.refdef.floatTime = backEnd.refdef.time / 1000.0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -435,6 +488,9 @@ RE_Scissor
|
|||
================
|
||||
*/
|
||||
void RE_Scissor(int x, int y, int width, int height) {
|
||||
// FIXME: unimplemented (GL2)
|
||||
#if 0
|
||||
qglEnable(GL_SCISSOR_TEST);
|
||||
qglScissor(x, y, width, height);
|
||||
#endif
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
Copyright (C) 2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
|
@ -22,16 +22,41 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
// tr_font.cpp -- font rendering
|
||||
|
||||
#include "../tr_local.h"
|
||||
#include "tr_local.h"
|
||||
|
||||
#define MAX_LOADED_FONTS 255
|
||||
|
||||
static fontheader_sgl_t s_loadedFonts_sgl[MAX_LOADED_FONTS];
|
||||
static int s_numLoadedFonts_sgl = 0;
|
||||
static fontheader_t s_loadedFonts[MAX_LOADED_FONTS];
|
||||
static int s_numLoadedFonts = 0;
|
||||
static float s_fontHeightScale = 1.0;
|
||||
static float s_fontGeneralScale = 1.0;
|
||||
static float s_fontZ = 0.0;
|
||||
|
||||
void R_ShutdownFont() {
|
||||
int i;
|
||||
fontheader_t *header;
|
||||
fontheader_sgl_t *header_sgl;
|
||||
|
||||
for (i = 0; i < s_numLoadedFonts; i++)
|
||||
{
|
||||
header = &s_loadedFonts[i];
|
||||
if (header->charTable) {
|
||||
ri.Free(header->charTable);
|
||||
header->charTable = NULL;
|
||||
}
|
||||
|
||||
memset(header, 0, sizeof(*header));
|
||||
}
|
||||
|
||||
for (i = 0; i < s_numLoadedFonts_sgl; i++)
|
||||
{
|
||||
header_sgl = &s_loadedFonts_sgl[i];
|
||||
memset(header_sgl, 0, sizeof(*header_sgl));
|
||||
}
|
||||
}
|
||||
|
||||
void R_SetFontHeightScale(float scale)
|
||||
{
|
||||
s_fontHeightScale = scale;
|
||||
|
@ -47,20 +72,75 @@ void R_SetFontZ(float zed)
|
|||
s_fontZ = zed;
|
||||
}
|
||||
|
||||
fontheader_t* R_LoadFont(const char* name)
|
||||
static int CodeSearch(const fontheader_t* font, unsigned short uch) {
|
||||
int mid;
|
||||
int l, r;
|
||||
|
||||
r = font->charTableLength;
|
||||
l = 0;
|
||||
while (l < r) {
|
||||
mid = (l + r) / 2;
|
||||
|
||||
if (font->charTable[mid].cp > uch) {
|
||||
r = (l + r) / 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (uch == font->charTable[mid].cp) {
|
||||
return (l + r) / 2;
|
||||
}
|
||||
|
||||
l = mid + 1;
|
||||
}
|
||||
|
||||
if (uch != font->charTable[l].cp) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
static qboolean DBCSIsLeadByte(const fontheader_t* font, unsigned short uch) {
|
||||
// Byte ranges found in Wikipedia articles with relevant search strings in each case
|
||||
switch (font->codePage) {
|
||||
case 932:
|
||||
// Shift_jis
|
||||
return ((uch >= 0x81) && (uch <= 0x9F)) ||
|
||||
((uch >= 0xE0) && (uch <= 0xFC));
|
||||
// Lead bytes F0 to FC may be a Microsoft addition.
|
||||
case 936:
|
||||
// GBK
|
||||
return (uch >= 0x81) && (uch <= 0xFE);
|
||||
case 949:
|
||||
// Korean Wansung KS C-5601-1987
|
||||
return (uch >= 0x81) && (uch <= 0xFE);
|
||||
case 950:
|
||||
// Big5
|
||||
return (uch >= 0x81) && (uch <= 0xFE);
|
||||
case 1361:
|
||||
// Korean Johab KS C-5601-1992
|
||||
return
|
||||
((uch >= 0x84) && (uch <= 0xD3)) ||
|
||||
((uch >= 0xD8) && (uch <= 0xDE)) ||
|
||||
((uch >= 0xE0) && (uch <= 0xF9));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
fontheader_sgl_t* R_LoadFont_sgl(const char* name)
|
||||
{
|
||||
int i;
|
||||
char* theFile;
|
||||
fontheader_t* header;
|
||||
fontheader_sgl_t* header;
|
||||
char* ref;
|
||||
const char* token;
|
||||
qboolean error;
|
||||
|
||||
error = qfalse;
|
||||
|
||||
for (i = 0; i < s_numLoadedFonts; i++)
|
||||
for (i = 0; i < s_numLoadedFonts_sgl; i++)
|
||||
{
|
||||
header = &s_loadedFonts[i];
|
||||
header = &s_loadedFonts_sgl[i];
|
||||
if (!Q_stricmp(name, header->name)) {
|
||||
return header;
|
||||
}
|
||||
|
@ -72,14 +152,13 @@ fontheader_t* R_LoadFont(const char* name)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
va("fonts/%s.RitualFont", name);
|
||||
if (ri.FS_ReadFile(va("fonts/%s.RitualFont", name), (void**)&theFile) == -1)
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "LoadFont: Couldn't load font %s\n", name);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
header = &s_loadedFonts[s_numLoadedFonts];
|
||||
header = &s_loadedFonts_sgl[s_numLoadedFonts_sgl];
|
||||
header->height = 0.0;
|
||||
header->aspectRatio = 0.0;
|
||||
Q_strncpyz(header->name, name, sizeof(header->name));
|
||||
|
@ -152,7 +231,7 @@ fontheader_t* R_LoadFont(const char* name)
|
|||
header->locations[i].pos[1] = atof(COM_Parse(&ref)) * header->aspectRatio / 256.0;
|
||||
header->locations[i].size[0] = atof(COM_Parse(&ref)) / 256.0;
|
||||
header->locations[i].size[1] = atof(COM_Parse(&ref)) * header->aspectRatio / 256.0;
|
||||
|
||||
|
||||
token = COM_Parse(&ref);
|
||||
if (Q_stricmp(token, "}"))
|
||||
{
|
||||
|
@ -211,14 +290,228 @@ fontheader_t* R_LoadFont(const char* name)
|
|||
}
|
||||
else
|
||||
{
|
||||
s_numLoadedFonts++;
|
||||
s_numLoadedFonts_sgl++;
|
||||
return header;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void R_LoadFontShader(fontheader_t* font)
|
||||
fontheader_t* R_LoadFont(const char* name) {
|
||||
int i;
|
||||
char* theFile;
|
||||
fontheader_t* header;
|
||||
char* ref;
|
||||
const char* token;
|
||||
qboolean error;
|
||||
char* pRitFontNames[32];
|
||||
|
||||
error = qfalse;
|
||||
|
||||
for (i = 0; i < s_numLoadedFonts; i++)
|
||||
{
|
||||
header = &s_loadedFonts[i];
|
||||
if (!Q_stricmp(name, header->name)) {
|
||||
return header;
|
||||
}
|
||||
}
|
||||
|
||||
if (s_numLoadedFonts >= MAX_LOADED_FONTS)
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "LoadFont: Too many fonts loaded! Couldn't load %s\n", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ri.FS_ReadFile(va("fonts/%s.RitualFont", name), (void**)&theFile) == -1)
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "LoadFont: Couldn't load font %s\n", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(pRitFontNames, 0, sizeof(pRitFontNames));
|
||||
ref = theFile;
|
||||
header = &s_loadedFonts[s_numLoadedFonts];
|
||||
|
||||
token = COM_Parse(&ref);
|
||||
if (Q_stricmp(token, "RitFontList"))
|
||||
{
|
||||
if (Q_stricmp(token, "RitFont"))
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "LoadFont: Not actual font %s\n", name);
|
||||
return NULL;
|
||||
}
|
||||
header->numPages = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (ref && !error)
|
||||
{
|
||||
token = COM_Parse(&ref);
|
||||
if (!Q_stricmp(token, "CodePage"))
|
||||
{
|
||||
header->codePage = atoi(COM_Parse(&ref));
|
||||
}
|
||||
else if (!Q_stricmp(token, "Chars"))
|
||||
{
|
||||
header->charTableLength = atoi(COM_Parse(&ref));
|
||||
header->charTable = (fontchartable_t*)ri.Malloc(header->charTableLength * sizeof(fontchartable_t));
|
||||
if (!header->charTable)
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "LoadFont: Couldn't alloc mem %s\n", name);
|
||||
error = qtrue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (!Q_stricmp(token, "Pages"))
|
||||
{
|
||||
header->numPages = atoi(COM_Parse(&ref));
|
||||
}
|
||||
else if (!Q_stricmp(token, "RitFontName"))
|
||||
{
|
||||
token = COM_Parse(&ref);
|
||||
if (Q_stricmp(token, "{"))
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "LoadFont: Bad Format %s\n", name);
|
||||
error = qtrue;
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < header->numPages; i++)
|
||||
{
|
||||
token = COM_Parse(&ref);
|
||||
if (!token[0])
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "LoadFont: Bad Token %s\n", name);
|
||||
error = qtrue;
|
||||
break;
|
||||
}
|
||||
|
||||
pRitFontNames[i] = (char*)ri.Malloc(strlen(token) + 1);
|
||||
if (!pRitFontNames[i])
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "LoadFont: Couldn't alloc mem %s\n", name);
|
||||
error = qtrue;
|
||||
break;
|
||||
}
|
||||
|
||||
strcpy(pRitFontNames[i], token);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
break;
|
||||
}
|
||||
|
||||
token = COM_Parse(&ref);
|
||||
if (Q_stricmp(token, "}"))
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "LoadFont: Bad Format %s\n", name);
|
||||
error = qtrue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (!Q_stricmp(token, "CharTable"))
|
||||
{
|
||||
token = COM_Parse(&ref);
|
||||
if (Q_stricmp(token, "{"))
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "LoadFont: Bad Format %s\n", name);
|
||||
error = qtrue;
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < header->charTableLength; i++) {
|
||||
token = COM_Parse(&ref);
|
||||
if (Q_stricmp(token, "{"))
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "LoadFont: Bad Token %s\n", name);
|
||||
error = qtrue;
|
||||
break;
|
||||
}
|
||||
|
||||
header->charTable[i].cp = atoi(COM_Parse(&ref));
|
||||
header->charTable[i].index = atoi(COM_Parse(&ref));
|
||||
header->charTable[i].loc = atoi(COM_Parse(&ref));
|
||||
atoi(COM_Parse(&ref));
|
||||
|
||||
token = COM_Parse(&ref);
|
||||
if (Q_stricmp(token, "}"))
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "LoadFont: Bad Format %s\n", name);
|
||||
error = qtrue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (error) {
|
||||
break;
|
||||
}
|
||||
|
||||
token = COM_Parse(&ref);
|
||||
if (Q_stricmp(token, "}"))
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "LoadFont: Bad Format %s\n", name);
|
||||
error = qtrue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "LoadFont: Bad Token %s\n", name);
|
||||
error = qtrue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ri.FS_FreeFile(theFile);
|
||||
|
||||
if (!header->numPages)
|
||||
{
|
||||
header->charTableLength = 0;
|
||||
header->charTable = NULL;
|
||||
header->sgl[0] = R_LoadFont_sgl(name);
|
||||
if (!header->sgl[0])
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "LoadFont: failed %s\n", name);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < header->numPages; i++)
|
||||
{
|
||||
header->sgl[i] = R_LoadFont_sgl(pRitFontNames[i]);
|
||||
if (!header->sgl[i])
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "LoadFont: failed %s(%s)\n", pRitFontNames[i], name);
|
||||
error = qtrue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Free all allocated strings
|
||||
for (i = 0; i < header->numPages; i++) {
|
||||
ri.Free(pRitFontNames[i]);
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
if (header->charTable) {
|
||||
ri.Free(header->charTable);
|
||||
}
|
||||
|
||||
header->numPages = 0;
|
||||
header->charTableLength = 0;
|
||||
header->charTable = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(header->name, name);
|
||||
s_numLoadedFonts++;
|
||||
return header;
|
||||
}
|
||||
|
||||
void R_LoadFontShader(fontheader_sgl_t* font)
|
||||
{
|
||||
int i;
|
||||
int save;
|
||||
|
@ -255,7 +548,7 @@ void R_LoadFontShader(fontheader_t* font)
|
|||
}
|
||||
}
|
||||
|
||||
void R_DrawString(fontheader_t* font, const char* text, float x, float y, int maxlen, qboolean bVirtualScreen) {
|
||||
void R_DrawString_sgl(fontheader_sgl_t* font, const char* text, float x, float y, int maxlen, const float *pvVirtualScreen) {
|
||||
float charHeight;
|
||||
float startx, starty;
|
||||
int i;
|
||||
|
@ -264,14 +557,25 @@ void R_DrawString(fontheader_t* font, const char* text, float x, float y, int ma
|
|||
i = 0;
|
||||
startx = x;
|
||||
starty = y;
|
||||
fWidthScale = (double)glConfig.vidWidth / 640.0;
|
||||
fHeightScale = (double)glConfig.vidHeight / 480.0;
|
||||
if (pvVirtualScreen) {
|
||||
if (pvVirtualScreen[0]) {
|
||||
fWidthScale = pvVirtualScreen[0];
|
||||
} else {
|
||||
fWidthScale = (double)glConfig.vidWidth / 640.0;
|
||||
}
|
||||
|
||||
if (pvVirtualScreen[1]) {
|
||||
fHeightScale = pvVirtualScreen[1];
|
||||
} else {
|
||||
fHeightScale = (double)glConfig.vidHeight / 480.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!font) {
|
||||
return;
|
||||
}
|
||||
|
||||
R_SyncRenderThread();
|
||||
R_IssuePendingRenderCommands();
|
||||
|
||||
if (font->trhandle != r_sequencenumber) {
|
||||
font->shader = NULL;
|
||||
|
@ -300,9 +604,8 @@ void R_DrawString(fontheader_t* font, const char* text, float x, float y, int ma
|
|||
case '\t':
|
||||
indirected = font->indirection[32];
|
||||
if (indirected == -1) {
|
||||
Com_DPrintf("R_DrawString: no space-character in font!\n");
|
||||
}
|
||||
else {
|
||||
ri.Printf(PRINT_DEVELOPER, "R_DrawString: no space-character in font!\n");
|
||||
} else {
|
||||
x = s_fontGeneralScale * font->locations[indirected].size[0] * 256.0 * 3.0 + x;
|
||||
}
|
||||
break;
|
||||
|
@ -321,19 +624,17 @@ void R_DrawString(fontheader_t* font, const char* text, float x, float y, int ma
|
|||
indirected = font->indirection[c];
|
||||
if (indirected == -1)
|
||||
{
|
||||
Com_DPrintf("R_DrawString: no 0x%02x-character in font!\n", c);
|
||||
ri.Printf(PRINT_DEVELOPER, "R_DrawString: no 0x%02x-character in font!\n", c);
|
||||
indirected = font->indirection['?'];
|
||||
if (indirected == -1) {
|
||||
Com_DPrintf("R_DrawString: no '?' character in font!\n");
|
||||
ri.Printf(PRINT_DEVELOPER, "R_DrawString: no '?' character in font!\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
// set the indirection for the next time
|
||||
font->indirection[c] = indirected;
|
||||
font->indirection[c] = indirected;
|
||||
}
|
||||
|
||||
if (tess.numVertexes + 4 >= SHADER_MAX_VERTEXES || tess.numIndexes + 6 >= SHADER_MAX_INDEXES) {
|
||||
RB_CheckOverflow(4, 6);
|
||||
}
|
||||
RB_CHECKOVERFLOW(4, 6);
|
||||
|
||||
loc = &font->locations[indirected];
|
||||
|
||||
|
@ -369,7 +670,7 @@ void R_DrawString(fontheader_t* font, const char* text, float x, float y, int ma
|
|||
tess.indexes[tess.numIndexes + 4] = tess.numVertexes + 3;
|
||||
tess.indexes[tess.numIndexes + 5] = tess.numVertexes + 2;
|
||||
|
||||
if (bVirtualScreen)
|
||||
if (pvVirtualScreen)
|
||||
{
|
||||
// scale the string properly if virtual screen
|
||||
tess.xyz[tess.numVertexes][0] *= fWidthScale;
|
||||
|
@ -392,7 +693,96 @@ void R_DrawString(fontheader_t* font, const char* text, float x, float y, int ma
|
|||
RB_EndSurface();
|
||||
}
|
||||
|
||||
void R_DrawFloatingString(fontheader_t* font, const char* text, const vec3_t org, const vec4_t color, float scale, int maxlen) {
|
||||
void R_DrawString(fontheader_t* font, const char* text, float x, float y, int maxlen, const float *pvVirtualScreen) {
|
||||
int i;
|
||||
int code;
|
||||
unsigned short uch;
|
||||
char buffer[512];
|
||||
size_t buflen;
|
||||
int cursgl;
|
||||
float curX, curY;
|
||||
float curHeight;
|
||||
|
||||
if (!font->numPages) {
|
||||
if (font->sgl[0]) {
|
||||
R_DrawString_sgl(font->sgl[0], text, x, y, maxlen, pvVirtualScreen);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (maxlen < 0) {
|
||||
maxlen = strlen(text);
|
||||
}
|
||||
|
||||
curX = x;
|
||||
curY = y;
|
||||
curHeight = 0.f;
|
||||
cursgl = -1;
|
||||
buflen = 0;
|
||||
|
||||
i = 0;
|
||||
while(i < maxlen) {
|
||||
fontchartable_t* ct;
|
||||
|
||||
uch = text[i];
|
||||
i++;
|
||||
|
||||
if (DBCSIsLeadByte(font, uch)) {
|
||||
uch = (uch << 8) | text[i];
|
||||
i++;
|
||||
}
|
||||
|
||||
if (!uch) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (uch == '\n' || uch == '\r') {
|
||||
buffer[buflen] = 0;
|
||||
R_DrawString_sgl(font->sgl[cursgl], buffer, curX, curY, maxlen, pvVirtualScreen);
|
||||
|
||||
curX = x;
|
||||
curHeight = 0.f;
|
||||
buflen = 0;
|
||||
if (uch == '\n') {
|
||||
curY += font->sgl[0]->height * s_fontGeneralScale * s_fontHeightScale;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
code = CodeSearch(font, uch);
|
||||
if (code < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cursgl == -1) {
|
||||
cursgl = font->charTable[code].index;
|
||||
}
|
||||
|
||||
ct = &font->charTable[code];
|
||||
if (cursgl != ct->index || buflen >= ARRAY_LEN(buffer) - 2) {
|
||||
buffer[buflen] = 0;
|
||||
R_DrawString_sgl(font->sgl[cursgl], buffer, curX, curY, maxlen, pvVirtualScreen);
|
||||
|
||||
curX += curHeight;
|
||||
curHeight = 0.f;
|
||||
buflen = 0;
|
||||
ct = &font->charTable[code];
|
||||
cursgl = ct->index;
|
||||
}
|
||||
|
||||
buffer[buflen++] = ct->loc;
|
||||
curHeight += font->sgl[cursgl]->locations[ct->loc].size[0] * 256.0f;
|
||||
}
|
||||
|
||||
if (buflen)
|
||||
{
|
||||
buffer[buflen] = 0;
|
||||
R_DrawString_sgl(font->sgl[cursgl], buffer, curX, y, buflen, pvVirtualScreen);
|
||||
}
|
||||
}
|
||||
|
||||
void R_DrawFloatingString_sgl(fontheader_sgl_t* font, const char* text, const vec3_t org, const vec4_t color, float scale, int maxlen) {
|
||||
shader_t* fontshader;
|
||||
qhandle_t fsh;
|
||||
float charWidth, charHeight;
|
||||
|
@ -404,8 +794,7 @@ void R_DrawFloatingString(fontheader_t* font, const char* text, const vec3_t org
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
R_SyncRenderThread();
|
||||
R_IssuePendingRenderCommands();
|
||||
if (font->trhandle != r_sequencenumber) {
|
||||
font->shader = NULL;
|
||||
}
|
||||
|
@ -435,12 +824,12 @@ void R_DrawFloatingString(fontheader_t* font, const char* text, const vec3_t org
|
|||
unsigned char c;
|
||||
int indirected;
|
||||
letterloc_t* loc;
|
||||
|
||||
|
||||
c = text[i];
|
||||
indirected = font->indirection[c];
|
||||
if (indirected == -1)
|
||||
{
|
||||
Com_Printf("R_DrawFloatingString: no 0x%02x-character in font!\n", c);
|
||||
ri.Printf(PRINT_ALL, "R_DrawFloatingString: no 0x%02x-character in font!\n", c);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -485,8 +874,10 @@ void R_DrawFloatingString(fontheader_t* font, const char* text, const vec3_t org
|
|||
verts[0].xyz[1] = verts[1].xyz[1] + tr.refdef.viewaxis[1][1] * charWidth;
|
||||
verts[0].xyz[2] = verts[1].xyz[2] + tr.refdef.viewaxis[1][2] * charWidth;
|
||||
verts[0].xyz[0] = verts[1].xyz[0] + tr.refdef.viewaxis[1][0] * charWidth;
|
||||
|
||||
RE_AddPolyToScene(fsh, 4, verts, 1);
|
||||
|
||||
if (RE_AddPolyToScene2(fsh, 4, verts, 0)) {
|
||||
++tr.refdef.numPolys;
|
||||
}
|
||||
|
||||
pos[0] = verts[2].xyz[0];
|
||||
pos[1] = verts[2].xyz[1];
|
||||
|
@ -494,16 +885,20 @@ void R_DrawFloatingString(fontheader_t* font, const char* text, const vec3_t org
|
|||
}
|
||||
}
|
||||
|
||||
void R_DrawFloatingString(fontheader_t* font, const char* text, const vec3_t org, const vec4_t color, float scale, int maxlen) {
|
||||
return R_DrawFloatingString_sgl(font->sgl[0], text, org, color, scale, maxlen);
|
||||
}
|
||||
|
||||
float R_GetFontHeight(const fontheader_t* font)
|
||||
{
|
||||
if (!font) {
|
||||
if (!font || !font->sgl[0]) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return font->height * s_fontGeneralScale * s_fontHeightScale;
|
||||
return font->sgl[0]->height * s_fontGeneralScale * s_fontHeightScale;
|
||||
}
|
||||
|
||||
float R_GetFontStringWidth(const fontheader_t* font, const char* s)
|
||||
float R_GetFontStringWidth_sgl(const fontheader_sgl_t* font, const char* s)
|
||||
{
|
||||
float widths;
|
||||
int i;
|
||||
|
@ -519,14 +914,13 @@ float R_GetFontStringWidth(const fontheader_t* font, const char* s)
|
|||
int indirected;
|
||||
char c = *s;
|
||||
|
||||
if (c == 9)
|
||||
if (c == '\t')
|
||||
{
|
||||
indirected = font->indirection[32];
|
||||
if (indirected != -1) {
|
||||
widths += font->locations[indirected].size[0] * 3.0;
|
||||
}
|
||||
else {
|
||||
Com_Printf("R_GetFontStringWidth: no space-character in font!\n");
|
||||
} else {
|
||||
ri.Printf(PRINT_ALL, "R_GetFontStringWidth: no space-character in font!\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -534,12 +928,52 @@ float R_GetFontStringWidth(const fontheader_t* font, const char* s)
|
|||
indirected = font->indirection[c];
|
||||
if (indirected != -1) {
|
||||
widths += font->locations[indirected].size[0];
|
||||
}
|
||||
else {
|
||||
Com_Printf("R_GetFontStringWidth: no 0x%02x-character in font!\n", c);
|
||||
} else {
|
||||
ri.Printf(PRINT_ALL, "R_GetFontStringWidth: no 0x%02x-character in font!\n", c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return widths * s_fontGeneralScale * 256.0;
|
||||
}
|
||||
|
||||
float R_GetFontStringWidth(const fontheader_t* font, const char* s)
|
||||
{
|
||||
int i;
|
||||
int code;
|
||||
fontchartable_t* ct;
|
||||
float width = 0.f;
|
||||
|
||||
if (!font->numPages) {
|
||||
return R_GetFontStringWidth_sgl(font->sgl[0], s);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while(s[i]) {
|
||||
unsigned char uch = s[i++];
|
||||
|
||||
if (DBCSIsLeadByte(font, uch)) {
|
||||
uch = (uch << 8) | s[i++];
|
||||
if (!uch) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (uch == '\t') {
|
||||
code = CodeSearch(font, ' ');
|
||||
if (code >= 0) {
|
||||
ct = &font->charTable[code];
|
||||
width += font->sgl[ct->index]->locations[ct->loc].size[0] * 3.f;
|
||||
}
|
||||
}
|
||||
else {
|
||||
code = CodeSearch(font, uch);
|
||||
if (code >= 0) {
|
||||
ct = &font->charTable[code];
|
||||
width += font->sgl[ct->index]->locations[ct->loc].size[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return width;
|
||||
}
|
1662
code/renderergl2/tr_ghost.cpp
Normal file
1662
code/renderergl2/tr_ghost.cpp
Normal file
File diff suppressed because it is too large
Load diff
300
code/renderergl2/tr_ghost.h
Normal file
300
code/renderergl2/tr_ghost.h
Normal file
|
@ -0,0 +1,300 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023-2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "tr_local.h"
|
||||
#include "../qcommon/vector.h"
|
||||
#include "../qcommon/container.h"
|
||||
#include "../qcommon/str.h"
|
||||
|
||||
using outcode = unsigned int;
|
||||
|
||||
class Particle
|
||||
{
|
||||
private:
|
||||
float m_startTime;
|
||||
float m_dieTime;
|
||||
|
||||
Vector m_velocity;
|
||||
Vector m_acceleration;
|
||||
Vector m_perp;
|
||||
|
||||
qboolean m_wavy;
|
||||
float m_wavyDist;
|
||||
float m_wavyOffset;
|
||||
|
||||
int m_srcColor;
|
||||
int m_dstColor;
|
||||
int m_deltaR;
|
||||
int m_deltaG;
|
||||
int m_deltaB;
|
||||
int m_srcR;
|
||||
int m_srcG;
|
||||
int m_srcB;
|
||||
int m_dstR;
|
||||
int m_dstG;
|
||||
int m_dstB;
|
||||
float m_colorRate;
|
||||
|
||||
Vector m_realposition;
|
||||
|
||||
float m_life;
|
||||
float m_maxspeed;
|
||||
|
||||
qboolean m_swarm;
|
||||
int m_swarmfrequency;
|
||||
int m_swarmdelta;
|
||||
|
||||
Vector m_parentOrigin;
|
||||
|
||||
public:
|
||||
Vector m_position;
|
||||
int m_color;
|
||||
|
||||
public:
|
||||
Particle(
|
||||
Vector pos,
|
||||
Vector vel,
|
||||
Vector acc,
|
||||
int srcColor,
|
||||
int dstColor,
|
||||
float colorRate,
|
||||
qboolean wavy,
|
||||
float wavyDist,
|
||||
float currentTime,
|
||||
float dieTime,
|
||||
float maxspeed,
|
||||
Vector parentOrg,
|
||||
qboolean swarm,
|
||||
int freq,
|
||||
int delta
|
||||
);
|
||||
|
||||
void Update(float currentTime);
|
||||
float GetDieTime();
|
||||
};
|
||||
|
||||
class ParticleEmitter
|
||||
{
|
||||
private:
|
||||
float m_time;
|
||||
float m_lasttime;
|
||||
|
||||
Vector m_position;
|
||||
|
||||
int m_srcColor;
|
||||
int m_dstColor;
|
||||
float m_minColorRate;
|
||||
float m_maxColorRate;
|
||||
|
||||
float m_minRate;
|
||||
float m_maxRate;
|
||||
|
||||
float m_minLife;
|
||||
float m_maxLife;
|
||||
|
||||
float m_angle;
|
||||
float m_angleVar;
|
||||
|
||||
float m_minSpeed;
|
||||
float m_maxSpeed;
|
||||
float m_accAngle;
|
||||
float m_accAngleVar;
|
||||
float m_minAccSpeed;
|
||||
float m_maxAccSpeed;
|
||||
|
||||
float m_minWavyDist;
|
||||
float m_maxWavyDist;
|
||||
qboolean m_wavy;
|
||||
|
||||
qboolean m_gravityWell;
|
||||
float m_gravityWellStrength;
|
||||
|
||||
qboolean m_particles;
|
||||
Vector m_gravityEffectVector;
|
||||
|
||||
qboolean m_ballLightning;
|
||||
int m_minBallLightningRadius;
|
||||
int m_maxBallLightningRadius;
|
||||
float m_lightningVar;
|
||||
int m_lightningSubdivisions;
|
||||
|
||||
qboolean m_swarm;
|
||||
int m_swarmfrequency;
|
||||
int m_swarmdelta;
|
||||
|
||||
int m_maxspeed;
|
||||
|
||||
public:
|
||||
Container<Particle *> particleList;
|
||||
|
||||
public:
|
||||
ParticleEmitter(
|
||||
Vector position,
|
||||
float minSpeed,
|
||||
float maxSpeed,
|
||||
float angle,
|
||||
float angleVar,
|
||||
float minAccSpeed,
|
||||
float maxAccSpeed,
|
||||
float accAngle,
|
||||
float accAngleVar,
|
||||
float minRate,
|
||||
float maxRate,
|
||||
int srcColor,
|
||||
int dstColor,
|
||||
float minColorRate,
|
||||
float maxColorRate,
|
||||
qboolean wavy,
|
||||
float minWavyDist,
|
||||
float maxWavyDist,
|
||||
float minLife,
|
||||
float maxLife,
|
||||
qboolean particles,
|
||||
qboolean gravityWell,
|
||||
float gravityWellStrength,
|
||||
qboolean ballLightning,
|
||||
int minBallLightningRadius,
|
||||
int maxBallLightningRadius,
|
||||
float lightningVar,
|
||||
int lightningSubdivisions,
|
||||
qboolean swarm,
|
||||
int swarmfreq,
|
||||
int swarmdelta
|
||||
);
|
||||
ParticleEmitter();
|
||||
~ParticleEmitter();
|
||||
|
||||
void Emit(float currentTime);
|
||||
void UpdateValues();
|
||||
|
||||
Vector GetPosition();
|
||||
Vector GetVelocity();
|
||||
Vector GetVelocityDirection();
|
||||
Vector GetVelocityDirectionMin();
|
||||
Vector GetVelocityDirectionMax();
|
||||
Vector GetAcceleration();
|
||||
Vector GetAccelerationDirection();
|
||||
Vector GetAccelerationDirectionMin();
|
||||
Vector GetAccelerationDirectionMax();
|
||||
|
||||
int GetSrcColor();
|
||||
int GetDstColor();
|
||||
|
||||
float GetGravityWellStrength();
|
||||
float GetRate();
|
||||
float GetColorRate();
|
||||
|
||||
float GetWavyDistance();
|
||||
float GetDieTime(float currentTime);
|
||||
int GetBallLightningRadius();
|
||||
float GetLightningVar();
|
||||
int GetLightningSubdivisions();
|
||||
|
||||
qboolean IsWavy();
|
||||
qboolean IsGravityWell();
|
||||
qboolean IsParticles();
|
||||
qboolean IsBallLightning();
|
||||
qboolean IsSwarm();
|
||||
|
||||
void SetMinSpeed(float value);
|
||||
void SetMaxSpeed(float value);
|
||||
|
||||
void SetAngle(float value);
|
||||
void SetAngleVar(float value);
|
||||
|
||||
void SetMinAccSpeed(float value);
|
||||
void SetMaxAccSpeed(float value);
|
||||
void SetAccAngle(float value);
|
||||
void SetAccAngleVar(float value);
|
||||
|
||||
void SetMinRate(float value);
|
||||
void SetMaxRate(float value);
|
||||
|
||||
void SetSrcColor(int value);
|
||||
void SetDstColor(int value);
|
||||
void SetMinColorRate(float value);
|
||||
void SetMaxColorRate(float value);
|
||||
|
||||
void SetWavy(int value);
|
||||
|
||||
void SetParticles(int value);
|
||||
void SetGravityWell(int value);
|
||||
|
||||
void SetMinWavyDist(float value);
|
||||
void SetMaxWavyDist(float value);
|
||||
|
||||
void SetMinLife(float value);
|
||||
void SetMaxLife(float value);
|
||||
|
||||
void SetGravityWellStrength(float value);
|
||||
void SetGravityEffectVector(Vector value);
|
||||
|
||||
void SetBallLightning(int value);
|
||||
void SetMinBallLightningRadius(int value);
|
||||
void SetMaxBallLightningRadius(int value);
|
||||
void SetLightningVar(float value);
|
||||
void SetLightningSubdivisions(int value);
|
||||
|
||||
float RandomizeRange(float minRange, float maxRange);
|
||||
float RandomizeAngle(float minAngle, float maxAngle);
|
||||
|
||||
Vector CalculateDirection(float value);
|
||||
|
||||
void Load(char **buf_p);
|
||||
};
|
||||
|
||||
class GhostTexture
|
||||
{
|
||||
public:
|
||||
Container<ParticleEmitter *> m_emitterList;
|
||||
|
||||
int m_width;
|
||||
int m_height;
|
||||
|
||||
image_t *m_image;
|
||||
unsigned int *m_texture;
|
||||
str m_name;
|
||||
|
||||
qboolean m_isburn;
|
||||
qboolean m_isfade;
|
||||
int m_faderate;
|
||||
int m_burnrate;
|
||||
|
||||
public:
|
||||
GhostTexture();
|
||||
|
||||
void Update();
|
||||
void SetTexel(int x, int y, unsigned int color);
|
||||
void Burn();
|
||||
void GenerateLightning(Vector p1, Vector p2, int color, float angleVar, int numSubdivisions, int maxSubdivisions);
|
||||
Vector RotateVector(Vector v, float angle);
|
||||
void ClipAndDrawLine(Vector p0, Vector p1, int color);
|
||||
outcode ComputeOutCode(int x, int y, int xmin, int xmax, int ymin, int ymax);
|
||||
};
|
||||
|
||||
class GhostManager
|
||||
{
|
||||
public:
|
||||
Container<GhostTexture *> m_textureList;
|
||||
};
|
|
@ -3388,4 +3388,99 @@ void R_SkinList_f( void ) {
|
|||
ri.Printf (PRINT_ALL, "------------------\n");
|
||||
}
|
||||
|
||||
//
|
||||
// OPENMOHAA-specific stuff
|
||||
//
|
||||
|
||||
image_t* R_RefreshImageFile(const char* name, imgType_t type, imgFlags_t flags) {
|
||||
// FIXME: unimplemented (GL2)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
R_ImageExists
|
||||
================
|
||||
*/
|
||||
qboolean R_ImageExists(const char* name) {
|
||||
image_t* image;
|
||||
long int hash;
|
||||
|
||||
if (name)
|
||||
{
|
||||
hash = generateHashValue(name);
|
||||
image = hashTable[hash];
|
||||
|
||||
if (hash)
|
||||
{
|
||||
for (; image != NULL; image = image->next)
|
||||
{
|
||||
if (!strcmp(name, image->imgName)) {
|
||||
return qtrue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_DumpTextureMemory
|
||||
===============
|
||||
*/
|
||||
void R_DumpTextureMemory() {
|
||||
int i;
|
||||
char str_buffer[32];
|
||||
char* Label1, * Label2;
|
||||
fileHandle_t stat_file;
|
||||
|
||||
stat_file = ri.FS_OpenFileWrite("textureuse.csv");
|
||||
|
||||
Label1 = "Texture Name,";
|
||||
ri.FS_Write(Label1, strlen(Label1), stat_file);
|
||||
Label2 = "Size (kb),";
|
||||
ri.FS_Write(Label2, strlen(Label2), stat_file);
|
||||
Label1 = "Num Uses,";
|
||||
ri.FS_Write(Label1, strlen(Label1), stat_file);
|
||||
Label2 = "Miplevels\n";
|
||||
ri.FS_Write(Label2, strlen(Label2), stat_file);
|
||||
|
||||
for (i = 0; i < tr.numImages; i++) {
|
||||
image_t* image = tr.images[i];
|
||||
|
||||
ri.FS_Write(image->imgName, strlen(image->imgName), stat_file);
|
||||
ri.FS_Write(", ", 2, stat_file);
|
||||
|
||||
// Write the number of bytes (in KiB)
|
||||
Q_snprintf(str_buffer, sizeof(str_buffer), "%d", image->bytesUsed >> 10);
|
||||
ri.FS_Write(str_buffer, strlen(str_buffer), stat_file);
|
||||
ri.FS_Write(", ", 2, stat_file);
|
||||
|
||||
// Write the sequence
|
||||
Q_snprintf(str_buffer, sizeof(str_buffer), "%d", image->r_sequence);
|
||||
ri.FS_Write(str_buffer, strlen(str_buffer), stat_file);
|
||||
ri.FS_Write(", ", 2, stat_file);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_CountTextureMemory
|
||||
===============
|
||||
*/
|
||||
int R_CountTextureMemory() {
|
||||
int total_bytes;
|
||||
int i;
|
||||
|
||||
R_DumpTextureMemory();
|
||||
|
||||
total_bytes = 0;
|
||||
|
||||
for (i = 0; i < tr.numImages; i++) {
|
||||
total_bytes = tr.images[i]->bytesUsed;
|
||||
}
|
||||
|
||||
return total_bytes;
|
||||
}
|
||||
|
|
|
@ -236,6 +236,86 @@ int max_polys;
|
|||
cvar_t *r_maxpolyverts;
|
||||
int max_polyverts;
|
||||
|
||||
//
|
||||
// OPENMOHAA-specific stuff
|
||||
//=========================
|
||||
|
||||
int r_sequencenumber;
|
||||
|
||||
// DRAWING
|
||||
|
||||
cvar_t *r_drawentitypoly;
|
||||
cvar_t *r_drawstaticmodels;
|
||||
cvar_t *r_drawstaticmodelpoly;
|
||||
cvar_t *r_drawstaticdecals;
|
||||
cvar_t *r_drawterrain;
|
||||
cvar_t *r_drawsprites;
|
||||
cvar_t *r_drawspherelights;
|
||||
|
||||
cvar_t *r_numdebuglines;
|
||||
cvar_t *r_stipplelines;
|
||||
cvar_t *r_debuglines_depthmask;
|
||||
|
||||
cvar_t *r_maxpolys;
|
||||
int max_polys;
|
||||
cvar_t *r_maxpolyverts;
|
||||
int max_polyverts;
|
||||
cvar_t* r_maxtermarks;
|
||||
int max_termarks;
|
||||
|
||||
cvar_t* r_skyportal;
|
||||
cvar_t* r_skyportal_origin;
|
||||
cvar_t* r_lightcoronasize;
|
||||
|
||||
// LOD
|
||||
|
||||
cvar_t* r_staticlod;
|
||||
cvar_t* r_lodscale;
|
||||
cvar_t* r_lodcap;
|
||||
cvar_t* r_lodviewmodelcap;
|
||||
|
||||
cvar_t* r_uselod;
|
||||
cvar_t* lod_LOD;
|
||||
cvar_t* lod_minLOD;
|
||||
cvar_t* lod_maxLOD;
|
||||
cvar_t* lod_LOD_slider;
|
||||
cvar_t* lod_curve_0_val;
|
||||
cvar_t* lod_curve_1_val;
|
||||
cvar_t* lod_curve_2_val;
|
||||
cvar_t* lod_curve_3_val;
|
||||
cvar_t* lod_curve_4_val;
|
||||
cvar_t* lod_edit_0;
|
||||
cvar_t* lod_edit_1;
|
||||
cvar_t* lod_edit_2;
|
||||
cvar_t* lod_edit_3;
|
||||
cvar_t* lod_edit_4;
|
||||
cvar_t* lod_curve_0_slider;
|
||||
cvar_t* lod_curve_1_slider;
|
||||
cvar_t* lod_curve_2_slider;
|
||||
cvar_t* lod_curve_3_slider;
|
||||
cvar_t* lod_curve_4_slider;
|
||||
cvar_t* lod_pitch_val;
|
||||
cvar_t* lod_zee_val;
|
||||
cvar_t* lod_mesh;
|
||||
cvar_t* lod_meshname;
|
||||
cvar_t* lod_tikiname;
|
||||
cvar_t* lod_metric;
|
||||
cvar_t* lod_tris;
|
||||
cvar_t* lod_position;
|
||||
cvar_t* lod_save;
|
||||
cvar_t* lod_tool;
|
||||
|
||||
// Utils
|
||||
|
||||
cvar_t* r_developer;
|
||||
cvar_t* r_fps;
|
||||
cvar_t* r_showstaticbboxes;
|
||||
cvar_t* r_showcull;
|
||||
cvar_t* r_showlod;
|
||||
cvar_t* r_showstaticlod;
|
||||
|
||||
//=========================
|
||||
|
||||
/*
|
||||
** InitOpenGL
|
||||
**
|
||||
|
@ -1452,6 +1532,77 @@ void R_Register( void )
|
|||
ri.Cmd_AddCommand( "minimize", GLimp_Minimize );
|
||||
ri.Cmd_AddCommand( "gfxmeminfo", GfxMemInfo_f );
|
||||
ri.Cmd_AddCommand( "exportCubemaps", R_ExportCubemaps_f );
|
||||
|
||||
//
|
||||
// OPENMOHAA-specific stuff
|
||||
//
|
||||
|
||||
// Draw
|
||||
|
||||
r_drawentitypoly = ri.Cvar_Get("r_drawentitypoly", "1", CVAR_CHEAT);
|
||||
r_drawstaticmodels = ri.Cvar_Get("r_drawstaticmodels", "1", CVAR_CHEAT);
|
||||
r_drawstaticmodelpoly = ri.Cvar_Get("r_drawstaticmodelpoly", "1", CVAR_CHEAT);
|
||||
r_drawstaticdecals = ri.Cvar_Get("r_drawstaticdecals", "0", 0);
|
||||
r_drawterrain = ri.Cvar_Get("r_drawterrain", "1", CVAR_CHEAT);
|
||||
r_drawsprites = ri.Cvar_Get("r_drawsprites", "1", CVAR_CHEAT);
|
||||
r_drawspherelights = ri.Cvar_Get("r_drawspherelights", "1", CVAR_CHEAT);
|
||||
|
||||
r_debuglines_depthmask = ri.Cvar_Get("r_debuglines_depthmask", "0", CVAR_ARCHIVE);
|
||||
r_stipplelines = ri.Cvar_Get("r_stipplelines", "1", CVAR_ARCHIVE);
|
||||
r_numdebuglines = ri.Cvar_Get("g_numdebuglines", "4096", CVAR_LATCH);
|
||||
|
||||
r_maxtermarks = ri.Cvar_Get("r_maxtermarks", va("%d", MAX_TERMARKS), 0);
|
||||
|
||||
r_skyportal = ri.Cvar_Get("r_skyportal", "0", 0);
|
||||
r_skyportal_origin = ri.Cvar_Get("r_skyportal_origin", "0 0 0", 0);
|
||||
r_lightcoronasize = ri.Cvar_Get("r_lightcoronasize", ".1", CVAR_ARCHIVE);
|
||||
|
||||
// LOD
|
||||
|
||||
r_staticlod = ri.Cvar_Get("r_staticlod", "1", CVAR_CHEAT);
|
||||
r_lodscale = ri.Cvar_Get("r_lodscale", "5", CVAR_ARCHIVE);
|
||||
r_lodcap = ri.Cvar_Get("r_lodcap", "0.35", CVAR_ARCHIVE);
|
||||
r_lodviewmodelcap = ri.Cvar_Get("r_lodviewmodelcap", "0.25", CVAR_ARCHIVE);
|
||||
|
||||
r_uselod = ri.Cvar_Get("r_uselod", "1", CVAR_TEMP);
|
||||
lod_LOD = ri.Cvar_Get("lod_LOD", "0", CVAR_TEMP);
|
||||
lod_minLOD = ri.Cvar_Get("lod_minLOD", "1.0", CVAR_TEMP);
|
||||
lod_maxLOD = ri.Cvar_Get("lod_maxLOD", "0.3", CVAR_TEMP);
|
||||
lod_LOD_slider = ri.Cvar_Get("lod_LOD_slider", "0.5", CVAR_TEMP);
|
||||
lod_edit_0 = ri.Cvar_Get("lod_edit_0", "0", CVAR_TEMP);
|
||||
lod_edit_1 = ri.Cvar_Get("lod_edit_1", "0", CVAR_TEMP);
|
||||
lod_edit_2 = ri.Cvar_Get("lod_edit_2", "0", CVAR_TEMP);
|
||||
lod_edit_3 = ri.Cvar_Get("lod_edit_3", "0", CVAR_TEMP);
|
||||
lod_edit_4 = ri.Cvar_Get("lod_edit_4", "0", CVAR_TEMP);
|
||||
lod_curve_0_val = ri.Cvar_Get("lod_curve_0_val", "0", CVAR_TEMP);
|
||||
lod_curve_1_val = ri.Cvar_Get("lod_curve_1_val", "0", CVAR_TEMP);
|
||||
lod_curve_2_val = ri.Cvar_Get("lod_curve_2_val", "0", CVAR_TEMP);
|
||||
lod_curve_3_val = ri.Cvar_Get("lod_curve_3_val", "0", CVAR_TEMP);
|
||||
lod_curve_4_val = ri.Cvar_Get("lod_curve_4_val", "0", CVAR_TEMP);
|
||||
lod_curve_0_slider = ri.Cvar_Get("lod_curve_0_slider", "0", CVAR_TEMP);
|
||||
lod_curve_1_slider = ri.Cvar_Get("lod_curve_1_slider", "0", CVAR_TEMP);
|
||||
lod_curve_2_slider = ri.Cvar_Get("lod_curve_2_slider", "0", CVAR_TEMP);
|
||||
lod_curve_3_slider = ri.Cvar_Get("lod_curve_3_slider", "0", CVAR_TEMP);
|
||||
lod_curve_4_slider = ri.Cvar_Get("lod_curve_4_slider", "0", CVAR_TEMP);
|
||||
lod_pitch_val = ri.Cvar_Get("lod_pitch_val", "0", CVAR_TEMP);
|
||||
lod_zee_val = ri.Cvar_Get("lod_zee_val", "0", CVAR_TEMP);
|
||||
lod_mesh = ri.Cvar_Get("lod_mesh", "0", CVAR_TEMP);
|
||||
lod_meshname = ri.Cvar_Get("lod_meshname", "", CVAR_TEMP);
|
||||
lod_tikiname = ri.Cvar_Get("lod_tikiname", "", CVAR_TEMP);
|
||||
lod_metric = ri.Cvar_Get("lod_metric", "0.0", CVAR_TEMP);
|
||||
lod_tris = ri.Cvar_Get("lod_tris", "", CVAR_TEMP);
|
||||
lod_save = ri.Cvar_Get("lod_save", "0", CVAR_TEMP);
|
||||
lod_position = ri.Cvar_Get("lod_position", "0 0 0", CVAR_TEMP);
|
||||
lod_tool = ri.Cvar_Get("lod_tool", "0", CVAR_TEMP);
|
||||
|
||||
// Utils
|
||||
|
||||
r_fps = ri.Cvar_Get("fps", "0", 0);
|
||||
r_developer = ri.Cvar_Get("developer", "", 0);
|
||||
r_showstaticbboxes = ri.Cvar_Get("r_showstaticbboxes", "0", CVAR_CHEAT);
|
||||
r_showcull = ri.Cvar_Get("r_showcull", "0", CVAR_CHEAT);
|
||||
r_showlod = ri.Cvar_Get("r_showlod", "0", CVAR_TEMP);
|
||||
r_showstaticlod = ri.Cvar_Get("r_showstaticlod", "0", CVAR_TEMP);
|
||||
}
|
||||
|
||||
void R_InitQueries(void)
|
||||
|
@ -1628,6 +1779,28 @@ void RE_Shutdown( qboolean destroyWindow ) {
|
|||
tr.registered = qfalse;
|
||||
}
|
||||
|
||||
//
|
||||
// OPENMOHAA-specific stuff
|
||||
//=========================
|
||||
|
||||
/*
|
||||
** RE_BeginRegistration
|
||||
*/
|
||||
void RE_BeginRegistration(glconfig_t* glconfigOut) {
|
||||
|
||||
R_Init();
|
||||
|
||||
*glconfigOut = glConfig;
|
||||
|
||||
R_IssuePendingRenderCommands();
|
||||
|
||||
tr.viewCluster = -1; // force markleafs to regenerate
|
||||
R_ClearFlares();
|
||||
RE_ClearScene();
|
||||
|
||||
tr.registered = qtrue;
|
||||
}
|
||||
//=========================
|
||||
|
||||
/*
|
||||
=============
|
||||
|
@ -1643,6 +1816,52 @@ void RE_EndRegistration( void ) {
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// OPENMOHAA-specific stuff
|
||||
//=========================
|
||||
|
||||
/*
|
||||
==================
|
||||
R_SetMode
|
||||
==================
|
||||
*/
|
||||
qboolean R_SetMode(int mode, const glconfig_t* glConfig) {
|
||||
// FIXME: unimplemented (GL2)
|
||||
ri.Printf(PRINT_WARNING, "R_SetMode is unimplemented. To change the video mode, set the \"r_mode\" variable and execute the \"vid_restart\" command.\n");
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
R_SetFullscreen
|
||||
==================
|
||||
*/
|
||||
void R_SetFullscreen(qboolean fullscreen) {
|
||||
// FIXME: unimplemented (GL2)
|
||||
ri.Printf(PRINT_WARNING, "R_SetFullscreen is unimplemented. To change the fullscreen mode, set the \"r_fullscreen\" variable and execute the \"vid_restart\" command.\n");
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
RE_SetRenderTime
|
||||
=============
|
||||
*/
|
||||
void RE_SetRenderTime(int t) {
|
||||
backEnd.refdef.floatTime = (long double)t / 1000.0;
|
||||
R_UpdateGhostTextures();
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
RE_GetGraphicsInfo
|
||||
==================
|
||||
*/
|
||||
const char* RE_GetGraphicsInfo() {
|
||||
// FIXME: unimplemented (GL2)
|
||||
// Looks like it's unused anyway
|
||||
}
|
||||
|
||||
//=========================
|
||||
|
||||
/*
|
||||
@@@@@@@@@@@@@@@@@@@@@
|
||||
|
@ -1708,5 +1927,70 @@ refexport_t *GetRefAPI ( int apiVersion, refimport_t *rimp ) {
|
|||
|
||||
re.TakeVideoFrame = RE_TakeVideoFrame;
|
||||
|
||||
//
|
||||
// After ioquake3 imports
|
||||
//
|
||||
|
||||
re.FreeModels = RE_FreeModels;
|
||||
re.EndRegistration = RE_EndRegistration;
|
||||
re.SpawnEffectModel = RE_SpawnEffectModel;
|
||||
re.RegisterServerModel = RE_RegisterServerModel;
|
||||
re.UnregisterServerModel = RE_UnregisterServerModel;
|
||||
re.RefreshShaderNoMip = RE_RefreshShaderNoMip;
|
||||
re.PrintBSPFileSizes = RE_PrintBSPFileSizes;
|
||||
re.MapVersion = RE_MapVersion;
|
||||
re.LoadFont = R_LoadFont;
|
||||
|
||||
re.MarkFragmentsForInlineModel = R_MarkFragmentsForInlineModel;
|
||||
re.GetInlineModelBounds = R_GetInlineModelBounds;
|
||||
re.GetLightingForDecal = R_GetLightingForDecal;
|
||||
re.GetLightingForSmoke = R_GetLightingForSmoke;
|
||||
re.R_GatherLightSources = R_GatherLightSources;
|
||||
re.ModelRadius = R_ModelRadius;
|
||||
re.AddRefSpriteToScene = RE_AddRefSpriteToScene;
|
||||
re.AddTerrainMarkToScene = RE_AddTerrainMarkToScene;
|
||||
|
||||
re.GetRenderEntity = RE_GetRenderEntity;
|
||||
|
||||
re.SavePerformanceCounters = R_SavePerformanceCounters;
|
||||
|
||||
re.R_Model_GetHandle = R_Model_GetHandle;
|
||||
re.SetColor = Draw_SetColor;
|
||||
re.DrawStretchPic = Draw_StretchPic;
|
||||
re.DrawStretchPic2 = Draw_StretchPic2;
|
||||
re.DrawStretchRaw = RE_StretchRaw;
|
||||
re.DebugLine = R_DebugLine;
|
||||
re.DrawTilePic = Draw_TilePic;
|
||||
re.DrawTilePicOffset = Draw_TilePicOffset;
|
||||
re.DrawTrianglePic = Draw_TrianglePic;
|
||||
re.DrawBox = DrawBox;
|
||||
re.AddBox = AddBox;
|
||||
re.Set2DWindow = Set2DWindow;
|
||||
re.Scissor = RE_Scissor;
|
||||
re.DrawLineLoop = DrawLineLoop;
|
||||
re.DrawString = R_DrawString;
|
||||
re.GetFontHeight = R_GetFontHeight;
|
||||
re.GetFontStringWidth = R_GetFontStringWidth;
|
||||
re.SwipeBegin = RE_SwipeBegin;
|
||||
re.SwipeEnd = RE_SwipeEnd;
|
||||
re.SetRenderTime = RE_SetRenderTime;
|
||||
re.Noise = R_NoiseGet4f;
|
||||
|
||||
re.SetMode = R_SetMode;
|
||||
re.SetFullscreen = R_SetFullscreen;
|
||||
|
||||
re.GetShaderHeight = RE_GetShaderHeight;
|
||||
re.GetShaderWidth = RE_GetShaderWidth;
|
||||
re.GetShaderName = RE_GetShaderName;
|
||||
re.GetModelName = RE_GetModelName;
|
||||
re.GetGraphicsInfo = RE_GetGraphicsInfo;
|
||||
re.ForceUpdatePose = RE_ForceUpdatePose;
|
||||
re.TIKI_Orientation = RE_TIKI_Orientation;
|
||||
re.TIKI_IsOnGround = RE_TIKI_IsOnGround;
|
||||
re.SetFrameNumber = RE_SetFrameNumber;
|
||||
|
||||
re.ImageExists = R_ImageExists;
|
||||
re.CountTextureMemory = R_CountTextureMemory;
|
||||
|
||||
return &re;
|
||||
}
|
||||
|
|
|
@ -509,3 +509,27 @@ int R_CubemapForPoint( vec3_t point )
|
|||
|
||||
return cubemapIndex + 1;
|
||||
}
|
||||
|
||||
//
|
||||
// OPENMOHAA-specific stuff
|
||||
//
|
||||
|
||||
/*
|
||||
===============
|
||||
R_GetLightingForDecal
|
||||
===============
|
||||
*/
|
||||
void R_GetLightingForDecal(vec3_t vLight, const vec3_t vFacing, const vec3_t vOrigin)
|
||||
{
|
||||
// FIXME: unimplemented (GL2)
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_GetLightingForSmoke
|
||||
===============
|
||||
*/
|
||||
void R_GetLightingForSmoke(vec3_t vLight, const vec3_t vOrigin)
|
||||
{
|
||||
// FIXME: unimplemented (GL2)
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1729,6 +1729,220 @@ void R_DebugGraphics( void ) {
|
|||
ri.CM_DrawDebugSurface( R_DebugPolygon );
|
||||
}
|
||||
|
||||
#define CIRCLE_LENGTH 25
|
||||
|
||||
/*
|
||||
================
|
||||
R_DebugCircle
|
||||
================
|
||||
*/
|
||||
void R_DebugCircle(const vec3_t org, float radius, float r, float g, float b, float alpha, qboolean horizontal) {
|
||||
int i;
|
||||
float ang;
|
||||
debugline_t* line;
|
||||
vec3_t forward, right;
|
||||
vec3_t pos, lastpos;
|
||||
|
||||
if (!ri.DebugLines || !ri.numDebugLines) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (horizontal)
|
||||
{
|
||||
VectorSet(forward, 1, 0, 0);
|
||||
VectorSet(right, 0, 1, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorCopy(tr.refdef.viewaxis[1], right);
|
||||
VectorCopy(tr.refdef.viewaxis[2], forward);
|
||||
}
|
||||
|
||||
VectorClear(pos);
|
||||
VectorClear(lastpos);
|
||||
|
||||
for (i = 0; i < CIRCLE_LENGTH; i++) {
|
||||
VectorCopy(pos, lastpos);
|
||||
|
||||
ang = DEG2RAD((float)(i * 15));
|
||||
pos[0] = (org[0] + sin(ang) * radius * forward[0]) +
|
||||
cos(ang) * radius * right[0];
|
||||
pos[1] = (org[1] + sin(ang) * radius * forward[1]) +
|
||||
cos(ang) * radius * right[1];
|
||||
pos[2] = (org[2] + sin(ang) * radius * forward[2]) +
|
||||
cos(ang) * radius * right[2];
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
if (*ri.numDebugLines >= r_numdebuglines->integer) {
|
||||
ri.Printf(PRINT_ALL, "R_DebugCircle: Exceeded MAX_DEBUG_LINES\n");
|
||||
return;
|
||||
}
|
||||
|
||||
line = &(*ri.DebugLines)[*ri.numDebugLines];
|
||||
(*ri.numDebugLines)++;
|
||||
VectorCopy(lastpos, line->start);
|
||||
VectorCopy(pos, line->end);
|
||||
VectorSet(line->color, r, g, b);
|
||||
line->alpha = alpha;
|
||||
line->width = 1.0;
|
||||
line->factor = 1;
|
||||
line->pattern = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
R_DebugLine
|
||||
================
|
||||
*/
|
||||
void R_DebugLine(const vec3_t start, const vec3_t end, float r, float g, float b, float alpha) {
|
||||
debugline_t* line;
|
||||
|
||||
if (!ri.DebugLines || !ri.numDebugLines) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (*ri.numDebugLines >= r_numdebuglines->integer) {
|
||||
ri.Printf(PRINT_ALL, "R_DebugLine: Exceeded MAX_DEBUG_LINES\n");
|
||||
return;
|
||||
}
|
||||
|
||||
line = &(*ri.DebugLines)[*ri.numDebugLines];
|
||||
(*ri.numDebugLines)++;
|
||||
VectorCopy(start, line->start);
|
||||
VectorCopy(end, line->end);
|
||||
VectorSet(line->color, r, g, b);
|
||||
line->alpha = alpha;
|
||||
line->width = 1.0;
|
||||
line->factor = 1;
|
||||
line->pattern = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
R_DrawDebugLines
|
||||
================
|
||||
*/
|
||||
void R_DrawDebugLines(void) {
|
||||
debugline_t* line;
|
||||
int i;
|
||||
float width;
|
||||
int factor;
|
||||
unsigned short pattern;
|
||||
|
||||
if (!ri.DebugLines || !ri.numDebugLines) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!*ri.numDebugLines) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (tr.refdef.rdflags & RDF_NOWORLDMODEL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (tr.viewParms.isPortalSky) {
|
||||
return;
|
||||
}
|
||||
|
||||
R_IssuePendingRenderCommands();
|
||||
GL_BindToTMU(tr.whiteImage, 0);
|
||||
if (r_debuglines_depthmask->integer) {
|
||||
GL_State(GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE);
|
||||
} else {
|
||||
GL_State(GLS_POLYMODE_LINE);
|
||||
}
|
||||
|
||||
qglDisableClientState(GL_COLOR_ARRAY);
|
||||
qglDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
width = 1.0;
|
||||
factor = 4;
|
||||
pattern = -1;
|
||||
|
||||
if (r_stipplelines->integer)
|
||||
{
|
||||
qglEnable(GL_LINE_STIPPLE);
|
||||
qglLineStipple(4, -1);
|
||||
qglLineWidth(1.0f);
|
||||
}
|
||||
|
||||
qglBegin(GL_LINES);
|
||||
|
||||
for (i = 0; i < *ri.numDebugLines; i++) {
|
||||
line = &(*ri.DebugLines)[i];
|
||||
|
||||
if (r_stipplelines->integer) {
|
||||
if (line->width != width || line->factor != factor || line->pattern != pattern) {
|
||||
qglEnd();
|
||||
qglLineStipple(line->factor, line->pattern);
|
||||
qglLineWidth(line->width);
|
||||
qglBegin(GL_LINES);
|
||||
factor = line->factor;
|
||||
width = line->width;
|
||||
pattern = line->pattern;
|
||||
}
|
||||
}
|
||||
|
||||
qglColor4f(line->color[0], line->color[1], line->color[2], line->alpha);
|
||||
qglVertex3fv(line->start);
|
||||
qglVertex3fv(line->end);
|
||||
}
|
||||
|
||||
qglEnd();
|
||||
|
||||
if (r_stipplelines->integer)
|
||||
{
|
||||
qglDisable(GL_LINE_STIPPLE);
|
||||
qglLineStipple(1, -1);
|
||||
qglLineWidth(1.0);
|
||||
}
|
||||
|
||||
qglDepthRange(0.0, 1.0);
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
R_DrawDebugLines
|
||||
================
|
||||
*/
|
||||
void R_DrawDebugStrings(void) {
|
||||
int i;
|
||||
debugstring_t* string;
|
||||
|
||||
if (!ri.DebugStrings || !ri.numDebugStrings) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!*ri.numDebugStrings) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (tr.refdef.rdflags & RDF_NOWORLDMODEL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (tr.viewParms.isPortalSky) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < *ri.numDebugStrings; i++) {
|
||||
string = &(*ri.DebugStrings)[i];
|
||||
|
||||
R_DrawFloatingString(
|
||||
tr.pFontDebugStrings,
|
||||
string->szText,
|
||||
string->pos,
|
||||
string->color,
|
||||
string->scale,
|
||||
64
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
|
@ -2672,3 +2886,207 @@ void R_RenderCubemapSide( int cubemapIndex, int cubemapSide, qboolean subscene )
|
|||
if (!subscene)
|
||||
RE_EndScene();
|
||||
}
|
||||
|
||||
//
|
||||
// OPENMOHAA-specific stuff
|
||||
//
|
||||
|
||||
/*
|
||||
=================
|
||||
R_RotateForStaticModel
|
||||
|
||||
Generates an orientation for a static model and viewParms
|
||||
=================
|
||||
*/
|
||||
void R_RotateForStaticModel( cStaticModelUnpacked_t *SM, const viewParms_t *viewParms,
|
||||
orientationr_t *ori ) {
|
||||
float glMatrix[16];
|
||||
vec3_t delta;
|
||||
float tiki_scale;
|
||||
|
||||
tiki_scale = SM->tiki->load_scale * SM->scale;
|
||||
|
||||
VectorCopy( SM->origin, ori->origin );
|
||||
|
||||
VectorCopy( SM->axis[0], ori->axis[0] );
|
||||
VectorCopy( SM->axis[1], ori->axis[1] );
|
||||
VectorCopy( SM->axis[2], ori->axis[2] );
|
||||
|
||||
glMatrix[0] = ori->axis[0][0] * tiki_scale;
|
||||
glMatrix[4] = ori->axis[1][0] * tiki_scale;
|
||||
glMatrix[8] = ori->axis[2][0] * tiki_scale;
|
||||
glMatrix[12] = ori->origin[0];
|
||||
|
||||
glMatrix[1] = ori->axis[0][1] * tiki_scale;
|
||||
glMatrix[5] = ori->axis[1][1] * tiki_scale;
|
||||
glMatrix[9] = ori->axis[2][1] * tiki_scale;
|
||||
glMatrix[13] = ori->origin[1];
|
||||
|
||||
glMatrix[2] = ori->axis[0][2] * tiki_scale;
|
||||
glMatrix[6] = ori->axis[1][2] * tiki_scale;
|
||||
glMatrix[10] = ori->axis[2][2] * tiki_scale;
|
||||
glMatrix[14] = ori->origin[2];
|
||||
|
||||
glMatrix[3] = 0;
|
||||
glMatrix[7] = 0;
|
||||
glMatrix[11] = 0;
|
||||
glMatrix[15] = 1;
|
||||
|
||||
myGlMultMatrix( glMatrix, viewParms->world.modelMatrix, ori->modelMatrix );
|
||||
|
||||
// calculate the viewer origin in the model's space
|
||||
// needed for fog, specular, and environment mapping
|
||||
VectorSubtract( viewParms->or.origin, ori->origin, delta );
|
||||
|
||||
ori->viewOrigin[0] = DotProduct( delta, ori->axis[0] );
|
||||
ori->viewOrigin[1] = DotProduct( delta, ori->axis[1] );
|
||||
ori->viewOrigin[2] = DotProduct( delta, ori->axis[2] );
|
||||
}
|
||||
|
||||
int R_DistanceCullLocalPointAndRadius(float fDist, const vec3_t pt, float radius) {
|
||||
vec3_t transformed;
|
||||
|
||||
R_LocalPointToWorld(pt, transformed);
|
||||
|
||||
return R_DistanceCullPointAndRadius(fDist, transformed, radius);
|
||||
}
|
||||
|
||||
int R_DistanceCullPointAndRadius(float fDist, const vec3_t pt, float radius) {
|
||||
if (!r_nocull->integer)
|
||||
{
|
||||
vec3_t vDelta;
|
||||
float fLengthSquared;
|
||||
float fTotalDistSquared;
|
||||
|
||||
VectorSubtract(pt, tr.viewParms.or.origin, vDelta);
|
||||
fLengthSquared = VectorLengthSquared(vDelta);
|
||||
fTotalDistSquared = Square(fDist + radius);
|
||||
|
||||
if (Square(fDist + radius) < Square(vDelta[2]) + fLengthSquared) {
|
||||
return CULL_OUT;
|
||||
} else if (Square(fDist - radius) > Square(vDelta[2]) + fLengthSquared) {
|
||||
return CULL_IN;
|
||||
}
|
||||
}
|
||||
|
||||
return CULL_CLIP;
|
||||
}
|
||||
|
||||
/*
|
||||
** SurfIsOffscreen
|
||||
**
|
||||
** Determines if a surface is completely offscreen.
|
||||
*/
|
||||
qboolean SurfIsOffscreen2(const srfBspSurface_t* surface, shader_t* shader, int entityNum) {
|
||||
float shortest = 100000000;
|
||||
int numTriangles;
|
||||
qboolean doRange;
|
||||
orientationr_t surfOr;
|
||||
unsigned int* indices;
|
||||
vec4_t clip, eye;
|
||||
int i;
|
||||
unsigned int pointOr = 0;
|
||||
unsigned int pointAnd = (unsigned int)~0;
|
||||
|
||||
if (surface->surfaceType != SF_FACE) {
|
||||
ri.Printf(PRINT_WARNING, "WARNING: SurfIsOffscreen called on non-bmodel!\n");
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if ( glConfig.smpActive ) { // FIXME! we can't do RB_BeginSurface/RB_EndSurface stuff with smp!
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if (entityNum == ENTITYNUM_WORLD) {
|
||||
surfOr = tr.viewParms.world;
|
||||
} else {
|
||||
R_RotateForEntity(&tr.refdef.entities[entityNum], &tr.viewParms, &surfOr);
|
||||
}
|
||||
|
||||
for ( i = 0; i < surface->numVerts; i++ )
|
||||
{
|
||||
int j;
|
||||
unsigned int pointFlags = 0;
|
||||
|
||||
R_TransformModelToClip( surface->verts[i].xyz, surfOr.modelMatrix, tr.viewParms.projectionMatrix, eye, clip );
|
||||
|
||||
for ( j = 0; j < 3; j++ )
|
||||
{
|
||||
if ( clip[j] >= clip[3] )
|
||||
{
|
||||
pointFlags |= (1 << (j*2));
|
||||
}
|
||||
else if ( clip[j] <= -clip[3] )
|
||||
{
|
||||
pointFlags |= ( 1 << (j*2+1));
|
||||
}
|
||||
}
|
||||
pointAnd &= pointFlags;
|
||||
pointOr |= pointFlags;
|
||||
}
|
||||
|
||||
// trivially reject
|
||||
if ( pointAnd )
|
||||
{
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
// determine if this surface is backfaced and also determine the distance
|
||||
// to the nearest vertex so we can cull based on portal range. Culling
|
||||
// based on vertex distance isn't 100% correct (we should be checking for
|
||||
// range to the surface), but it's good enough for the types of portals
|
||||
// we have in the game right now.
|
||||
numTriangles = surface->numIndexes / 3;
|
||||
|
||||
for ( i = 0; i < surface->numIndexes; i += 3 )
|
||||
{
|
||||
vec3_t normal;
|
||||
float dot;
|
||||
float len;
|
||||
unsigned* indices;
|
||||
|
||||
indices = surface->indexes; // (unsigned*)(((char*)surface) + surface->ofsIndices);
|
||||
|
||||
VectorSubtract( surface->verts[indices[i]].xyz, surfOr.viewOrigin, normal);
|
||||
|
||||
if (shader->fDistRange > 0) {
|
||||
len = VectorLengthSquared(normal); // lose the sqrt
|
||||
if (len < shortest)
|
||||
{
|
||||
shortest = len;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ( dot = DotProduct( normal, surface->cullPlane.normal ) ) >= 0 )
|
||||
{
|
||||
numTriangles--;
|
||||
}
|
||||
}
|
||||
if ( !numTriangles )
|
||||
{
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
if (shader->fDistRange > 0.0)
|
||||
{
|
||||
if (shortest > Square(shader->fDistRange))
|
||||
{
|
||||
return qtrue;
|
||||
}
|
||||
}
|
||||
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
static qboolean DrawSurfIsOffscreen(drawSurf_t* drawSurf) {
|
||||
// FIXME: unimplemented (GL2)
|
||||
#if 0
|
||||
int entityNum;
|
||||
shader_t* shader;
|
||||
int dlighted;
|
||||
qboolean bStaticModel;
|
||||
|
||||
R_DecomposeSort(drawSurf->sort, &entityNum, &shader, &dlighted, &bStaticModel);
|
||||
return SurfIsOffscreen2((srfBspSurface_t*)drawSurf->surface, shader, entityNum);
|
||||
#endif
|
||||
}
|
|
@ -469,7 +469,10 @@ int R_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projectio
|
|||
return returnedFragments;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int R_MarkFragmentsForInlineModel(clipHandle_t bmodel, const vec3_t vAngles, const vec3_t vOrigin, int numPoints,
|
||||
const vec3_t* points, const vec3_t projection, int maxPoints, vec3_t pointBuffer,
|
||||
int maxFragments, markFragment_t* fragmentBuffer, float fRadiusSquared)
|
||||
{
|
||||
// FIXME: unimplemented (GL2)
|
||||
return 0;
|
||||
}
|
||||
|
|
2001
code/renderergl2/tr_marks_permanent.c
Normal file
2001
code/renderergl2/tr_marks_permanent.c
Normal file
File diff suppressed because it is too large
Load diff
1880
code/renderergl2/tr_model.cpp
Normal file
1880
code/renderergl2/tr_model.cpp
Normal file
File diff suppressed because it is too large
Load diff
|
@ -35,6 +35,17 @@ int r_firstScenePoly;
|
|||
|
||||
int r_numpolyverts;
|
||||
|
||||
//
|
||||
// OPENMOHAA-specific stuff
|
||||
//=========================
|
||||
|
||||
int r_numsprites;
|
||||
int r_firstSceneSprite;
|
||||
|
||||
int r_numtermarks;
|
||||
int r_firstSceneTerMark;
|
||||
|
||||
//=========================
|
||||
|
||||
/*
|
||||
====================
|
||||
|
@ -57,6 +68,16 @@ void R_InitNextFrame( void ) {
|
|||
r_firstScenePoly = 0;
|
||||
|
||||
r_numpolyverts = 0;
|
||||
|
||||
//
|
||||
// OPENMOHAA-specific stuff
|
||||
//
|
||||
|
||||
r_numsprites = 0;
|
||||
r_firstSceneSprite = 0;
|
||||
|
||||
r_numtermarks = 0;
|
||||
r_firstSceneTerMark = 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -571,3 +592,134 @@ void RE_RenderScene( const refdef_t *fd ) {
|
|||
|
||||
tr.frontEndMsec += ri.Milliseconds() - startTime;
|
||||
}
|
||||
|
||||
//
|
||||
// OPENMOHAA-specific stuff
|
||||
//
|
||||
|
||||
void RE_AddRefSpriteToScene(const refEntity_t* ent) {
|
||||
refSprite_t* spr;
|
||||
int i;
|
||||
|
||||
if (!tr.registered) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (r_numsprites >= MAX_SPRITES) {
|
||||
return;
|
||||
}
|
||||
|
||||
spr = &backEndData->sprites[r_numsprites];
|
||||
VectorCopy(ent->origin, spr->origin);
|
||||
spr->surftype = SF_SPRITE;
|
||||
spr->hModel = ent->hModel;
|
||||
spr->scale = ent->scale;
|
||||
spr->renderfx = ent->renderfx;
|
||||
spr->shaderTime = ent->shaderTime;
|
||||
AxisCopy(ent->axis, spr->axis);
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
spr->shaderRGBA[i] = ent->shaderRGBA[i];
|
||||
}
|
||||
|
||||
++r_numsprites;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
RE_AddPolyToScene
|
||||
|
||||
=====================
|
||||
*/
|
||||
qboolean RE_AddPolyToScene2(qhandle_t hShader, int numVerts, const polyVert_t* verts, int renderfx) {
|
||||
srfPoly_t *poly;
|
||||
|
||||
if ( !tr.registered ) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
if (numVerts + r_numpolyverts > max_polyverts || r_numpolys >= max_polys) {
|
||||
ri.Printf(PRINT_WARNING, "Exceeded MAX POLYS\n");
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
poly = &backEndData->polys[r_numpolys];
|
||||
poly->surfaceType = SF_POLY;
|
||||
poly->hShader = hShader;
|
||||
poly->numVerts = numVerts;
|
||||
poly->verts = &backEndData->polyVerts[r_numpolyverts];
|
||||
poly->renderfx = renderfx;
|
||||
|
||||
Com_Memcpy(poly->verts, verts, sizeof(polyVert_t) * numVerts);
|
||||
++r_numpolys;
|
||||
r_numpolyverts += numVerts;
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
R_AddTerrainMarkSurfaces
|
||||
=====================
|
||||
*/
|
||||
void R_AddTerrainMarkSurfaces(void) {
|
||||
srfMarkFragment_t* terMark;
|
||||
int j;
|
||||
shader_t* shader;
|
||||
|
||||
for (j = 0; j < tr.refdef.numTerMarks; j++)
|
||||
{
|
||||
terMark = &tr.refdef.terMarks[j];
|
||||
|
||||
shader = R_GetShaderByHandle(terMark->surfaceType);
|
||||
terMark->surfaceType = SF_MARK_FRAG;
|
||||
R_AddDrawSurf(&terMark->surfaceType, shader, 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
RE_AddTerrainMarkToScene
|
||||
=====================
|
||||
*/
|
||||
void RE_AddTerrainMarkToScene(int iTerrainIndex, qhandle_t hShader, int numVerts, const polyVert_t* verts, int renderfx) {
|
||||
srfMarkFragment_t* terMark;
|
||||
|
||||
if (!tr.registered) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (numVerts + r_numpolyverts > max_polyverts || r_numtermarks >= max_termarks) {
|
||||
ri.Printf(PRINT_WARNING, "Exceeded MAX TERRAIN MARKS\n");
|
||||
return;
|
||||
}
|
||||
|
||||
terMark = &backEndData->terMarks[r_numtermarks];
|
||||
terMark->surfaceType = hShader;
|
||||
terMark->iIndex = iTerrainIndex;
|
||||
terMark->numVerts = numVerts;
|
||||
terMark->verts = &backEndData->polyVerts[r_numpolyverts];
|
||||
memcpy(terMark->verts, verts, sizeof(polyVert_t) * numVerts);
|
||||
|
||||
r_numtermarks++;
|
||||
r_numpolyverts += numVerts;
|
||||
}
|
||||
|
||||
//=================================================================================
|
||||
|
||||
/*
|
||||
=====================
|
||||
RE_GetRenderEntity
|
||||
=====================
|
||||
*/
|
||||
refEntity_t* RE_GetRenderEntity(int entityNumber) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < r_numentities; i++) {
|
||||
if (backEndData->entities[i].e.entityNumber == entityNumber) {
|
||||
return &backEndData->entities[i].e;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -4025,3 +4025,38 @@ void R_InitShaders( void ) {
|
|||
|
||||
CreateExternalShaders();
|
||||
}
|
||||
|
||||
qhandle_t RE_RefreshShaderNoMip(const char* name) {
|
||||
shader_t* sh;
|
||||
char strippedName[64];
|
||||
int hash;
|
||||
|
||||
if (!name || !*name) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
COM_StripExtension(name, strippedName, sizeof(strippedName));
|
||||
|
||||
hash = generateHashValue(strippedName, FILE_HASH_SIZE);
|
||||
|
||||
for (sh = hashTable[hash]; sh; sh = sh->next) {
|
||||
if (Q_stricmp(sh->name, strippedName) == 0) {
|
||||
image_t* image;
|
||||
|
||||
image = sh->stages[0]->bundle[0].image[0];
|
||||
|
||||
if (image) {
|
||||
sh->stages[0]->bundle[0].image[0] = R_RefreshImageFile(image->imgName, IMGTYPE_COLORALPHA, image->flags);
|
||||
}
|
||||
|
||||
return sh->index;
|
||||
}
|
||||
}
|
||||
|
||||
sh = R_FindShader(name, -4, qfalse);
|
||||
if (sh->defaultShader) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return sh->index;
|
||||
}
|
254
code/renderergl2/tr_sky_portal.cpp
Normal file
254
code/renderergl2/tr_sky_portal.cpp
Normal file
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// tr_sky_portal.cpp: sky portal
|
||||
|
||||
#include "tr_local.h"
|
||||
|
||||
/*
|
||||
=================
|
||||
R_Sky_Init
|
||||
|
||||
=================
|
||||
*/
|
||||
void R_Sky_Init()
|
||||
{
|
||||
tr.viewParms.isPortalSky = qfalse;
|
||||
tr.portalsky.numSurfs = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_Sky_Reset
|
||||
|
||||
=================
|
||||
*/
|
||||
void R_Sky_Reset()
|
||||
{
|
||||
if (tr.viewParms.isPortalSky) {
|
||||
return;
|
||||
}
|
||||
|
||||
tr.portalsky.mins[0] = 8192.0;
|
||||
tr.portalsky.mins[1] = 8192.0;
|
||||
tr.portalsky.mins[2] = 8192.0;
|
||||
tr.portalsky.maxs[0] = -8192.0;
|
||||
tr.portalsky.maxs[1] = -8192.0;
|
||||
tr.portalsky.maxs[2] = -8192.0;
|
||||
tr.portalsky.cntNode = 0;
|
||||
tr.portalsky.numSurfs = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_Sky_AddSurf
|
||||
|
||||
=================
|
||||
*/
|
||||
void R_Sky_AddSurf(msurface_t *surf)
|
||||
{
|
||||
if (tr.viewParms.isPortalSky) {
|
||||
static int last_sky_warning = 0;
|
||||
|
||||
if (tr.refdef.time - 1000 > last_sky_warning) {
|
||||
ri.Printf(3, "WARNING: sky being drawn in a sky portal! Bad! Bad!\n");
|
||||
last_sky_warning = tr.refdef.time;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (tr.portalsky.numSurfs < 32) {
|
||||
tr.portalsky.skySurfs[tr.portalsky.numSurfs++] = surf;
|
||||
}
|
||||
|
||||
if (tr.portalsky.cntNode) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (tr.portalsky.mins[i] >= tr.portalsky.cntNode->mins[i]) {
|
||||
tr.portalsky.mins[i] = tr.portalsky.cntNode->mins[i];
|
||||
}
|
||||
|
||||
if (tr.portalsky.maxs[i] >= tr.portalsky.cntNode->maxs[i]) {
|
||||
tr.portalsky.maxs[i] = tr.portalsky.cntNode->maxs[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_Sky_Render
|
||||
|
||||
=================
|
||||
*/
|
||||
void R_Sky_Render()
|
||||
{
|
||||
int i;
|
||||
viewParms_t newParms, oldParms;
|
||||
mnode_t *leaf;
|
||||
|
||||
if (!tr.portalsky.numSurfs) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!tr.refdef.sky_portal) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (tr.skyRendered) {
|
||||
// already rendered
|
||||
return;
|
||||
}
|
||||
|
||||
if (tr.viewParms.isPortalSky) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < tr.portalsky.numSurfs; i++) {
|
||||
if (!SurfIsOffscreen2(
|
||||
(const srfBspSurface_t*)tr.portalsky.skySurfs[i]->data,
|
||||
tr.portalsky.skySurfs[i]->shader,
|
||||
ENTITYNUM_WORLD
|
||||
)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == tr.portalsky.numSurfs) {
|
||||
return;
|
||||
}
|
||||
|
||||
oldParms = tr.viewParms;
|
||||
newParms = tr.viewParms;
|
||||
|
||||
if (r_skyportal->integer) {
|
||||
if (sscanf(
|
||||
r_skyportal_origin->string,
|
||||
"%f %f %f",
|
||||
&newParms.or.origin[0],
|
||||
&newParms.or.origin[1],
|
||||
&newParms.or.origin[2]
|
||||
)
|
||||
!= 3) {
|
||||
ri.Printf(PRINT_WARNING, "WARNING: Invalid sky portal origin: %s\n", r_skyportal_origin->string);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
VectorCopy(tr.refdef.sky_origin, newParms.or.origin);
|
||||
MatrixMultiply(newParms.or.axis, tr.refdef.sky_axis, newParms.or.axis);
|
||||
}
|
||||
|
||||
VectorCopy(newParms.or.origin, newParms.pvsOrigin);
|
||||
newParms.isPortalSky = qtrue;
|
||||
newParms.farplane_distance = tr.refdef.skybox_farplane;
|
||||
newParms.renderTerrain = tr.refdef.render_terrain;
|
||||
|
||||
if (oldParms.farplane_bias == 0.0 || oldParms.farplane_distance == 0.0) {
|
||||
newParms.farplane_bias = 0.0;
|
||||
} else {
|
||||
newParms.farplane_bias = newParms.farplane_distance / oldParms.farplane_distance * oldParms.farplane_bias;
|
||||
}
|
||||
|
||||
leaf = R_PointInLeaf(newParms.pvsOrigin);
|
||||
if (leaf) {
|
||||
R_RenderView(&newParms);
|
||||
}
|
||||
|
||||
tr.viewParms = oldParms;
|
||||
|
||||
tr.portalsky.numSurfs = 0;
|
||||
tr.skyRendered = qtrue;
|
||||
|
||||
R_RotateForViewer();
|
||||
R_SetupFrustum();
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
R_Sky_ChangeFrustum
|
||||
|
||||
=================
|
||||
*/
|
||||
void R_Sky_ChangeFrustum()
|
||||
{
|
||||
cplane_t *frust;
|
||||
int i;
|
||||
vec3_t bounds[2];
|
||||
vec3_t origin;
|
||||
cplane_t abouts[4];
|
||||
|
||||
VectorCopy(tr.portalsky.mins, bounds[0]);
|
||||
VectorCopy(tr.portalsky.maxs, bounds[1]);
|
||||
VectorCopy(tr.viewParms.or.origin, origin);
|
||||
|
||||
VectorCopy(tr.viewParms.or.axis[2], abouts[0].normal);
|
||||
VectorNegate(tr.viewParms.or.axis[2], abouts[1].normal);
|
||||
VectorCopy(tr.viewParms.or.axis[1], abouts[2].normal);
|
||||
VectorNegate(tr.viewParms.or.axis[1], abouts[3].normal);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
cplane_t out;
|
||||
int i1;
|
||||
float leastfov = 99999;
|
||||
|
||||
frust = &tr.viewParms.frustum[i];
|
||||
|
||||
abouts[i].dist = DotProduct(tr.viewParms.or.origin, abouts[i].normal);
|
||||
CrossProduct(frust->normal, abouts[i].normal, out.normal);
|
||||
|
||||
for (i1 = 0; i1 < 8; i1++) {
|
||||
vec3_t point;
|
||||
vec_t distFromFrustum;
|
||||
float angle;
|
||||
int i2;
|
||||
|
||||
for (i2 = 0; i2 < 3; i2++) {
|
||||
point[i2] = bounds[i1 % 3][i2];
|
||||
}
|
||||
|
||||
VectorSubtract(point, origin, point);
|
||||
distFromFrustum = DotProduct(point, frust->normal);
|
||||
if (distFromFrustum <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
angle = atan2(DotProduct(point, out.normal), distFromFrustum);
|
||||
if (angle >= 0) {
|
||||
angle = RAD2DEG(angle);
|
||||
if (leastfov > angle) {
|
||||
leastfov = angle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (leastfov > 0 && leastfov < 180) {
|
||||
RotatePointAroundVector(frust->normal, abouts[i].normal, frust->normal, leastfov);
|
||||
VectorNormalize(frust->normal);
|
||||
|
||||
frust->type = PLANE_NON_AXIAL;
|
||||
frust->dist = DotProduct(origin, frust->normal);
|
||||
SetPlaneSignbits(frust);
|
||||
}
|
||||
}
|
||||
}
|
1465
code/renderergl2/tr_sphere_shade.cpp
Normal file
1465
code/renderergl2/tr_sphere_shade.cpp
Normal file
File diff suppressed because it is too large
Load diff
218
code/renderergl2/tr_sprite.c
Normal file
218
code/renderergl2/tr_sprite.c
Normal file
|
@ -0,0 +1,218 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2010 su44
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
// tr_sprite.c - MoHAA sprite system
|
||||
|
||||
#include "tr_local.h"
|
||||
|
||||
/*
|
||||
=====================
|
||||
SPR_RegisterSprite
|
||||
=====================
|
||||
*/
|
||||
sprite_t *SPR_RegisterSprite(const char *name)
|
||||
{
|
||||
image_t *spriteImage;
|
||||
shader_t *shader;
|
||||
sprite_t *spr;
|
||||
char shadername[256];
|
||||
COM_StripExtension(name,shadername,sizeof(shadername));
|
||||
shader = R_FindShader(shadername,-1,qfalse);
|
||||
if(shader) {
|
||||
spriteImage = 0;
|
||||
if(shader->stages[0])
|
||||
spriteImage = shader->stages[0]->bundle[0].image[0];
|
||||
if ( !spriteImage ) {
|
||||
ri.Printf(1, "Could not find image for sprite in shader %s\n", name);
|
||||
return 0;
|
||||
}
|
||||
spr = ri.Hunk_Alloc(sizeof(sprite_t), h_dontcare);
|
||||
spr->height = spriteImage->height;
|
||||
spr->width = spriteImage->width;
|
||||
spr->origin_x = spr->width * 0.5;
|
||||
spr->origin_y = spr->height * 0.5;
|
||||
spr->shader = shader;
|
||||
spr->scale = spr->shader->sprite.scale;
|
||||
return spr;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int CullSprite(const vec3_t* points) {
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < backEnd.viewParms.fog.extrafrustums + 4; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
if (DotProduct(points[j], backEnd.viewParms.frustum[i].normal) - backEnd.viewParms.frustum[i].dist > 0.0f) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (j == 4) {
|
||||
return CULL_CLIP;
|
||||
}
|
||||
}
|
||||
|
||||
return CULL_IN;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
RB_DrawSprite
|
||||
=====================
|
||||
*/
|
||||
void RB_DrawSprite( const refSprite_t *spr ) {
|
||||
model_t* model;
|
||||
vec3_t norm;
|
||||
vec3_t up, right;
|
||||
vec3_t points[4];
|
||||
float org_x, org_y;
|
||||
float scale;
|
||||
int i;
|
||||
|
||||
if (!spr->hModel)
|
||||
{
|
||||
ri.Printf(PRINT_WARNING, "No model found for Sprite\n");
|
||||
return;
|
||||
}
|
||||
|
||||
model = tr.models;
|
||||
if (spr->hModel > 0 && spr->hModel < tr.numModels) {
|
||||
model = &tr.models[spr->hModel];
|
||||
}
|
||||
|
||||
scale = spr->scale * model->d.sprite->scale;
|
||||
|
||||
switch (model->d.sprite->shader->sprite.type)
|
||||
{
|
||||
case SPRITE_PARALLEL_ORIENTED:
|
||||
{
|
||||
float invmag;
|
||||
float cr, sr;
|
||||
int i;
|
||||
|
||||
invmag = 1.0 / sqrt(spr->axis[1][2] * spr->axis[1][2] + spr->axis[1][1] * spr->axis[1][1]);
|
||||
|
||||
cr = invmag * spr->axis[1][1];
|
||||
sr = invmag * spr->axis[1][2];
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
up[i] = backEnd.viewParms.or.axis[2][i] * cr - backEnd.viewParms.or.axis[1][i] * sr;
|
||||
right[i] = backEnd.viewParms.or.axis[1][i] * cr + backEnd.viewParms.or.axis[2][i] * sr;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SPRITE_PARALLEL:
|
||||
VectorCopy(backEnd.viewParms.or.axis[2], up);
|
||||
if (!backEnd.viewParms.isMirror) {
|
||||
VectorNegate(backEnd.viewParms.or.axis[1], right);
|
||||
} else {
|
||||
VectorCopy(backEnd.viewParms.or.axis[1], right);
|
||||
}
|
||||
break;
|
||||
case SPRITE_ORIENTED:
|
||||
VectorCopy(spr->axis[1], right);
|
||||
VectorCopy(spr->axis[2], up);
|
||||
break;
|
||||
case SPRITE_PARALLEL_UPRIGHT:
|
||||
VectorCopy(backEnd.viewParms.or.axis[0], norm);
|
||||
VectorCopy(backEnd.viewParms.or.axis[1], right);
|
||||
VectorCopy(backEnd.viewParms.or.axis[2], up);
|
||||
if (backEnd.viewParms.or.axis[0][2] > 0.999) {
|
||||
return;
|
||||
} else if (backEnd.viewParms.or.axis[0][2] < -0.999) {
|
||||
return;
|
||||
}
|
||||
|
||||
VectorSet(up, 0.0f, 0.0f, 1.0f);
|
||||
VectorSet(right, backEnd.viewParms.or.axis[0][1], -backEnd.viewParms.or.axis[0][0], 0.0f);
|
||||
VectorNormalize(right);
|
||||
VectorSet(norm, -right[1], right[0], 0.0f);
|
||||
break;
|
||||
}
|
||||
|
||||
org_x = model->d.sprite->origin_x * scale;
|
||||
org_y = model->d.sprite->origin_y * scale;
|
||||
|
||||
VectorScale(up, org_y, up);
|
||||
VectorScale(right, org_x, right);
|
||||
|
||||
points[0][0] = spr->origin[0] + up[0] - right[0];
|
||||
points[1][0] = spr->origin[0] + up[0] + right[0];
|
||||
points[2][0] = spr->origin[0] - up[0] - right[0];
|
||||
points[3][0] = spr->origin[0] - up[0] + right[0];
|
||||
|
||||
points[0][1] = spr->origin[1] + up[1] - right[1];
|
||||
points[1][1] = spr->origin[1] + up[1] + right[1];
|
||||
points[2][1] = spr->origin[1] - up[1] - right[1];
|
||||
points[3][1] = spr->origin[1] - up[1] + right[1];
|
||||
|
||||
points[0][2] = spr->origin[2] + up[2] - right[2];
|
||||
points[1][2] = spr->origin[2] + up[2] + right[2];
|
||||
points[2][2] = spr->origin[2] - up[2] - right[2];
|
||||
points[3][2] = spr->origin[2] - up[2] + right[2];
|
||||
|
||||
if (CullSprite(points) == CULL_OUT) {
|
||||
return;
|
||||
}
|
||||
|
||||
RB_CHECKOVERFLOW(4, 6);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
tess.color[tess.numVertexes + i][0] = spr->shaderRGBA[0] * 0xffff / 0xff;
|
||||
tess.color[tess.numVertexes + i][1] = spr->shaderRGBA[1] * 0xffff / 0xff;
|
||||
tess.color[tess.numVertexes + i][2] = spr->shaderRGBA[2] * 0xffff / 0xff;
|
||||
tess.color[tess.numVertexes + i][3] = spr->shaderRGBA[3] * 0xffff / 0xff;
|
||||
}
|
||||
|
||||
tess.texCoords[tess.numVertexes][0] = 0.0f;
|
||||
tess.texCoords[tess.numVertexes][1] = 0.0f;
|
||||
tess.texCoords[tess.numVertexes + 1][0] = 1.0f;
|
||||
tess.texCoords[tess.numVertexes + 1][1] = 0.0f;
|
||||
tess.texCoords[tess.numVertexes + 2][0] = 0.0f;
|
||||
tess.texCoords[tess.numVertexes + 2][1] = 1.0f;
|
||||
tess.texCoords[tess.numVertexes + 3][0] = 1.0f;
|
||||
tess.texCoords[tess.numVertexes + 3][1] = 1.0f;
|
||||
|
||||
tess.xyz[tess.numVertexes][0] = points[0][0];
|
||||
tess.xyz[tess.numVertexes][1] = points[0][1];
|
||||
tess.xyz[tess.numVertexes][2] = points[0][2];
|
||||
tess.xyz[tess.numVertexes + 1][0] = points[1][0];
|
||||
tess.xyz[tess.numVertexes + 1][1] = points[1][1];
|
||||
tess.xyz[tess.numVertexes + 1][2] = points[1][2];
|
||||
tess.xyz[tess.numVertexes + 2][0] = points[2][0];
|
||||
tess.xyz[tess.numVertexes + 2][1] = points[2][1];
|
||||
tess.xyz[tess.numVertexes + 2][2] = points[2][2];
|
||||
tess.xyz[tess.numVertexes + 3][0] = points[3][0];
|
||||
tess.xyz[tess.numVertexes + 3][1] = points[3][1];
|
||||
tess.xyz[tess.numVertexes + 3][2] = points[3][2];
|
||||
|
||||
tess.indexes[tess.numIndexes] = tess.numVertexes + 2;
|
||||
tess.indexes[tess.numIndexes + 1] = tess.numVertexes + 1;
|
||||
tess.indexes[tess.numIndexes + 2] = tess.numVertexes;
|
||||
tess.indexes[tess.numIndexes + 3] = tess.numVertexes + 2;
|
||||
tess.indexes[tess.numIndexes + 4] = tess.numVertexes + 3;
|
||||
tess.indexes[tess.numIndexes + 5] = tess.numVertexes + 1;
|
||||
|
||||
tess.numVertexes += 4;
|
||||
tess.numIndexes += 6;
|
||||
}
|
586
code/renderergl2/tr_staticmodels.cpp
Normal file
586
code/renderergl2/tr_staticmodels.cpp
Normal file
|
@ -0,0 +1,586 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// tr_staticmodels.cpp -- static model rendering
|
||||
|
||||
#include "tr_local.h"
|
||||
#include "tiki.h"
|
||||
|
||||
#define MAX_STATIC_MODELS_SURFS 8192
|
||||
#define MAX_DISTINCT_STATIC_MODELS 1000
|
||||
|
||||
int g_nStaticSurfaces;
|
||||
staticSurface_t g_staticSurfaces[MAX_STATIC_MODELS_SURFS];
|
||||
qboolean g_bInfostaticmodels = qfalse;
|
||||
|
||||
/*
|
||||
==============
|
||||
R_InitStaticModels
|
||||
==============
|
||||
*/
|
||||
void R_InitStaticModels(void)
|
||||
{
|
||||
cStaticModelUnpacked_t *pSM;
|
||||
char szTemp[1024];
|
||||
skelBoneCache_t bones[128];
|
||||
float radius;
|
||||
int i, j, k, l;
|
||||
|
||||
g_bInfostaticmodels = qfalse;
|
||||
|
||||
if (tr.overbrightShift) {
|
||||
for (i = 0; i < tr.world->numStaticModelData; i++) {
|
||||
int r, g, b;
|
||||
|
||||
r = (int)((float)tr.world->staticModelData[i * 4] * tr.overbrightMult);
|
||||
g = (int)((float)tr.world->staticModelData[i * 4 + 1] * tr.overbrightMult);
|
||||
b = (int)((float)tr.world->staticModelData[i * 4 + 2] * tr.overbrightMult);
|
||||
|
||||
if (r > 0xFF || g > 0xFF || b > 0xFF) {
|
||||
float t;
|
||||
|
||||
t = 255.0 / (float)Q_max(r, Q_max(g, b));
|
||||
|
||||
r = (int)((float)r * t);
|
||||
g = (int)((float)g * t);
|
||||
b = (int)((float)b * t);
|
||||
}
|
||||
|
||||
tr.world->staticModelData[i * 4] = r;
|
||||
tr.world->staticModelData[i * 4 + 1] = g;
|
||||
tr.world->staticModelData[i * 4 + 2] = b;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < tr.world->numStaticModels; i++) {
|
||||
vec3_t mins, maxs;
|
||||
|
||||
pSM = &tr.world->staticModels[i];
|
||||
|
||||
pSM->bRendered = qfalse;
|
||||
AngleVectorsLeft(pSM->angles, pSM->axis[0], pSM->axis[1], pSM->axis[2]);
|
||||
|
||||
if (!strnicmp(pSM->model, "models", 6)) {
|
||||
Q_strncpyz(szTemp, pSM->model, sizeof(szTemp));
|
||||
} else {
|
||||
Com_sprintf(szTemp, sizeof(szTemp), "models/%s", pSM->model);
|
||||
}
|
||||
|
||||
ri.FS_CanonicalFilename(szTemp);
|
||||
//const bool exists = ri.TIKI_FindTiki(szTemp) != NULL;
|
||||
pSM->tiki = ri.TIKI_RegisterTikiFlags(szTemp, qfalse);
|
||||
|
||||
if (!pSM->tiki) {
|
||||
ri.Printf(PRINT_WARNING, "^~^~^: Warning: Cannot Load Static Model %s\n", szTemp);
|
||||
continue;
|
||||
}
|
||||
|
||||
pSM->radius = ri.TIKI_GlobalRadius(pSM->tiki);
|
||||
|
||||
//
|
||||
// register shaders
|
||||
//
|
||||
for (j = 0; j < pSM->tiki->num_surfaces; j++) {
|
||||
dtikisurface_t *surf = &pSM->tiki->surfaces[j];
|
||||
|
||||
for (k = 0; k < surf->numskins; k++) {
|
||||
if (surf->shader[k][0]) {
|
||||
shader_t *sh = R_FindShader(surf->shader[k], -1, !(surf->flags & TIKI_SURF_NOMIPMAPS));
|
||||
surf->hShader[k] = sh->index;
|
||||
} else {
|
||||
surf->hShader[k] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// prepare the skeleton frame for the static model
|
||||
ri.TIKI_GetSkelAnimFrame(pSM->tiki, bones, &radius, &mins, &maxs);
|
||||
pSM->cull_radius = radius * pSM->tiki->load_scale * pSM->scale;
|
||||
|
||||
// Suggestion:
|
||||
// It would be cool to have animated static model in the future
|
||||
|
||||
// Removed in 2.0
|
||||
// This only leads to issues where pStaticXyz is not initialized
|
||||
// and it can occurs if the TIKI model is registered before the static model
|
||||
//if (exists) {
|
||||
// continue;
|
||||
//}
|
||||
|
||||
for (j = 0; j < pSM->tiki->numMeshes; j++) {
|
||||
skelHeaderGame_t *skelmodel = ri.TIKI_GetSkel(pSM->tiki->mesh[j]);
|
||||
skelSurfaceGame_t *surf;
|
||||
|
||||
if (!skelmodel) {
|
||||
ri.Printf(PRINT_WARNING, "^~^~^: Warning: Missing mesh in Static Model %s\n", skelmodel->name);
|
||||
continue;
|
||||
}
|
||||
|
||||
surf = skelmodel->pSurfaces;
|
||||
|
||||
for (k = 0; k < skelmodel->numSurfaces; k++, surf = surf->pNext) {
|
||||
byte *buf;
|
||||
byte *p;
|
||||
skelWeight_t *weight;
|
||||
skeletorVertex_t *vert;
|
||||
|
||||
if (surf->pStaticXyz) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// allocate static vectors
|
||||
p = buf =
|
||||
(byte *)ri.TIKI_Alloc((sizeof(vec4_t) + sizeof(vec4_t) + sizeof(vec2_t) * 2) * surf->numVerts);
|
||||
surf->pStaticXyz = (vec4_t *)p;
|
||||
p += sizeof(vec4_t) * surf->numVerts;
|
||||
surf->pStaticNormal = (vec4_t *)p;
|
||||
p += sizeof(vec4_t) * surf->numVerts;
|
||||
surf->pStaticTexCoords = (vec2_t(*)[2])p;
|
||||
|
||||
vert = surf->pVerts;
|
||||
|
||||
for (l = 0; l < surf->numVerts; l++) {
|
||||
int channel;
|
||||
skelBoneCache_t *bone;
|
||||
|
||||
weight = (skelWeight_t *)((byte *)vert + sizeof(skeletorVertex_t)
|
||||
+ vert->numMorphs * sizeof(skeletorMorph_t));
|
||||
|
||||
if (j > 0) {
|
||||
channel = ri.TIKI_GetLocalChannel(pSM->tiki, skelmodel->pBones[weight->boneIndex].channel);
|
||||
} else {
|
||||
channel = weight->boneIndex;
|
||||
}
|
||||
|
||||
bone = &bones[channel];
|
||||
|
||||
surf->pStaticXyz[l][0] =
|
||||
((weight->offset[0] * bone->matrix[0][0] + weight->offset[1] * bone->matrix[1][0]
|
||||
+ weight->offset[2] * bone->matrix[2][0])
|
||||
+ bone->offset[0])
|
||||
* weight->boneWeight;
|
||||
surf->pStaticXyz[l][1] =
|
||||
((weight->offset[0] * bone->matrix[0][1] + weight->offset[1] * bone->matrix[1][1]
|
||||
+ weight->offset[2] * bone->matrix[2][1])
|
||||
+ bone->offset[1])
|
||||
* weight->boneWeight;
|
||||
surf->pStaticXyz[l][2] =
|
||||
((weight->offset[0] * bone->matrix[0][2] + weight->offset[1] * bone->matrix[1][2]
|
||||
+ weight->offset[2] * bone->matrix[2][2])
|
||||
+ bone->offset[2])
|
||||
* weight->boneWeight;
|
||||
surf->pStaticXyz[l][3] = 0.f;
|
||||
|
||||
surf->pStaticNormal[l][0] = vert->normal[0] * bone->matrix[0][0]
|
||||
+ vert->normal[1] * bone->matrix[1][0]
|
||||
+ vert->normal[2] * bone->matrix[2][0];
|
||||
surf->pStaticNormal[l][1] = vert->normal[0] * bone->matrix[0][1]
|
||||
+ vert->normal[1] * bone->matrix[1][1]
|
||||
+ vert->normal[2] * bone->matrix[2][1];
|
||||
surf->pStaticNormal[l][2] = vert->normal[0] * bone->matrix[0][2]
|
||||
+ vert->normal[1] * bone->matrix[1][2]
|
||||
+ vert->normal[2] * bone->matrix[2][2];
|
||||
surf->pStaticNormal[l][3] = 0.f;
|
||||
|
||||
surf->pStaticTexCoords[l][0][0] = vert->texCoords[0];
|
||||
surf->pStaticTexCoords[l][0][1] = vert->texCoords[1];
|
||||
surf->pStaticTexCoords[l][1][0] = vert->texCoords[0];
|
||||
surf->pStaticTexCoords[l][1][1] = vert->texCoords[1];
|
||||
|
||||
vert = (skeletorVertex_t *)((byte *)vert + sizeof(skeletorVertex_t)
|
||||
+ sizeof(skeletorMorph_t) * vert->numMorphs
|
||||
+ sizeof(skelWeight_t) * vert->numWeights);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tr.refdef.numStaticModels = tr.world->numStaticModels;
|
||||
tr.refdef.staticModels = tr.world->staticModels;
|
||||
tr.refdef.numStaticModelData = tr.world->numStaticModelData;
|
||||
tr.refdef.staticModelData = tr.world->staticModelData;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
R_CullStaticModel
|
||||
==============
|
||||
*/
|
||||
static int R_CullStaticModel(dtiki_t *tiki, float fScale, const vec3_t vLocalOrg)
|
||||
{
|
||||
vec3_t bounds[2];
|
||||
int i;
|
||||
int cull;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
bounds[0][i] = vLocalOrg[i] + tiki->a->mins[i] * fScale;
|
||||
bounds[1][i] = vLocalOrg[i] + tiki->a->maxs[i] * fScale;
|
||||
}
|
||||
|
||||
cull = R_CullLocalBox(bounds);
|
||||
|
||||
if (r_showcull->integer & 4) {
|
||||
float fR, fG, fB;
|
||||
vec3_t vAngles;
|
||||
|
||||
switch (cull) {
|
||||
case CULL_CLIP:
|
||||
fR = 1.0f;
|
||||
fG = 1.0f;
|
||||
fB = 0.0f;
|
||||
break;
|
||||
case CULL_IN:
|
||||
fR = 0.0f;
|
||||
fG = 1.0f;
|
||||
fB = 0.0f;
|
||||
break;
|
||||
case CULL_OUT:
|
||||
fR = 1.0f;
|
||||
fG = 0.2f;
|
||||
fB = 0.2f;
|
||||
for (i = 0; i < 2; i++) {
|
||||
bounds[0][i] = bounds[0][i] - 16.0;
|
||||
bounds[1][i] = bounds[1][i] + 16.0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
MatrixToEulerAngles(tr.or.axis, vAngles);
|
||||
R_DebugRotatedBBox(tr.or.origin, vAngles, bounds[0], bounds[1], fR, fG, fB, 0.5);
|
||||
}
|
||||
|
||||
switch (cull) {
|
||||
case CULL_CLIP:
|
||||
tr.pc.c_box_cull_md3_clip++;
|
||||
break;
|
||||
case CULL_IN:
|
||||
tr.pc.c_box_cull_md3_in++;
|
||||
break;
|
||||
case CULL_OUT:
|
||||
tr.pc.c_box_cull_md3_out++;
|
||||
break;
|
||||
}
|
||||
|
||||
return cull;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
R_AddStaticModelSurfaces
|
||||
==============
|
||||
*/
|
||||
void R_AddStaticModelSurfaces(void)
|
||||
{
|
||||
cStaticModelUnpacked_t *SM;
|
||||
int i, j, k;
|
||||
int ofsStaticData;
|
||||
int iRadiusCull;
|
||||
dtiki_t *tiki;
|
||||
float tiki_scale;
|
||||
vec3_t tiki_localorigin;
|
||||
vec3_t tiki_worldorigin;
|
||||
|
||||
if (!tr.world->numStaticModels) {
|
||||
return;
|
||||
}
|
||||
|
||||
tr.shiftedIsStatic = (1 << QSORT_STATICMODEL_SHIFT);
|
||||
|
||||
for (i = 0; i < tr.world->numStaticModels; i++) {
|
||||
SM = &tr.world->staticModels[i];
|
||||
|
||||
//if( SM->visCount != tr.visCounts[ tr.visIndex ] ) {
|
||||
// continue;
|
||||
//}
|
||||
|
||||
tiki = SM->tiki;
|
||||
|
||||
if (!tiki) {
|
||||
continue;
|
||||
}
|
||||
|
||||
tr.currentEntityNum = i;
|
||||
tr.shiftedEntityNum = i << QSORT_REFENTITYNUM_SHIFT;
|
||||
|
||||
R_RotateForStaticModel(SM, &tr.viewParms, &tr.or);
|
||||
|
||||
ofsStaticData = 0;
|
||||
|
||||
// get the world position
|
||||
tiki_scale = tiki->load_scale * SM->scale;
|
||||
VectorScale(tiki->load_origin, tiki_scale, tiki_localorigin);
|
||||
R_LocalPointToWorld(tiki_localorigin, tiki_worldorigin);
|
||||
|
||||
iRadiusCull = R_CullPointAndRadius(tiki_worldorigin, SM->cull_radius);
|
||||
|
||||
if (r_showcull->integer & 8) {
|
||||
switch (iRadiusCull) {
|
||||
case CULL_IN:
|
||||
R_DebugCircle(tiki_worldorigin, SM->cull_radius * 1.2, 0.0, 1.0, 0.0, 0.5, 0);
|
||||
break;
|
||||
case CULL_OUT:
|
||||
R_DebugCircle(tiki_worldorigin, SM->cull_radius * 1.4 + 16.0, 1.0, 0.2, 0.2, 0.5, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (iRadiusCull != CULL_OUT
|
||||
&& (iRadiusCull != CULL_CLIP || R_CullStaticModel(SM->tiki, tiki_scale, tiki_localorigin) != CULL_OUT)) {
|
||||
dtikisurface_t *dsurf;
|
||||
|
||||
if (tr.viewParms.isPortal) {
|
||||
SM->lodpercentage[1] = R_CalcLod(tiki_worldorigin, SM->cull_radius / SM->scale);
|
||||
} else {
|
||||
SM->lodpercentage[0] = R_CalcLod(tiki_worldorigin, SM->cull_radius / SM->scale);
|
||||
}
|
||||
|
||||
//
|
||||
// draw all meshes
|
||||
//
|
||||
dsurf = tiki->surfaces;
|
||||
for (int mesh = 0; mesh < tiki->numMeshes; mesh++) {
|
||||
skelHeaderGame_t *skelmodel = ri.TIKI_GetSkel(tiki->mesh[mesh]);
|
||||
skelSurfaceGame_t *surface;
|
||||
staticSurface_t *s_surface;
|
||||
shader_t *shader;
|
||||
float fDist;
|
||||
vec3_t vDelta;
|
||||
|
||||
if (!skelmodel) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// draw all surfaces
|
||||
//
|
||||
surface = skelmodel->pSurfaces;
|
||||
for (j = 0; j < skelmodel->numSurfaces;
|
||||
j++, ofsStaticData += surface->numVerts, surface = surface->pNext, dsurf++) {
|
||||
if (g_nStaticSurfaces >= MAX_STATIC_MODELS_SURFS) {
|
||||
ri.Printf(
|
||||
PRINT_DEVELOPER,
|
||||
"^~^~^ ERROR: MAX_STATIC_MODELS_SURFS exceeded - surface of '%s' skipped\n",
|
||||
tiki->a->name
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
s_surface = &g_staticSurfaces[g_nStaticSurfaces++];
|
||||
s_surface->ident = SF_TIKI_STATIC;
|
||||
s_surface->ofsStaticData = ofsStaticData;
|
||||
s_surface->surface = surface;
|
||||
s_surface->meshNum = mesh;
|
||||
|
||||
shader = tr.shaders[dsurf->hShader[0]];
|
||||
|
||||
if (shader->numUnfoggedPasses == 1 && !r_nocull->integer) {
|
||||
switch (shader->stages[0]->alphaGen) {
|
||||
case AGEN_DIST_FADE:
|
||||
if (R_DistanceCullPointAndRadius(
|
||||
shader->fDistNear + shader->fDistRange, tiki_worldorigin, SM->cull_radius
|
||||
)
|
||||
== CULL_OUT) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case AGEN_ONE_MINUS_DIST_FADE:
|
||||
if (R_DistanceCullPointAndRadius(shader->fDistNear, tiki_worldorigin, SM->cull_radius)
|
||||
== CULL_IN) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case AGEN_TIKI_DIST_FADE:
|
||||
fDist = (shader->fDistNear + shader->fDistRange);
|
||||
VectorSubtract(tiki_worldorigin, tr.viewParms.or.origin, vDelta);
|
||||
if (VectorLengthSquared(vDelta) >= Square(fDist)) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case AGEN_ONE_MINUS_TIKI_DIST_FADE:
|
||||
fDist = (shader->fDistNear + shader->fDistRange);
|
||||
VectorSubtract(tiki_worldorigin, tr.viewParms.or.origin, vDelta);
|
||||
if (VectorLengthSquared(vDelta) <= Square(shader->fDistNear)) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SM->bRendered = qtrue;
|
||||
R_AddDrawSurf((surfaceType_t *)s_surface, shader, 0, 0, 0, 0);
|
||||
|
||||
if (r_showstaticlod->integer) {
|
||||
vec3_t org;
|
||||
int render_count, total_tris;
|
||||
|
||||
VectorCopy(SM->origin, org);
|
||||
org[2] += 100.0;
|
||||
R_DrawDebugNumber(org, SM->lodpercentage[0], r_showstaticlod->value * 2, 1.0, 1.0, 0.0, 3);
|
||||
|
||||
org[2] += 125.0;
|
||||
R_CountTikiLodTris(tiki, SM->lodpercentage[0], &render_count, &total_tris);
|
||||
R_DrawDebugNumber(org, render_count, r_showstaticlod->value * 2, 1.0, 1.0, 0.0, 0);
|
||||
}
|
||||
|
||||
if (r_showstaticbboxes->integer) {
|
||||
vec3_t vMins, vMaxs;
|
||||
|
||||
for (k = 0; k < 3; k++) {
|
||||
vMins[k] = tiki->a->mins[k] * tiki->load_scale * SM->scale;
|
||||
vMaxs[k] = tiki->a->maxs[k] * tiki->load_scale * SM->scale;
|
||||
}
|
||||
|
||||
R_DebugRotatedBBox(SM->origin, SM->angles, vMins, vMaxs, 1.0, 0.0, 1.0, 0.75);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tr.shiftedIsStatic = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
RB_Static_BuildDLights
|
||||
==============
|
||||
*/
|
||||
void RB_Static_BuildDLights()
|
||||
{
|
||||
int i;
|
||||
|
||||
backEnd.currentStaticModel->useSpecialLighting = backEnd.refdef.num_dlights > 0;
|
||||
backEnd.currentStaticModel->numdlights = 0;
|
||||
|
||||
if (!backEnd.currentStaticModel->useSpecialLighting) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < backEnd.refdef.num_dlights && backEnd.currentStaticModel->numdlights != 32; i++) {
|
||||
vec3_t lightorigin, delta;
|
||||
|
||||
VectorCopy(backEnd.refdef.dlights[i].origin, lightorigin);
|
||||
VectorSubtract(lightorigin, backEnd.currentStaticModel->origin, delta);
|
||||
if (backEnd.refdef.dlights[i].radius * 2.0 >= VectorLength(delta)) {
|
||||
MatrixTransformVectorRight(
|
||||
backEnd.currentStaticModel->axis,
|
||||
delta,
|
||||
backEnd.currentStaticModel->dlights[backEnd.currentStaticModel->numdlights].transformed
|
||||
);
|
||||
|
||||
backEnd.currentStaticModel->dlights[backEnd.currentStaticModel->numdlights++].index = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (!backEnd.currentStaticModel->numdlights) {
|
||||
backEnd.currentStaticModel->useSpecialLighting = qfalse;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
R_InfoStaticModels_f
|
||||
==============
|
||||
*/
|
||||
void R_InfoStaticModels_f(void)
|
||||
{
|
||||
g_bInfostaticmodels = qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
R_PrintInfoStaticModels
|
||||
==============
|
||||
*/
|
||||
void R_PrintInfoStaticModels()
|
||||
{
|
||||
int iRenderCount;
|
||||
int i, j;
|
||||
cStaticModelUnpacked_t *SM;
|
||||
dtiki_t *tikis[MAX_DISTINCT_STATIC_MODELS];
|
||||
int tiki_count[MAX_DISTINCT_STATIC_MODELS];
|
||||
cStaticModelUnpacked_t *pSM[MAX_DISTINCT_STATIC_MODELS];
|
||||
int count;
|
||||
|
||||
ri.Printf(PRINT_ALL, "Static model info:\n");
|
||||
ri.Printf(PRINT_ALL, "------------------\n");
|
||||
|
||||
count = 0;
|
||||
iRenderCount = 0;
|
||||
|
||||
for (i = 0; i < tr.world->numStaticModels; i++) {
|
||||
SM = &tr.world->staticModels[i];
|
||||
if (!SM->bRendered) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SM->bRendered = qfalse;
|
||||
iRenderCount++;
|
||||
|
||||
if (!SM->tiki) {
|
||||
ri.Printf(PRINT_ALL, "ERROR: static model with no tiki\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
for (j = 0; j < count; j++) {
|
||||
if (SM->tiki == tikis[j]) {
|
||||
tiki_count[j]++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (count >= MAX_DISTINCT_STATIC_MODELS) {
|
||||
ri.Printf(PRINT_ALL, "R_PrintInfoStaticModels: MAX_DISTINCT_STATIC_MODELS exceeded - increase and recompile\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (j == count) {
|
||||
tikis[count] = SM->tiki;
|
||||
pSM[count] = SM;
|
||||
tiki_count[count] = 1;
|
||||
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
ri.Printf(PRINT_ALL, "Total static models rendered: %d\n", iRenderCount);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
skelHeaderGame_t *skelmodel = ri.TIKI_GetSkel(tikis[i]->mesh[0]);
|
||||
|
||||
ri.Printf(PRINT_ALL,
|
||||
"model: %s, version: %d, count: %d,\n culling min %.1f %.1f %.1f, max %.1f %.1f %.1f, radius %.1f\n",
|
||||
tikis[i]->a->name,
|
||||
skelmodel ? skelmodel->version : -1,
|
||||
tiki_count[i],
|
||||
tikis[i]->a->mins[0],
|
||||
tikis[i]->a->mins[1],
|
||||
tikis[i]->a->mins[2],
|
||||
tikis[i]->a->maxs[0],
|
||||
tikis[i]->a->maxs[1],
|
||||
tikis[i]->a->maxs[2],
|
||||
pSM[i]->cull_radius
|
||||
);
|
||||
}
|
||||
}
|
732
code/renderergl2/tr_sun_flare.cpp
Normal file
732
code/renderergl2/tr_sun_flare.cpp
Normal file
|
@ -0,0 +1,732 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023-2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// tr_sun_flare.cpp: Sun flares
|
||||
|
||||
#include "tr_local.h"
|
||||
|
||||
#define MAX_FLARES 20
|
||||
|
||||
class flare_s
|
||||
{
|
||||
public:
|
||||
float size;
|
||||
float where;
|
||||
shader_t *shader;
|
||||
float alphascale;
|
||||
};
|
||||
|
||||
class lens_flare
|
||||
{
|
||||
public:
|
||||
static int max_flares;
|
||||
|
||||
float dot_min;
|
||||
float fullscale;
|
||||
|
||||
// List of flares
|
||||
int num_flares;
|
||||
flare_s flares[MAX_FLARES];
|
||||
|
||||
shader_t *fullscreen;
|
||||
int fullfade;
|
||||
qboolean blend_active;
|
||||
|
||||
// Flare location
|
||||
vec3_t trace_v;
|
||||
vec3_t v;
|
||||
|
||||
// Color and alpha
|
||||
vec3_t color;
|
||||
float alpha;
|
||||
|
||||
// Screen projection
|
||||
vec2_t screen;
|
||||
float dot;
|
||||
|
||||
int lasttime;
|
||||
float lastbright;
|
||||
|
||||
// Whether or not it's inside a portal sky
|
||||
bool inportalsky;
|
||||
|
||||
qboolean initted;
|
||||
|
||||
public:
|
||||
lens_flare()
|
||||
{
|
||||
color[0] = 1.0;
|
||||
color[1] = 1.0;
|
||||
color[2] = 1.0;
|
||||
alpha = 1.0;
|
||||
initted = false;
|
||||
}
|
||||
|
||||
bool CheckRange();
|
||||
bool CheckRay();
|
||||
bool ScreenCalc();
|
||||
virtual void Try();
|
||||
virtual void Init(const char *which);
|
||||
void ScreenBlend();
|
||||
void InPortalSky();
|
||||
void NotInPortalSky();
|
||||
void SetVect(const float *vect);
|
||||
|
||||
void SetColor(const float *c) { VectorCopy(c, color); }
|
||||
|
||||
void SetAlpha(float a) { alpha = a; }
|
||||
};
|
||||
|
||||
class dlight_lens_flare : public lens_flare
|
||||
{
|
||||
public:
|
||||
shader_t *corona_shader;
|
||||
|
||||
public:
|
||||
dlight_lens_flare() { corona_shader = NULL; }
|
||||
|
||||
void Try() override;
|
||||
|
||||
void Init(const char *which) override
|
||||
{
|
||||
lens_flare::Init(which);
|
||||
corona_shader = R_FindShader("textures/sprites/corona", -1, qfalse);
|
||||
}
|
||||
};
|
||||
|
||||
class sun_flare_class : public lens_flare
|
||||
{
|
||||
public:
|
||||
bool SunCheckRay();
|
||||
void SunScreenCalc();
|
||||
void SunTry();
|
||||
};
|
||||
|
||||
lens_flare torches;
|
||||
dlight_lens_flare dlights;
|
||||
sun_flare_class sunFlare;
|
||||
int lens_flare::max_flares;
|
||||
|
||||
void lens_flare::SetVect(const float *vect)
|
||||
{
|
||||
if (inportalsky) {
|
||||
vec3_t offset;
|
||||
vec3_t rot_offset;
|
||||
|
||||
VectorSubtract(vect, tr.refdef.sky_origin, offset);
|
||||
VectorRotate(offset, tr.refdef.sky_axis, rot_offset);
|
||||
VectorAdd(tr.refdef.vieworg, rot_offset, v);
|
||||
|
||||
VectorNormalize(offset);
|
||||
VectorMA(tr.refdef.vieworg, 16384, offset, trace_v);
|
||||
} else {
|
||||
VectorCopy(vect, v);
|
||||
VectorCopy(vect, trace_v);
|
||||
}
|
||||
}
|
||||
|
||||
void lens_flare::InPortalSky()
|
||||
{
|
||||
inportalsky = true;
|
||||
}
|
||||
|
||||
void lens_flare::NotInPortalSky()
|
||||
{
|
||||
inportalsky = false;
|
||||
}
|
||||
|
||||
bool lens_flare::CheckRange()
|
||||
{
|
||||
vec3_t diff;
|
||||
|
||||
VectorSubtract(v, backEnd.viewParms.or.origin, diff);
|
||||
VectorNormalizeFast(diff);
|
||||
dot = DotProduct(backEnd.viewParms.or.axis[0], diff);
|
||||
|
||||
return dot > dot_min;
|
||||
}
|
||||
|
||||
bool lens_flare::CheckRay()
|
||||
{
|
||||
trace_t trace;
|
||||
|
||||
ri.CM_BoxTrace(&trace, backEnd.viewParms.or.origin, trace_v, vec3_origin, vec3_origin, 0, CONTENTS_SOLID, qfalse);
|
||||
if (inportalsky) {
|
||||
return (trace.surfaceFlags & 4) != 0;
|
||||
}
|
||||
|
||||
return trace.fraction == 1.0;
|
||||
}
|
||||
|
||||
bool lens_flare::ScreenCalc()
|
||||
{
|
||||
vec4_t eye;
|
||||
vec4_t clip;
|
||||
vec4_t point;
|
||||
bool retval;
|
||||
int i, j;
|
||||
|
||||
retval = true;
|
||||
|
||||
VectorCopy(v, point);
|
||||
point[3] = 1.0;
|
||||
|
||||
VectorClear4(eye);
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
eye[i] += point[j] * tr.or.modelMatrix[i + j * 4];
|
||||
}
|
||||
}
|
||||
|
||||
VectorClear4(clip);
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
clip[i] += eye[j] * tr.viewParms.projectionMatrix[i + j * 4];
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (clip[i] >= clip[3] || clip[i] <= -clip[3]) {
|
||||
retval = false;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
screen[i] = clip[i] / clip[3];
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void lens_flare::Try()
|
||||
{
|
||||
vec2_t diff;
|
||||
vec2_t point;
|
||||
float alpha;
|
||||
int i;
|
||||
|
||||
if (!ScreenCalc()) {
|
||||
return;
|
||||
}
|
||||
if (!CheckRange()) {
|
||||
return;
|
||||
}
|
||||
if (!CheckRay()) {
|
||||
return;
|
||||
}
|
||||
|
||||
VectorScale2D(screen, -2.0, diff);
|
||||
alpha = (dot - dot_min) / (1.0 - dot_min);
|
||||
|
||||
for (i = 0; i < num_flares; i++) {
|
||||
flare_s *flare = &flares[i];
|
||||
|
||||
VectorMA2D(screen, flare->where, diff, point);
|
||||
|
||||
RB_Color4f(color[0], color[1], color[2], alpha * this->alpha * flare->alphascale);
|
||||
RB_StreamBegin(flare->shader);
|
||||
RB_Texcoord2f(0.0, 0.0);
|
||||
|
||||
RB_Vertex2f(point[0] - flare->size, point[1] + flare->size);
|
||||
RB_Texcoord2f(1.0, 0.0);
|
||||
|
||||
RB_Vertex2f(point[0] + flare->size, point[1] + flare->size);
|
||||
RB_Texcoord2f(0.0, 1.0);
|
||||
|
||||
RB_Vertex2f(point[0] - flare->size, point[1] - flare->size);
|
||||
RB_Texcoord2f(1.0, 1.0);
|
||||
|
||||
RB_Vertex2f(point[0] + flare->size, point[1] - flare->size);
|
||||
RB_StreamEnd();
|
||||
}
|
||||
|
||||
lasttime = backEnd.refdef.time;
|
||||
blend_active = true;
|
||||
lastbright = Square(alpha) * Square(alpha) * this->fullscale;
|
||||
}
|
||||
|
||||
void dlight_lens_flare::Try()
|
||||
{
|
||||
float size;
|
||||
|
||||
size = r_lightcoronasize->value;
|
||||
lens_flare::Try();
|
||||
lens_flare::CheckRange();
|
||||
|
||||
if (dot <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CheckRay()) {
|
||||
return;
|
||||
}
|
||||
|
||||
RB_Color4f(color[0], color[1], color[2], alpha);
|
||||
RB_StreamBegin(corona_shader);
|
||||
RB_Texcoord2f(0.0, 0.0);
|
||||
|
||||
RB_Vertex2f(screen[0] - size, screen[1] + size);
|
||||
RB_Texcoord2f(1.0, 0.0);
|
||||
|
||||
RB_Vertex2f(screen[0] + size, screen[1] + size);
|
||||
RB_Texcoord2f(0.0, 1.0);
|
||||
|
||||
RB_Vertex2f(screen[0] - size, screen[1] - size);
|
||||
RB_Texcoord2f(1.0, 1.0);
|
||||
|
||||
RB_Vertex2f(screen[0] + size, screen[1] - size);
|
||||
RB_StreamEnd();
|
||||
}
|
||||
|
||||
void lens_flare::ScreenBlend()
|
||||
{
|
||||
float alpha;
|
||||
int timediff;
|
||||
|
||||
if (!fullscreen || !blend_active) {
|
||||
return;
|
||||
}
|
||||
|
||||
timediff = backEnd.refdef.time - lasttime;
|
||||
if (timediff > fullfade) {
|
||||
blend_active = false;
|
||||
return;
|
||||
}
|
||||
|
||||
alpha = (float)(fullfade - timediff) / fullfade * lastbright;
|
||||
if (alpha <= 0.0001) {
|
||||
blend_active = false;
|
||||
return;
|
||||
}
|
||||
|
||||
RB_Color4f(1.0, 1.0, 1.0, alpha);
|
||||
|
||||
RB_StreamBegin(fullscreen);
|
||||
RB_Vertex2f(-1.0, -1.0);
|
||||
RB_Vertex2f(1.0, -1.0);
|
||||
RB_Vertex2f(-1.0, 1.0);
|
||||
RB_Vertex2f(1.0, 1.0);
|
||||
|
||||
RB_StreamEnd();
|
||||
}
|
||||
|
||||
class tmpRiFile
|
||||
{
|
||||
private:
|
||||
bool file_exists;
|
||||
void *buf;
|
||||
|
||||
public:
|
||||
tmpRiFile()
|
||||
{
|
||||
file_exists = false;
|
||||
buf = NULL;
|
||||
}
|
||||
|
||||
~tmpRiFile() { close(); }
|
||||
|
||||
int open(const char *which, void **buffer)
|
||||
{
|
||||
close();
|
||||
|
||||
if (ri.FS_ReadFile(which, buffer) != -1) {
|
||||
file_exists = true;
|
||||
buf = *buffer;
|
||||
}
|
||||
|
||||
return file_exists;
|
||||
}
|
||||
|
||||
bool exists() const { return file_exists; }
|
||||
|
||||
void close()
|
||||
{
|
||||
if (file_exists) {
|
||||
ri.FS_FreeFile(buf);
|
||||
file_exists = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void lens_flare::Init(const char *which)
|
||||
{
|
||||
char *file;
|
||||
const char *token;
|
||||
tmpRiFile theFile;
|
||||
|
||||
initted = false;
|
||||
theFile.open("global/lensflaredefs.txt", (void **)&file);
|
||||
|
||||
if (!theFile.exists()) {
|
||||
ri.Printf(PRINT_WARNING, "WARNING: Could not open lens flare info file!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
while ((token = COM_ParseExt(&file, qtrue))) {
|
||||
if (!file) {
|
||||
ri.Printf(PRINT_WARNING, "WARNING: could not find begin for section '%s' in lensflares\n", which);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Q_stricmp(token, "begin")) {
|
||||
token = COM_ParseExt(&file, qfalse);
|
||||
if (!Q_stricmp(token, which)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dot_min = 0.8f;
|
||||
fullscale = 0.7f;
|
||||
num_flares = 0;
|
||||
fullscreen = NULL;
|
||||
initted = true;
|
||||
fullfade = 0;
|
||||
blend_active = false;
|
||||
|
||||
while ((token = COM_ParseExt(&file, qtrue))) {
|
||||
if (!file) {
|
||||
ri.Printf(PRINT_WARNING, "WARNING: could not find end for section '%s' in lensflares\n", which);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!Q_stricmp(token, "dot_min")) {
|
||||
token = COM_ParseExt(&file, qfalse);
|
||||
if (!token[0]) {
|
||||
ri.Printf(PRINT_WARNING, "WARNING: invalid dot_min in lensflares\n");
|
||||
continue;
|
||||
}
|
||||
dot_min = atof(token);
|
||||
} else if (!Q_stricmp(token, "flare")) {
|
||||
assert(num_flares < MAX_FLARES);
|
||||
|
||||
flares[num_flares].alphascale = 1.0;
|
||||
|
||||
token = COM_ParseExt(&file, qfalse);
|
||||
if (!token[0]) {
|
||||
ri.Printf(PRINT_WARNING, "WARNING: no flare arg 1 for flare '%d' in lensflares\n", num_flares);
|
||||
continue;
|
||||
}
|
||||
flares[num_flares].size = atof(token);
|
||||
|
||||
token = COM_ParseExt(&file, qfalse);
|
||||
if (!token[0]) {
|
||||
ri.Printf(PRINT_WARNING, "WARNING: no flare arg 2 for flare '%d' in lensflares\n", num_flares);
|
||||
continue;
|
||||
}
|
||||
flares[num_flares].where = atof(token);
|
||||
|
||||
token = COM_ParseExt(&file, qfalse);
|
||||
if (!token[0]) {
|
||||
ri.Printf(PRINT_WARNING, "WARNING: no flare arg 3 for flare '%d' in lensflares\n", num_flares);
|
||||
continue;
|
||||
}
|
||||
flares[num_flares].shader = R_FindShader(token, -1, qfalse);
|
||||
|
||||
token = COM_ParseExt(&file, qfalse);
|
||||
if (token[0]) {
|
||||
flares[num_flares].alphascale = atof(token);
|
||||
}
|
||||
|
||||
num_flares++;
|
||||
} else if (!Q_stricmp(token, "fullscale")) {
|
||||
token = COM_ParseExt(&file, qfalse);
|
||||
if (!token[0]) {
|
||||
ri.Printf(PRINT_WARNING, "WARNING: no arg for fullscale, assuming default (in lensflares)\n");
|
||||
continue;
|
||||
}
|
||||
fullscale = atof(token);
|
||||
} else if (!Q_stricmp(token, "fullscreen")) {
|
||||
token = COM_ParseExt(&file, qfalse);
|
||||
if (!token[0]) {
|
||||
ri.Printf(PRINT_WARNING, "WARNING: no arg for fullsreen in lensflares\n");
|
||||
continue;
|
||||
}
|
||||
fullscreen = R_FindShader(token, -1, qfalse);
|
||||
} else if (!Q_stricmp(token, "fullfade")) {
|
||||
token = COM_ParseExt(&file, qfalse);
|
||||
if (!token[0]) {
|
||||
ri.Printf(PRINT_WARNING, "WARNING: no arg for fullfade in lensflares\n");
|
||||
continue;
|
||||
}
|
||||
fullfade = atof(token);
|
||||
} else if (!Q_stricmp(token, "end")) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!num_flares) {
|
||||
ri.Printf(PRINT_WARNING, "WARNING: no lensflares defined!\n");
|
||||
}
|
||||
lasttime = backEnd.refdef.time - fullfade;
|
||||
}
|
||||
|
||||
static void R_DrawSunFlare()
|
||||
{
|
||||
if (!s_sun.exists) {
|
||||
return;
|
||||
}
|
||||
if (!sunFlare.initted) {
|
||||
if (!s_sun.szFlareName[0]) {
|
||||
return;
|
||||
}
|
||||
if (Q_stricmp(s_sun.szFlareName, "none")) {
|
||||
sunFlare.Init(s_sun.szFlareName);
|
||||
}
|
||||
}
|
||||
|
||||
if (!sunFlare.initted) {
|
||||
s_sun.szFlareName[0] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sunFlare.num_flares) {
|
||||
return;
|
||||
}
|
||||
|
||||
VectorMA(backEnd.viewParms.or.origin, 16384, s_sun.flaredirection, sunFlare.trace_v);
|
||||
VectorMA(backEnd.viewParms.or.origin, 128, s_sun.flaredirection, sunFlare.v);
|
||||
|
||||
sunFlare.SunTry();
|
||||
}
|
||||
|
||||
static void R_DrawSunFlareBlend()
|
||||
{
|
||||
if (!s_sun.exists) {
|
||||
return;
|
||||
}
|
||||
if (!sunFlare.initted) {
|
||||
return;
|
||||
}
|
||||
|
||||
sunFlare.ScreenBlend();
|
||||
}
|
||||
|
||||
void R_DrawLensFlares()
|
||||
{
|
||||
// FIXME: unimplemented (GL2)
|
||||
#if 0
|
||||
int i;
|
||||
|
||||
R_RotateForViewer();
|
||||
|
||||
qglPushMatrix();
|
||||
qglLoadIdentity();
|
||||
qglMatrixMode(GL_PROJECTION);
|
||||
qglPushMatrix();
|
||||
qglLoadIdentity();
|
||||
qglOrtho(-1.0, 1.0, -1.0, 1.0, -99999.0, 99999.0);
|
||||
|
||||
tess.no_global_fog = true;
|
||||
R_DrawSunFlare();
|
||||
|
||||
for (i = 0; i < backEnd.refdef.num_entities; i++) {
|
||||
if ((backEnd.viewParms.isPortalSky && !(backEnd.refdef.entities[i].e.renderfx & RF_SKYENTITY))
|
||||
|| (!backEnd.viewParms.isPortalSky && (backEnd.refdef.entities[i].e.renderfx & RF_SKYENTITY))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (backEnd.refdef.entities[i].e.renderfx & RF_LENSFLARE) {
|
||||
vec3_t rgb;
|
||||
|
||||
if (backEnd.refdef.entities[i].e.renderfx & RF_SKYENTITY) {
|
||||
dlights.InPortalSky();
|
||||
} else {
|
||||
dlights.NotInPortalSky();
|
||||
}
|
||||
|
||||
dlights.SetVect(backEnd.refdef.entities[i].e.origin);
|
||||
|
||||
//
|
||||
// Set the dlight color from entity
|
||||
//
|
||||
|
||||
rgb[0] = backEnd.refdef.entities[i].e.shaderRGBA[0] / 255.0;
|
||||
rgb[1] = backEnd.refdef.entities[i].e.shaderRGBA[1] / 255.0;
|
||||
rgb[2] = backEnd.refdef.entities[i].e.shaderRGBA[2] / 255.0;
|
||||
dlights.SetColor(rgb);
|
||||
|
||||
dlights.Try();
|
||||
}
|
||||
|
||||
if (backEnd.refdef.entities[i].e.renderfx & RF_VIEWLENSFLARE) {
|
||||
vec3_t rgb;
|
||||
|
||||
if (backEnd.refdef.entities[i].e.renderfx & RF_SKYENTITY) {
|
||||
torches.InPortalSky();
|
||||
} else {
|
||||
torches.NotInPortalSky();
|
||||
}
|
||||
|
||||
torches.SetVect(backEnd.refdef.entities[i].e.origin);
|
||||
|
||||
rgb[0] = backEnd.refdef.entities[i].e.shaderRGBA[0] / 255.0;
|
||||
rgb[1] = backEnd.refdef.entities[i].e.shaderRGBA[1] / 255.0;
|
||||
rgb[2] = backEnd.refdef.entities[i].e.shaderRGBA[2] / 255.0;
|
||||
torches.SetColor(rgb);
|
||||
|
||||
torches.Try();
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < backEnd.refdef.num_dlights; i++) {
|
||||
if ((backEnd.refdef.dlights[i].type & dlighttype_t::lensflare)
|
||||
|| (backEnd.refdef.dlights[i].type & dlighttype_t::additive)) {
|
||||
dlights.NotInPortalSky();
|
||||
dlights.SetVect(backEnd.refdef.dlights[i].origin);
|
||||
dlights.SetColor(backEnd.refdef.dlights[i].color);
|
||||
|
||||
dlights.Try();
|
||||
}
|
||||
}
|
||||
|
||||
R_DrawSunFlareBlend();
|
||||
tess.no_global_fog = qfalse;
|
||||
|
||||
qglPopMatrix();
|
||||
qglMatrixMode(GL_MODELVIEW);
|
||||
qglPopMatrix();
|
||||
#endif
|
||||
}
|
||||
|
||||
void R_InitLensFlare()
|
||||
{
|
||||
torches.Init("entity");
|
||||
dlights.Init("dlight");
|
||||
sunFlare.initted = false;
|
||||
}
|
||||
|
||||
bool sun_flare_class::SunCheckRay()
|
||||
{
|
||||
mnode_t *pViewLeaf;
|
||||
trace_t trace;
|
||||
|
||||
pViewLeaf = R_PointInLeaf(tr.refdef.vieworg);
|
||||
|
||||
if (pViewLeaf->area == -1 || !tr.world->vis || tr.sSunLight.leaf != (mnode_s *)-1
|
||||
|| pViewLeaf->numlights && pViewLeaf->lights[0] == &tr.sSunLight) {
|
||||
ri.CM_BoxTrace(
|
||||
&trace, backEnd.viewParms.or.origin, trace_v, vec3_origin, vec3_origin, 0, CONTENTS_SOLID, qfalse
|
||||
);
|
||||
|
||||
if (trace.surfaceFlags & SURF_SKY) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void sun_flare_class::SunScreenCalc()
|
||||
{
|
||||
vec4_t eye;
|
||||
vec4_t clip;
|
||||
vec4_t point;
|
||||
int i, j;
|
||||
|
||||
VectorCopy(v, point);
|
||||
point[3] = 1.0;
|
||||
|
||||
VectorClear4(eye);
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
eye[i] += point[j] * tr.or.modelMatrix[i + j * 4];
|
||||
}
|
||||
}
|
||||
|
||||
VectorClear4(clip);
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
clip[i] += eye[j] * tr.viewParms.projectionMatrix[i + j * 4];
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
screen[i] = clip[i] / clip[3];
|
||||
}
|
||||
}
|
||||
|
||||
void sun_flare_class::SunTry()
|
||||
{
|
||||
vec2_t diff;
|
||||
vec2_t point;
|
||||
float alpha;
|
||||
int i;
|
||||
qboolean bDrawingFade = qfalse;
|
||||
|
||||
if (!CheckRange()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (SunCheckRay()) {
|
||||
alpha = (dot - dot_min) / (1.0 - dot_min);
|
||||
} else {
|
||||
int timediff;
|
||||
|
||||
if (!fullscreen) {
|
||||
return;
|
||||
}
|
||||
if (!blend_active) {
|
||||
return;
|
||||
}
|
||||
|
||||
timediff = backEnd.refdef.time - lasttime;
|
||||
alpha = (float)(fullfade - timediff) / fullfade * lastbright;
|
||||
|
||||
if (alpha <= 0.0001) {
|
||||
return;
|
||||
}
|
||||
|
||||
bDrawingFade = qtrue;
|
||||
}
|
||||
|
||||
SunScreenCalc();
|
||||
VectorScale2D(screen, -2.0, diff);
|
||||
|
||||
for (i = 0; i < num_flares; i++) {
|
||||
flare_s *flare = &flares[i];
|
||||
|
||||
VectorMA2D(screen, flare->where, diff, point);
|
||||
|
||||
RB_Color4f(color[0], color[1], color[2], alpha * this->alpha * flare->alphascale);
|
||||
RB_StreamBegin(flare->shader);
|
||||
RB_Texcoord2f(0.0, 0.0);
|
||||
|
||||
RB_Vertex2f(point[0] - flare->size, point[1] + flare->size);
|
||||
RB_Texcoord2f(1.0, 0.0);
|
||||
|
||||
RB_Vertex2f(point[0] + flare->size, point[1] + flare->size);
|
||||
RB_Texcoord2f(0.0, 1.0);
|
||||
|
||||
RB_Vertex2f(point[0] - flare->size, point[1] - flare->size);
|
||||
RB_Texcoord2f(1.0, 1.0);
|
||||
|
||||
RB_Vertex2f(point[0] + flare->size, point[1] - flare->size);
|
||||
RB_StreamEnd();
|
||||
}
|
||||
|
||||
if (!bDrawingFade) {
|
||||
lasttime = backEnd.refdef.time;
|
||||
blend_active = true;
|
||||
lastbright = Square(alpha) * Square(alpha) * fullscale;
|
||||
}
|
||||
}
|
183
code/renderergl2/tr_swipe.cpp
Normal file
183
code/renderergl2/tr_swipe.cpp
Normal file
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2023-2024 the OpenMoHAA team
|
||||
|
||||
This file is part of OpenMoHAA source code.
|
||||
|
||||
OpenMoHAA source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
OpenMoHAA source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenMoHAA source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
// tr_swipe.cpp -- swipe rendering
|
||||
|
||||
#include "tr_local.h"
|
||||
|
||||
#define MAX_SWIPE_POINTS 1024
|
||||
#define MAX_SWIPES 32
|
||||
|
||||
typedef struct {
|
||||
vec3_t points[2];
|
||||
float time;
|
||||
} rswipepoint_t;
|
||||
|
||||
typedef struct {
|
||||
surfaceType_t surftype;
|
||||
float life;
|
||||
float time;
|
||||
int lastrendtime;
|
||||
qhandle_t shader;
|
||||
int numswipes;
|
||||
rswipepoint_t swipes[MAX_SWIPE_POINTS];
|
||||
} rendswipe_t;
|
||||
|
||||
static int lastswipeframe;
|
||||
static int numswipes;
|
||||
static rendswipe_t swipes[MAX_SWIPES];
|
||||
|
||||
/*
|
||||
======================
|
||||
RE_SwipeBegin
|
||||
======================
|
||||
*/
|
||||
void RE_SwipeBegin(float thistime, float life, qhandle_t shader)
|
||||
{
|
||||
rendswipe_t *swipe;
|
||||
|
||||
if (tr.frameCount != lastswipeframe) {
|
||||
swipe = &swipes[0];
|
||||
numswipes = 0;
|
||||
}
|
||||
|
||||
if (numswipes >= MAX_SWIPES) {
|
||||
return;
|
||||
}
|
||||
|
||||
swipe = &swipes[numswipes++];
|
||||
|
||||
swipe->life = life;
|
||||
swipe->time = thistime;
|
||||
swipe->surftype = SF_SWIPE;
|
||||
swipe->numswipes = 0;
|
||||
swipe->lastrendtime = 0;
|
||||
swipe->shader = shader;
|
||||
|
||||
if (shader < 0 && life) {
|
||||
ri.Printf(PRINT_DEVELOPER, "RE_SwipeBegin: Invalid shader handle\n");
|
||||
}
|
||||
|
||||
lastswipeframe = tr.frameCount;
|
||||
}
|
||||
|
||||
/*
|
||||
======================
|
||||
RE_SwipePoint
|
||||
======================
|
||||
*/
|
||||
void RE_SwipePoint(vec3_t point1, vec3_t point2, float time)
|
||||
{
|
||||
rendswipe_t *swipe = &swipes[numswipes - 1];
|
||||
|
||||
if (swipe->numswipes >= MAX_SWIPE_POINTS) {
|
||||
return;
|
||||
}
|
||||
|
||||
VectorCopy(point1, swipe->swipes[swipe->numswipes - 1].points[0]);
|
||||
VectorCopy(point2, swipe->swipes[swipe->numswipes - 1].points[1]);
|
||||
}
|
||||
|
||||
/*
|
||||
======================
|
||||
RE_SwipeEnd
|
||||
======================
|
||||
*/
|
||||
void RE_SwipeEnd() {}
|
||||
|
||||
/*
|
||||
======================
|
||||
R_AddSwipeSurfaces
|
||||
======================
|
||||
*/
|
||||
void R_AddSwipeSurfaces()
|
||||
{
|
||||
shader_t *shader;
|
||||
int at;
|
||||
|
||||
if (!numswipes) {
|
||||
return;
|
||||
}
|
||||
|
||||
tr.currentEntityNum = ENTITYNUM_WORLD;
|
||||
tr.shiftedEntityNum = tr.currentEntityNum << QSORT_REFENTITYNUM_SHIFT;
|
||||
|
||||
for (at = 0; at < numswipes; at++) {
|
||||
rendswipe_t *swipe = &swipes[at];
|
||||
int timedelta = 0;
|
||||
|
||||
if (!swipe->numswipes) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (swipe->lastrendtime) {
|
||||
timedelta = tr.refdef.time - swipe->lastrendtime;
|
||||
}
|
||||
swipe->lastrendtime = tr.refdef.time;
|
||||
|
||||
if (timedelta) {
|
||||
swipe->time += timedelta;
|
||||
}
|
||||
|
||||
shader = R_GetShaderByHandle(swipe->shader);
|
||||
R_AddDrawSurf(&swipe->surftype, shader, 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
======================
|
||||
RB_DrawSwipeSurface
|
||||
======================
|
||||
*/
|
||||
void RB_DrawSwipeSurface(surfaceType_t *pswipe)
|
||||
{
|
||||
int i;
|
||||
float oolife;
|
||||
rendswipe_t *swipe = (rendswipe_t *)pswipe;
|
||||
|
||||
oolife = 1.0 / swipe->life;
|
||||
|
||||
RB_CHECKOVERFLOW(swipe->numswipes * 2, swipe->numswipes * 6);
|
||||
|
||||
RB_StreamBeginDrawSurf();
|
||||
|
||||
for (i = 0; i < swipe->numswipes; i++) {
|
||||
rswipepoint_t *swipepoint = &swipe->swipes[i];
|
||||
float alpha;
|
||||
float f;
|
||||
|
||||
f = 1.0 - (swipe->time - swipepoint->time) * oolife;
|
||||
if (f > 0 && swipe->time >= swipepoint->time) {
|
||||
alpha = f - Q_max(f - 1.0, 0);
|
||||
|
||||
RB_Color4f(alpha, alpha, alpha, alpha);
|
||||
RB_Texcoord2f(i / (float)swipe->numswipes, 1.0);
|
||||
RB_Vertex3fv(swipepoint->points[0]);
|
||||
RB_Texcoord2f(i / (float)swipe->numswipes, 1.0);
|
||||
RB_Vertex3fv(swipepoint->points[1]);
|
||||
} else if (i == swipe->numswipes - 1) {
|
||||
swipe->numswipes = 0;
|
||||
}
|
||||
}
|
||||
|
||||
RB_StreamEndDrawSurf();
|
||||
}
|
388
code/renderergl2/tr_util.cpp
Normal file
388
code/renderergl2/tr_util.cpp
Normal file
|
@ -0,0 +1,388 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
// tr_util.c -- renderer utility
|
||||
|
||||
#include "tr_local.h"
|
||||
#include "../qcommon/str.h"
|
||||
|
||||
static byte cntColor[4];
|
||||
static float cntSt[2];
|
||||
|
||||
static int Numbers[12][8] = {
|
||||
{1, 3, 4, 5, 6, 7, 0, 0},
|
||||
{4, 5, 0, 0, 0, 0, 0, 0},
|
||||
{1, 4, 2, 7, 3, 0, 0, 0},
|
||||
{1, 4, 2, 5, 3, 0, 0, 0},
|
||||
{6, 4, 2, 5, 0, 0, 0, 0},
|
||||
{1, 6, 2, 5, 3, 0, 0, 0},
|
||||
{1, 6, 2, 5, 7, 3, 0, 0},
|
||||
{1, 8, 0, 0, 0, 0, 0, 0},
|
||||
{1, 2, 3, 4, 5, 6, 7, 0},
|
||||
{1, 6, 4, 2, 5, 3, 0, 0},
|
||||
{9, 10, 11, 12, 0, 0, 0, 0},
|
||||
{2, 0, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
static float Lines[13][4] = {
|
||||
{0.0, 0.0, 0.0, 0.0},
|
||||
{-4.0, 8.0, 4.0, 8.0},
|
||||
{-4.0, 4.0, 4.0, 4.0},
|
||||
{-4.0, 0.0, 4.0, 0.0},
|
||||
{4.0, 8.0, 4.0, 4.0},
|
||||
{4.0, 4.0, 4.0, 0.0},
|
||||
{-4.0, 8.0, -4.0, 4.0},
|
||||
{-4.0, 4.0, -4.0, 0.0},
|
||||
{4.0, 8.0, -4.0, 0.0},
|
||||
{-1.0, 2.0, 1.0, 2.0},
|
||||
{1.0, 2.0, 1.0, 0.0},
|
||||
{-1.0, 0.0, 1.0, 0.0},
|
||||
{-1.0, 0.0, -1.0, 2.0}
|
||||
};
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_StreamBegin
|
||||
===============
|
||||
*/
|
||||
void RB_StreamBegin(shader_t *shader)
|
||||
{
|
||||
RB_BeginSurface(shader, 0, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_StreamEnd
|
||||
===============
|
||||
*/
|
||||
void RB_StreamEnd(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (tess.numVertexes <= 2) {
|
||||
RB_EndSurface();
|
||||
return;
|
||||
}
|
||||
|
||||
tess.indexes[0] = 0;
|
||||
tess.indexes[1] = 1;
|
||||
tess.indexes[2] = 2;
|
||||
|
||||
for (i = 0; i < tess.numVertexes - 2; i++) {
|
||||
tess.indexes[i * 3 + 0] = (i & 1) + i;
|
||||
tess.indexes[i * 3 + 1] = i - ((i & 1) - 1);
|
||||
tess.indexes[i * 3 + 2] = i + 2;
|
||||
tess.numIndexes += 3;
|
||||
}
|
||||
|
||||
RB_EndSurface();
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_StreamBeginDrawSurf
|
||||
===============
|
||||
*/
|
||||
void RB_StreamBeginDrawSurf(void)
|
||||
{
|
||||
// FIXME: unimplemented (GL2)
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_StreamEndDrawSurf
|
||||
===============
|
||||
*/
|
||||
void RB_StreamEndDrawSurf(void)
|
||||
{
|
||||
// FIXME: unimplemented (GL2)
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
addTriangle
|
||||
===============
|
||||
*/
|
||||
static void addTriangle(void)
|
||||
{
|
||||
tess.texCoords[tess.numVertexes][0] = cntSt[0];
|
||||
tess.texCoords[tess.numVertexes][1] = cntSt[1];
|
||||
tess.color[tess.numVertexes][0] = cntColor[0];
|
||||
tess.color[tess.numVertexes][1] = cntColor[1];
|
||||
tess.color[tess.numVertexes][2] = cntColor[2];
|
||||
tess.color[tess.numVertexes][3] = cntColor[3];
|
||||
tess.numVertexes++;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_Vertex3fv
|
||||
===============
|
||||
*/
|
||||
void RB_Vertex3fv(vec3_t v)
|
||||
{
|
||||
VectorCopy(v, tess.xyz[tess.numVertexes]);
|
||||
addTriangle();
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_Vertex3f
|
||||
===============
|
||||
*/
|
||||
void RB_Vertex3f(vec_t x, vec_t y, vec_t z)
|
||||
{
|
||||
tess.xyz[tess.numVertexes][0] = x;
|
||||
tess.xyz[tess.numVertexes][1] = y;
|
||||
tess.xyz[tess.numVertexes][2] = z;
|
||||
addTriangle();
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_Vertex2f
|
||||
===============
|
||||
*/
|
||||
void RB_Vertex2f(vec_t x, vec_t y)
|
||||
{
|
||||
RB_Vertex3f(x, y, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_Color4f
|
||||
===============
|
||||
*/
|
||||
void RB_Color4f(vec_t r, vec_t g, vec_t b, vec_t a)
|
||||
{
|
||||
cntColor[0] = r * tr.identityLightByte;
|
||||
cntColor[1] = g * tr.identityLightByte;
|
||||
cntColor[2] = b * tr.identityLightByte;
|
||||
cntColor[3] = a * 255.0;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_Color3f
|
||||
===============
|
||||
*/
|
||||
void RB_Color3f(vec_t r, vec_t g, vec_t b)
|
||||
{
|
||||
RB_Color4f(r, g, b, 1.0);
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_Color3fv
|
||||
===============
|
||||
*/
|
||||
void RB_Color3fv(vec3_t col)
|
||||
{
|
||||
RB_Color3f(col[0], col[1], col[2]);
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_Color4bv
|
||||
===============
|
||||
*/
|
||||
void RB_Color4bv(unsigned char *colors)
|
||||
{
|
||||
cntColor[0] = colors[0];
|
||||
cntColor[1] = colors[1];
|
||||
cntColor[2] = colors[2];
|
||||
cntColor[3] = colors[3];
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_Texcoord2f
|
||||
===============
|
||||
*/
|
||||
void RB_Texcoord2f(float s, float t)
|
||||
{
|
||||
cntSt[0] = s;
|
||||
cntSt[1] = t;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RB_Texcoord2fv
|
||||
===============
|
||||
*/
|
||||
void RB_Texcoord2fv(vec2_t st)
|
||||
{
|
||||
cntSt[0] = st[0];
|
||||
cntSt[1] = st[1];
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_DrawDebugNumber
|
||||
===============
|
||||
*/
|
||||
void R_DrawDebugNumber(const vec3_t org, float number, float scale, float r, float g, float b, int precision)
|
||||
{
|
||||
vec3_t up, right;
|
||||
vec3_t pos1, pos2;
|
||||
vec3_t start;
|
||||
str text;
|
||||
char format[20];
|
||||
int i;
|
||||
int j;
|
||||
int l;
|
||||
int num;
|
||||
|
||||
VectorCopy(tr.viewParms.or.axis[2], up);
|
||||
VectorCopy(tr.viewParms.or.axis[1], right);
|
||||
VectorNegate(right, right);
|
||||
|
||||
VectorNormalize(up);
|
||||
VectorNormalize(right);
|
||||
|
||||
VectorScale(up, scale, up);
|
||||
VectorScale(right, scale, right);
|
||||
|
||||
if (precision > 0) {
|
||||
Com_sprintf(format, sizeof(format), "%%.%df", precision);
|
||||
text = va(format, number);
|
||||
} else {
|
||||
text = va("%d", (int)number);
|
||||
}
|
||||
|
||||
// NOTE: this cast here is needed!
|
||||
// Otherwise the compiler will do very nasty implicit casting of negative
|
||||
// numbers to unsigned numbers, resulting in incorrect values.
|
||||
// -------------------v
|
||||
VectorMA(org, 5 - 5 * (int)text.length(), right, start);
|
||||
|
||||
// Draw each character/digit of the text
|
||||
for (i = 0; i < text.length(); i++) {
|
||||
if (text[i] == '.') {
|
||||
num = 10;
|
||||
} else if (text[i] == '-') {
|
||||
num = 11;
|
||||
} else {
|
||||
num = text[i] - '0';
|
||||
}
|
||||
|
||||
// Get the first line index for the number to be drawn
|
||||
l = Numbers[num][0];
|
||||
|
||||
// Draw each line of the character/digit
|
||||
for (j = 0; j < 8 && l; ++j, l = Numbers[num][j]) {
|
||||
pos1[0] = start[0] + Lines[l][0] * right[0] + Lines[l][1] * up[0];
|
||||
pos1[1] = start[1] + Lines[l][0] * right[1] + Lines[l][1] * up[1];
|
||||
pos1[2] = start[2] + Lines[l][0] * right[2] + Lines[l][1] * up[2];
|
||||
|
||||
pos2[0] = start[0] + Lines[l][2] * right[0] + Lines[l][3] * up[0];
|
||||
pos2[1] = start[1] + Lines[l][2] * right[1] + Lines[l][3] * up[1];
|
||||
pos2[2] = start[2] + Lines[l][2] * right[2] + Lines[l][3] * up[2];
|
||||
|
||||
R_DebugLine(pos1, pos2, r, g, b, 1.0);
|
||||
}
|
||||
|
||||
VectorMA(start, 10.0, right, start);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_DebugRotatedBBox
|
||||
===============
|
||||
*/
|
||||
void R_DebugRotatedBBox(
|
||||
const vec3_t org, const vec3_t ang, const vec3_t mins, const vec3_t maxs, float r, float g, float b, float alpha
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RE_GetShaderWidth
|
||||
===============
|
||||
*/
|
||||
int RE_GetShaderWidth(qhandle_t hShader)
|
||||
{
|
||||
shader_t *shader;
|
||||
|
||||
if (hShader) {
|
||||
shader = R_GetShaderByHandle(hShader);
|
||||
} else {
|
||||
shader = tr.defaultShader;
|
||||
}
|
||||
|
||||
return shader->stages[0]->bundle[0].image[0]->uploadWidth;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RE_GetShaderHeight
|
||||
===============
|
||||
*/
|
||||
int RE_GetShaderHeight(qhandle_t hShader)
|
||||
{
|
||||
shader_t *shader;
|
||||
|
||||
if (hShader) {
|
||||
shader = R_GetShaderByHandle(hShader);
|
||||
} else {
|
||||
shader = tr.defaultShader;
|
||||
}
|
||||
|
||||
return shader->stages[0]->bundle[0].image[0]->uploadHeight;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RE_GetShaderName
|
||||
===============
|
||||
*/
|
||||
const char *RE_GetShaderName(qhandle_t hShader)
|
||||
{
|
||||
shader_t *shader;
|
||||
|
||||
if (hShader) {
|
||||
shader = R_GetShaderByHandle(hShader);
|
||||
} else {
|
||||
shader = tr.defaultShader;
|
||||
}
|
||||
|
||||
return shader->name;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
RE_GetModelName
|
||||
===============
|
||||
*/
|
||||
const char *RE_GetModelName(qhandle_t hModel)
|
||||
{
|
||||
model_t *model;
|
||||
|
||||
if (!hModel) {
|
||||
return "";
|
||||
}
|
||||
|
||||
model = R_GetModelByHandle(hModel);
|
||||
|
||||
return model->name;
|
||||
}
|
|
@ -589,7 +589,7 @@ static void R_RecursiveWorldNode( mnode_t *node, uint32_t planeBits, uint32_t dl
|
|||
R_PointInLeaf
|
||||
===============
|
||||
*/
|
||||
static mnode_t *R_PointInLeaf( const vec3_t p ) {
|
||||
mnode_t *R_PointInLeaf( const vec3_t p ) {
|
||||
mnode_t *node;
|
||||
float d;
|
||||
cplane_t *plane;
|
||||
|
@ -807,3 +807,16 @@ void R_AddWorldSurfaces (void) {
|
|||
tr.refdef.dlightMask = ~tr.refdef.dlightMask;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// OPENMOHAA-specific stuff
|
||||
//
|
||||
|
||||
void R_GetInlineModelBounds(int iIndex, vec3_t vMins, vec3_t vMaxs)
|
||||
{
|
||||
bmodel_t* bmodel;
|
||||
|
||||
bmodel = &tr.world->bmodels[iIndex];
|
||||
VectorCopy(bmodel->bounds[0], vMins);
|
||||
VectorCopy(bmodel->bounds[1], vMaxs);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue