Merge pull request #317 from 0lvin/render_speedup_review

Cleanup code in soft render
This commit is contained in:
Yamagi 2018-09-05 14:39:24 +02:00 committed by GitHub
commit 7b0bcec11e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 373 additions and 493 deletions

View file

@ -42,7 +42,7 @@ extern cvar_t *vid_gamma;
extern cvar_t *vid_fullscreen;
extern cvar_t *vid_renderer;
static cvar_t *r_vsync;
static cvar_t *r_anisotropic;
static cvar_t *gl_anisotropic;
static cvar_t *gl_msaa_samples;
static menuframework_s s_opengl_menu;
@ -126,11 +126,11 @@ AnisotropicCallback(void *s)
if (list->curvalue == 0)
{
Cvar_SetValue("r_anisotropic", 0);
Cvar_SetValue("gl_anisotropic", 0);
}
else
{
Cvar_SetValue("r_anisotropic", pow(2, list->curvalue));
Cvar_SetValue("gl_anisotropic", pow(2, list->curvalue));
}
}
@ -362,9 +362,9 @@ VID_MenuInit(void)
r_vsync = Cvar_Get("r_vsync", "1", CVAR_ARCHIVE);
}
if (!r_anisotropic)
if (!gl_anisotropic)
{
r_anisotropic = Cvar_Get("r_anisotropic", "0", CVAR_ARCHIVE);
gl_anisotropic = Cvar_Get("gl_anisotropic", "0", CVAR_ARCHIVE);
}
if (!gl_msaa_samples)
@ -462,13 +462,13 @@ VID_MenuInit(void)
s_af_list.generic.callback = AnisotropicCallback;
s_af_list.itemnames = pow2_names;
s_af_list.curvalue = 0;
if (r_anisotropic->value)
if (gl_anisotropic->value)
{
do
{
s_af_list.curvalue++;
} while (pow2_names[s_af_list.curvalue] &&
pow(2, s_af_list.curvalue) <= r_anisotropic->value);
pow(2, s_af_list.curvalue) <= gl_anisotropic->value);
s_af_list.curvalue--;
}

View file

@ -202,18 +202,18 @@ R_TextureMode(char *string)
/* clamp selected anisotropy */
if (gl_config.anisotropic)
{
if (r_anisotropic->value > gl_config.max_anisotropy)
if (gl_anisotropic->value > gl_config.max_anisotropy)
{
ri.Cvar_SetValue("r_anisotropic", gl_config.max_anisotropy);
ri.Cvar_SetValue("gl_anisotropic", gl_config.max_anisotropy);
}
else if (r_anisotropic->value < 1.0)
else if (gl_anisotropic->value < 1.0)
{
ri.Cvar_SetValue("r_anisotropic", 1.0);
ri.Cvar_SetValue("gl_anisotropic", 1.0);
}
}
else
{
ri.Cvar_SetValue("r_anisotropic", 0.0);
ri.Cvar_SetValue("gl_anisotropic", 0.0);
}
/* change all the existing mipmap texture objects */
@ -228,10 +228,10 @@ R_TextureMode(char *string)
gl_filter_max);
/* Set anisotropic filter if supported and enabled */
if (gl_config.anisotropic && r_anisotropic->value)
if (gl_config.anisotropic && gl_anisotropic->value)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT,
r_anisotropic->value);
gl_anisotropic->value);
}
}
}
@ -788,10 +788,10 @@ R_Upload32(unsigned *data, int width, int height, qboolean mipmap)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
}
if (mipmap && gl_config.anisotropic && r_anisotropic->value)
if (mipmap && gl_config.anisotropic && gl_anisotropic->value)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT,
r_anisotropic->value);
gl_anisotropic->value);
}
return res;
}

View file

@ -124,7 +124,7 @@ cvar_t *r_vsync;
cvar_t *gl_texturemode;
cvar_t *gl1_texturealphamode;
cvar_t *gl1_texturesolidmode;
cvar_t *r_anisotropic;
cvar_t *gl_anisotropic;
cvar_t *r_lockpvs;
cvar_t *gl_msaa_samples;
@ -1241,7 +1241,7 @@ R_Register(void)
gl_texturemode = ri.Cvar_Get("gl_texturemode", "GL_LINEAR_MIPMAP_NEAREST", CVAR_ARCHIVE);
gl1_texturealphamode = ri.Cvar_Get("gl1_texturealphamode", "default", CVAR_ARCHIVE);
gl1_texturesolidmode = ri.Cvar_Get("gl1_texturesolidmode", "default", CVAR_ARCHIVE);
r_anisotropic = ri.Cvar_Get("r_anisotropic", "0", CVAR_ARCHIVE);
gl_anisotropic = ri.Cvar_Get("gl_anisotropic", "0", CVAR_ARCHIVE);
r_lockpvs = ri.Cvar_Get("r_lockpvs", "0", 0);
gl1_palettedtexture = ri.Cvar_Get("gl1_palettedtexture", "0", CVAR_ARCHIVE);
@ -1676,11 +1676,11 @@ RI_BeginFrame(float camera_separation)
}
/* texturemode stuff */
if (gl_texturemode->modified || (gl_config.anisotropic && r_anisotropic->modified))
if (gl_texturemode->modified || (gl_config.anisotropic && gl_anisotropic->modified))
{
R_TextureMode(gl_texturemode->string);
gl_texturemode->modified = false;
r_anisotropic->modified = false;
gl_anisotropic->modified = false;
}
if (gl1_texturealphamode->modified)

View file

@ -215,7 +215,7 @@ extern cvar_t *gl1_flashblend;
extern cvar_t *r_modulate;
extern cvar_t *gl_drawbuffer;
extern cvar_t *r_vsync;
extern cvar_t *r_anisotropic;
extern cvar_t *gl_anisotropic;
extern cvar_t *gl_texturemode;
extern cvar_t *gl1_texturealphamode;
extern cvar_t *gl1_texturesolidmode;

View file

@ -74,18 +74,18 @@ GL3_TextureMode(char *string)
/* clamp selected anisotropy */
if (gl3config.anisotropic)
{
if (r_anisotropic->value > gl3config.max_anisotropy)
if (gl_anisotropic->value > gl3config.max_anisotropy)
{
ri.Cvar_SetValue("r_anisotropic", gl3config.max_anisotropy);
ri.Cvar_SetValue("gl_anisotropic", gl3config.max_anisotropy);
}
else if (r_anisotropic->value < 1.0)
else if (gl_anisotropic->value < 1.0)
{
ri.Cvar_SetValue("r_anisotropic", 1.0);
ri.Cvar_SetValue("gl_anisotropic", 1.0);
}
}
else
{
ri.Cvar_SetValue("r_anisotropic", 0.0);
ri.Cvar_SetValue("gl_anisotropic", 0.0);
}
gl3image_t *glt;
@ -101,9 +101,9 @@ GL3_TextureMode(char *string)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
/* Set anisotropic filter if supported and enabled */
if (gl3config.anisotropic && r_anisotropic->value)
if (gl3config.anisotropic && gl_anisotropic->value)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, r_anisotropic->value);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_anisotropic->value);
}
}
}
@ -200,9 +200,9 @@ GL3_Upload32(unsigned *data, int width, int height, qboolean mipmap)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
}
if (mipmap && gl3config.anisotropic && r_anisotropic->value)
if (mipmap && gl3config.anisotropic && gl_anisotropic->value)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, r_anisotropic->value);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_anisotropic->value);
}
return res;

View file

@ -87,7 +87,7 @@ cvar_t *r_mode;
cvar_t *r_customwidth;
cvar_t *r_customheight;
cvar_t *vid_gamma;
cvar_t *r_anisotropic;
cvar_t *gl_anisotropic;
cvar_t *gl_texturemode;
cvar_t *gl_drawbuffer;
cvar_t *r_clear;
@ -216,7 +216,7 @@ GL3_Register(void)
gl_nobind = ri.Cvar_Get("gl_nobind", "0", 0);
gl_texturemode = ri.Cvar_Get("gl_texturemode", "GL_LINEAR_MIPMAP_NEAREST", CVAR_ARCHIVE);
r_anisotropic = ri.Cvar_Get("r_anisotropic", "0", CVAR_ARCHIVE);
gl_anisotropic = ri.Cvar_Get("gl_anisotropic", "0", CVAR_ARCHIVE);
vid_fullscreen = ri.Cvar_Get("vid_fullscreen", "0", CVAR_ARCHIVE);
vid_gamma = ri.Cvar_Get("vid_gamma", "1.2", CVAR_ARCHIVE);
@ -276,7 +276,7 @@ GL3_Register(void)
//gl_texturemode = ri.Cvar_Get("gl_texturemode", "GL_LINEAR_MIPMAP_NEAREST", CVAR_ARCHIVE);
gl1_texturealphamode = ri.Cvar_Get("gl1_texturealphamode", "default", CVAR_ARCHIVE);
gl1_texturesolidmode = ri.Cvar_Get("gl1_texturesolidmode", "default", CVAR_ARCHIVE);
//r_anisotropic = ri.Cvar_Get("r_anisotropic", "0", CVAR_ARCHIVE);
//gl_anisotropic = ri.Cvar_Get("gl_anisotropic", "0", CVAR_ARCHIVE);
//r_lockpvs = ri.Cvar_Get("r_lockpvs", "0", 0);
//gl1_palettedtexture = ri.Cvar_Get("gl1_palettedtexture", "0", CVAR_ARCHIVE); NOPE.
@ -1657,11 +1657,11 @@ GL3_BeginFrame(float camera_separation)
}
/* texturemode stuff */
if (gl_texturemode->modified || (gl3config.anisotropic && r_anisotropic->modified))
if (gl_texturemode->modified || (gl3config.anisotropic && gl_anisotropic->modified))
{
GL3_TextureMode(gl_texturemode->string);
gl_texturemode->modified = false;
r_anisotropic->modified = false;
gl_anisotropic->modified = false;
}
if (r_vsync->modified)

View file

@ -498,7 +498,7 @@ extern cvar_t *r_drawworld;
extern cvar_t *vid_gamma;
extern cvar_t *gl3_intensity;
extern cvar_t *gl3_intensity_2D;
extern cvar_t *r_anisotropic;
extern cvar_t *gl_anisotropic;
extern cvar_t *r_lightlevel;
extern cvar_t *gl3_overbrightbits;

View file

@ -375,7 +375,6 @@ extern int d_pix_min, d_pix_max, d_pix_mul;
extern pixel_t *d_viewbuffer;
extern zvalue_t *d_pzbuffer;
extern unsigned int d_zwidth;
extern int d_minmip;
extern float d_scalemip[NUM_MIPS-1];
@ -384,7 +383,6 @@ extern float d_scalemip[NUM_MIPS-1];
extern int cachewidth;
extern pixel_t *cacheblock;
extern int r_screenwidth;
extern int r_drawnpolycount;
@ -508,7 +506,7 @@ typedef struct {
int sfrac, tfrac, light;
zvalue_t zi;
} spanpackage_t;
extern spanpackage_t *triangle_spans;
extern spanpackage_t *triangle_spans, *triangles_max;
extern byte **warp_rowptr;
extern int *warp_column;
@ -523,6 +521,7 @@ extern float aliasxscale, aliasyscale, aliasxcenter, aliasycenter;
extern int r_outofsurfaces;
extern int r_outofedges;
extern int r_outofverts;
extern int r_outoftriangles;
extern mvertex_t *r_pcurrentvertbase;

View file

@ -786,7 +786,7 @@ D_FlatFillSurface (surf_t *surf, pixel_t color)
{
pixel_t *pdest;
pdest = d_viewbuffer + r_screenwidth*span->v + span->u;
pdest = d_viewbuffer + vid.width*span->v + span->u;
memset(pdest, color&0xFF, span->count * sizeof(pixel_t));
}
}

View file

@ -59,10 +59,6 @@ typedef struct swstate_s
unsigned char gammatable[256];
unsigned char currentpalette[1024];
// SDL colors
Uint32 palette_colors[256];
} swstate_t;
static swstate_t sw_state;
@ -71,10 +67,12 @@ void *colormap;
float r_time1;
int r_numallocatededges;
int r_numallocatedverts;
int r_numallocatedtriangles;
float r_aliasuvscale = 1.0;
int r_outofsurfaces;
int r_outofedges;
int r_outofverts;
int r_outoftriangles;
qboolean r_dowarp;
@ -101,8 +99,6 @@ float xscaleinv, yscaleinv;
float xscaleshrink, yscaleshrink;
float aliasxscale, aliasyscale, aliasxcenter, aliasycenter;
int r_screenwidth;
mplane_t screenedge[4];
//
@ -137,7 +133,7 @@ cvar_t *sw_surfcacheoverride;
cvar_t *sw_waterwarp;
static cvar_t *sw_overbrightbits;
cvar_t *sw_custom_particles;
cvar_t *r_anisotropic;
cvar_t *sw_texture_filtering;
cvar_t *r_drawworld;
static cvar_t *r_drawentities;
@ -197,12 +193,9 @@ pixel_t *cacheblock;
int cachewidth;
pixel_t *d_viewbuffer;
zvalue_t *d_pzbuffer;
unsigned int d_zwidth;
qboolean insubmodel;
static qboolean sdl_palette_outdated;
static struct texture_buffer {
image_t image;
byte buffer[1024];
@ -290,7 +283,7 @@ R_Register (void)
sw_waterwarp = ri.Cvar_Get ("sw_waterwarp", "1", 0);
sw_overbrightbits = ri.Cvar_Get("sw_overbrightbits", "1.0", CVAR_ARCHIVE);
sw_custom_particles = ri.Cvar_Get("sw_custom_particles", "0", CVAR_ARCHIVE);
r_anisotropic = ri.Cvar_Get("r_anisotropic", "0", CVAR_ARCHIVE);
sw_texture_filtering = ri.Cvar_Get("sw_texture_filtering", "0", CVAR_ARCHIVE);
r_mode = ri.Cvar_Get( "r_mode", "0", CVAR_ARCHIVE );
r_lefthand = ri.Cvar_Get( "hand", "0", CVAR_USERINFO | CVAR_ARCHIVE );
@ -332,7 +325,9 @@ R_UnRegister (void)
ri.Cmd_RemoveCommand( "imagelist" );
}
static void SWimp_DestroyRender(void);
static void RE_ShutdownContext(void);
static void SWimp_CreateRender(void);
static int RE_InitContext(void *win);
/*
===============
@ -402,7 +397,7 @@ RE_Shutdown (void)
Mod_FreeAll ();
R_ShutdownImages ();
SWimp_DestroyRender();
RE_ShutdownContext();
}
/*
@ -528,6 +523,35 @@ R_ReallocateMapBuffers (void)
R_Printf(PRINT_ALL, "Allocated %d verts\n", r_numallocatedverts);
}
if (!r_numallocatedtriangles || r_outoftriangles)
{
if (triangle_spans)
{
free(triangle_spans);
}
if (r_outoftriangles)
{
//R_Printf(PRINT_ALL, "%s: not enough %d(+%d) triangles\n",
// __func__, r_numallocatedtriangles, r_outoftriangles);
r_numallocatedtriangles *= 2;
}
if (r_numallocatedtriangles < vid.height)
r_numallocatedtriangles = vid.height;
triangle_spans = malloc(r_numallocatedtriangles * sizeof(spanpackage_t));
if (!triangle_spans)
{
R_Printf(PRINT_ALL, "%s: Couldn't malloc %d bytes\n",
__func__, (int)(r_numallocatedtriangles * sizeof(spanpackage_t)));
return;
}
triangles_max = &triangle_spans[r_numallocatedtriangles];
R_Printf(PRINT_ALL, "Allocated %d triangles\n", r_numallocatedtriangles);
}
}
@ -1269,12 +1293,11 @@ R_GammaCorrectAndSetPalette( const unsigned char *palette )
for ( i = 0; i < 256; i++ )
{
sw_state.currentpalette[i*4+0] = sw_state.gammatable[palette[i*4+0]];
sw_state.currentpalette[i*4+1] = sw_state.gammatable[palette[i*4+1]];
sw_state.currentpalette[i*4+2] = sw_state.gammatable[palette[i*4+2]];
sw_state.currentpalette[i*4+0] = sw_state.gammatable[palette[i*4+2]]; // blue
sw_state.currentpalette[i*4+1] = sw_state.gammatable[palette[i*4+1]]; // green
sw_state.currentpalette[i*4+2] = sw_state.gammatable[palette[i*4+0]]; // red
sw_state.currentpalette[i*4+3] = 0xFF; // alpha
}
sdl_palette_outdated = true;
}
/*
@ -1508,6 +1531,12 @@ RE_IsVsyncActive(void)
}
}
static int RE_PrepareForWindow(void)
{
int flags = SDL_SWSURFACE;
return flags;
}
/*
===============
GetRefAPI
@ -1546,6 +1575,9 @@ GetRefAPI(refimport_t imp)
re.Init = RE_Init;
re.IsVSyncActive = RE_IsVsyncActive;
re.Shutdown = RE_Shutdown;
re.InitContext = RE_InitContext;
re.ShutdownContext = RE_ShutdownContext;
re.PrepareForWindow = RE_PrepareForWindow;
re.SetPalette = RE_SetPalette;
re.BeginFrame = RE_BeginFrame;
@ -1571,106 +1603,26 @@ GetRefAPI(refimport_t imp)
*/
static SDL_Window *window = NULL;
static SDL_Surface *surface = NULL;
static SDL_Texture *texture = NULL;
static SDL_Renderer *renderer = NULL;
/*
* Sets the window icon
*/
static void
SetSDLIcon()
{
/* The 64x64 32bit window icon */
#include "../../vid/icon/q2icon64.h"
/* these masks are needed to tell SDL_CreateRGBSurface(From)
to assume the data it gets is byte-wise RGB(A) data */
Uint32 rmask, gmask, bmask, amask;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
int shift = (q2icon64.bytes_per_pixel == 3) ? 8 : 0;
rmask = 0xff000000 >> shift;
gmask = 0x00ff0000 >> shift;
bmask = 0x0000ff00 >> shift;
amask = 0x000000ff >> shift;
#else /* little endian, like x86 */
rmask = 0x000000ff;
gmask = 0x0000ff00;
bmask = 0x00ff0000;
amask = (q2icon64.bytes_per_pixel == 3) ? 0 : 0xff000000;
#endif
SDL_Surface* icon = SDL_CreateRGBSurfaceFrom((void*)q2icon64.pixel_data, q2icon64.width,
q2icon64.height, q2icon64.bytes_per_pixel*8, q2icon64.bytes_per_pixel*q2icon64.width,
rmask, gmask, bmask, amask);
SDL_SetWindowIcon(window, icon);
SDL_FreeSurface(icon);
}
static int
IsFullscreen()
{
if (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN_DESKTOP) {
return 1;
} else if (SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN) {
return 2;
} else {
return 0;
}
}
static qboolean
GetWindowSize(int* w, int* h)
{
if(window == NULL || w == NULL || h == NULL)
return false;
SDL_DisplayMode m;
if(SDL_GetWindowDisplayMode(window, &m) != 0)
{
Com_Printf("Can't get Displaymode: %s\n", SDL_GetError());
return false;
}
*w = m.w;
*h = m.h;
return true;
}
static int
R_InitContext(SDL_Window *win)
RE_InitContext(void *win)
{
char title[40] = {0};
if(win == NULL)
{
ri.Sys_Error(ERR_FATAL, "R_InitContext() must not be called with NULL argument!");
ri.Sys_Error(ERR_FATAL, "RE_InitContext() must not be called with NULL argument!");
return false;
}
window = win;
window = (SDL_Window *)win;
/* Window title - set here so we can display renderer name in it */
snprintf(title, sizeof(title), "Yamagi Quake II %s - Soft Render", YQ2VERSION);
SDL_SetWindowTitle(window, title);
return true;
}
static qboolean
CreateSDLWindow(int flags, int w, int h)
{
Uint32 Rmask, Gmask, Bmask, Amask;
int bpp;
int windowPos = SDL_WINDOWPOS_UNDEFINED;
if (!SDL_PixelFormatEnumToMasks(SDL_PIXELFORMAT_ARGB8888, &bpp, &Rmask, &Gmask, &Bmask, &Amask))
return 0;
// TODO: support fullscreen on different displays with SDL_WINDOWPOS_UNDEFINED_DISPLAY(displaynum)
window = SDL_CreateWindow("Yamagi Quake II", windowPos, windowPos, w, h, flags);
if (r_vsync->value)
{
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
@ -1680,17 +1632,30 @@ CreateSDLWindow(int flags, int w, int h)
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
}
surface = SDL_CreateRGBSurface(0, w, h, bpp, Rmask, Gmask, Bmask, Amask);
/* Select the color for drawing. It is set to black here. */
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
/* Clear the entire screen to our selected color. */
SDL_RenderClear(renderer);
/* Up until now everything was drawn behind the scenes.
This will show the new, black contents of the window. */
SDL_RenderPresent(renderer);
texture = SDL_CreateTexture(renderer,
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
SDL_PIXELFORMAT_BGRA8888,
#else
SDL_PIXELFORMAT_ARGB8888,
#endif
SDL_TEXTUREACCESS_STREAMING,
w, h);
return window != NULL;
vid.width, vid.height);
return true;
}
static void
SWimp_DestroyRender(void)
RE_ShutdownContext(void)
{
if (vid_buffer)
{
@ -1788,24 +1753,11 @@ SWimp_DestroyRender(void)
}
texture = NULL;
if (surface)
{
SDL_FreeSurface(surface);
}
surface = NULL;
if (renderer)
{
SDL_DestroyRenderer(renderer);
}
renderer = NULL;
/* Is the surface used? */
if (window)
{
SDL_DestroyWindow(window);
}
window = NULL;
}
/*
@ -1814,165 +1766,10 @@ point math used in R_ScanEdges() overflows at width 2048 !!
*/
char shift_size;
/*
** SWimp_InitGraphics
**
** This initializes the software refresh's implementation specific
** graphics subsystem. In the case of Windows it creates DIB or
** DDRAW surfaces.
**
** The necessary width and height parameters are grabbed from
** vid.width and vid.height.
*/
static qboolean
SWimp_InitGraphics(int fullscreen, int *pwidth, int *pheight)
{
int flags;
int curWidth, curHeight;
int width = *pwidth;
int height = *pheight;
unsigned int fs_flag = 0;
if (fullscreen == 1) {
fs_flag = SDL_WINDOW_FULLSCREEN_DESKTOP;
} else if (fullscreen == 2) {
fs_flag = SDL_WINDOW_FULLSCREEN;
}
if (GetWindowSize(&curWidth, &curHeight) && (curWidth == width) && (curHeight == height))
{
/* If we want fullscreen, but aren't */
if (fullscreen != IsFullscreen())
{
SDL_SetWindowFullscreen(window, fs_flag);
ri.Cvar_SetValue("vid_fullscreen", fullscreen);
}
/* Are we now? */
if (fullscreen == IsFullscreen())
{
return true;
}
}
SWimp_DestroyRender();
// let the sound and input subsystems know about the new window
ri.Vid_NewWindow (vid.width, vid.height);
flags = SDL_SWSURFACE;
if (fs_flag)
{
flags |= fs_flag;
}
while (1)
{
if (!CreateSDLWindow(flags, width, height))
{
Sys_Error("(SOFTSDL) SDL SetVideoMode failed: %s\n", SDL_GetError());
return false;
}
else
{
break;
}
}
if(!R_InitContext(window))
{
// InitContext() should have logged an error
return false;
}
/* Note: window title is now set in re.InitContext() to include renderer name */
/* Set the window icon - For SDL2, this must be done after creating the window */
SetSDLIcon();
/* No cursor */
SDL_ShowCursor(0);
vid_buffer = malloc(vid.height * vid.width * sizeof(pixel_t));
sintable = malloc((vid.width+CYCLE) * sizeof(int));
intsintable = malloc((vid.width+CYCLE) * sizeof(int));
blanktable = malloc((vid.width+CYCLE) * sizeof(int));
newedges = malloc(vid.width * sizeof(edge_t *));
removeedges = malloc(vid.width * sizeof(edge_t *));
// 1 extra for spanpackage that marks end
triangle_spans = malloc((vid.width + 1) * sizeof(spanpackage_t));
warp_rowptr = malloc((vid.width+AMP2*2) * sizeof(byte*));
warp_column = malloc((vid.width+AMP2*2) * sizeof(int));
edge_basespans = malloc((vid.width*2) * sizeof(espan_t));
// count of "out of items"
r_outofsurfaces = r_outofedges = r_outofverts = 0;
// pointers to allocated buffers
finalverts = NULL;
r_edges = NULL;
lsurfs = NULL;
// curently allocated items
r_cnumsurfs = r_numallocatededges = r_numallocatedverts = 0;
R_ReallocateMapBuffers();
r_warpbuffer = malloc(vid.height * vid.width * sizeof(pixel_t));
if ((vid.width >= 2048) && (sizeof(shift20_t) == 4)) // 2k+ resolution and 32 == shift20_t
{
shift_size = 18;
}
else
{
shift_size = 20;
}
R_InitTurb ();
vid_polygon_spans = malloc(sizeof(espan_t) * (vid.height + 1));
memset(sw_state.currentpalette, 0, sizeof(sw_state.currentpalette));
memset(sw_state.palette_colors, 0, sizeof(sw_state.palette_colors));
sdl_palette_outdated = true;
return true;
}
static void
RE_SDLPaletteConvert (void)
{
int i;
const unsigned char *palette = sw_state.currentpalette;
Uint32 *sdl_palette = sw_state.palette_colors;
if (!sdl_palette_outdated)
return;
sdl_palette_outdated = false;
for ( i = 0; i < 256; i++ )
{
if (surface)
{
sdl_palette[i] = SDL_MapRGB(surface->format,
palette[i * 4 + 0], // red
palette[i * 4 + 1], // green
palette[i * 4 + 2] //blue
);
}
}
}
static void
RE_CopyFrame (Uint32 * pixels, int pitch)
{
RE_SDLPaletteConvert();
Uint32 *sdl_palette = (Uint32 *)sw_state.currentpalette;
// no gaps between images rows
if (pitch == vid.width)
@ -1986,7 +1783,7 @@ RE_CopyFrame (Uint32 * pixels, int pitch)
for (pixels_pos = pixels; pixels_pos < max_pixels; pixels_pos++)
{
*pixels_pos = sw_state.palette_colors[*buffer_pos];
*pixels_pos = sdl_palette[*buffer_pos];
buffer_pos++;
}
}
@ -1999,7 +1796,7 @@ RE_CopyFrame (Uint32 * pixels, int pitch)
{
for (x=0; x < vid.width; x ++)
{
pixels[x] = sw_state.palette_colors[vid_buffer[buffer_pos + x]];
pixels[x] = sdl_palette[vid_buffer[buffer_pos + x]];
}
pixels += pitch;
buffer_pos += vid.width;
@ -2019,14 +1816,16 @@ static void
RE_EndFrame (void)
{
int pitch;
Uint32 * pixels;
Uint32 * pixels = (Uint32 *)surface->pixels;
pitch = surface->pitch / sizeof(Uint32);
if (SDL_LockTexture(texture, NULL, (void**)&pixels, &pitch))
{
Com_Printf("Can't lock texture: %s\n", SDL_GetError());
return;
}
RE_CopyFrame (pixels, pitch / sizeof(Uint32));
SDL_UnlockTexture(texture);
RE_CopyFrame (pixels, pitch);
SDL_UpdateTexture(texture, NULL, surface->pixels, surface->pitch);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
}
@ -2049,16 +1848,66 @@ SWimp_SetMode(int *pwidth, int *pheight, int mode, int fullscreen )
R_Printf( PRINT_ALL, " %d %d\n", *pwidth, *pheight);
if ( !SWimp_InitGraphics(fullscreen, pwidth, pheight) ) {
if (!ri.GLimp_InitGraphics(fullscreen, pwidth, pheight))
{
// failed to set a valid mode in windowed mode
return rserr_invalid_mode;
}
R_GammaCorrectAndSetPalette( ( const unsigned char * ) d_8to24table );
SWimp_CreateRender();
return retval;
}
static void
SWimp_CreateRender(void)
{
vid_buffer = malloc(vid.height * vid.width * sizeof(pixel_t));
sintable = malloc((vid.width+CYCLE) * sizeof(int));
intsintable = malloc((vid.width+CYCLE) * sizeof(int));
blanktable = malloc((vid.width+CYCLE) * sizeof(int));
newedges = malloc(vid.width * sizeof(edge_t *));
removeedges = malloc(vid.width * sizeof(edge_t *));
warp_rowptr = malloc((vid.width+AMP2*2) * sizeof(byte*));
warp_column = malloc((vid.width+AMP2*2) * sizeof(int));
edge_basespans = malloc((vid.width*2) * sizeof(espan_t));
// count of "out of items"
r_outofsurfaces = r_outofedges = r_outofverts = r_outoftriangles = 0;
// pointers to allocated buffers
finalverts = NULL;
r_edges = NULL;
lsurfs = NULL;
triangle_spans = NULL;
// curently allocated items
r_cnumsurfs = r_numallocatededges = r_numallocatedverts = r_numallocatedtriangles = 0;
R_ReallocateMapBuffers();
r_warpbuffer = malloc(vid.height * vid.width * sizeof(pixel_t));
if ((vid.width >= 2048) && (sizeof(shift20_t) == 4)) // 2k+ resolution and 32 == shift20_t
{
shift_size = 18;
}
else
{
shift_size = 20;
}
R_InitTurb ();
vid_polygon_spans = malloc(sizeof(espan_t) * (vid.height + 1));
memset(sw_state.currentpalette, 0, sizeof(sw_state.currentpalette));
R_GammaCorrectAndSetPalette( ( const unsigned char * ) d_8to24table );
}
// this is only here so the functions in q_shared.c and q_shwin.c can link
void
Sys_Error (char *error, ...)
@ -2116,9 +1965,9 @@ R_ScreenShot_f(void)
{
for (y=0; y < vid.height; y ++) {
int buffer_pos = y * vid.width + x;
buffer[buffer_pos * 3 + 0] = palette[vid_buffer[buffer_pos] * 4 + 0]; // red
buffer[buffer_pos * 3 + 0] = palette[vid_buffer[buffer_pos] * 4 + 2]; // red
buffer[buffer_pos * 3 + 1] = palette[vid_buffer[buffer_pos] * 4 + 1]; // green
buffer[buffer_pos * 3 + 2] = palette[vid_buffer[buffer_pos] * 4 + 2]; // blue
buffer[buffer_pos * 3 + 2] = palette[vid_buffer[buffer_pos] * 4 + 0]; // blue
}
}

View file

@ -47,8 +47,6 @@ D_ViewChanged (void)
if (yscale > xscale)
scale_for_mip = yscale;
d_zwidth = vid.width;
d_pix_min = r_refdef.vrect.height / 240;
if (d_pix_min < 1)
d_pix_min = 1;
@ -360,7 +358,6 @@ R_SetupFrame (void)
vrect.height = r_newrefdef.height;
d_viewbuffer = r_warpbuffer;
r_screenwidth = vid.width;
}
else
{
@ -370,7 +367,6 @@ R_SetupFrame (void)
vrect.height = r_newrefdef.height;
d_viewbuffer = vid_buffer;
r_screenwidth = vid.width;
}
R_ViewChanged (&vrect);
@ -392,6 +388,7 @@ R_SetupFrame (void)
r_outofsurfaces = 0;
r_outofverts = 0;
r_outofedges = 0;
r_outoftriangles = 0;
// d_setup
d_minmip = sw_mipcap->value;

View file

@ -83,8 +83,8 @@ R_DrawParticle(particle_t *pparticle, int level)
** compute addresses of zbuffer, framebuffer, and
** compute the Z-buffer reference value.
*/
pz = d_pzbuffer + (d_zwidth * v) + u;
pdest = d_viewbuffer + r_screenwidth * v + u;
pz = d_pzbuffer + (vid.width * v) + u;
pdest = d_viewbuffer + vid.width * v + u;
izi = (int)(zi * 0x8000);
/*
@ -106,7 +106,7 @@ R_DrawParticle(particle_t *pparticle, int level)
{
switch (level) {
case PARTICLE_33 :
for ( ; count ; count--, pz += d_zwidth, pdest += r_screenwidth)
for ( ; count ; count--, pz += vid.width, pdest += vid.width)
{
//FIXME--do it in blocks of 8?
for (i=0 ; i<pix ; i++)
@ -123,7 +123,7 @@ R_DrawParticle(particle_t *pparticle, int level)
case PARTICLE_66 :
{
int color_part = (color<<8);
for ( ; count ; count--, pz += d_zwidth, pdest += r_screenwidth)
for ( ; count ; count--, pz += vid.width, pdest += vid.width)
{
for (i=0 ; i<pix ; i++)
{
@ -138,7 +138,7 @@ R_DrawParticle(particle_t *pparticle, int level)
}
default: //100
for ( ; count ; count--, pz += d_zwidth, pdest += r_screenwidth)
for ( ; count ; count--, pz += vid.width, pdest += vid.width)
{
for (i=0 ; i<pix ; i++)
{
@ -160,7 +160,7 @@ R_DrawParticle(particle_t *pparticle, int level)
switch (level) {
case PARTICLE_33 :
for ( ; count ; count--, pz += d_zwidth, pdest += r_screenwidth)
for ( ; count ; count--, pz += vid.width, pdest += vid.width)
{
//FIXME--do it in blocks of 8?
for (i=0 ; i<pix ; i++)
@ -178,7 +178,7 @@ R_DrawParticle(particle_t *pparticle, int level)
case PARTICLE_66 :
{
int color_part = (color<<8);
for ( ; count ; count--, pz += d_zwidth, pdest += r_screenwidth)
for ( ; count ; count--, pz += vid.width, pdest += vid.width)
{
for (i=0 ; i<pix ; i++)
{
@ -194,7 +194,7 @@ R_DrawParticle(particle_t *pparticle, int level)
}
default: //100
for ( ; count ; count--, pz += d_zwidth, pdest += r_screenwidth)
for ( ; count ; count--, pz += vid.width, pdest += vid.width)
{
for (i=0 ; i<pix ; i++)
{

View file

@ -622,8 +622,8 @@ R_PolygonDrawSpans(espan_t *pspan, int iswater )
{
int count;
s_spanletvars.pdest = d_viewbuffer + (r_screenwidth * pspan->v) + pspan->u;
s_spanletvars.pz = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u;
s_spanletvars.pdest = d_viewbuffer + (vid.width * pspan->v) + pspan->u;
s_spanletvars.pz = d_pzbuffer + (vid.width * pspan->v) + pspan->u;
s_spanletvars.u = pspan->u;
s_spanletvars.v = pspan->v;
count = pspan->count;

View file

@ -65,10 +65,9 @@ static int r_sstepx, r_tstepx, r_lstepy, r_sstepy, r_tstepy;
static zvalue_t r_zistepx, r_zistepy;
static int d_aspancount, d_countextrastep;
static spanpackage_t *a_spans;
static spanpackage_t *d_pedgespanpackage;
spanpackage_t *triangle_spans;
spanpackage_t *triangle_spans, *triangles_max;
static int ystart;
static pixel_t *d_pdest, *d_ptex;
@ -208,8 +207,6 @@ R_DrawTriangle(const finalvert_t *a, const finalvert_t *b, const finalvert_t *c)
if ( d_xdenom < 0 )
{
a_spans = triangle_spans;
r_p0[0] = a->u; // u
r_p0[1] = a->v; // v
r_p0[2] = a->s; // s
@ -236,6 +233,30 @@ R_DrawTriangle(const finalvert_t *a, const finalvert_t *b, const finalvert_t *c)
}
}
static void
R_PushEdgesSpan()
{
if (d_pedgespanpackage >= triangles_max)
{
// no space any more
r_outoftriangles++;
return;
}
d_pedgespanpackage->pdest = d_pdest;
d_pedgespanpackage->pz = d_pz;
d_pedgespanpackage->count = d_aspancount;
d_pedgespanpackage->ptex = d_ptex;
d_pedgespanpackage->sfrac = d_sfrac;
d_pedgespanpackage->tfrac = d_tfrac;
// FIXME: need to clamp l, s, t, at both ends?
d_pedgespanpackage->light = d_light;
d_pedgespanpackage->zi = d_zi;
d_pedgespanpackage++;
}
/*
===================
@ -247,19 +268,7 @@ R_PolysetScanLeftEdge_C(int height)
{
do
{
d_pedgespanpackage->pdest = d_pdest;
d_pedgespanpackage->pz = d_pz;
d_pedgespanpackage->count = d_aspancount;
d_pedgespanpackage->ptex = d_ptex;
d_pedgespanpackage->sfrac = d_sfrac;
d_pedgespanpackage->tfrac = d_tfrac;
// FIXME: need to clamp l, s, t, at both ends?
d_pedgespanpackage->light = d_light;
d_pedgespanpackage->zi = d_zi;
d_pedgespanpackage++;
R_PushEdgesSpan();
errorterm += erroradjustup;
if (errorterm >= 0)
@ -359,8 +368,6 @@ R_PolysetSetUpForLineScan(fixed8_t startvertu, fixed8_t startvertv,
int tm, tn;
adivtab_t *ptemp;
// TODO: implement x86 version
errorterm = -1;
tm = endvertu - startvertu;
@ -782,7 +789,7 @@ R_RasterizeAliasPolySmooth (void)
//
// scan out the top (and possibly only) part of the left edge
//
d_pedgespanpackage = a_spans;
d_pedgespanpackage = triangle_spans;
ystart = plefttop[1];
d_aspancount = plefttop[0] - prighttop[0];
@ -796,35 +803,23 @@ R_RasterizeAliasPolySmooth (void)
d_light = plefttop[4];
d_zi = plefttop[5];
d_pdest = d_viewbuffer + ystart * r_screenwidth + plefttop[0];
d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0];
d_pdest = d_viewbuffer + ystart * vid.width + plefttop[0];
d_pz = d_pzbuffer + ystart * vid.width + plefttop[0];
if (initialleftheight == 1)
{
d_pedgespanpackage->pdest = d_pdest;
d_pedgespanpackage->pz = d_pz;
d_pedgespanpackage->count = d_aspancount;
d_pedgespanpackage->ptex = d_ptex;
d_pedgespanpackage->sfrac = d_sfrac;
d_pedgespanpackage->tfrac = d_tfrac;
// FIXME: need to clamp l, s, t, at both ends?
d_pedgespanpackage->light = d_light;
d_pedgespanpackage->zi = d_zi;
d_pedgespanpackage++;
R_PushEdgesSpan();
}
else
{
R_PolysetSetUpForLineScan(plefttop[0], plefttop[1],
pleftbottom[0], pleftbottom[1]);
{
d_pzbasestep = d_zwidth + ubasestep;
d_pzbasestep = vid.width + ubasestep;
d_pzextrastep = d_pzbasestep + 1;
}
d_pdestbasestep = r_screenwidth + ubasestep;
d_pdestbasestep = vid.width + ubasestep;
d_pdestextrastep = d_pdestbasestep + 1;
// TODO: can reuse partial expressions here
@ -886,35 +881,23 @@ R_RasterizeAliasPolySmooth (void)
d_light = plefttop[4];
d_zi = plefttop[5];
d_pdest = d_viewbuffer + ystart * r_screenwidth + plefttop[0];
d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0];
d_pdest = d_viewbuffer + ystart * vid.width + plefttop[0];
d_pz = d_pzbuffer + ystart * vid.width + plefttop[0];
if (height == 1)
{
d_pedgespanpackage->pdest = d_pdest;
d_pedgespanpackage->pz = d_pz;
d_pedgespanpackage->count = d_aspancount;
d_pedgespanpackage->ptex = d_ptex;
d_pedgespanpackage->sfrac = d_sfrac;
d_pedgespanpackage->tfrac = d_tfrac;
// FIXME: need to clamp l, s, t, at both ends?
d_pedgespanpackage->light = d_light;
d_pedgespanpackage->zi = d_zi;
d_pedgespanpackage++;
R_PushEdgesSpan();
}
else
{
R_PolysetSetUpForLineScan(plefttop[0], plefttop[1],
pleftbottom[0], pleftbottom[1]);
d_pdestbasestep = r_screenwidth + ubasestep;
d_pdestbasestep = vid.width + ubasestep;
d_pdestextrastep = d_pdestbasestep + 1;
{
d_pzbasestep = d_zwidth + ubasestep;
d_pzbasestep = vid.width + ubasestep;
d_pzextrastep = d_pzbasestep + 1;
}
@ -952,15 +935,21 @@ R_RasterizeAliasPolySmooth (void)
// scan out the top (and possibly only) part of the right edge, updating the
// count field
d_pedgespanpackage = a_spans;
d_pedgespanpackage = triangle_spans;
R_PolysetSetUpForLineScan(prighttop[0], prighttop[1],
prightbottom[0], prightbottom[1]);
d_aspancount = 0;
d_countextrastep = ubasestep + 1;
originalcount = a_spans[initialrightheight].count;
a_spans[initialrightheight].count = -999999; // mark end of the spanpackages
(*d_pdrawspans) (a_spans);
if ((triangle_spans + initialrightheight) >= triangles_max)
{
// we dont have enough triangles for save full height
r_outoftriangles++;
return;
}
originalcount = triangle_spans[initialrightheight].count;
triangle_spans[initialrightheight].count = -999999; // mark end of the spanpackages
(*d_pdrawspans) (triangle_spans);
// scan out the bottom part of the right edge, if it exists
if (pedgetable->numrightedges == 2)
@ -968,7 +957,7 @@ R_RasterizeAliasPolySmooth (void)
int height;
spanpackage_t *pstart;
pstart = a_spans + initialrightheight;
pstart = triangle_spans + initialrightheight;
pstart->count = originalcount;
d_aspancount = prightbottom[0] - prighttop[0];
@ -982,7 +971,14 @@ R_RasterizeAliasPolySmooth (void)
prightbottom[0], prightbottom[1]);
d_countextrastep = ubasestep + 1;
a_spans[initialrightheight + height].count = -999999; // mark end of the spanpackages
if ((triangle_spans + initialrightheight + height) >= triangles_max)
{
// we dont have enough triangles for save full height
r_outoftriangles++;
return;
}
triangle_spans[initialrightheight + height].count = -999999; // mark end of the spanpackages
(*d_pdrawspans) (pstart);
}
}

View file

@ -25,7 +25,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define SPANSTEP_SHIFT 4
#define SPANSTEP (1 << SPANSTEP_SHIFT)
byte **warp_rowptr;
int *warp_column;
@ -100,7 +99,7 @@ Return safe span step for u/z and v/z
=============
*/
static int
D_DrawSpanGetStep(float d_zistepu, float d_zistepv, int cachewidth)
D_DrawSpanGetStep(float d_zistepu, float d_zistepv)
{
int spanzshift = SPANSTEP_SHIFT;
int spanzshift_value = (1 << spanzshift);
@ -115,24 +114,46 @@ D_DrawSpanGetStep(float d_zistepu, float d_zistepv, int cachewidth)
(int)(d_zistepv_shifted * spanzshift_value) == 0)
{
// search next safe value
while (spanzshift_value < vid.width &&
(int)(d_zistepu_shifted * spanzshift_value) == 0 &&
(int)(d_zistepv_shifted * spanzshift_value) == 0)
do
{
spanzshift ++;
spanzshift_value <<= 1;
}
// step back to last safe value
if ((int)(d_zistepu_shifted * spanzshift_value) != 0 ||
(int)(d_zistepv_shifted * spanzshift_value) != 0)
{
spanzshift --;
if ((int)(d_zistepu_shifted * spanzshift_value) != 0 ||
(int)(d_zistepv_shifted * spanzshift_value) != 0)
{
// step back to last safe value
return spanzshift - 1;
}
}
while (spanzshift_value < vid.width);
}
return spanzshift;
}
/*
=============
D_DrawZSpanGetStepValue
Return safe span step for izistep
=============
*/
static int
D_DrawZSpanGetStepValue(zvalue_t izistep)
{
// check that we can draw parallel surfaces to screen surface
// (both ends have same z value)
int count = 1;
while ((izistep * count) >> SHIFT16XYZ == 0 && count < vid.width)
{
count <<= 1;
}
return count;
}
/*
=============
D_DrawTurbulentSpan
@ -169,14 +190,18 @@ TurbulentPow2 (espan_t *pspan)
float sdivzpow2stepu, tdivzpow2stepu, zipow2stepu;
pixel_t *r_turb_pbase;
int *r_turb_turb;
int spanstep_shift, spanstep_value;
spanstep_shift = D_DrawSpanGetStep(d_zistepu, d_zistepv);
spanstep_value = (1 << spanstep_shift);
r_turb_turb = sintable + ((int)(r_newrefdef.time*SPEED)&(CYCLE-1));
r_turb_pbase = (unsigned char *)cacheblock;
sdivzpow2stepu = d_sdivzstepu * SPANSTEP;
tdivzpow2stepu = d_tdivzstepu * SPANSTEP;
zipow2stepu = d_zistepu * SPANSTEP;
sdivzpow2stepu = d_sdivzstepu * spanstep_value;
tdivzpow2stepu = d_tdivzstepu * spanstep_value;
zipow2stepu = d_zistepu * spanstep_value;
do
{
@ -184,7 +209,7 @@ TurbulentPow2 (espan_t *pspan)
float sdivz, tdivz, zi, z, du, dv;
pixel_t *r_turb_pdest;
r_turb_pdest = d_viewbuffer + (r_screenwidth * pspan->v) + pspan->u;
r_turb_pdest = d_viewbuffer + (vid.width * pspan->v) + pspan->u;
count = pspan->count;
@ -219,8 +244,8 @@ TurbulentPow2 (espan_t *pspan)
r_turb_tstep = 0; // ditto
// calculate s and t at the far end of the span
if (count >= SPANSTEP)
r_turb_spancount = SPANSTEP;
if (count >= spanstep_value)
r_turb_spancount = spanstep_value;
else
r_turb_spancount = count;
@ -238,21 +263,21 @@ TurbulentPow2 (espan_t *pspan)
snext = (int)(sdivz * z) + sadjust;
if (snext > bbextents)
snext = bbextents;
else if (snext < SPANSTEP)
else if (snext < spanstep_value)
// prevent round-off error on <0 steps from
// from causing overstepping & running off the
// edge of the texture
snext = SPANSTEP;
snext = spanstep_value;
tnext = (int)(tdivz * z) + tadjust;
if (tnext > bbextentt)
tnext = bbextentt;
else if (tnext < SPANSTEP)
else if (tnext < spanstep_value)
// guard against round-off error on <0 steps
tnext = SPANSTEP;
tnext = spanstep_value;
r_turb_sstep = (snext - r_turb_s) >> SPANSTEP_SHIFT;
r_turb_tstep = (tnext - r_turb_t) >> SPANSTEP_SHIFT;
r_turb_sstep = (snext - r_turb_s) >> spanstep_shift;
r_turb_tstep = (tnext - r_turb_t) >> spanstep_shift;
}
else
{
@ -268,18 +293,18 @@ TurbulentPow2 (espan_t *pspan)
snext = (int)(sdivz * z) + sadjust;
if (snext > bbextents)
snext = bbextents;
else if (snext < SPANSTEP)
else if (snext < spanstep_value)
// prevent round-off error on <0 steps from
// from causing overstepping & running off the
// edge of the texture
snext = SPANSTEP;
snext = spanstep_value;
tnext = (int)(tdivz * z) + tadjust;
if (tnext > bbextentt)
tnext = bbextentt;
else if (tnext < SPANSTEP)
else if (tnext < spanstep_value)
// guard against round-off error on <0 steps
tnext = SPANSTEP;
tnext = spanstep_value;
if (r_turb_spancount > 1)
{
@ -320,14 +345,18 @@ NonTurbulentPow2 (espan_t *pspan)
float sdivzpow2stepu, tdivzpow2stepu, zipow2stepu;
pixel_t *r_turb_pbase;
int *r_turb_turb;
int spanstep_shift, spanstep_value;
spanstep_shift = D_DrawSpanGetStep(d_zistepu, d_zistepv);
spanstep_value = (1 << spanstep_shift);
r_turb_turb = blanktable;
r_turb_pbase = (unsigned char *)cacheblock;
sdivzpow2stepu = d_sdivzstepu * SPANSTEP;
tdivzpow2stepu = d_tdivzstepu * SPANSTEP;
zipow2stepu = d_zistepu * SPANSTEP;
sdivzpow2stepu = d_sdivzstepu * spanstep_value;
tdivzpow2stepu = d_tdivzstepu * spanstep_value;
zipow2stepu = d_zistepu * spanstep_value;
do
{
@ -335,7 +364,7 @@ NonTurbulentPow2 (espan_t *pspan)
float sdivz, tdivz, zi, z, dv, du;
pixel_t *r_turb_pdest;
r_turb_pdest = d_viewbuffer + (r_screenwidth * pspan->v) + pspan->u;
r_turb_pdest = d_viewbuffer + (vid.width * pspan->v) + pspan->u;
count = pspan->count;
@ -370,8 +399,8 @@ NonTurbulentPow2 (espan_t *pspan)
r_turb_tstep = 0; // ditto
// calculate s and t at the far end of the span
if (count >= SPANSTEP)
r_turb_spancount = SPANSTEP;
if (count >= spanstep_value)
r_turb_spancount = spanstep_value;
else
r_turb_spancount = count;
@ -389,21 +418,21 @@ NonTurbulentPow2 (espan_t *pspan)
snext = (int)(sdivz * z) + sadjust;
if (snext > bbextents)
snext = bbextents;
else if (snext < SPANSTEP)
else if (snext < spanstep_value)
// prevent round-off error on <0 steps from
// from causing overstepping & running off the
// edge of the texture
snext = SPANSTEP;
snext = spanstep_value;
tnext = (int)(tdivz * z) + tadjust;
if (tnext > bbextentt)
tnext = bbextentt;
else if (tnext < SPANSTEP)
else if (tnext < spanstep_value)
// guard against round-off error on <0 steps
tnext = SPANSTEP;
tnext = spanstep_value;
r_turb_sstep = (snext - r_turb_s) >> SPANSTEP_SHIFT;
r_turb_tstep = (tnext - r_turb_t) >> SPANSTEP_SHIFT;
r_turb_sstep = (snext - r_turb_s) >> spanstep_shift;
r_turb_tstep = (tnext - r_turb_t) >> spanstep_shift;
}
else
{
@ -419,18 +448,18 @@ NonTurbulentPow2 (espan_t *pspan)
snext = (int)(sdivz * z) + sadjust;
if (snext > bbextents)
snext = bbextents;
else if (snext < SPANSTEP)
else if (snext < spanstep_value)
// prevent round-off error on <0 steps from
// from causing overstepping & running off the
// edge of the texture
snext = SPANSTEP;
snext = spanstep_value;
tnext = (int)(tdivz * z) + tadjust;
if (tnext > bbextentt)
tnext = bbextentt;
else if (tnext < SPANSTEP)
else if (tnext < spanstep_value)
// guard against round-off error on <0 steps
tnext = SPANSTEP;
tnext = spanstep_value;
if (r_turb_spancount > 1)
{
@ -459,7 +488,7 @@ NonTurbulentPow2 (espan_t *pspan)
//====================
// Enable custom filtering
extern cvar_t *r_anisotropic;
extern cvar_t *sw_texture_filtering;
static const int filtering_kernel[2][2][2] = {
{
{0x1 << (SHIFT16XYZ-2), 0x0},
@ -572,12 +601,12 @@ D_DrawSpansPow2 (espan_t *pspan)
int texture_filtering;
int spanstep_shift, spanstep_value;
spanstep_shift = D_DrawSpanGetStep(d_zistepu, d_zistepv, cachewidth);
spanstep_shift = D_DrawSpanGetStep(d_zistepu, d_zistepv);
spanstep_value = (1 << spanstep_shift);
pbase = (unsigned char *)cacheblock;
texture_filtering = (int)r_anisotropic->value;
texture_filtering = (int)sw_texture_filtering->value;
sdivzpow2stepu = d_sdivzstepu * spanstep_value;
tdivzpow2stepu = d_tdivzstepu * spanstep_value;
zipow2stepu = d_zistepu * spanstep_value;
@ -588,7 +617,7 @@ D_DrawSpansPow2 (espan_t *pspan)
int count, s, t;
float sdivz, tdivz, zi, z, du, dv;
pdest = d_viewbuffer + (r_screenwidth * pspan->v) + pspan->u;
pdest = d_viewbuffer + (vid.width * pspan->v) + pspan->u;
count = pspan->count;
@ -717,10 +746,12 @@ void
D_DrawZSpans (espan_t *pspan)
{
zvalue_t izistep;
int safe_step;
// FIXME: check for clamping/range problems
// we count on FP exceptions being turned off to avoid range problems
izistep = (int)(d_zistepu * 0x8000 * (float)SHIFT16XYZ_MULT);
safe_step = D_DrawZSpanGetStepValue(izistep);
do
{
@ -730,7 +761,7 @@ D_DrawZSpans (espan_t *pspan)
float zi;
float du, dv;
pdest = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u;
pdest = d_pzbuffer + (vid.width * pspan->v) + pspan->u;
count = pspan->count;
@ -742,11 +773,29 @@ D_DrawZSpans (espan_t *pspan)
// we count on FP exceptions being turned off to avoid range problems
izi = (int)(zi * 0x8000 * (float)SHIFT16XYZ_MULT);
while (count > 0)
if (safe_step > 1)
{
*pdest++ = izi >> SHIFT16XYZ;
izi += izistep;
count--;
const zvalue_t *tdest_max = pdest + count;
do
{
int step;
zvalue_t izi_shifted = izi >> SHIFT16XYZ;
for(step = 0; (step < safe_step) && (pdest < tdest_max); step++)
{
*pdest++ = izi_shifted;
}
izi += (izistep * safe_step);
} while (pdest < tdest_max);
}
else
{
while (count > 0)
{
*pdest++ = izi >> SHIFT16XYZ;
izi += izistep;
count--;
}
}
} while ((pspan = pspan->pnext) != NULL);
}

View file

@ -80,7 +80,6 @@ R_DrawSurface (drawsurf_t *drawsurf)
int smax, tmax, twidth;
int u;
int soffset, basetoffset, texwidth;
int horzblockstep;
unsigned char *pcolumndest;
image_t *mt;
@ -104,7 +103,7 @@ R_DrawSurface (drawsurf_t *drawsurf)
//==============================
// TODO: only needs to be set when there is a display settings change
horzblockstep = blocksize;
blocksize = blocksize;
smax = mt->width >> drawsurf->surfmip;
twidth = texwidth;
@ -138,7 +137,7 @@ R_DrawSurface (drawsurf_t *drawsurf)
if (soffset >= smax)
soffset = 0;
pcolumndest += horzblockstep;
pcolumndest += blocksize;
}
}

View file

@ -36,6 +36,7 @@
cvar_t *vid_displayrefreshrate;
int glimp_refreshRate = -1;
static int last_flags = 0;
static SDL_Window* window = NULL;
static qboolean initSuccessful = false;
@ -219,9 +220,9 @@ GLimp_InitGraphics(int fullscreen, int *pwidth, int *pheight)
}
/* Only do this if we already have a working window and a fully
initialized rendering backend GLimp_InitGraphics() is also
called when recovering if creating GL context fails or the
one we got is unusable. */
initialized rendering backend GLimp_InitGraphics() is also
called when recovering if creating GL context fails or the
one we got is unusable. */
if (initSuccessful && GetWindowSize(&curWidth, &curHeight)
&& (curWidth == width) && (curHeight == height))
{
@ -252,8 +253,11 @@ GLimp_InitGraphics(int fullscreen, int *pwidth, int *pheight)
viddef.width = width;
viddef.height = height;
/* Reset SDL. */
SDL_GL_ResetAttributes();
if(last_flags != -1 && (last_flags & SDL_WINDOW_OPENGL))
{
/* Reset SDL. */
SDL_GL_ResetAttributes();
}
/* Let renderer prepare things (set OpenGL attributes).
FIXME: This is no longer necessary, the renderer
@ -317,6 +321,8 @@ GLimp_InitGraphics(int fullscreen, int *pwidth, int *pheight)
}
}
last_flags = flags;
if (!re.InitContext(window))
{
/* InitContext() should have logged an error. */

View file

@ -226,7 +226,6 @@ typedef struct
qboolean (IMPORT *Vid_GetModeInfo)(int *width, int *height, int mode);
void (IMPORT *Vid_MenuInit)( void );
void (IMPORT *Vid_NewWindow)( int width, int height );
// called with image data of width*height pixel which comp bytes per pixel (must be 3 or 4 for RGB or RGBA)
// expects the pixels data to be row-wise, starting at top left
void (IMPORT *Vid_WriteScreenshot)( int width, int height, int comp, const void* data );

View file

@ -309,18 +309,6 @@ VID_Restart_f(void)
vid_fullscreen->modified = true;
}
/*
* FIXME: This is only used by the softrenderer. The software
* renderer should be ported to the API provided by refresh.c
* and this call removed.
*/
void
VID_NewWindow(int width, int height)
{
viddef.width = width;
viddef.height = height;
}
/*
* Shuts the renderer down and unloads it.
*/
@ -402,7 +390,6 @@ VID_LoadRenderer(void)
ri.Sys_Error = Com_Error;
ri.Vid_GetModeInfo = VID_GetModeInfo;
ri.Vid_MenuInit = VID_MenuInit;
ri.Vid_NewWindow = VID_NewWindow;
ri.Vid_WriteScreenshot = VID_WriteScreenshot;
// Exchange our export struct with the renderers import struct.
@ -469,7 +456,7 @@ VID_CheckChanges(void)
// Mkay, let's try our luck.
while (!VID_LoadRenderer())
{
// We try: gl3 -> gl1 -> soft.
// We try: gl3 -> gl1 -> soft.
if (strcmp(vid_renderer->string, "gl3") == 0)
{
Com_Printf("Retrying with gl1...\n");
@ -480,7 +467,7 @@ VID_CheckChanges(void)
Com_Printf("Retrying with soft...\n");
Cvar_Set("vid_renderer", "soft");
}
else if (strcmp("vid_renderer", "soft") == 0)
else if (strcmp(vid_renderer->string, "soft") == 0)
{
// Sorry, no usable renderer found.
Com_Error(ERR_FATAL, "No usable renderer found!\n");

View file

@ -39,7 +39,6 @@ typedef struct
replacement_t replacements[] = {
{"cd_shuffle", "ogg_shuffle"},
{"cl_drawfps", "cl_showfps"},
{"gl_anisotropic", "r_anisotropic"},
{"gl_drawentities", "r_drawentities"},
{"gl_drawworld", "r_drawworld"},
{"gl_fullbright", "r_fullbright"},

View file

@ -163,15 +163,15 @@ Graphics (all renderers):
* **r_vsync**: Enables the vsync: frames are synchronized with
display refresh rate, should (but doesn't always) prevent tearing.
* **r_anisotropic**: Anisotropic filtering. Possible values are
dependent on the GPU driver, most of them support `1`, `2`, `4`, `8`
and `16`. Anisotropic filtering gives a huge improvement to texture
quality by a negligible performance impact.
Graphics (GL renderers only):
-----------------------------
* **gl_anisotropic**: Anisotropic filtering. Possible values are
dependent on the GPU driver, most of them support `1`, `2`, `4`, `8`
and `16`. Anisotropic filtering gives a huge improvement to texture
quality by a negligible performance impact.
* **gl_msaa_samples**: Full scene anti aliasing samples. The number of
samples depends on the GPU driver, most drivers support at least
`2`, `4` and `8` samples. If an invalid value is set, the value is