From dbfd69f572f0a7b9cb21cf925bc12c70039c4751 Mon Sep 17 00:00:00 2001 From: Spoike Date: Tue, 14 Oct 2014 16:42:48 +0000 Subject: [PATCH] preliminary support for qc rendertargets with d3d11. I took some shortcuts so try not to combine it with other render target stuff just yet. flipped gl qc rendertargets to logically be top-down. the joys of weird matricies is a sight to behold. try to fix threading dependency on recent versions of windows. break some other related stuff. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4768 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/client/console.c | 2 +- engine/client/image.c | 20 +++ engine/client/r_2d.c | 2 +- engine/common/bothdefs.h | 6 + engine/common/cmd.c | 2 +- engine/common/common.c | 4 +- engine/common/sys.h | 3 +- engine/common/sys_linux_threads.c | 8 +- engine/common/sys_win_threads.c | 8 +- engine/d3d/d3d11_image.c | 23 ++++ engine/d3d/vid_d3d11.c | 83 ++++++++++++- engine/gl/gl_backend.c | 95 +++++++++------ engine/gl/gl_draw.c | 2 + engine/gl/gl_font.c | 7 +- engine/gl/gl_model.c | 2 +- engine/gl/gl_rmain.c | 21 +++- engine/gl/gl_shader.c | 2 +- engine/sw/sw.h | 1 + engine/sw/sw_backend.c | 7 +- engine/sw/sw_rast.c | 195 +++++++++++++++--------------- 20 files changed, 336 insertions(+), 157 deletions(-) diff --git a/engine/client/console.c b/engine/client/console.c index 1f1584ae8..23bc72e45 100644 --- a/engine/client/console.c +++ b/engine/client/console.c @@ -844,7 +844,7 @@ void VARGS Con_Printf (const char *fmt, ...) vsnprintf (msg,sizeof(msg), fmt,argptr); va_end (argptr); - if (!Sys_IsThread(NULL)) + if (!Sys_IsMainThread()) { COM_AddWork(0, Con_PrintFromThread, NULL, Z_StrDup(msg), 0, 0); return; diff --git a/engine/client/image.c b/engine/client/image.c index 0fb983526..cc7170615 100644 --- a/engine/client/image.c +++ b/engine/client/image.c @@ -3368,6 +3368,26 @@ static qboolean Image_GenMip0(struct pendingtextureinfo *mips, unsigned int flag switch(fmt) { + case TF_DEPTH16: + mips->encoding = PTI_DEPTH16; + break; + case TF_DEPTH24: + mips->encoding = PTI_DEPTH24; + break; + case TF_DEPTH32: + mips->encoding = PTI_DEPTH32; + break; + case TF_RGBA16F: + case TF_RGBA32F: + if (rawdata) + { + Con_Printf("R_LoadRawTexture: bad format"); + if (freedata) + BZ_Free(rawdata); + return false; + } + break; + default: case TF_INVALID: Con_Printf("R_LoadRawTexture: bad format"); diff --git a/engine/client/r_2d.c b/engine/client/r_2d.c index 0cda681de..a718ab134 100644 --- a/engine/client/r_2d.c +++ b/engine/client/r_2d.c @@ -1312,7 +1312,7 @@ void R2D_DrawCrosshair(void) R2D_ImageColours(1, 1, 1, 1); } -#define RT_IMAGEFLAGS IF_NOMIPMAP|IF_CLAMP|IF_LINEAR +#define RT_IMAGEFLAGS IF_NOMIPMAP|IF_CLAMP|IF_LINEAR|IF_RENDERTARGET static texid_t internalrt; //resize a texture for a render target and specify the format of it. //pass TF_INVALID and sizes=0 to get without configuring (shaders that hardcode an $rt1 etc). diff --git a/engine/common/bothdefs.h b/engine/common/bothdefs.h index d056990c2..8d8c226cc 100644 --- a/engine/common/bothdefs.h +++ b/engine/common/bothdefs.h @@ -258,6 +258,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #endif +//software rendering is just too glitchy, don't use it. +#if defined(SWQUAKE) && !defined(_DEBUG) + #undef SWQUAKE +#endif + + //include a file to update the various configurations for game-specific configs (hopefully just names) #ifdef BRANDING_INC #define STRINGIFY2(s) #s diff --git a/engine/common/cmd.c b/engine/common/cmd.c index 479f3ad84..db9cc2a41 100644 --- a/engine/common/cmd.c +++ b/engine/common/cmd.c @@ -202,7 +202,7 @@ void Cbuf_AddText (const char *text, int level) { int l; - if (!Sys_IsThread(NULL)) + if (!Sys_IsMainThread()) { COM_AddWork(0, Cbuf_WorkerAddText, NULL, Z_StrDup(text), level, 0); return; diff --git a/engine/common/common.c b/engine/common/common.c index 03a50a0f7..c058fdd47 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -4710,7 +4710,7 @@ void COM_WorkerAbort(char *message) { struct com_work_s work; com_fatalerror = true; - if (Sys_IsThread(NULL)) + if (Sys_IsMainThread()) return; work.func = Sys_ErrorThread; @@ -4834,7 +4834,7 @@ static void COM_WorkerSync_Stop(void *ctx, void *data, size_t a, size_t b) #ifndef COM_AssertMainThread void COM_AssertMainThread(const char *msg) { - if (com_resourcemutex && !Sys_IsThread(NULL)) + if (com_resourcemutex && !Sys_IsMainThread()) { Sys_Error("Not on main thread: %s", msg); } diff --git a/engine/common/sys.h b/engine/common/sys.h index 7188876b9..66fc0f99c 100644 --- a/engine/common/sys.h +++ b/engine/common/sys.h @@ -99,7 +99,8 @@ void Sys_SetThreadName(unsigned int dwThreadID, char *threadName); #endif void Sys_ThreadsInit(void); -qboolean Sys_IsThread(void *thread); +//qboolean Sys_IsThread(void *thread); +qboolean Sys_IsMainThread(void); void *Sys_CreateThread(char *name, int (*func)(void *), void *args, int priority, int stacksize); void Sys_WaitOnThread(void *thread); void Sys_DetachThread(void *thread); diff --git a/engine/common/sys_linux_threads.c b/engine/common/sys_linux_threads.c index 38519d3c0..1880da6a1 100644 --- a/engine/common/sys_linux_threads.c +++ b/engine/common/sys_linux_threads.c @@ -34,12 +34,14 @@ void Sys_ThreadsInit(void) { mainthread = pthread_self(); } -qboolean Sys_IsThread(void *thread) +static qboolean Sys_IsThread(void *thread) { - if (!thread) - thread = &mainthread; return pthread_equal(pthread_self(), *(pthread_t*)thread); } +static qboolean Sys_IsMainThread(void) +{ + return Sys_IsThread(&mainthread); +} void Sys_ThreadAbort(void) { pthread_exit(NULL); diff --git a/engine/common/sys_win_threads.c b/engine/common/sys_win_threads.c index d4887e36f..2bf6001af 100644 --- a/engine/common/sys_win_threads.c +++ b/engine/common/sys_win_threads.c @@ -148,12 +148,16 @@ void Sys_ThreadsInit(void) { mainthread = GetCurrentThreadId(); } +qboolean Sys_IsMainThread(void) +{ + return mainthread == GetCurrentThreadId(); +} +/* qboolean Sys_IsThread(void *thread) { - if (!thread) - return mainthread == GetCurrentThreadId(); return GetThreadId(thread) == GetCurrentThreadId(); } +*/ /* Mutex calls */ /* diff --git a/engine/d3d/d3d11_image.c b/engine/d3d/d3d11_image.c index 6542c3704..8645e945c 100644 --- a/engine/d3d/d3d11_image.c +++ b/engine/d3d/d3d11_image.c @@ -125,6 +125,13 @@ qboolean D3D11_LoadTextureMips(image_t *tex, struct pendingtextureinfo *mips) tdesc.CPUAccessFlags = (mips->mip[0].data)?0:D3D11_CPU_ACCESS_WRITE; tdesc.MiscFlags = 0; + if (tex->flags & IF_RENDERTARGET) + { + tdesc.BindFlags |= D3D11_BIND_RENDER_TARGET; + tdesc.Usage = D3D11_USAGE_DEFAULT; + tdesc.CPUAccessFlags = 0; + } + if (mips->type == PTI_CUBEMAP) { tdesc.ArraySize *= 6; @@ -140,6 +147,22 @@ qboolean D3D11_LoadTextureMips(image_t *tex, struct pendingtextureinfo *mips) { default: return false; + case PTI_DEPTH16: + tdesc.Format = DXGI_FORMAT_D16_UNORM; + tdesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; + break; + case PTI_DEPTH24: + tdesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; + tdesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; + break; + case PTI_DEPTH32: + tdesc.Format = DXGI_FORMAT_D32_FLOAT; + tdesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; + break; + case PTI_DEPTH24_8: + tdesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; + tdesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; + break; case PTI_RGB565: tdesc.Format = DXGI_FORMAT_B5G6R5_UNORM; break; diff --git a/engine/d3d/vid_d3d11.c b/engine/d3d/vid_d3d11.c index ac3a66999..3e0e21064 100644 --- a/engine/d3d/vid_d3d11.c +++ b/engine/d3d/vid_d3d11.c @@ -148,6 +148,61 @@ static void D3D11_PresentOrCrash(void) typedef enum {MS_WINDOWED, MS_FULLSCREEN, MS_FULLDIB, MS_UNINIT} modestate_t; static modestate_t modestate; +//FIXME: need to push/pop render targets like gl does, to not harm shadowmaps/refraction/etc. +void D3D11_ApplyRenderTargets(qboolean usedepth) +{ + unsigned int width = 0, height = 0; + int i; + texid_t textures[1]; + texid_t depth; + ID3D11RenderTargetView *rtv[sizeof(textures)/sizeof(textures[0])]; + ID3D11DepthStencilView *dsv; + + for (i = 0; i < sizeof(textures)/sizeof(textures[0]); i++) + { + if (!*r_refdef.rt_destcolour[i].texname) + break; + textures[i] = R2D_RT_GetTexture(r_refdef.rt_destcolour[i].texname, &width, &height); + if (textures[i]->ptr2) + { + ID3D11ShaderResourceView_Release((ID3D11ShaderResourceView*)textures[i]->ptr2); + textures[i]->ptr2 = NULL; + } + ID3D11Device_CreateRenderTargetView(pD3DDev11, textures[i]->ptr, NULL, &rtv[i]); + } + + if (usedepth) + { + if (*r_refdef.rt_depth.texname) + depth = R2D_RT_GetTexture(r_refdef.rt_depth.texname, &width, &height); + else + depth = R2D_RT_Configure("depth", width, height, 5); + } + else + depth = NULL; + if (depth && depth->ptr) + { + if (depth->ptr2) + { + ID3D11DepthStencilView_Release((ID3D11DepthStencilView*)depth->ptr2); + depth->ptr2 = NULL; + } + ID3D11Device_CreateDepthStencilView(pD3DDev11, depth->ptr, NULL, &dsv); + } + else + dsv = NULL; + + ID3D11DeviceContext_OMSetRenderTargets(d3ddevctx, i, rtv, dsv); + for (i = 0; i < sizeof(textures)/sizeof(textures[0]); i++) + if (rtv[i]) + ID3D11RenderTargetView_Release(rtv[i]); + if (dsv) + { + ID3D11DeviceContext_ClearDepthStencilView(d3ddevctx, dsv, D3D11_CLEAR_DEPTH, 1, 0); //is it faster to clear the stencil too? + ID3D11DepthStencilView_Release(dsv); + } +} + #ifndef WINRT //winrt crap has its own non-hwnd window crap, after years of microsoft forcing everyone to use hwnds for everything. I wonder why they don't have that many winrt apps. static void D3DVID_UpdateWindowStatus (HWND hWnd) @@ -1351,14 +1406,20 @@ static void (D3D11_R_RenderView) (void) { float x, x2, y, y2; double time1 = 0, time2 = 0; + qboolean dofbo = *r_refdef.rt_destcolour[0].texname || *r_refdef.rt_depth.texname; +// texid_t colourrt[1]; if (r_speeds.ival) time1 = Sys_DoubleTime(); + if (dofbo) + D3D11_ApplyRenderTargets(true); + else + ID3D11DeviceContext_ClearDepthStencilView(d3ddevctx, fb_backdepthstencil, D3D11_CLEAR_DEPTH, 1, 0); //is it faster to clear the stencil too? + D3D11_SetupViewPort(); //unlike gl, we clear colour beforehand, because that seems more sane. //always clear depth - ID3D11DeviceContext_ClearDepthStencilView(d3ddevctx, fb_backdepthstencil, D3D11_CLEAR_DEPTH, 1, 0); //is it faster to clear the stencil too? x = (r_refdef.vrect.x * (int)vid.pixelwidth)/(int)vid.width; x2 = (r_refdef.vrect.x + r_refdef.vrect.width) * (int)vid.pixelwidth/(int)vid.width; @@ -1388,6 +1449,9 @@ static void (D3D11_R_RenderView) (void) R2D_ImageColours(0, 0, 0, 1); R2D_FillBlock(r_refdef.vrect.x, r_refdef.vrect.y, r_refdef.vrect.width, r_refdef.vrect.height); R2D_ImageColours(1, 1, 1, 1); + + if (dofbo) + D3D11_ApplyRenderTargets(false); return; } Surf_DrawWorld(); @@ -1400,10 +1464,27 @@ static void (D3D11_R_RenderView) (void) time2 = Sys_DoubleTime(); RQuantAdd(RQUANT_MSECS, (int)((time2-time1)*1000000)); } + + if (dofbo) + D3D11_ApplyRenderTargets(false); } void D3D11BE_RenderToTextureUpdate2d(qboolean destchanged) { + if (destchanged) + { + if (*r_refdef.rt_destcolour[0].texname) + D3D11_ApplyRenderTargets(false); + else + ID3D11DeviceContext_OMSetRenderTargets(d3ddevctx, 1, &fb_backbuffer, fb_backdepthstencil); + + D3D11_Set2D(); + } + else + { +// shaderstate.tex_sourcecol = R2D_RT_GetTexture(r_refdef.rt_sourcecolour.texname, &width, &height); +// shaderstate.tex_sourcedepth = R2D_RT_GetTexture(r_refdef.rt_depth.texname, &width, &height); + } } rendererinfo_t d3d11rendererinfo = diff --git a/engine/gl/gl_backend.c b/engine/gl/gl_backend.c index 7924c2f66..474c6cdec 100644 --- a/engine/gl/gl_backend.c +++ b/engine/gl/gl_backend.c @@ -4341,15 +4341,10 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist) if (!shaderstate.tex_reflection) { shaderstate.tex_reflection = Image_CreateTexture("***tex_reflection***", NULL, 0); - qglGenTextures(1, &shaderstate.tex_reflection->num); - GL_MTBind(0, GL_TEXTURE_2D, shaderstate.tex_reflection); - qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, vid.pixelwidth/2, vid.pixelheight/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + if (!shaderstate.tex_reflection->num) + qglGenTextures(1, &shaderstate.tex_reflection->num); } - oldfbo = GLBE_FBO_Update(&shaderstate.fbo_reflectrefrac, FBO_RB_DEPTH, &shaderstate.tex_reflection, 1, r_nulltex, vid.pixelwidth/2, vid.pixelheight/2); + r_refdef.vrect.x = 0; r_refdef.vrect.y = 0; r_refdef.vrect.width = vid.fbvwidth/2; @@ -4358,6 +4353,18 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist) r_refdef.pxrect.y = 0; r_refdef.pxrect.width = vid.fbpwidth/2; r_refdef.pxrect.height = vid.fbpheight/2; + if (shaderstate.tex_reflection->width!=r_refdef.pxrect.width || shaderstate.tex_reflection->height!=r_refdef.pxrect.height) + { + shaderstate.tex_reflection->width = r_refdef.pxrect.width; + shaderstate.tex_reflection->height = r_refdef.pxrect.height; + GL_MTBind(0, GL_TEXTURE_2D, shaderstate.tex_reflection); + qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, shaderstate.tex_reflection->width, shaderstate.tex_reflection->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + oldfbo = GLBE_FBO_Update(&shaderstate.fbo_reflectrefrac, FBO_RB_DEPTH, &shaderstate.tex_reflection, 1, r_nulltex, shaderstate.tex_reflection->width, shaderstate.tex_reflection->height); r_refdef.pxrect.maxheight = shaderstate.fbo_reflectrefrac.rb_size[1]; GL_ViewportUpdate(); GL_ForceDepthWritable(); @@ -4375,13 +4382,27 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist) { vrect_t ovrect = r_refdef.vrect; pxrect_t oprect = r_refdef.pxrect; + r_refdef.vrect.x = 0; + r_refdef.vrect.y = 0; + r_refdef.vrect.width = vid.fbvwidth/2; + r_refdef.vrect.height = vid.fbvheight/2; + r_refdef.pxrect.x = 0; + r_refdef.pxrect.y = 0; + r_refdef.pxrect.width = vid.fbpwidth/2; + r_refdef.pxrect.height = vid.fbpheight/2; if (!shaderstate.tex_refraction) { shaderstate.tex_refraction = Image_CreateTexture("***tex_refraction***", NULL, 0); + if (!shaderstate.tex_refraction->num) qglGenTextures(1, &shaderstate.tex_refraction->num); + } + if (shaderstate.tex_refraction->width != r_refdef.pxrect.width || shaderstate.tex_refraction->height != r_refdef.pxrect.height) + { + shaderstate.tex_refraction->width = r_refdef.pxrect.width; + shaderstate.tex_refraction->height = r_refdef.pxrect.height; GL_MTBind(0, GL_TEXTURE_2D, shaderstate.tex_refraction); - qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, vid.pixelwidth/2, vid.pixelheight/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, r_refdef.pxrect.width, r_refdef.pxrect.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); @@ -4392,29 +4413,26 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist) if (!shaderstate.tex_refractiondepth) { shaderstate.tex_refractiondepth = Image_CreateTexture("***tex_refractiondepth***", NULL, 0); - qglGenTextures(1, &shaderstate.tex_refractiondepth->num); + if (!shaderstate.tex_refractiondepth->num) + qglGenTextures(1, &shaderstate.tex_refractiondepth->num); + } + if (shaderstate.tex_refractiondepth->width != r_refdef.pxrect.width || shaderstate.tex_refractiondepth->height != r_refdef.pxrect.height) + { + shaderstate.tex_refractiondepth->width = r_refdef.pxrect.width; + shaderstate.tex_refractiondepth->height = r_refdef.pxrect.height; GL_MTBind(0, GL_TEXTURE_2D, shaderstate.tex_refractiondepth); - qglTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24_ARB, vid.pixelwidth/2, vid.pixelheight/2, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); + qglTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24_ARB, r_refdef.pxrect.width, r_refdef.pxrect.height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } - oldfbo = GLBE_FBO_Update(&shaderstate.fbo_reflectrefrac, FBO_TEX_DEPTH, &shaderstate.tex_refraction, 1, shaderstate.tex_refractiondepth, vid.pixelwidth/2, vid.pixelheight/2); + oldfbo = GLBE_FBO_Update(&shaderstate.fbo_reflectrefrac, FBO_TEX_DEPTH, &shaderstate.tex_refraction, 1, shaderstate.tex_refractiondepth, r_refdef.pxrect.width, r_refdef.pxrect.height); } else { - oldfbo = GLBE_FBO_Update(&shaderstate.fbo_reflectrefrac, FBO_RB_DEPTH, &shaderstate.tex_refraction, 1, r_nulltex, vid.pixelwidth/2, vid.pixelheight/2); + oldfbo = GLBE_FBO_Update(&shaderstate.fbo_reflectrefrac, FBO_RB_DEPTH, &shaderstate.tex_refraction, 1, r_nulltex, r_refdef.pxrect.width, r_refdef.pxrect.height); } - - r_refdef.vrect.x = 0; - r_refdef.vrect.y = 0; - r_refdef.vrect.width = vid.fbvwidth/2; - r_refdef.vrect.height = vid.fbvheight/2; - r_refdef.pxrect.x = 0; - r_refdef.pxrect.y = 0; - r_refdef.pxrect.width = vid.fbpwidth/2; - r_refdef.pxrect.height = vid.fbpheight/2; r_refdef.pxrect.maxheight = shaderstate.fbo_reflectrefrac.rb_size[1]; GL_ViewportUpdate(); @@ -4435,19 +4453,6 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist) { vrect_t orect = r_refdef.vrect; pxrect_t oprect = r_refdef.pxrect; - if (!shaderstate.tex_ripplemap) - { - //FIXME: can we use RGB8 instead? - shaderstate.tex_ripplemap = Image_CreateTexture("***tex_ripplemap***", NULL, 0); - qglGenTextures(1, &shaderstate.tex_ripplemap->num); - GL_MTBind(0, GL_TEXTURE_2D, shaderstate.tex_ripplemap); - qglTexImage2D(GL_TEXTURE_2D, 0, /*(gl_config.glversion>3.1)?GL_RGBA8_SNORM:*/GL_RGBA16F_ARB, vid.pixelwidth/2, vid.pixelheight/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - } - oldfbo = GLBE_FBO_Update(&shaderstate.fbo_reflectrefrac, 0, &shaderstate.tex_ripplemap, 1, r_nulltex, vid.pixelwidth/2, vid.pixelheight/2); r_refdef.vrect.x = 0; r_refdef.vrect.y = 0; r_refdef.vrect.width = vid.fbvwidth/2; @@ -4456,6 +4461,26 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist) r_refdef.pxrect.y = 0; r_refdef.pxrect.width = vid.fbpwidth/2; r_refdef.pxrect.height = vid.fbpheight/2; + + if (!shaderstate.tex_ripplemap) + { + //FIXME: can we use RGB8 instead? + shaderstate.tex_ripplemap = Image_CreateTexture("***tex_ripplemap***", NULL, 0); + if (!shaderstate.tex_ripplemap->num) + qglGenTextures(1, &shaderstate.tex_ripplemap->num); + } + if (shaderstate.tex_ripplemap->width != r_refdef.pxrect.width || shaderstate.tex_ripplemap->height != r_refdef.pxrect.height) + { + shaderstate.tex_ripplemap->width = r_refdef.pxrect.width; + shaderstate.tex_ripplemap->height = r_refdef.pxrect.height; + GL_MTBind(0, GL_TEXTURE_2D, shaderstate.tex_ripplemap); + qglTexImage2D(GL_TEXTURE_2D, 0, /*(gl_config.glversion>3.1)?GL_RGBA8_SNORM:*/GL_RGBA16F_ARB, r_refdef.pxrect.width, r_refdef.pxrect.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + oldfbo = GLBE_FBO_Update(&shaderstate.fbo_reflectrefrac, 0, &shaderstate.tex_ripplemap, 1, r_nulltex, r_refdef.pxrect.width, r_refdef.pxrect.height); r_refdef.pxrect.maxheight = shaderstate.fbo_reflectrefrac.rb_size[1]; GL_ViewportUpdate(); diff --git a/engine/gl/gl_draw.c b/engine/gl/gl_draw.c index 39da371c6..29e17bbf7 100644 --- a/engine/gl/gl_draw.c +++ b/engine/gl/gl_draw.c @@ -144,6 +144,8 @@ void GL_Set2D (qboolean flipped) R2D_RT_GetTexture(r_refdef.rt_destcolour[0].texname, &vid.fbpwidth, &vid.fbpheight); vid.fbvwidth = vid.fbpwidth; vid.fbvheight = vid.fbpheight; + + flipped ^= true; } else { diff --git a/engine/gl/gl_font.c b/engine/gl/gl_font.c index ae6cb69e2..239cbbe81 100644 --- a/engine/gl/gl_font.c +++ b/engine/gl/gl_font.c @@ -332,7 +332,7 @@ static void Font_Flush(void) fontplanes.planechanged = false; } font_foremesh.istrifan = (font_foremesh.numvertexes == 4); - if (font_colourmask & CON_NONCLEARBG) + if ((font_colourmask & CON_NONCLEARBG) && font_foremesh.numindexes) { font_backmesh.numindexes = font_foremesh.numindexes; font_backmesh.numvertexes = font_foremesh.numvertexes; @@ -1426,6 +1426,8 @@ void Font_Free(struct font_s *f) //maps a given virtual screen coord to a pixel coord, which matches the font's height/width values void Font_BeginString(struct font_s *font, float vx, float vy, int *px, int *py) { + Font_Flush(); + curfont = font; *px = (vx*(int)vid.rotpixelwidth) / (float)vid.width; *py = (vy*(int)vid.rotpixelheight) / (float)vid.height; @@ -1433,6 +1435,7 @@ void Font_BeginString(struct font_s *font, float vx, float vy, int *px, int *py) curfont_scale[0] = curfont->charheight; curfont_scale[1] = curfont->charheight; curfont_scaled = false; + font_colourmask = ~0u; //force the colour to be recalculated. } void Font_Transform(float vx, float vy, int *px, int *py) @@ -1444,6 +1447,8 @@ void Font_Transform(float vx, float vy, int *px, int *py) } void Font_BeginScaledString(struct font_s *font, float vx, float vy, float szx, float szy, float *px, float *py) { + Font_Flush(); + curfont = font; *px = (vx*(float)vid.rotpixelwidth) / (float)vid.width; *py = (vy*(float)vid.rotpixelheight) / (float)vid.height; diff --git a/engine/gl/gl_model.c b/engine/gl/gl_model.c index df951fdf6..5ca01d404 100644 --- a/engine/gl/gl_model.c +++ b/engine/gl/gl_model.c @@ -1470,7 +1470,7 @@ static void Mod_LoadMiptex(model_t *loadmodel, char *loadname, texture_t *tx, mi { maps &= ~LMT_BUMP; snprintf(altname, sizeof(altname)-1, "%s_norm", mt->name); - tx->texnums.bump = R_LoadReplacementTexture(altname, loadname, IF_NOGAMMA|IF_MIPCAP|IF_TRYBUMP, mipbase, mipwidth, mipheight, TF_HEIGHT8PAL); + tx->texnums.bump = R_LoadReplacementTexture(altname, loadname, IF_NOGAMMA|IF_MIPCAP|IF_TRYBUMP|(*mt->name == '*'?IF_LINEAR:0), mipbase, mipwidth, mipheight, TF_HEIGHT8PAL); } } diff --git a/engine/gl/gl_rmain.c b/engine/gl/gl_rmain.c index fd69a6328..3729383d1 100644 --- a/engine/gl/gl_rmain.c +++ b/engine/gl/gl_rmain.c @@ -455,14 +455,21 @@ void R_SetupGL (float stereooffset) fov_x = r_refdef.fov_x;//+sin(cl.time)*5; fov_y = r_refdef.fov_y;//-sin(cl.time+1)*5; - GL_ViewportUpdate(); - - if ((r_refdef.flags & RDF_UNDERWATER) && !(r_refdef.flags & RDF_WATERWARP)) + if (*r_refdef.rt_destcolour[0].texname || *r_refdef.rt_depth.texname) + { + r_refdef.pxrect.y = r_refdef.pxrect.maxheight - (r_refdef.pxrect.height+r_refdef.pxrect.y); + fov_y *= -1; + r_refdef.flipcull ^= SHADER_CULL_FLIP; + } + else if ((r_refdef.flags & RDF_UNDERWATER) && !(r_refdef.flags & RDF_WATERWARP)) { fov_x *= 1 + (((sin(cl.time * 4.7) + 1) * 0.015) * r_waterwarp.value); fov_y *= 1 + (((sin(cl.time * 3.0) + 1) * 0.015) * r_waterwarp.value); } + GL_ViewportUpdate(); + + if (r_refdef.useperspective) { int stencilshadows = Sh_StencilShadowsActive(); @@ -826,7 +833,7 @@ void R_ObliqueNearClip(float *viewmat, mplane_t *wplane) // by the inverse of the projection matrix q[0] = (sgn(vplane[0]) + r_refdef.m_projection[8]) / r_refdef.m_projection[0]; - q[1] = (sgn(vplane[1]) + r_refdef.m_projection[9]) / r_refdef.m_projection[5]; + q[1] = (sgn(vplane[1]) + fabs(r_refdef.m_projection[9])) / fabs(r_refdef.m_projection[5]); q[2] = -1.0F; q[3] = (1.0F + r_refdef.m_projection[10]) / r_refdef.m_projection[14]; @@ -1058,7 +1065,6 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, batch_t *depthmasklist[2], TransformDir(vup, paxis, vaxis, vup); Matrix4x4_CM_ModelViewMatrixFromAxis(vmat, vpn, vright, vup, r_refdef.vieworg); - //transform the old surface plane into the new view matrix if (Matrix4_Invert(r_refdef.m_view, ivmat)) { @@ -1163,6 +1169,8 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, batch_t *depthmasklist[2], r_refdef.flipcull |= SHADER_CULL_FLIP; else r_refdef.flipcull &= ~SHADER_CULL_FLIP; + if (r_refdef.m_projection[5]<0) + r_refdef.flipcull ^= SHADER_CULL_FLIP; GL_CullFace(0);//make sure flipcull takes effect //FIXME: just call Surf_DrawWorld instead? @@ -1687,6 +1695,7 @@ void GLR_RenderView (void) vid.fbpwidth = vid.pixelwidth; vid.fbpheight = vid.pixelheight; } + r_refdef.flipcull = 0; if (qglPNTrianglesiATI) { @@ -1700,7 +1709,7 @@ void GLR_RenderView (void) qglPNTrianglesiATI(GL_PN_TRIANGLES_NORMAL_MODE_ATI, GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI); qglPNTrianglesiATI(GL_PN_TRIANGLES_POINT_MODE_ATI, GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI); } - qglPNTrianglesfATI(GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI, gl_ati_truform_tesselation.value); + qglPNTrianglesfATI(GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI, gl_ati_truform_tesselation.value); } if (gl_finish.ival) diff --git a/engine/gl/gl_shader.c b/engine/gl/gl_shader.c index 0b7877e34..47c10760c 100644 --- a/engine/gl/gl_shader.c +++ b/engine/gl/gl_shader.c @@ -609,7 +609,7 @@ static int Shader_SetImageFlags(shader_t *shader, shaderpass_t *pass, char **nam if (!Q_strnicmp(*name, "$rt:", 4)) { *name += 4; - flags |= IF_RENDERTARGET; + flags |= IF_NOMIPMAP|IF_CLAMP|IF_LINEAR|IF_RENDERTARGET; } else if (!Q_strnicmp(*name, "$clamp:", 7)) { diff --git a/engine/sw/sw.h b/engine/sw/sw.h index b86a97f41..6d3e662c4 100644 --- a/engine/sw/sw.h +++ b/engine/sw/sw.h @@ -40,6 +40,7 @@ typedef struct typedef struct { int scoord[2]; + float zicoord; vec4_t vcoord; vec2_t tccoord; vec2_t lmcoord; diff --git a/engine/sw/sw_backend.c b/engine/sw/sw_backend.c index d2b8f6fee..9eb23f640 100644 --- a/engine/sw/sw_backend.c +++ b/engine/sw/sw_backend.c @@ -616,8 +616,11 @@ void SWBE_DrawWorld(qboolean drawworld, qbyte *vis) } void SWBE_Init(void) { - memset(&r_config, 0, sizeof(r_config)); - r_config.maxtexturesize = 512; + memset(&sh_config, 0, sizeof(sh_config)); + sh_config.texfmt[PTI_BGRA8] = true; + sh_config.texfmt[PTI_BGRX8] = true; + sh_config.texfmt[PTI_RGBA8] = true; + sh_config.texfmt[PTI_RGBX8] = true; BE_InitTables(); } void SWBE_GenBrushModelVBO(struct model_s *mod) diff --git a/engine/sw/sw_rast.c b/engine/sw/sw_rast.c index 93fcdeebf..774288b2d 100644 --- a/engine/sw/sw_rast.c +++ b/engine/sw/sw_rast.c @@ -14,6 +14,8 @@ #define restrict #endif +#define ZI_MAX 0xffff + /* Our software rendering basically works like this: @@ -39,8 +41,19 @@ struct workqueue_s spanqueue; static void WT_Triangle(swthread_t *th, swimage_t *img, swvert_t *v1, swvert_t *v2, swvert_t *v3) { + //affine vs correct: + //to correct perspective, divide interpolants by z. + //per pixel, divide by interpolated 1 (actually 1/z) + unsigned int tpix; +#if 1 + #define PERSPECTIVE(v) (v>>16) +#else + #define PERSPECTIVE(v) (v/zi) + #define SPAN_ZI +#endif #define SPAN_ST + #define SPAN_Z #define PLOT_PIXEL(o) \ { \ @@ -48,8 +61,8 @@ static void WT_Triangle(swthread_t *th, swimage_t *img, swvert_t *v1, swvert_t * { \ *zb = z; \ tpix = img->data[ \ - ((unsigned)(s>>16)&img->pwidthmask) \ - + (((unsigned)(t>>16)&img->pheightmask) * img->pitch) \ + ((unsigned)PERSPECTIVE(s)&img->pwidthmask) \ + + (((unsigned)PERSPECTIVE(t)&img->pheightmask) * img->pitch) \ ]; \ if (tpix&0xff000000) \ o = tpix; \ @@ -74,11 +87,18 @@ SPAN_ST - interpolates S+T across the span. access with 'sc' and 'tc' swvert_t *vt; int y; int secondhalf; + + //l=value on left + //ld=change per y (on left) + //d=change per x int xl,xld, xr,xrd; #ifdef SPAN_ST int sl,sld, sd; int tl,tld, td; #endif +#ifdef SPAN_ZI + int zil, zild, zid; +#endif #ifdef SPAN_Z int zl,zld, zd; #endif @@ -136,8 +156,8 @@ SPAN_ST - interpolates S+T across the span. access with 'sc' and 'tc' return; if (v[i]->scoord[1] < 0 || v[i]->scoord[1] > th->vpheight) return; -// if (v[i]->scoord[3] < 0) -// return; + if (v[i]->zicoord < 0) + return; } for (i = 0; i < 2; i++) @@ -178,9 +198,15 @@ SPAN_ST - interpolates S+T across the span. access with 'sc' and 'tc' tld = fdx1*d2 - fdx2*d1; td = fdy2*d1 - fdy1*d2; #endif +#ifdef SPAN_ZI + d1 = (1<<16); + d2 = (1<<16); + zild = 0;//fdx1*d2 - fdx2*d1; + zid = 0;//fdy2*d1 - fdy1*d2; +#endif #ifdef SPAN_Z - d1 = (v2->vcoord[3] - v1->vcoord[3])*(1<<16); - d2 = (v3->vcoord[3] - v1->vcoord[3])*(1<<16); + d1 = (v2->zicoord - v1->zicoord)*(1<<16); + d2 = (v3->zicoord - v1->zicoord)*(1<<16); zld = fdx1*d2 - fdx2*d1; zd = fdy2*d1 - fdy1*d2; #endif @@ -208,6 +234,9 @@ SPAN_ST - interpolates S+T across the span. access with 'sc' and 'tc' sl += sld*interlace; tl += tld*interlace; #endif +#ifdef SPAN_ZI + zil += zild*interlace; +#endif #ifdef SPAN_Z zl += zld*interlace; #endif @@ -227,6 +256,9 @@ SPAN_ST - interpolates S+T across the span. access with 'sc' and 'tc' sld -= (((long long)sd*xld)>>16); tld -= (((long long)td*xld)>>16); #endif +#ifdef SPAN_ZI + zild -= (((long long)zid*xld)>>16); +#endif #ifdef SPAN_Z zld -= (((long long)zd*xld)>>16); #endif @@ -281,8 +313,12 @@ SPAN_ST - interpolates S+T across the span. access with 'sc' and 'tc' tl = vlt->tccoord[1] * (img->pheight<<16); tld = tld + (((long long)td*xld+32767)>>16); #endif +#ifdef SPAN_ZI + zil = (1<<16);///vlt->zicoord; + zild = zild + (((long long)zid*xld)>>16); +#endif #ifdef SPAN_Z - zl = vlt->vcoord[3] * (1<<16); + zl = vlt->zicoord * (1<<16); zld = zld + (((long long)zd*xld)>>16); #endif } @@ -328,6 +364,9 @@ SPAN_ST - interpolates S+T across the span. access with 'sc' and 'tc' sl += sld*interlace; tl += tld*interlace; #endif +#ifdef SPAN_ZI + zil += zild*interlace; +#endif #ifdef SPAN_Z zl += zld*interlace; #endif @@ -344,6 +383,9 @@ SPAN_ST - interpolates S+T across the span. access with 'sc' and 'tc' ,sl += sld*th->interlacemod ,tl += tld*th->interlacemod #endif +#ifdef SPAN_ZI + ,zil += zild*th->interlacemod +#endif #ifdef SPAN_Z ,zl += zld*th->interlacemod #endif @@ -353,6 +395,11 @@ SPAN_ST - interpolates S+T across the span. access with 'sc' and 'tc' unsigned int s = sl; unsigned int t = tl; #endif +#ifdef SPAN_ZI + unsigned int zi = zil; +#else + const unsigned int zi = (1<<16); +#endif #ifdef SPAN_Z unsigned int z = zl; unsigned int *restrict zb = th->vpdbuf + y * th->vpwidth + (xl>>16); @@ -361,7 +408,7 @@ SPAN_ST - interpolates S+T across the span. access with 'sc' and 'tc' spanlen = (xr - xl)>>16; outbuf = vplout + (xl>>16); - while(spanlen-->=0) + while(spanlen-->0) { PLOT_PIXEL(*outbuf); outbuf++; @@ -370,6 +417,9 @@ SPAN_ST - interpolates S+T across the span. access with 'sc' and 'tc' s += sd; t += td; #endif +#ifdef SPAN_ZI + zi += zid; +#endif #ifdef SPAN_Z z += zd; zb++; @@ -388,52 +438,52 @@ SPAN_ST - interpolates S+T across the span. access with 'sc' and 'tc' static void WT_Clip_Top(swthread_t *th, swvert_t *out, swvert_t *in, swvert_t *result) { float frac; - frac = (1 - in->scoord[1]) / - (out->scoord[1] - in->scoord[1]); + frac = (0 - in->scoord[1]) / + (float)(out->scoord[1] - in->scoord[1]); Vector2Interpolate(in->scoord, frac, out->scoord, result->scoord); - Vector2Interpolate(in->vcoord+2, frac, out->vcoord+2, result->vcoord+2); -// result->vcoord[1] = 0; + FloatInterpolate(in->zicoord, frac, out->zicoord, result->zicoord); + result->scoord[1] = 0; Vector2Interpolate(in->tccoord, frac, out->tccoord, result->tccoord); } static void WT_Clip_Bottom(swthread_t *th, swvert_t *out, swvert_t *in, swvert_t *result) { float frac; - frac = ((th->vpheight) - in->vcoord[1]) / - (out->vcoord[1] - in->vcoord[1]); + frac = ((th->vpheight) - in->scoord[1]) / + (float)(out->scoord[1] - in->scoord[1]); Vector2Interpolate(in->scoord, frac, out->scoord, result->scoord); - Vector2Interpolate(in->vcoord+2, frac, out->vcoord+2, result->vcoord+2); -// result->vcoord[1] = vid.pixelheight-1; + FloatInterpolate(in->zicoord, frac, out->zicoord, result->zicoord); + result->scoord[1] = th->vpheight; Vector2Interpolate(in->tccoord, frac, out->tccoord, result->tccoord); } static void WT_Clip_Left(swthread_t *th, swvert_t *out, swvert_t *in, swvert_t *result) { float frac; - frac = (1 - in->vcoord[0]) / - (out->vcoord[0] - in->vcoord[0]); + frac = (0 - in->scoord[0]) / + (float)(out->scoord[0] - in->scoord[0]); Vector2Interpolate(in->scoord, frac, out->scoord, result->scoord); - Vector2Interpolate(in->vcoord+2, frac, out->vcoord+2, result->vcoord+2); -// result->vcoord[0] = 0; + FloatInterpolate(in->zicoord, frac, out->zicoord, result->zicoord); + result->scoord[0] = 0; Vector2Interpolate(in->tccoord, frac, out->tccoord, result->tccoord); } static void WT_Clip_Right(swthread_t *th, swvert_t *out, swvert_t *in, swvert_t *result) { float frac; - frac = ((th->vpwidth) - in->vcoord[0]) / - (out->vcoord[0] - in->vcoord[0]); + frac = ((th->vpwidth) - in->scoord[0]) / + (float)(out->scoord[0] - in->scoord[0]); Vector2Interpolate(in->scoord, frac, out->scoord, result->scoord); - Vector2Interpolate(in->vcoord+2, frac, out->vcoord+2, result->vcoord+2); -// result->vcoord[0] = vid.pixelwidth-1; + FloatInterpolate(in->zicoord, frac, out->zicoord, result->zicoord); + result->scoord[0] = th->vpwidth; Vector2Interpolate(in->tccoord, frac, out->tccoord, result->tccoord); } static void WT_Clip_Near(swthread_t *th, swvert_t *out, swvert_t *in, swvert_t *result) { float nearclip = 0; double frac; - frac = (nearclip - in->vcoord[3]) / - (out->vcoord[3] - in->vcoord[3]); - Vector2Interpolate(in->scoord, frac, out->scoord, result->scoord); - Vector2Interpolate(in->vcoord+2, frac, out->vcoord+2, result->vcoord+2); - result->vcoord[3] = nearclip; + frac = (nearclip - in->zicoord) / + (out->zicoord - in->zicoord); + VectorInterpolate(in->vcoord, frac, out->vcoord, result->vcoord); + FloatInterpolate(in->zicoord, frac, out->zicoord, result->zicoord); + result->zicoord = nearclip; Vector2Interpolate(in->tccoord, frac, out->tccoord, result->tccoord); } @@ -441,11 +491,11 @@ static void WT_Clip_Far(swthread_t *th, swvert_t *out, swvert_t *in, swvert_t *r { float farclip = 1; double frac; - frac = (farclip - in->vcoord[3]) / - (out->vcoord[3] - in->vcoord[3]); - Vector2Interpolate(in->scoord, frac, out->scoord, result->scoord); - Vector2Interpolate(in->vcoord+2, frac, out->vcoord+2, result->vcoord+2); - result->vcoord[3] = farclip; + frac = (farclip - in->zicoord) / + (out->zicoord - in->zicoord); + VectorInterpolate(in->vcoord, frac, out->vcoord, result->vcoord); + FloatInterpolate(in->zicoord, frac, out->zicoord, result->zicoord); + result->zicoord = farclip; Vector2Interpolate(in->tccoord, frac, out->tccoord, result->tccoord); } @@ -482,9 +532,9 @@ static int WT_ClipPoly(swthread_t *th, int incount, swvert_t *inv, swvert_t *out if (outv[result].scoord[1] > th->vpheight) outv[result].clipflags |= CLIP_BOTTOM_FLAG; - if (outv[result].scoord[3] < 0) + if (outv[result].zicoord < 0) outv[result].clipflags |= CLIP_NEAR_FLAG; - if (outv[result].scoord[3] > 1) + if (outv[result].zicoord > ZI_MAX) outv[result].clipflags |= CLIP_FAR_FLAG; result++; @@ -522,6 +572,7 @@ static int WT_TransformVertXY(swthread_t *th, swvert_t *v) result |= CLIP_TOP_FLAG; if (v->scoord[1] > th->vpheight) result |= CLIP_BOTTOM_FLAG; + v->clipflags = result; return result; @@ -536,12 +587,12 @@ static void WT_ClipTriangle(swthread_t *th, swimage_t *img, swvert_t *v1, swvert int count; //check the near/far planes. - v1->vcoord[3] = DotProduct(v1->vcoord, th->u.viewplane) - th->u.viewplane[3]; - if (v1->vcoord[3] < 0) v1->clipflags = CLIP_NEAR_FLAG; else if (v1->vcoord[3] > 1) v1->clipflags = CLIP_FAR_FLAG; else v1->clipflags = 0; - v2->vcoord[3] = DotProduct(v2->vcoord, th->u.viewplane) - th->u.viewplane[3]; - if (v2->vcoord[3] < 0) v2->clipflags = CLIP_NEAR_FLAG; else if (v2->vcoord[3] > 1) v2->clipflags = CLIP_FAR_FLAG; else v2->clipflags = 0; - v3->vcoord[3] = DotProduct(v3->vcoord, th->u.viewplane) - th->u.viewplane[3]; - if (v3->vcoord[3] < 0) v3->clipflags = CLIP_NEAR_FLAG; else if (v3->vcoord[3] > 1) v3->clipflags = CLIP_FAR_FLAG; else v3->clipflags = 0; + v1->zicoord = DotProduct(v1->vcoord, th->u.viewplane) - th->u.viewplane[3]; + if (v1->zicoord < 0) v1->clipflags = CLIP_NEAR_FLAG; else if (v1->zicoord >= ZI_MAX) v1->clipflags = CLIP_FAR_FLAG; else v1->clipflags = 0; + v2->zicoord = DotProduct(v2->vcoord, th->u.viewplane) - th->u.viewplane[3]; + if (v2->zicoord < 0) v2->clipflags = CLIP_NEAR_FLAG; else if (v2->zicoord >= ZI_MAX) v2->clipflags = CLIP_FAR_FLAG; else v2->clipflags = 0; + v3->zicoord = DotProduct(v3->vcoord, th->u.viewplane) - th->u.viewplane[3]; + if (v3->zicoord < 0) v3->clipflags = CLIP_NEAR_FLAG; else if (v3->zicoord >= ZI_MAX) v3->clipflags = CLIP_FAR_FLAG; else v3->clipflags = 0; if (v1->clipflags & v2->clipflags & v3->clipflags) return; //all verticies are off at least one plane @@ -565,6 +616,7 @@ static void WT_ClipTriangle(swthread_t *th, swimage_t *img, swvert_t *v1, swvert //clip to the screen if (cflags & CLIP_NEAR_FLAG) { +// return; count = WT_ClipPoly(th, count, final[list], final[list^1], CLIP_NEAR_FLAG, WT_Clip_Near); list ^= 1; } @@ -889,63 +941,6 @@ void SW_R_RenderView(void) cl_numvisedicts = tmpvisents; } -void SW_R_NewMap(void) -{ - char namebuf[MAX_QPATH]; - extern cvar_t host_mapname, r_shadow_realtime_dlight, r_shadow_realtime_world; - int i; - - for (i=0 ; i<256 ; i++) - d_lightstylevalue[i] = 264; // normal light value - - memset (&r_worldentity, 0, sizeof(r_worldentity)); - AngleVectors(r_worldentity.angles, r_worldentity.axis[0], r_worldentity.axis[1], r_worldentity.axis[2]); - VectorInverse(r_worldentity.axis[1]); - r_worldentity.model = cl.worldmodel; - Vector4Set(r_worldentity.shaderRGBAf, 1, 1, 1, 1); - - - COM_StripExtension(COM_SkipPath(cl.worldmodel->name), namebuf, sizeof(namebuf)); - Cvar_Set(&host_mapname, namebuf); - - Surf_DeInit(); - - r_viewleaf = NULL; - r_viewcluster = -1; - r_oldviewcluster = 0; - r_viewcluster2 = -1; - - Mod_ParseInfoFromEntityLump(cl.worldmodel, cl.worldmodel->entities, cl.worldmodel->name); - - P_ClearParticles (); - Surf_WipeStains(); - CL_RegisterParticles(); - Surf_BuildLightmaps (); - - -#ifdef VM_UI - UI_Reset(); -#endif - - TP_NewMap(); - R_SetSky(cl.skyname); - -#ifdef MAP_PROC - if (cl.worldmodel->fromgame == fg_doom3) - D3_GenerateAreas(cl.worldmodel); -#endif - -#ifdef RTLIGHTS - Sh_PreGenerateLights(); -#endif -} -void SW_R_PreNewMap(void) -{ - r_viewleaf = NULL; - r_oldviewleaf = NULL; - r_viewleaf2 = NULL; - r_oldviewleaf2 = NULL; -} void SW_SCR_UpdateScreen(void) { wqcom_t *com; @@ -982,6 +977,8 @@ void SW_SCR_UpdateScreen(void) Shader_DoReload(); + R2D_Font_Changed(); + //FIXME: playfilm/editor+q3ui SCR_SetUpToDrawConsole ();