ref_gl.so builds and works (on Linux, with Makefile)

still dirty, seems to use some symbols from client directly, which will
not work on Windows.
This commit is contained in:
Daniel Gibson 2016-10-02 00:40:52 +02:00
parent 3a65b41d60
commit f13e15e561
19 changed files with 1138 additions and 572 deletions

136
Makefile
View file

@ -302,12 +302,12 @@ endif
# ----------
# Phony targets
.PHONY : all client game icon server
.PHONY : all client game icon server ref_gl
# ----------
# Builds everything
all: config client server game
all: config client server game ref_gl
# Print config values
config:
@ -344,6 +344,10 @@ endif
# Cleanup
clean:
@echo "===> CLEAN"
${Q}rm -Rf build release/*
cleanall:
@echo "===> CLEAN"
${Q}rm -Rf build release
@ -384,7 +388,9 @@ release/quake2.exe : CFLAGS += -DSDL2
endif
release/quake2.exe : LDFLAGS += -mwindows -lopengl32
else # not Windows
client:
@echo "===> Building quake2"
${Q}mkdir -p release
@ -393,7 +399,7 @@ client:
build/client/%.o: %.c
@echo "===> CC $<"
${Q}mkdir -p $(@D)
${Q}$(CC) -c $(CFLAGS) $(SDLCFLAGS) $(X11CFLAGS) $(INCLUDE) -o $@ $<
${Q}$(CC) -c $(CFLAGS) $(SDLCFLAGS) $(INCLUDE) -o $@ $<
ifeq ($(OSTYPE), Darwin)
build/client/%.o : %.m
@ -439,9 +445,9 @@ endif
ifeq ($(WITH_SDL2),yes)
release/quake2 : CFLAGS += -DSDL2
endif
ifneq ($(OSTYPE), Darwin)
release/quake2 : LDFLAGS += -lGL
release/ref_gl.so : LDFLAGS += -lGL
endif
ifeq ($(OSTYPE), FreeBSD)
@ -507,6 +513,53 @@ release/q2ded : LDFLAGS += -lz
endif
endif
# ----------
# The renderer lib
ifeq ($(OSTYPE), Windows)
ref_gl:
@echo "===> Building ref_gl.dll"
$(MAKE) release/ref_gl.dll
ifeq ($(WITH_SDL2),yes)
release/ref_gl.dll : CFLAGS += -DSDL2
endif
else ifeq ($(OSTYPE), Darwin)
ref_gl:
@echo "===> Building ref_gl.dylib"
$(MAKE) release/ref_gl.dylib
ifeq ($(WITH_SDL2),yes)
release/ref_gl.dylib : CFLAGS += -DSDL2
endif
else # not Windows or Darwin
ref_gl:
@echo "===> Building ref_gl.so"
$(MAKE) release/ref_gl.so
release/ref_gl.so : CFLAGS += -fPIC
release/ref_gl.so : LDFLAGS += -shared
ifeq ($(WITH_SDL2),yes)
release/ref_gl.so : CFLAGS += -DSDL2
endif
endif # OS specific ref_gl shit
build/ref_gl/%.o: %.c
@echo "===> CC $<"
${Q}mkdir -p $(@D)
${Q}$(CC) -c $(CFLAGS) $(SDLCFLAGS) $(X11CFLAGS) $(INCLUDE) -o $@ $<
# ----------
# The baseq2 game
@ -610,7 +663,6 @@ CLIENT_OBJS_ := \
src/backends/generic/misc.o \
src/backends/generic/qal.o \
src/backends/generic/vid.o \
src/backends/generic/qgl.o \
src/backends/sdl/cd.o \
src/backends/sdl/input.o \
src/backends/sdl/refresh.o \
@ -632,22 +684,6 @@ CLIENT_OBJS_ := \
src/client/cl_screen.o \
src/client/cl_tempentities.o \
src/client/cl_view.o \
src/client/refresh/r_draw.o \
src/client/refresh/r_image.o \
src/client/refresh/r_light.o \
src/client/refresh/r_lightmap.o \
src/client/refresh/r_main.o \
src/client/refresh/r_mesh.o \
src/client/refresh/r_misc.o \
src/client/refresh/r_model.o \
src/client/refresh/r_scrap.o \
src/client/refresh/r_surf.o \
src/client/refresh/r_warp.o \
src/client/refresh/files/md2.o \
src/client/refresh/files/pcx.o \
src/client/refresh/files/sp2.o \
src/client/refresh/files/stb.o \
src/client/refresh/files/wal.o \
src/client/menu/menu.o \
src/client/menu/qmenu.o \
src/client/menu/videomenu.o \
@ -684,7 +720,7 @@ CLIENT_OBJS_ := \
src/server/sv_save.o \
src/server/sv_send.o \
src/server/sv_user.o \
src/server/sv_world.o
src/server/sv_world.o
ifeq ($(OSTYPE), Windows)
CLIENT_OBJS_ += \
@ -702,6 +738,41 @@ endif
# ----------
# TODO: move qgl.c to refresh/gl/ (and probably the header as well)
REFGL_OBJS_ := \
src/backends/generic/qgl.o \
src/client/refresh/gl/r_draw.o \
src/client/refresh/gl/r_image.o \
src/client/refresh/gl/r_light.o \
src/client/refresh/gl/r_lightmap.o \
src/client/refresh/gl/r_main.o \
src/client/refresh/gl/r_mesh.o \
src/client/refresh/gl/r_misc.o \
src/client/refresh/gl/r_model.o \
src/client/refresh/gl/r_scrap.o \
src/client/refresh/gl/r_surf.o \
src/client/refresh/gl/r_warp.o \
src/client/refresh/gl/r_sdl.o \
src/client/refresh/files/md2.o \
src/client/refresh/files/pcx.o \
src/client/refresh/files/sp2.o \
src/client/refresh/files/stb.o \
src/client/refresh/files/wal.o \
src/common/shared/flash.o \
src/common/shared/rand.o \
src/common/shared/shared.o
ifeq ($(OSTYPE), Windows)
REFGL_OBJS_ += \
src/backends/windows/shared/mem.o
else # not Windows
REFGL_OBJS_ += \
src/backends/unix/shared/hunk.o
endif
# ----------
# Used by the server
SERVER_OBJS_ := \
src/common/argproc.o \
@ -753,6 +824,7 @@ endif
# Rewrite pathes to our object directory
CLIENT_OBJS = $(patsubst %,build/client/%,$(CLIENT_OBJS_))
REFGL_OBJS = $(patsubst %,build/ref_gl/%,$(REFGL_OBJS_))
SERVER_OBJS = $(patsubst %,build/server/%,$(SERVER_OBJS_))
GAME_OBJS = $(patsubst %,build/baseq2/%,$(GAME_OBJS_))
@ -760,6 +832,7 @@ GAME_OBJS = $(patsubst %,build/baseq2/%,$(GAME_OBJS_))
# Generate header dependencies
CLIENT_DEPS= $(CLIENT_OBJS:.o=.d)
REFGL_DEPS= $(REFGL_OBJS:.o=.d)
SERVER_DEPS= $(SERVER_OBJS:.o=.d)
GAME_DEPS= $(GAME_OBJS:.o=.d)
@ -767,6 +840,7 @@ GAME_DEPS= $(GAME_OBJS:.o=.d)
# Suck header dependencies in
-include $(CLIENT_DEPS)
-include $(REFGL_DEPS)
-include $(SERVER_DEPS)
-include $(GAME_DEPS)
@ -796,6 +870,22 @@ release/q2ded : $(SERVER_OBJS)
${Q}$(CC) $(SERVER_OBJS) $(LDFLAGS) -o $@
endif
# release/ref_gl.so
ifeq ($(OSTYPE), Windows)
release/ref_gl.dll : $(REFGL_OBJS)
@echo "===> LD $@"
${Q}$(CC) $(REFGL_OBJS) $(LDFLAGS) $(SDLLDFLAGS) -o $@
$(Q)strip $@
else ifeq ($(OSTYPE), Darwin)
release/ref_gl.dylib : $(REFGL_OBJS)
@echo "===> LD $@"
${Q}$(CC) $(GAME_OBJS) $(LDFLAGS) $(SDLLDFLAGS) -o $@
else
release/ref_gl.so : $(REFGL_OBJS)
@echo "===> LD $@"
${Q}$(CC) $(REFGL_OBJS) $(LDFLAGS) $(SDLLDFLAGS) -o $@
endif
# release/baseq2/game.so
ifeq ($(OSTYPE), Windows)
release/baseq2/game.dll : $(GAME_OBJS)

View file

@ -41,6 +41,8 @@
#include "../../client/header/client.h"
#include "../../client/header/keyboard.h"
qboolean VID_LoadRefresh(void);
typedef struct vidmode_s
{
const char *description;
@ -82,7 +84,6 @@ cvar_t *vid_fullscreen;
/* Global variables used internally by this module */
viddef_t viddef; /* global video state; used by other modules */
qboolean ref_active = false; /* Is the refresher being used? */
#define VID_NUM_MODES (sizeof(vid_modes) / sizeof(vid_modes[0]))
#define MAXPRINTMSG 4096
@ -152,33 +153,6 @@ VID_NewWindow(int width, int height)
viddef.height = height;
}
qboolean
VID_LoadRefresh(void)
{
// If the refresher is already active
// we'll shut it down
VID_Shutdown();
// Log it!
Com_Printf("----- refresher initialization -----\n");
// Declare the refresher as active
ref_active = true;
// Initiate the refresher
if (R_Init(0, 0) == -1)
{
VID_Shutdown(); // Isn't that just too bad? :(
return false;
}
/* Ensure that all key states are cleared */
Key_MarkAllUp();
Com_Printf("------------------------------------\n\n");
return true;
}
/*
* This function gets called once just before drawing each frame, and
* it's sole purpose in life is to check to see if any of the video mode
@ -217,15 +191,272 @@ VID_Init(void)
VID_CheckChanges();
}
// Structure containing functions exported from refresh DLL
refexport_t re;
void *reflib_handle = NULL; // Handle to refresh DLL
qboolean ref_active = false; /* Is the refresher being used? */
void Key_MarkAllUp(void);
extern qboolean GLimp_InitGraphics(qboolean fullscreen, int *pwidth, int *pheight);
extern void VID_ShutdownWindow(void);
qboolean
VID_LoadRefresh(void)
{
refimport_t ri;
GetRefAPI_t GetRefAPI;
#ifdef __APPLE__
const char* lib_ext = "dylib";
#elif defined(_WIN32)
const char* lib_ext = "dll";
#else
const char* lib_ext = "so";
#endif
char reflib_path[MAX_OSPATH] = {0};
// If the refresher is already active
// we'll shut it down
VID_Shutdown();
// Log it!
Com_Printf("----- refresher initialization -----\n");
snprintf(reflib_path, sizeof(reflib_path), "./ref_gl.%s", lib_ext); // TODO: name from cvar
GetRefAPI = Sys_LoadLibrary(reflib_path, "GetRefAPI", &reflib_handle);
if(GetRefAPI == NULL)
{
Com_Error( ERR_FATAL, "Loading %s as renderer lib failed!", reflib_path );
return false;
}
ri.Cmd_AddCommand = Cmd_AddCommand;
ri.Cmd_RemoveCommand = Cmd_RemoveCommand;
ri.Cmd_Argc = Cmd_Argc;
ri.Cmd_Argv = Cmd_Argv;
ri.Cmd_ExecuteText = Cbuf_ExecuteText;
ri.Con_Printf = VID_Printf;
ri.Sys_Error = VID_Error;
ri.FS_LoadFile = FS_LoadFile;
ri.FS_FreeFile = FS_FreeFile;
ri.FS_Gamedir = FS_Gamedir;
ri.Cvar_Get = Cvar_Get;
ri.Cvar_Set = Cvar_Set;
ri.Cvar_SetValue = Cvar_SetValue;
ri.Vid_GetModeInfo = VID_GetModeInfo;
ri.Vid_MenuInit = VID_MenuInit;
ri.Vid_NewWindow = VID_NewWindow;
ri.Vid_ShutdownWindow = VID_ShutdownWindow;
ri.GLimp_InitGraphics = GLimp_InitGraphics;
re = GetRefAPI( ri );
// Declare the refresher as active
ref_active = true;
if (re.api_version != API_VERSION)
{
VID_Shutdown();
Com_Error (ERR_FATAL, "%s has incompatible api_version %d", reflib_path, re.api_version);
}
// Initiate the refresher
if (re.Init(0, 0) == -1)
{
VID_Shutdown(); // Isn't that just too bad? :(
return false;
}
/* Ensure that all key states are cleared */
Key_MarkAllUp();
Com_Printf("------------------------------------\n\n");
return true;
}
void
VID_Shutdown(void)
{
if (ref_active)
{
/* Shut down the renderer */
R_Shutdown();
re.Shutdown();
Sys_FreeLibrary(reflib_handle);
reflib_handle = NULL;
memset(&re, 0, sizeof(re));
}
// Declare the refresher as inactive
ref_active = false;
}
// ======== wrappers for functions from refresh lib ========
void
R_BeginRegistration(char *map)
{
if(ref_active)
{
re.BeginRegistration(map);
}
}
struct model_s*
R_RegisterModel(char *name)
{
if(ref_active)
{
return re.RegisterModel(name);
}
return NULL;
}
struct image_s*
R_RegisterSkin(char *name)
{
if(ref_active)
{
return re.RegisterSkin(name);
}
return NULL;
}
void
R_SetSky(char *name, float rotate, vec3_t axis)
{
if(ref_active)
{
re.SetSky(name, rotate, axis);
}
}
void
R_EndRegistration(void)
{
if(ref_active)
{
re.EndRegistration();
}
}
void
R_RenderFrame(refdef_t *fd)
{
if(ref_active)
{
re.RenderFrame(fd);
}
}
struct image_s*
Draw_FindPic(char *name)
{
if(ref_active)
{
return re.DrawFindPic(name);
}
return NULL;
}
void
Draw_GetPicSize(int *w, int *h, char *name)
{
if(ref_active)
{
re.DrawGetPicSize(w, h, name);
}
}
void
Draw_StretchPic(int x, int y, int w, int h, char *name)
{
if(ref_active)
{
re.DrawStretchPic(x, y, w, h, name);
}
}
void
Draw_PicScaled(int x, int y, char *pic, float factor)
{
if(ref_active)
{
re.DrawPicScaled(x, y, pic, factor);
}
}
void
Draw_CharScaled(int x, int y, int num, float scale)
{
if(ref_active)
{
re.DrawCharScaled(x, y, num, scale);
}
}
void
Draw_TileClear(int x, int y, int w, int h, char *name)
{
if(ref_active)
{
re.DrawTileClear(x, y, w, h, name);
}
}
void
Draw_Fill(int x, int y, int w, int h, int c)
{
if(ref_active)
{
re.DrawFill(x, y, w, h, c);
}
}
void
Draw_FadeScreen(void)
{
if(ref_active)
{
re.DrawFadeScreen();
}
}
void
Draw_StretchRaw(int x, int y, int w, int h, int cols, int rows, byte *data)
{
if(ref_active)
{
re.DrawStretchRaw(x, y, w, h, cols, rows, data);
}
}
void
R_SetPalette(const unsigned char *palette)
{
if(ref_active)
{
re.SetPalette(palette);
}
}
void
R_BeginFrame(float camera_separation)
{
if(ref_active)
{
re.BeginFrame(camera_separation);
}
}
void
R_EndFrame(void)
{
if(ref_active)
{
re.EndFrame();
}
}

View file

@ -35,11 +35,7 @@
*/
#include "../../client/refresh/header/local.h"
#if defined(__APPLE__)
#include <OpenGL/gl.h>
#else
#include <GL/gl.h>
#endif
#ifdef SDL2
#include <SDL2/SDL.h>
@ -49,42 +45,24 @@
#include <SDL/SDL.h>
#endif //SDL2
/* X.org stuff */
#ifdef X11GAMMA
#include <X11/Xos.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/xf86vmode.h>
#include <X11/extensions/Xrandr.h>
#include <SDL_syswm.h>
#endif
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_Window* window = NULL;
SDL_GLContext context = NULL;
static SDL_Window* window = NULL;
#else
SDL_Surface* window = NULL;
static SDL_Surface* window = NULL;
#endif
qboolean have_stencil = false;
qboolean vsync_active;
#ifdef X11GAMMA
XRRCrtcGamma** gammaRamps = NULL;
int noGammaRamps = 0;
#endif
#if SDL_VERSION_ATLEAST(2, 0, 0)
// some compatibility defines
#define SDL_SRCCOLORKEY SDL_TRUE
#define SDL_FULLSCREEN SDL_WINDOW_FULLSCREEN
#define SDL_OPENGL SDL_WINDOW_OPENGL
#endif
/*
* Initialzes the SDL OpenGL context
* Initializes the SDL video subsystem
*/
int
GLimp_Init(void)
@ -110,15 +88,6 @@ GLimp_Init(void)
return true;
}
/*
* Returns the adress of a GL function
*/
void *
GLimp_GetProcAddress (const char* proc)
{
return SDL_GL_GetProcAddress ( proc );
}
/*
* Sets the window icon
*/
@ -208,127 +177,6 @@ SetSDLIcon()
}
#endif /* SDL 1.2 */
/*
* from SDL2 SDL_CalculateGammaRamp, adjusted for arbitrary ramp sizes
* because xrandr seems to support ramp sizes != 256 (in theory at least)
*/
void CalculateGammaRamp(float gamma, Uint16* ramp, int len)
{
int i;
/* Input validation */
if (gamma < 0.0f ) {
return;
}
if (ramp == NULL) {
return;
}
/* 0.0 gamma is all black */
if (gamma == 0.0f) {
for (i = 0; i < len; ++i) {
ramp[i] = 0;
}
return;
} else if (gamma == 1.0f) {
/* 1.0 gamma is identity */
for (i = 0; i < len; ++i) {
ramp[i] = (i << 8) | i;
}
return;
} else {
/* Calculate a real gamma ramp */
int value;
gamma = 1.0f / gamma;
for (i = 0; i < len; ++i) {
value = (int) (pow((double) i / (double) len, gamma) * 65535.0 + 0.5);
if (value > 65535) {
value = 65535;
}
ramp[i] = (Uint16) value;
}
}
}
/*
* Sets the hardware gamma
*/
#ifdef X11GAMMA
void
UpdateHardwareGamma(void)
{
float gamma = (vid_gamma->value);
int i;
Display* dpy = NULL;
SDL_SysWMinfo info;
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_VERSION(&info.version);
if(!SDL_GetWindowWMInfo(window, &info))
#else
if(SDL_GetWMInfo(&info) != 1)
#endif
{
VID_Printf(PRINT_ALL, "Couldn't get Window info from SDL\n");
return;
}
dpy = info.info.x11.display;
XRRScreenResources* res = XRRGetScreenResources(dpy, info.info.x11.window);
if(res == NULL)
{
VID_Printf(PRINT_ALL, "Unable to get xrandr screen resources.\n");
return;
}
for(i=0; i < res->ncrtc; ++i)
{
int len = XRRGetCrtcGammaSize(dpy, res->crtcs[i]);
size_t rampSize = len*sizeof(Uint16);
Uint16* ramp = malloc(rampSize); // TODO: check for NULL
if(ramp == NULL)
{
VID_Printf(PRINT_ALL, "Couldn't allocate &zd byte of memory for gamma ramp - OOM?!\n", rampSize);
return;
}
CalculateGammaRamp(gamma, ramp, len);
XRRCrtcGamma* gamma = XRRAllocGamma(len);
memcpy(gamma->red, ramp, rampSize);
memcpy(gamma->green, ramp, rampSize);
memcpy(gamma->blue, ramp, rampSize);
free(ramp);
XRRSetCrtcGamma(dpy, res->crtcs[i], gamma);
XRRFreeGamma(gamma);
}
XRRFreeScreenResources(res);
}
#else // no X11GAMMA
void
UpdateHardwareGamma(void)
{
float gamma = (vid_gamma->value);
Uint16 ramp[256];
CalculateGammaRamp(gamma, ramp, 256);
#if SDL_VERSION_ATLEAST(2, 0, 0)
if(SDL_SetWindowGammaRamp(window, ramp, ramp, ramp) != 0) {
#else
if(SDL_SetGammaRamp(ramp, ramp, ramp) < 0) {
#endif
VID_Printf(PRINT_ALL, "Setting gamma failed: %s\n", SDL_GetError());
}
}
#endif // X11GAMMA
static qboolean IsFullscreen()
{
#if SDL_VERSION_ATLEAST(2, 0, 0)
@ -338,30 +186,16 @@ static qboolean IsFullscreen()
#endif
}
static qboolean CreateSDLWindow(int flags)
static qboolean CreateSDLWindow(int flags, int w, int h)
{
#if SDL_VERSION_ATLEAST(2, 0, 0)
int windowPos = SDL_WINDOWPOS_UNDEFINED;
// TODO: support fullscreen on different displays with SDL_WINDOWPOS_UNDEFINED_DISPLAY(displaynum)
window = SDL_CreateWindow("Yamagi Quake II", windowPos, windowPos,
vid.width, vid.height, flags);
window = SDL_CreateWindow("Yamagi Quake II", windowPos, windowPos, w, h, flags);
if(window == NULL)
{
return false;
}
context = SDL_GL_CreateContext(window);
if(context == NULL)
{
SDL_DestroyWindow(window);
window = NULL;
return false;
}
return true;
return window != NULL;
#else
window = SDL_SetVideoMode(vid.width, vid.height, 0, flags);
window = SDL_SetVideoMode(w, h, 0, flags);
SDL_EnableUNICODE(SDL_TRUE);
return window != NULL;
#endif
@ -389,145 +223,20 @@ static qboolean GetWindowSize(int* w, int* h)
return true;
}
static void InitGamma()
{
#ifdef X11GAMMA
int i=0;
SDL_SysWMinfo info;
Display* dpy = NULL;
if(gammaRamps != NULL) // already saved gamma
return;
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_VERSION(&info.version);
if(!SDL_GetWindowWMInfo(window, &info))
#else
if(SDL_GetWMInfo(&info) != 1)
#endif
{
VID_Printf(PRINT_ALL, "Couldn't get Window info from SDL\n");
return;
}
dpy = info.info.x11.display;
XRRScreenResources* res = XRRGetScreenResources(dpy, info.info.x11.window);
if(res == NULL)
{
VID_Printf(PRINT_ALL, "Unable to get xrandr screen resources.\n");
return;
}
noGammaRamps = res->ncrtc;
gammaRamps = calloc(noGammaRamps, sizeof(XRRCrtcGamma*));
if(gammaRamps == NULL) {
VID_Printf(PRINT_ALL, "Couldn't allocate memory for %d gamma ramps - OOM?!\n", noGammaRamps);
return;
}
for(i=0; i < noGammaRamps; ++i)
{
int len = XRRGetCrtcGammaSize(dpy, res->crtcs[i]);
size_t rampSize = len*sizeof(Uint16);
XRRCrtcGamma* origGamma = XRRGetCrtcGamma(dpy, res->crtcs[i]);
XRRCrtcGamma* gammaCopy = XRRAllocGamma(len);
memcpy(gammaCopy->red, origGamma->red, rampSize);
memcpy(gammaCopy->green, origGamma->green, rampSize);
memcpy(gammaCopy->blue, origGamma->blue, rampSize);
gammaRamps[i] = gammaCopy;
}
XRRFreeScreenResources(res);
VID_Printf(PRINT_ALL, "Using hardware gamma via X11/xRandR.\n");
#elif __APPLE__
gl_state.hwgamma = false;
VID_Printf(PRINT_ALL, "Using software gamma (needs vid_restart after changes)\n");
return;
#else
VID_Printf(PRINT_ALL, "Using hardware gamma via SDL.\n");
#endif
gl_state.hwgamma = true;
vid_gamma->modified = true;
}
#ifdef X11GAMMA
static void RestoreGamma()
{
int i=0;
SDL_SysWMinfo info;
Display* dpy = NULL;
if(gammaRamps == NULL)
return;
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_VERSION(&info.version);
if(!SDL_GetWindowWMInfo(window, &info))
#else
if(SDL_GetWMInfo(&info) != 1)
#endif
{
VID_Printf(PRINT_ALL, "Couldn't get Window info from SDL\n");
return;
}
dpy = info.info.x11.display;
XRRScreenResources* res = XRRGetScreenResources(dpy, info.info.x11.window);
if(res == NULL)
{
VID_Printf(PRINT_ALL, "Unable to get xrandr screen resources.\n");
return;
}
for(i=0; i < noGammaRamps; ++i)
{
// in case a display was unplugged or something, noGammaRamps may be > res->ncrtc
if(i < res->ncrtc)
{
int len = XRRGetCrtcGammaSize(dpy, res->crtcs[i]);
if(len != gammaRamps[i]->size) {
VID_Printf(PRINT_ALL, "WTF, gamma ramp size for display %d has changed from %d to %d!\n",
i, gammaRamps[i]->size, len);
continue;
}
XRRSetCrtcGamma(dpy, res->crtcs[i], gammaRamps[i]);
}
// the ramp needs to be free()d either way
XRRFreeGamma(gammaRamps[i]);
gammaRamps[i] = NULL;
}
XRRFreeScreenResources(res);
free(gammaRamps);
gammaRamps = NULL;
VID_Printf(PRINT_ALL, "Restored original Gamma\n");
}
#endif // X11GAMMA
/*
* Initializes the OpenGL window
*/
static qboolean
GLimp_InitGraphics(qboolean fullscreen)
qboolean
GLimp_InitGraphics(qboolean fullscreen, int *pwidth, int *pheight)
{
int flags;
int msaa_samples;
int stencil_bits;
int width, height;
int curWidth, curHeight;
char title[24];
int width = *pwidth;
int height = *pheight;
if (GetWindowSize(&width, &height) && (width == vid.width) && (height == vid.height))
if (GetWindowSize(&curWidth, &curHeight) && (curWidth == width) && (curHeight == height))
{
/* If we want fullscreen, but aren't */
if (fullscreen != IsFullscreen())
@ -552,45 +261,21 @@ GLimp_InitGraphics(qboolean fullscreen)
if (window)
{
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_GL_DeleteContext(context);
re.ShutdownWindow(true);
SDL_DestroyWindow(window);
#else
SDL_FreeSurface(window);
#endif
window = NULL;
}
/* Create the window */
VID_NewWindow(vid.width, vid.height);
VID_NewWindow(width, height);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
if (gl_msaa_samples->value)
{
msaa_samples = gl_msaa_samples->value;
if (SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1) < 0)
{
Com_Printf("MSAA is unsupported: %s\n", SDL_GetError());
Cvar_SetValue ("gl_msaa_samples", 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
}
else if (SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, msaa_samples) < 0)
{
Com_Printf("MSAA %ix is unsupported: %s\n", msaa_samples, SDL_GetError());
Cvar_SetValue("gl_msaa_samples", 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
}
}
/* Initiate the flags */
flags = SDL_OPENGL;
// let renderer prepare things (set OpenGL attributes)
flags = re.PrepareForWindow();
if (fullscreen)
{
@ -598,34 +283,31 @@ GLimp_InitGraphics(qboolean fullscreen)
}
#if !SDL_VERSION_ATLEAST(2, 0, 0)
/* For SDL1.2, these things must be done before creating the window */
/* Set the icon */
/* Set window icon - For SDL1.2, this must be done before creating the window */
SetSDLIcon();
/* Set vsync */
SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, gl_swapinterval->value ? 1 : 0);
vsync_active = gl_swapinterval->value ? true : false;
#endif
while (1)
{
if (!CreateSDLWindow(flags))
if (!CreateSDLWindow(flags, width, height))
{
#if 0 // DG: do we really need to do this? it makes things complicated and belongs into ref dll
if (gl_msaa_samples->value)
{
VID_Printf(PRINT_ALL, "SDL SetVideoMode failed: %s\n",
SDL_GetError());
VID_Printf(PRINT_ALL, "Reverting to %s gl_mode %i (%ix%i) without MSAA.\n",
(flags & SDL_FULLSCREEN) ? "fullscreen" : "windowed",
(int)Cvar_VariableValue("gl_mode"), vid.width, vid.height);
(int)Cvar_VariableValue("gl_mode"), width, height);
/* Try to recover */
Cvar_SetValue("gl_msaa_samples", 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
}
else if (vid.width != 640 || vid.height != 480 || (flags & SDL_FULLSCREEN))
else
#endif // 0
if (width != 640 || height != 480 || (flags & SDL_FULLSCREEN))
{
VID_Printf(PRINT_ALL, "SDL SetVideoMode failed: %s\n",
SDL_GetError());
@ -634,8 +316,9 @@ GLimp_InitGraphics(qboolean fullscreen)
/* Try to recover */
Cvar_SetValue("gl_mode", 4);
Cvar_SetValue("vid_fullscreen", 0);
vid.width = 640;
vid.height = 480;
VID_NewWindow(width, height);
*pwidth = width = 640;
*pheight = height = 480;
flags &= ~SDL_FULLSCREEN;
}
else
@ -649,43 +332,25 @@ GLimp_InitGraphics(qboolean fullscreen)
break;
}
}
if (gl_msaa_samples->value)
if(!re.InitContext(window))
{
if (SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &msaa_samples) == 0)
{
Cvar_SetValue("gl_msaa_samples", msaa_samples);
}
// InitContext() should have logged an error
return false;
}
#if SDL_VERSION_ATLEAST(2, 0, 0)
/* For SDL2, these things must be done after creating the window */
/* Set the icon */
SetSDLIcon();
/* Set vsync - TODO: -1 could be set for "late swap tearing" */
SDL_GL_SetSwapInterval(gl_swapinterval->value ? 1 : 0);
// VSync is really set in the renderer dll, but we want vsync_active here
// so just get it from the Cvar here, even though it's a bit ugly
cvar_t* gl_swapinterval = Cvar_Get("gl_swapinterval", "1", CVAR_ARCHIVE);
vsync_active = gl_swapinterval->value ? true : false;
#endif
/* Initialize the stencil buffer */
if (!SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &stencil_bits))
{
VID_Printf(PRINT_ALL, "Got %d bits of stencil.\n", stencil_bits);
if (stencil_bits >= 1)
{
have_stencil = true;
}
}
/* Initialize hardware gamma */
InitGamma();
/* Window title */
snprintf(title, sizeof(title), "Yamagi Quake II %s", YQ2VERSION);
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_SetWindowTitle(window, title);
/* Also set the window icon - For SDL2, this must be done after creating the window */
SetSDLIcon();
#else
SDL_WM_SetCaption(title, title);
#endif
@ -696,45 +361,6 @@ GLimp_InitGraphics(qboolean fullscreen)
return true;
}
/*
* Swaps the buffers to show the new frame
*/
void
GLimp_EndFrame(void)
{
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_GL_SwapWindow(window);
#else
SDL_GL_SwapBuffers();
#endif
}
/*
* Changes the video mode
*/
int
GLimp_SetMode(int *pwidth, int *pheight, int mode, qboolean fullscreen)
{
VID_Printf(PRINT_ALL, "setting mode %d:", mode);
/* mode -1 is not in the vid mode table - so we keep the values in pwidth
and pheight and don't even try to look up the mode info */
if ((mode != -1) && !VID_GetModeInfo(pwidth, pheight, mode))
{
VID_Printf(PRINT_ALL, " invalid mode\n");
return rserr_invalid_mode;
}
VID_Printf(PRINT_ALL, " %d %d\n", *pwidth, *pheight);
if (!GLimp_InitGraphics(fullscreen))
{
return rserr_invalid_mode;
}
return rserr_ok;
}
/*
* (Un)grab Input
*/
@ -790,36 +416,14 @@ int GLimp_GetRefreshRate(void)
* Shuts the SDL render backend down
*/
void
GLimp_Shutdown(void)
VID_ShutdownWindow(void)
{
/* Clear the backbuffer and make it
current. This may help some broken
video drivers like the AMD Catalyst
to avoid artifacts in unused screen
areas. */
if (SDL_WasInit(SDL_INIT_VIDEO))
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GLimp_EndFrame();
}
#ifdef X11GAMMA
RestoreGamma();
#endif
if (window)
{
/* cleanly ungrab input (needs window) */
GLimp_GrabInput(false);
#if SDL_VERSION_ATLEAST(2, 0, 0)
if(context)
{
SDL_GL_DeleteContext(context);
context = NULL;
}
SDL_DestroyWindow(window);
#else
SDL_FreeSurface(window);
@ -836,7 +440,4 @@ GLimp_Shutdown(void)
{
SDL_QuitSubSystem(SDL_INIT_VIDEO);
}
gl_state.hwgamma = false;
}

View file

@ -658,7 +658,7 @@ SCR_TimeRefresh_f(void)
R_RenderFrame(&cl.refdef);
}
GLimp_EndFrame();
R_EndFrame();
}
}
else
@ -669,7 +669,7 @@ SCR_TimeRefresh_f(void)
R_BeginFrame(0);
R_RenderFrame(&cl.refdef);
GLimp_EndFrame();
R_EndFrame();
}
}
@ -1566,7 +1566,7 @@ SCR_UpdateScreen(void)
}
}
GLimp_EndFrame();
R_EndFrame();
}
static float

View file

@ -52,7 +52,6 @@
#define SHELL_WHITE_COLOR 0xD7
#define ENTITY_FLAGS 68
#define API_VERSION 3
typedef struct entity_s {
struct model_s *model; /* opaque type outside refresh */
@ -117,8 +116,127 @@ typedef struct {
particle_t *particles;
} refdef_t;
// Soon to be deleted
//void R_GetRefAPI(void);
// FIXME: bump API_VERSION?
#define API_VERSION 4
#define EXPORT
#define IMPORT
//
// these are the functions exported by the refresh module
//
typedef struct
{
// if api_version is different, the dll cannot be used
int api_version;
// called when the library is loaded - FIXME: remove arguments, not used anyway
int (EXPORT *Init) ( void *hinstance, void *wndproc );
// called before the library is unloaded
void (EXPORT *Shutdown) (void);
// called by GLimp_InitGraphics() before creating window,
// returns flags for SDL window creation
int (EXPORT *PrepareForWindow)(void);
// called by GLimp_InitGraphics() *after* creating window,
// passing the SDL_Window* (void* so we don't spill SDL.h here)
// returns true (1) on success
int (EXPORT *InitContext)(void* window);
// shuts down rendering (OpenGL) context, calls
// VID_ShutdownWindow() to shut down window as well, if !contextOnly
void (EXPORT *ShutdownWindow)(qboolean contextOnly);
// 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.
//
// EndRegistration will free any remaining data that wasn't registered.
// Any model_s or skin_s pointers from before the BeginRegistration
// are no longer valid after EndRegistration.
//
// Skins and images need to be differentiated, because skins
// are flood filled to eliminate mip map edge errors, and pics have
// an implicit "pics/" prepended to the name. (a pic name that starts with a
// slash will not use the "pics/" prefix or the ".pcx" postfix)
void (EXPORT *BeginRegistration) (char *map);
struct model_s * (EXPORT *RegisterModel) (char *name);
struct image_s * (EXPORT *RegisterSkin) (char *name);
void (EXPORT *SetSky) (char *name, float rotate, vec3_t axis);
void (EXPORT *EndRegistration) (void);
void (EXPORT *RenderFrame) (refdef_t *fd);
struct image_s * (EXPORT *DrawFindPic)(char *name);
void (EXPORT *DrawGetPicSize) (int *w, int *h, char *name); // will return 0 0 if not found
//void (EXPORT *DrawPic) (int x, int y, char *name); - apparently not used anymore
void (EXPORT *DrawPicScaled) (int x, int y, char *pic, float factor);
void (EXPORT *DrawStretchPic) (int x, int y, int w, int h, char *name);
void (EXPORT *DrawChar) (int x, int y, int c);
void (EXPORT *DrawCharScaled)(int x, int y, int num, float scale);
void (EXPORT *DrawTileClear) (int x, int y, int w, int h, char *name);
void (EXPORT *DrawFill) (int x, int y, int w, int h, int c);
void (EXPORT *DrawFadeScreen) (void);
// Draw images for cinematic rendering (which can have a different palette). Note that calls
void (EXPORT *DrawStretchRaw) (int x, int y, int w, int h, int cols, int rows, byte *data);
/*
** video mode and refresh state management entry points
*/
void (EXPORT *SetPalette)( const unsigned char *palette); // NULL = game palette
void (EXPORT *BeginFrame)( float camera_separation );
void (EXPORT *EndFrame) (void);
//void (EXPORT *AppActivate)( qboolean activate );
} refexport_t;
typedef struct
{
void (IMPORT *Sys_Error) (int err_level, char *str, ...) __attribute__ ((format (printf, 2, 3)));
void (IMPORT *Cmd_AddCommand) (char *name, void(*cmd)(void));
void (IMPORT *Cmd_RemoveCommand) (char *name);
int (IMPORT *Cmd_Argc) (void);
char *(IMPORT *Cmd_Argv) (int i);
void (IMPORT *Cmd_ExecuteText) (int exec_when, char *text);
void (IMPORT *Con_Printf) (int print_level, char *str, ...) __attribute__ ((format (printf, 2, 3)));
// files will be memory mapped read only
// the returned buffer may be part of a larger pak file,
// or a discrete file from anywhere in the quake search path
// a -1 return means the file does not exist
// NULL can be passed for buf to just determine existance
int (IMPORT *FS_LoadFile) (char *name, void **buf);
void (IMPORT *FS_FreeFile) (void *buf);
// gamedir will be the current directory that generated
// files should be stored to, ie: "f:\quake\id1"
char *(IMPORT *FS_Gamedir) (void);
cvar_t *(IMPORT *Cvar_Get) (char *name, char *value, int flags);
cvar_t *(IMPORT *Cvar_Set) (char *name, char *value);
void (IMPORT *Cvar_SetValue) (char *name, float value);
qboolean (IMPORT *Vid_GetModeInfo)(int *width, int *height, int mode);
void (IMPORT *Vid_MenuInit)( void );
void (IMPORT *Vid_NewWindow)( int width, int height );
void (IMPORT *Vid_ShutdownWindow)(void);
qboolean (IMPORT *GLimp_InitGraphics)(qboolean fullscreen, int *pwidth, int *pheight);
} refimport_t;
// this is the only function actually exported at the linker level
typedef refexport_t (EXPORT *GetRefAPI_t) (refimport_t);
// FIXME: #ifdef client/ref around this
extern refexport_t re;
extern refimport_t ri;
/*
* Refresh API
@ -132,19 +250,19 @@ void R_EndRegistration(void);
struct image_s *Draw_FindPic(char *name);
void R_RenderFrame(refdef_t *fd);
void Draw_GetPicSize(int *w, int *h, char *name);
void Draw_Pic(int x, int y, char *name);
void Draw_StretchPic(int x, int y, int w, int h, char *name);
void Draw_PicScaled(int x, int y, char *pic, float factor);
void Draw_Char(int x, int y, int c);
void Draw_CharScaled(int x, int y, int num, float scale);
void Draw_TileClear(int x, int y, int w, int h, char *name);
void Draw_Fill(int x, int y, int w, int h, int c);
void Draw_FadeScreen(void);
void Draw_StretchRaw(int x, int y, int w, int h, int cols, int rows, byte *data);
int R_Init(void *hinstance, void *hWnd);
void R_Shutdown(void);
//int R_Init(void *hinstance, void *hWnd);
//void R_Shutdown(void);
void R_SetPalette(const unsigned char *palette);
void R_BeginFrame(float camera_separation);
void GLimp_EndFrame(void);
void R_EndFrame(void);
#endif

View file

@ -1251,7 +1251,7 @@ UpdateSoundQualityFunc(void *unused)
M_Popup();
/* the text box won't show up unless we do a buffer swap */
GLimp_EndFrame();
R_EndFrame();
CL_Snd_Restart_f();
}
@ -2566,7 +2566,7 @@ SearchLocalGames(void)
M_Popup();
/* the text box won't show up unless we do a buffer swap */
GLimp_EndFrame();
R_EndFrame();
/* send out info packets */
CL_PingServers_f();

View file

@ -24,7 +24,7 @@
* =======================================================================
*/
#include "header/local.h"
#include "../header/local.h"
image_t *draw_chars;
@ -51,18 +51,7 @@ Draw_InitLocal(void)
* smoothly scrolled off.
*/
void
Draw_Char(int x, int y, int num)
{
Draw_CharScaled(x, y, num, 1.0f);
}
/*
* Draws one 8*8 graphics character with 0 being transparent.
* It can be clipped to the top of the screen to allow the console to be
* smoothly scrolled off.
*/
void
Draw_CharScaled(int x, int y, int num, float scale)
RDraw_CharScaled(int x, int y, int num, float scale)
{
int row, col;
float frow, fcol, size, scaledSize;
@ -116,7 +105,7 @@ Draw_CharScaled(int x, int y, int num, float scale)
}
image_t *
Draw_FindPic(char *name)
RDraw_FindPic(char *name)
{
image_t *gl;
char fullname[MAX_QPATH];
@ -135,11 +124,11 @@ Draw_FindPic(char *name)
}
void
Draw_GetPicSize(int *w, int *h, char *pic)
RDraw_GetPicSize(int *w, int *h, char *pic)
{
image_t *gl;
gl = Draw_FindPic(pic);
gl = RDraw_FindPic(pic);
if (!gl)
{
@ -152,11 +141,11 @@ Draw_GetPicSize(int *w, int *h, char *pic)
}
void
Draw_StretchPic(int x, int y, int w, int h, char *pic)
RDraw_StretchPic(int x, int y, int w, int h, char *pic)
{
image_t *gl;
gl = Draw_FindPic(pic);
gl = RDraw_FindPic(pic);
if (!gl)
{
@ -197,17 +186,11 @@ Draw_StretchPic(int x, int y, int w, int h, char *pic)
}
void
Draw_Pic(int x, int y, char *pic)
{
Draw_PicScaled(x, y, pic, 1.0f);
}
void
Draw_PicScaled(int x, int y, char *pic, float factor)
RDraw_PicScaled(int x, int y, char *pic, float factor)
{
image_t *gl;
gl = Draw_FindPic(pic);
gl = RDraw_FindPic(pic);
if (!gl)
{
@ -253,11 +236,11 @@ Draw_PicScaled(int x, int y, char *pic, float factor)
* refresh window.
*/
void
Draw_TileClear(int x, int y, int w, int h, char *pic)
RDraw_TileClear(int x, int y, int w, int h, char *pic)
{
image_t *image;
image = Draw_FindPic(pic);
image = RDraw_FindPic(pic);
if (!image)
{
@ -296,7 +279,7 @@ Draw_TileClear(int x, int y, int w, int h, char *pic)
* Fills a box of pixels with a single color
*/
void
Draw_Fill(int x, int y, int w, int h, int c)
RDraw_Fill(int x, int y, int w, int h, int c)
{
union
{
@ -334,7 +317,7 @@ Draw_Fill(int x, int y, int w, int h, int c)
}
void
Draw_FadeScreen(void)
RDraw_FadeScreen(void)
{
glEnable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
@ -360,7 +343,7 @@ Draw_FadeScreen(void)
}
void
Draw_StretchRaw(int x, int y, int w, int h, int cols, int rows, byte *data)
RDraw_StretchRaw(int x, int y, int w, int h, int cols, int rows, byte *data)
{
GLfloat tex[8];
byte *source;

View file

@ -24,7 +24,7 @@
* =======================================================================
*/
#include "header/local.h"
#include "../header/local.h"
image_t gltextures[MAX_GLTEXTURES];
int numgltextures;
@ -1201,7 +1201,7 @@ R_FindImage(char *name, imagetype_t type)
}
struct image_s *
R_RegisterSkin(char *name)
RI_RegisterSkin(char *name)
{
return R_FindImage(name, it_skin);
}

View file

@ -24,7 +24,7 @@
* =======================================================================
*/
#include "header/local.h"
#include "../header/local.h"
#define DLIGHT_CUTOFF 64

View file

@ -24,7 +24,7 @@
* =======================================================================
*/
#include "header/local.h"
#include "../header/local.h"
extern gllightmapstate_t gl_lms;

View file

@ -24,7 +24,7 @@
* =======================================================================
*/
#include "header/local.h"
#include "../header/local.h"
#define NUM_BEAM_SEGS 6
@ -134,6 +134,9 @@ cvar_t *gl_stereo_separation;
cvar_t *gl_stereo_anaglyph_colors;
cvar_t *gl_stereo_convergence;
refimport_t ri; // TODO: put this in some header ?
/*
* Returns true if the box is completely outside the frustom
*/
@ -1179,7 +1182,7 @@ R_SetLightLevel(void)
}
void
R_RenderFrame(refdef_t *fd)
RI_RenderFrame(refdef_t *fd)
{
R_RenderView(fd);
R_SetLightLevel();
@ -1263,6 +1266,32 @@ R_Register(void)
Cmd_AddCommand("gl_strings", R_Strings);
}
/*
* Changes the video mode
*/
static int
SetMode_impl(int *pwidth, int *pheight, int mode, qboolean fullscreen)
{
VID_Printf(PRINT_ALL, "setting mode %d:", mode);
/* mode -1 is not in the vid mode table - so we keep the values in pwidth
and pheight and don't even try to look up the mode info */
if ((mode != -1) && !VID_GetModeInfo(pwidth, pheight, mode))
{
VID_Printf(PRINT_ALL, " invalid mode\n");
return rserr_invalid_mode;
}
VID_Printf(PRINT_ALL, " %d %d\n", *pwidth, *pheight);
if (!ri.GLimp_InitGraphics(fullscreen, pwidth, pheight))
{
return rserr_invalid_mode;
}
return rserr_ok;
}
qboolean
R_SetMode(void)
{
@ -1279,7 +1308,7 @@ R_SetMode(void)
vid.width = gl_customwidth->value;
vid.height = gl_customheight->value;
if ((err = GLimp_SetMode(&vid.width, &vid.height, gl_mode->value,
if ((err = SetMode_impl(&vid.width, &vid.height, gl_mode->value,
fullscreen)) == rserr_ok)
{
if (gl_mode->value == -1)
@ -1299,7 +1328,7 @@ R_SetMode(void)
vid_fullscreen->modified = false;
VID_Printf(PRINT_ALL, "ref_gl::R_SetMode() - fullscreen unavailable in this mode\n");
if ((err = GLimp_SetMode(&vid.width, &vid.height, gl_mode->value, false)) == rserr_ok)
if ((err = SetMode_impl(&vid.width, &vid.height, gl_mode->value, false)) == rserr_ok)
{
return true;
}
@ -1312,7 +1341,7 @@ R_SetMode(void)
}
/* try setting it back to something safe */
if ((err = GLimp_SetMode(&vid.width, &vid.height, gl_state.prev_mode, false)) != rserr_ok)
if ((err = SetMode_impl(&vid.width, &vid.height, gl_state.prev_mode, false)) != rserr_ok)
{
VID_Printf(PRINT_ALL, "ref_gl::R_SetMode() - could not revert to safe mode\n");
return false;
@ -1323,7 +1352,7 @@ R_SetMode(void)
}
int
R_Init(void *hinstance, void *hWnd)
RI_Init(void *hinstance, void *hWnd)
{
int j;
extern float r_turbsin[256];
@ -1518,7 +1547,7 @@ R_Init(void *hinstance, void *hWnd)
}
void
R_Shutdown(void)
RI_Shutdown(void)
{
Cmd_RemoveCommand("modellist");
Cmd_RemoveCommand("screenshot");
@ -1530,7 +1559,7 @@ R_Shutdown(void)
R_ShutdownImages();
/* shutdown OS specific OpenGL stuff like contexts, etc. */
GLimp_Shutdown();
RI_ShutdownWindow(false);
/* shutdown our QGL subsystem */
QGL_Shutdown();
@ -1539,7 +1568,7 @@ R_Shutdown(void)
extern void UpdateHardwareGamma();
void
R_BeginFrame(float camera_separation)
RI_BeginFrame(float camera_separation)
{
gl_state.camera_separation = camera_separation;
@ -1666,7 +1695,7 @@ R_BeginFrame(float camera_separation)
}
void
R_SetPalette(const unsigned char *palette)
RI_SetPalette(const unsigned char *palette)
{
int i;
@ -1790,3 +1819,72 @@ R_DrawBeam(entity_t *e)
glDepthMask(GL_TRUE);
}
extern int RI_PrepareForWindow(void);
extern int RI_InitContext(void* win);
extern void RI_BeginRegistration(char *model);
extern struct model_s * RI_RegisterModel(char *name);
extern struct image_s * RI_RegisterSkin(char *name);
extern void RI_SetSky(char *name, float rotate, vec3_t axis);
extern void RI_EndRegistration(void);
extern void RI_RenderFrame(refdef_t *fd);
extern image_t * RDraw_FindPic(char *name);
extern void RDraw_GetPicSize(int *w, int *h, char *pic);
extern void RDraw_PicScaled(int x, int y, char *pic, float factor);
extern void RDraw_StretchPic(int x, int y, int w, int h, char *pic);
extern void RDraw_CharScaled(int x, int y, int num, float scale);
extern void RDraw_TileClear(int x, int y, int w, int h, char *pic);
extern void RDraw_Fill(int x, int y, int w, int h, int c);
extern void RDraw_FadeScreen(void);
extern void RDraw_StretchRaw(int x, int y, int w, int h, int cols, int rows, byte *data);
extern void RI_SetPalette(const unsigned char *palette);
extern void RI_EndFrame(void);
refexport_t
GetRefAPI(refimport_t imp)
{
refexport_t re = {0};
ri = imp;
re.api_version = API_VERSION;
re.Init = RI_Init;
re.Shutdown = RI_Shutdown;
re.PrepareForWindow = RI_PrepareForWindow;
re.InitContext = RI_InitContext;
re.ShutdownWindow = RI_ShutdownWindow;
re.BeginRegistration = RI_BeginRegistration;
re.RegisterModel = RI_RegisterModel;
re.RegisterSkin = RI_RegisterSkin;
re.SetSky = RI_SetSky;
re.EndRegistration = RI_EndRegistration;
re.RenderFrame = RI_RenderFrame;
re.DrawFindPic = RDraw_FindPic;
re.DrawGetPicSize = RDraw_GetPicSize;
//re.DrawPic = Draw_Pic;
re.DrawPicScaled = RDraw_PicScaled;
re.DrawStretchPic = RDraw_StretchPic;
//re.DrawChar = Draw_Char;
re.DrawCharScaled = RDraw_CharScaled;
re.DrawTileClear = RDraw_TileClear;
re.DrawFill = RDraw_Fill;
re.DrawFadeScreen = RDraw_FadeScreen;
re.DrawStretchRaw = RDraw_StretchRaw;
re.SetPalette = RI_SetPalette;
re.BeginFrame = RI_BeginFrame;
re.EndFrame = RI_EndFrame;
return re;
}

View file

@ -24,18 +24,18 @@
* =======================================================================
*/
#include "header/local.h"
#include "../header/local.h"
#define NUMVERTEXNORMALS 162
#define SHADEDOT_QUANT 16
float r_avertexnormals[NUMVERTEXNORMALS][3] = {
#include "constants/anorms.h"
#include "../constants/anorms.h"
};
/* precalculated dot products for quantized angles */
float r_avertexnormal_dots[SHADEDOT_QUANT][256] =
#include "constants/anormtab.h"
#include "../constants/anormtab.h"
;
typedef float vec4_t[4];

View file

@ -24,7 +24,7 @@
* =======================================================================
*/
#include "header/local.h"
#include "../header/local.h"
byte dottexture[8][8] = {
{0, 0, 0, 0, 0, 0, 0, 0},

View file

@ -24,7 +24,7 @@
* =======================================================================
*/
#include "header/local.h"
#include "../header/local.h"
#define MAX_MOD_KNOWN 512
@ -980,7 +980,7 @@ Mod_FreeAll(void)
* Specifies the model that will be used as the world
*/
void
R_BeginRegistration(char *model)
RI_BeginRegistration(char *model)
{
char fullname[MAX_QPATH];
cvar_t *flushmap;
@ -1006,7 +1006,7 @@ R_BeginRegistration(char *model)
}
struct model_s *
R_RegisterModel(char *name)
RI_RegisterModel(char *name)
{
model_t *mod;
int i;
@ -1055,7 +1055,7 @@ R_RegisterModel(char *name)
}
void
R_EndRegistration(void)
RI_EndRegistration(void)
{
int i;
model_t *mod;

View file

@ -25,7 +25,7 @@
* =======================================================================
*/
#include "header/local.h"
#include "../header/local.h"
int scrap_allocated[MAX_SCRAPS][BLOCK_WIDTH];
byte scrap_texels[MAX_SCRAPS][BLOCK_WIDTH * BLOCK_HEIGHT];

View file

@ -0,0 +1,449 @@
// SDL-specific OpenGL shit formerly in refresh.c
#include "../header/local.h"
#ifdef SDL2
#include <SDL2/SDL.h>
#else // SDL1.2
#include <SDL/SDL.h>
#endif //SDL2
#if defined(__APPLE__)
#include <OpenGL/gl.h>
#else
#include <GL/gl.h>
#endif
/* X.org stuff - put this here as more modern renderers wouldn't need it
* e.g. an OpenGL3 renderer could just apply gamma through a shader */
#ifdef X11GAMMA
#include <X11/Xos.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/xf86vmode.h>
#include <X11/extensions/Xrandr.h>
#include <SDL_syswm.h>
XRRCrtcGamma** gammaRamps = NULL;
int noGammaRamps = 0;
#endif
#if SDL_VERSION_ATLEAST(2, 0, 0)
static SDL_Window* window = NULL;
static SDL_GLContext context = NULL;
#else
static SDL_Surface* window = NULL;
#endif
qboolean have_stencil = false;
/*
* Returns the adress of a GL function
*/
void *
GLimp_GetProcAddress (const char* proc)
{
return SDL_GL_GetProcAddress ( proc );
}
/*
* from SDL2 SDL_CalculateGammaRamp, adjusted for arbitrary ramp sizes
* because xrandr seems to support ramp sizes != 256 (in theory at least)
*/
void CalculateGammaRamp(float gamma, Uint16* ramp, int len)
{
int i;
/* Input validation */
if (gamma < 0.0f ) {
return;
}
if (ramp == NULL) {
return;
}
/* 0.0 gamma is all black */
if (gamma == 0.0f) {
for (i = 0; i < len; ++i) {
ramp[i] = 0;
}
return;
} else if (gamma == 1.0f) {
/* 1.0 gamma is identity */
for (i = 0; i < len; ++i) {
ramp[i] = (i << 8) | i;
}
return;
} else {
/* Calculate a real gamma ramp */
int value;
gamma = 1.0f / gamma;
for (i = 0; i < len; ++i) {
value = (int) (pow((double) i / (double) len, gamma) * 65535.0 + 0.5);
if (value > 65535) {
value = 65535;
}
ramp[i] = (Uint16) value;
}
}
}
/*
* Sets the hardware gamma
*/
#ifdef X11GAMMA
void
UpdateHardwareGamma(void)
{
float gamma = (vid_gamma->value);
int i;
Display* dpy = NULL;
SDL_SysWMinfo info;
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_VERSION(&info.version);
if(!SDL_GetWindowWMInfo(window, &info))
#else
if(SDL_GetWMInfo(&info) != 1)
#endif
{
VID_Printf(PRINT_ALL, "Couldn't get Window info from SDL\n");
return;
}
dpy = info.info.x11.display;
XRRScreenResources* res = XRRGetScreenResources(dpy, info.info.x11.window);
if(res == NULL)
{
VID_Printf(PRINT_ALL, "Unable to get xrandr screen resources.\n");
return;
}
for(i=0; i < res->ncrtc; ++i)
{
int len = XRRGetCrtcGammaSize(dpy, res->crtcs[i]);
size_t rampSize = len*sizeof(Uint16);
Uint16* ramp = malloc(rampSize); // TODO: check for NULL
if(ramp == NULL)
{
VID_Printf(PRINT_ALL, "Couldn't allocate &zd byte of memory for gamma ramp - OOM?!\n", rampSize);
return;
}
CalculateGammaRamp(gamma, ramp, len);
XRRCrtcGamma* gamma = XRRAllocGamma(len);
memcpy(gamma->red, ramp, rampSize);
memcpy(gamma->green, ramp, rampSize);
memcpy(gamma->blue, ramp, rampSize);
free(ramp);
XRRSetCrtcGamma(dpy, res->crtcs[i], gamma);
XRRFreeGamma(gamma);
}
XRRFreeScreenResources(res);
}
#else // no X11GAMMA
void
UpdateHardwareGamma(void)
{
float gamma = (vid_gamma->value);
Uint16 ramp[256];
CalculateGammaRamp(gamma, ramp, 256);
#if SDL_VERSION_ATLEAST(2, 0, 0)
if(SDL_SetWindowGammaRamp(window, ramp, ramp, ramp) != 0) {
#else
if(SDL_SetGammaRamp(ramp, ramp, ramp) < 0) {
#endif
VID_Printf(PRINT_ALL, "Setting gamma failed: %s\n", SDL_GetError());
}
}
#endif // X11GAMMA
static void InitGamma()
{
#ifdef X11GAMMA
int i=0;
SDL_SysWMinfo info;
Display* dpy = NULL;
if(gammaRamps != NULL) // already saved gamma
return;
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_VERSION(&info.version);
if(!SDL_GetWindowWMInfo(window, &info))
#else
if(SDL_GetWMInfo(&info) != 1)
#endif
{
VID_Printf(PRINT_ALL, "Couldn't get Window info from SDL\n");
return;
}
dpy = info.info.x11.display;
XRRScreenResources* res = XRRGetScreenResources(dpy, info.info.x11.window);
if(res == NULL)
{
VID_Printf(PRINT_ALL, "Unable to get xrandr screen resources.\n");
return;
}
noGammaRamps = res->ncrtc;
gammaRamps = calloc(noGammaRamps, sizeof(XRRCrtcGamma*));
if(gammaRamps == NULL) {
VID_Printf(PRINT_ALL, "Couldn't allocate memory for %d gamma ramps - OOM?!\n", noGammaRamps);
return;
}
for(i=0; i < noGammaRamps; ++i)
{
int len = XRRGetCrtcGammaSize(dpy, res->crtcs[i]);
size_t rampSize = len*sizeof(Uint16);
XRRCrtcGamma* origGamma = XRRGetCrtcGamma(dpy, res->crtcs[i]);
XRRCrtcGamma* gammaCopy = XRRAllocGamma(len);
memcpy(gammaCopy->red, origGamma->red, rampSize);
memcpy(gammaCopy->green, origGamma->green, rampSize);
memcpy(gammaCopy->blue, origGamma->blue, rampSize);
gammaRamps[i] = gammaCopy;
}
XRRFreeScreenResources(res);
VID_Printf(PRINT_ALL, "Using hardware gamma via X11/xRandR.\n");
#elif __APPLE__
gl_state.hwgamma = false;
VID_Printf(PRINT_ALL, "Using software gamma (needs vid_restart after changes)\n");
return;
#else
VID_Printf(PRINT_ALL, "Using hardware gamma via SDL.\n");
#endif
gl_state.hwgamma = true;
vid_gamma->modified = true;
}
#ifdef X11GAMMA
static void RestoreGamma()
{
int i=0;
SDL_SysWMinfo info;
Display* dpy = NULL;
if(gammaRamps == NULL)
return;
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_VERSION(&info.version);
if(!SDL_GetWindowWMInfo(window, &info))
#else
if(SDL_GetWMInfo(&info) != 1)
#endif
{
VID_Printf(PRINT_ALL, "Couldn't get Window info from SDL\n");
return;
}
dpy = info.info.x11.display;
XRRScreenResources* res = XRRGetScreenResources(dpy, info.info.x11.window);
if(res == NULL)
{
VID_Printf(PRINT_ALL, "Unable to get xrandr screen resources.\n");
return;
}
for(i=0; i < noGammaRamps; ++i)
{
// in case a display was unplugged or something, noGammaRamps may be > res->ncrtc
if(i < res->ncrtc)
{
int len = XRRGetCrtcGammaSize(dpy, res->crtcs[i]);
if(len != gammaRamps[i]->size) {
VID_Printf(PRINT_ALL, "WTF, gamma ramp size for display %d has changed from %d to %d!\n",
i, gammaRamps[i]->size, len);
continue;
}
XRRSetCrtcGamma(dpy, res->crtcs[i], gammaRamps[i]);
}
// the ramp needs to be free()d either way
XRRFreeGamma(gammaRamps[i]);
gammaRamps[i] = NULL;
}
XRRFreeScreenResources(res);
free(gammaRamps);
gammaRamps = NULL;
VID_Printf(PRINT_ALL, "Restored original Gamma\n");
}
#endif // X11GAMMA
// called by GLimp_InitGraphics() before creating window,
// returns flags for SDL window creation
int RI_PrepareForWindow(void)
{
unsigned int flags = 0;
int msaa_samples = 0;
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
#if !SDL_VERSION_ATLEAST(2, 0, 0)
/* Set vsync - For SDL1.2, this must be done before creating the window */
SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, gl_swapinterval->value ? 1 : 0);
#endif
if (gl_msaa_samples->value)
{
msaa_samples = gl_msaa_samples->value;
if (SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1) < 0)
{
Com_Printf("MSAA is unsupported: %s\n", SDL_GetError());
Cvar_SetValue ("gl_msaa_samples", 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
}
else if (SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, msaa_samples) < 0)
{
Com_Printf("MSAA %ix is unsupported: %s\n", msaa_samples, SDL_GetError());
Cvar_SetValue("gl_msaa_samples", 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
}
}
/* Initiate the flags */
#if SDL_VERSION_ATLEAST(2, 0, 0)
flags = SDL_WINDOW_OPENGL;
#else // SDL 1.2
flags = SDL_OPENGL;
#endif
return flags;
}
int RI_InitContext(void* win)
{
int msaa_samples = 0, stencil_bits = 0;
if(win == NULL)
{
VID_Error(ERR_FATAL, "R_InitContext() must not be called with NULL argument!");
return false;
}
window = (SDL_Window*)win;
context = SDL_GL_CreateContext(window);
if(context == NULL)
{
VID_Printf(PRINT_ALL, "R_InitContext(): Creating OpenGL Context failed: %s\n", SDL_GetError());
window = NULL;
return false;
}
if (gl_msaa_samples->value)
{
if (SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &msaa_samples) == 0)
{
Cvar_SetValue("gl_msaa_samples", msaa_samples);
}
}
#if SDL_VERSION_ATLEAST(2, 0, 0)
/* For SDL2, this must be done after creating the window */
/* Set vsync - TODO: -1 could be set for "late swap tearing" */
SDL_GL_SetSwapInterval(gl_swapinterval->value ? 1 : 0);
#endif
/* Initialize the stencil buffer */
if (!SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &stencil_bits))
{
VID_Printf(PRINT_ALL, "Got %d bits of stencil.\n", stencil_bits);
if (stencil_bits >= 1)
{
have_stencil = true;
}
}
/* Initialize hardware gamma */
InitGamma();
return true;
}
/*
* Swaps the buffers to show the new frame
*/
void
RI_EndFrame(void)
{
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_GL_SwapWindow(window);
#else
SDL_GL_SwapBuffers();
#endif
}
/*
* Shuts the SDL render backend down
*/
void
RI_ShutdownWindow(qboolean contextOnly)
{
#ifdef X11GAMMA
RestoreGamma();
#endif
/* Clear the backbuffer and make it
current. This may help some broken
video drivers like the AMD Catalyst
to avoid artifacts in unused screen
areas. */
if (window)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
RI_EndFrame();
#if SDL_VERSION_ATLEAST(2, 0, 0)
if(context)
{
SDL_GL_DeleteContext(context);
context = NULL;
}
#endif
}
window = NULL;
gl_state.hwgamma = false;
if(!contextOnly)
{
ri.Vid_ShutdownWindow();
}
}

View file

@ -25,7 +25,7 @@
*/
#include <assert.h>
#include "header/local.h"
#include "../header/local.h"
int c_visible_lightmaps;
int c_visible_textures;

View file

@ -24,7 +24,7 @@
* =======================================================================
*/
#include "header/local.h"
#include "../header/local.h"
#define TURBSCALE (256.0 / (2 * M_PI))
#define SUBDIVIDE_SIZE 64
@ -48,7 +48,7 @@ unsigned int index_tex = 0;
char *suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"};
float r_turbsin[] = {
#include "constants/warpsin.h"
#include "../constants/warpsin.h"
};
vec3_t skyclip[6] = {
@ -724,7 +724,7 @@ R_DrawSkyBox(void)
}
void
R_SetSky(char *name, float rotate, vec3_t axis)
RI_SetSky(char *name, float rotate, vec3_t axis)
{
int i;
char pathname[MAX_QPATH];

View file

@ -412,14 +412,10 @@ extern glstate_t gl_state;
int GLimp_Init(void);
/*
* Shuts the SDL render backend down
* Shuts the render context and SDL window down
* (if contextOnly, the window will not be shutdown)
*/
void GLimp_Shutdown(void);
/*
* Changes the video mode
*/
int GLimp_SetMode(int *pwidth, int *pheight, int mode, qboolean fullscreen);
void RI_ShutdownWindow(qboolean contextOnly);
/*
* Returns the address of the GL function proc,