2011-11-22 21:28:15 +00:00
|
|
|
/*
|
|
|
|
===========================================================================
|
|
|
|
|
|
|
|
Doom 3 GPL Source Code
|
2011-12-06 18:20:15 +00:00
|
|
|
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
|
2011-11-22 21:28:15 +00:00
|
|
|
|
2011-12-06 16:14:59 +00:00
|
|
|
This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
|
2011-11-22 21:28:15 +00:00
|
|
|
|
|
|
|
Doom 3 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 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
Doom 3 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
|
|
|
|
|
|
|
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
|
|
|
|
|
|
|
===========================================================================
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __RENDERER_H__
|
|
|
|
#define __RENDERER_H__
|
|
|
|
|
2011-12-16 22:28:29 +00:00
|
|
|
#include "framework/Common.h"
|
|
|
|
#include "renderer/Model.h"
|
|
|
|
|
2011-11-22 21:28:15 +00:00
|
|
|
/*
|
|
|
|
===============================================================================
|
|
|
|
|
|
|
|
idRenderSystem is responsible for managing the screen, which can have
|
|
|
|
multiple idRenderWorld and 2D drawing done on it.
|
|
|
|
|
|
|
|
===============================================================================
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
// Contains variables specific to the OpenGL configuration being run right now.
|
|
|
|
// These are constant once the OpenGL subsystem is initialized.
|
|
|
|
typedef struct glconfig_s {
|
|
|
|
const char *renderer_string;
|
|
|
|
const char *vendor_string;
|
|
|
|
const char *version_string;
|
|
|
|
const char *extensions_string;
|
|
|
|
|
|
|
|
float glVersion; // atof( version_string )
|
|
|
|
|
|
|
|
|
|
|
|
int maxTextureSize; // queried from GL
|
|
|
|
int maxTextureUnits;
|
|
|
|
int maxTextureCoords;
|
|
|
|
int maxTextureImageUnits;
|
|
|
|
float maxTextureAnisotropy;
|
|
|
|
|
2021-04-12 23:04:18 +00:00
|
|
|
int colorBits, alphabits, depthBits, stencilBits;
|
2011-11-22 21:28:15 +00:00
|
|
|
|
|
|
|
bool multitextureAvailable;
|
|
|
|
bool textureCompressionAvailable;
|
|
|
|
bool anisotropicAvailable;
|
|
|
|
bool textureLODBiasAvailable;
|
|
|
|
bool textureEnvAddAvailable;
|
|
|
|
bool textureEnvCombineAvailable;
|
|
|
|
bool registerCombinersAvailable;
|
|
|
|
bool cubeMapAvailable;
|
|
|
|
bool envDot3Available;
|
|
|
|
bool texture3DAvailable;
|
|
|
|
bool sharedTexturePaletteAvailable;
|
|
|
|
bool ARBVertexBufferObjectAvailable;
|
|
|
|
bool ARBVertexProgramAvailable;
|
|
|
|
bool ARBFragmentProgramAvailable;
|
|
|
|
bool twoSidedStencilAvailable;
|
|
|
|
bool textureNonPowerOfTwoAvailable;
|
|
|
|
bool depthBoundsTestAvailable;
|
|
|
|
|
2024-06-03 09:55:49 +00:00
|
|
|
// GL framebuffer size, see also winWidth and winHeight
|
2011-11-22 21:28:15 +00:00
|
|
|
int vidWidth, vidHeight; // passed to R_BeginFrame
|
|
|
|
|
|
|
|
int displayFrequency;
|
|
|
|
|
|
|
|
bool isFullscreen;
|
|
|
|
|
|
|
|
bool allowARB2Path;
|
|
|
|
|
|
|
|
bool isInitialized;
|
Make window alpha chan opaque on Wayland, fix #426
For some reason Wayland thought it would be clever to be the only
windowing system that (non-optionally) uses the alpha chan of the
window's default OpenGL framebuffer for window transparency.
This always caused glitches with dhewm3, as Doom3 uses that alpha-chan
for blending tricks (with GL_DST_ALPHA) - especially visible in the main
menu or when the flashlight is on.
So far the workaround has been r_waylandcompat which requests an OpenGL
context/visual without alpha chan (0 alpha bits), but that also causes
glitches.
There's an EGL extension that's supposed to fix this issue
(EGL_EXT_present_opaque), and newer SDL2 versions use it (when using
the wayland backend) - but unfortunately the Mesa implementation is
broken (seems to provide a visual without alpha channel even if one was
requested), see https://gitlab.freedesktop.org/mesa/mesa/-/issues/5886
and https://github.com/libsdl-org/SDL/pull/4306#issuecomment-1014770600
for the corresponding SDL2 discussion
To work around this issue, dhewm3 now disables the use of that EGL
extension and (optionally) makes sure the alpha channel is opaque at
the end of the frame.
This behavior is controlled with the r_fillWindowAlphaChan CVar:
If it's 1, this always is done (regardless if wayland is used or not),
if it's 0 it's not done (even on wayland),
if it's -1 (the default) it's only done if the SDL "video driver" is
wayland (this could be easily enhanced later in case other windowing
systems have the same issue)
r_waylandcompat has been removed (it never worked properly anyway),
so now the window always has an alpha chan
2022-01-22 15:07:51 +00:00
|
|
|
|
|
|
|
// DG: current video backend is known to need opaque default framebuffer
|
|
|
|
// used if r_fillWindowAlphaChan == -1
|
|
|
|
bool shouldFillWindowAlpha;
|
2024-06-03 09:55:49 +00:00
|
|
|
|
|
|
|
// For some reason people decided that we need displays with ultra small pixels,
|
|
|
|
// so everything rendered on them must be scaled up to be legible.
|
|
|
|
// unfortunately, this bullshit feature was "improved" upon by deciding that the best
|
|
|
|
// way to implement "High DPI" was to pretend that windows have fewer pixels than they
|
|
|
|
// actually do, so the window size you get and mouse coordinates in them etc
|
|
|
|
// are in e.g. 1024x768, while the physical window size is e.g. 1536x1152 pixels
|
|
|
|
// (when the scaling factor is 1.5), and ideally the GL framebuffer has the physical
|
|
|
|
// window size so things still look crisp.
|
|
|
|
// Of course the reasonable solution would be to go back and time and nuke Cupertino,
|
|
|
|
// where this nonsense scheme was invented, but as I lack the necessary funds,
|
|
|
|
// I reluctantly add winWidth and winHeight and adjust the code that deals with window
|
|
|
|
// coordinates, as far as that's possible..
|
|
|
|
// (Isn't it fun that you have a 2256x1504 display, tell SDL to create a 1920x1080 window
|
|
|
|
// and you get one that's much bigger and doesn't fit on the screen?)
|
|
|
|
|
|
|
|
float winWidth, winHeight; // logical window size (different to vidWidth/height in HighDPI cases)
|
2011-11-22 21:28:15 +00:00
|
|
|
} glconfig_t;
|
|
|
|
|
|
|
|
|
2011-12-06 18:20:15 +00:00
|
|
|
// font support
|
2011-11-22 21:28:15 +00:00
|
|
|
const int GLYPH_START = 0;
|
|
|
|
const int GLYPH_END = 255;
|
|
|
|
const int GLYPH_CHARSTART = 32;
|
|
|
|
const int GLYPH_CHAREND = 127;
|
|
|
|
const int GLYPHS_PER_FONT = GLYPH_END - GLYPH_START + 1;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
int height; // number of scan lines
|
|
|
|
int top; // top of glyph in buffer
|
|
|
|
int bottom; // bottom of glyph in buffer
|
|
|
|
int pitch; // width for copying
|
|
|
|
int xSkip; // x adjustment
|
|
|
|
int imageWidth; // width of actual image
|
|
|
|
int imageHeight; // height of actual image
|
|
|
|
float s; // x offset in image where glyph starts
|
|
|
|
float t; // y offset in image where glyph starts
|
|
|
|
float s2;
|
|
|
|
float t2;
|
|
|
|
const idMaterial * glyph; // shader with the glyph
|
|
|
|
char shaderName[32];
|
|
|
|
} glyphInfo_t;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
glyphInfo_t glyphs [GLYPHS_PER_FONT];
|
|
|
|
float glyphScale;
|
|
|
|
char name[64];
|
|
|
|
} fontInfo_t;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
fontInfo_t fontInfoSmall;
|
|
|
|
fontInfo_t fontInfoMedium;
|
|
|
|
fontInfo_t fontInfoLarge;
|
|
|
|
int maxHeight;
|
|
|
|
int maxWidth;
|
|
|
|
int maxHeightSmall;
|
|
|
|
int maxWidthSmall;
|
|
|
|
int maxHeightMedium;
|
|
|
|
int maxWidthMedium;
|
|
|
|
int maxHeightLarge;
|
|
|
|
int maxWidthLarge;
|
|
|
|
char name[64];
|
|
|
|
} fontInfoEx_t;
|
|
|
|
|
|
|
|
const int SMALLCHAR_WIDTH = 8;
|
|
|
|
const int SMALLCHAR_HEIGHT = 16;
|
|
|
|
const int BIGCHAR_WIDTH = 16;
|
|
|
|
const int BIGCHAR_HEIGHT = 16;
|
|
|
|
|
|
|
|
// all drawing is done to a 640 x 480 virtual screen size
|
|
|
|
// and will be automatically scaled to the real resolution
|
|
|
|
const int SCREEN_WIDTH = 640;
|
|
|
|
const int SCREEN_HEIGHT = 480;
|
|
|
|
|
|
|
|
class idRenderWorld;
|
|
|
|
|
|
|
|
|
|
|
|
class idRenderSystem {
|
|
|
|
public:
|
|
|
|
|
|
|
|
virtual ~idRenderSystem() {}
|
|
|
|
|
|
|
|
// set up cvars and basic data structures, but don't
|
|
|
|
// init OpenGL, so it can also be used for dedicated servers
|
|
|
|
virtual void Init( void ) = 0;
|
|
|
|
|
|
|
|
// only called before quitting
|
|
|
|
virtual void Shutdown( void ) = 0;
|
|
|
|
|
|
|
|
virtual void InitOpenGL( void ) = 0;
|
|
|
|
|
|
|
|
virtual void ShutdownOpenGL( void ) = 0;
|
|
|
|
|
|
|
|
virtual bool IsOpenGLRunning( void ) const = 0;
|
|
|
|
|
|
|
|
virtual bool IsFullScreen( void ) const = 0;
|
2024-06-03 09:55:49 +00:00
|
|
|
// NOTE: this is the physical width of the GL drawable (framebuffer) in pixels,
|
|
|
|
// *not* the logical window size (in case of HighDPI that's not the same!)
|
2011-11-22 21:28:15 +00:00
|
|
|
virtual int GetScreenWidth( void ) const = 0;
|
2024-06-03 09:55:49 +00:00
|
|
|
// NOTE: this is the physical height of the GL drawable (framebuffer) in pixels,
|
|
|
|
// *not* the logical window size (in case of HighDPI that's not the same!)
|
2011-11-22 21:28:15 +00:00
|
|
|
virtual int GetScreenHeight( void ) const = 0;
|
|
|
|
|
|
|
|
// allocate a renderWorld to be used for drawing
|
|
|
|
virtual idRenderWorld * AllocRenderWorld( void ) = 0;
|
|
|
|
virtual void FreeRenderWorld( idRenderWorld * rw ) = 0;
|
|
|
|
|
|
|
|
// All data that will be used in a level should be
|
|
|
|
// registered before rendering any frames to prevent disk hits,
|
|
|
|
// but they can still be registered at a later time
|
|
|
|
// if necessary.
|
|
|
|
virtual void BeginLevelLoad( void ) = 0;
|
|
|
|
virtual void EndLevelLoad( void ) = 0;
|
|
|
|
|
|
|
|
// font support
|
|
|
|
virtual bool RegisterFont( const char *fontName, fontInfoEx_t &font ) = 0;
|
|
|
|
|
|
|
|
// GUI drawing just involves shader parameter setting and axial image subsections
|
|
|
|
virtual void SetColor( const idVec4 &rgba ) = 0;
|
|
|
|
virtual void SetColor4( float r, float g, float b, float a ) = 0;
|
|
|
|
|
|
|
|
virtual void DrawStretchPic( const idDrawVert *verts, const glIndex_t *indexes, int vertCount, int indexCount, const idMaterial *material,
|
|
|
|
bool clip = true, float min_x = 0.0f, float min_y = 0.0f, float max_x = 640.0f, float max_y = 480.0f ) = 0;
|
|
|
|
virtual void DrawStretchPic( float x, float y, float w, float h, float s1, float t1, float s2, float t2, const idMaterial *material ) = 0;
|
|
|
|
|
|
|
|
virtual void DrawStretchTri ( idVec2 p1, idVec2 p2, idVec2 p3, idVec2 t1, idVec2 t2, idVec2 t3, const idMaterial *material ) = 0;
|
|
|
|
virtual void GlobalToNormalizedDeviceCoordinates( const idVec3 &global, idVec3 &ndc ) = 0;
|
|
|
|
virtual void GetGLSettings( int& width, int& height ) = 0;
|
|
|
|
virtual void PrintMemInfo( MemInfo_t *mi ) = 0;
|
|
|
|
|
|
|
|
virtual void DrawSmallChar( int x, int y, int ch, const idMaterial *material ) = 0;
|
|
|
|
virtual void DrawSmallStringExt( int x, int y, const char *string, const idVec4 &setColor, bool forceColor, const idMaterial *material ) = 0;
|
|
|
|
virtual void DrawBigChar( int x, int y, int ch, const idMaterial *material ) = 0;
|
|
|
|
virtual void DrawBigStringExt( int x, int y, const char *string, const idVec4 &setColor, bool forceColor, const idMaterial *material ) = 0;
|
|
|
|
|
|
|
|
// dump all 2D drawing so far this frame to the demo file
|
|
|
|
virtual void WriteDemoPics() = 0;
|
|
|
|
|
|
|
|
// draw the 2D pics that were saved out with the current demo frame
|
|
|
|
virtual void DrawDemoPics() = 0;
|
|
|
|
|
|
|
|
// FIXME: add an interface for arbitrary point/texcoord drawing
|
|
|
|
|
|
|
|
|
|
|
|
// a frame cam consist of 2D drawing and potentially multiple 3D scenes
|
|
|
|
// window sizes are needed to convert SCREEN_WIDTH / SCREEN_HEIGHT values
|
|
|
|
virtual void BeginFrame( int windowWidth, int windowHeight ) = 0;
|
|
|
|
|
|
|
|
// if the pointers are not NULL, timing info will be returned
|
|
|
|
virtual void EndFrame( int *frontEndMsec, int *backEndMsec ) = 0;
|
|
|
|
|
|
|
|
// aviDemo uses this.
|
|
|
|
// Will automatically tile render large screen shots if necessary
|
|
|
|
// Samples is the number of jittered frames for anti-aliasing
|
|
|
|
// If ref == NULL, session->updateScreen will be used
|
|
|
|
// This will perform swapbuffers, so it is NOT an approppriate way to
|
|
|
|
// generate image files that happen during gameplay, as for savegame
|
|
|
|
// markers. Use WriteRender() instead.
|
|
|
|
virtual void TakeScreenshot( int width, int height, const char *fileName, int samples, struct renderView_s *ref ) = 0;
|
|
|
|
|
|
|
|
// the render output can be cropped down to a subset of the real screen, as
|
|
|
|
// for save-game reviews and split-screen multiplayer. Users of the renderer
|
|
|
|
// will not know the actual pixel size of the area they are rendering to
|
|
|
|
|
|
|
|
// the x,y,width,height values are in virtual SCREEN_WIDTH / SCREEN_HEIGHT coordinates
|
|
|
|
|
|
|
|
// to render to a texture, first set the crop size with makePowerOfTwo = true,
|
|
|
|
// then perform all desired rendering, then capture to an image
|
|
|
|
// if the specified physical dimensions are larger than the current cropped region, they will be cut down to fit
|
|
|
|
virtual void CropRenderSize( int width, int height, bool makePowerOfTwo = false, bool forceDimensions = false ) = 0;
|
|
|
|
virtual void CaptureRenderToImage( const char *imageName ) = 0;
|
|
|
|
// fixAlpha will set all the alpha channel values to 0xff, which allows screen captures
|
|
|
|
// to use the default tga loading code without having dimmed down areas in many places
|
|
|
|
virtual void CaptureRenderToFile( const char *fileName, bool fixAlpha = false ) = 0;
|
|
|
|
virtual void UnCrop() = 0;
|
|
|
|
|
|
|
|
// the image has to be already loaded ( most straightforward way would be through a FindMaterial )
|
|
|
|
// texture filter / mipmapping / repeat won't be modified by the upload
|
|
|
|
// returns false if the image wasn't found
|
|
|
|
virtual bool UploadImage( const char *imageName, const byte *data, int width, int height ) = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
extern idRenderSystem * renderSystem;
|
|
|
|
|
|
|
|
//
|
|
|
|
// functions mainly intended for editor and dmap integration
|
|
|
|
//
|
|
|
|
|
|
|
|
// returns the frustum planes in world space
|
|
|
|
void R_RenderLightFrustum( const struct renderLight_s &renderLight, idPlane lightFrustum[6] );
|
|
|
|
|
|
|
|
// for use by dmap to do the carving-on-light-boundaries and for the editor for display
|
|
|
|
void R_LightProjectionMatrix( const idVec3 &origin, const idPlane &rearPlane, idVec4 mat[4] );
|
|
|
|
|
|
|
|
// used by the view shot taker
|
|
|
|
void R_ScreenshotFilename( int &lastNumber, const char *base, idStr &fileName );
|
|
|
|
|
|
|
|
#endif /* !__RENDERER_H__ */
|