diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index 77d7133b67112ec6498ebcf79d3c6432952d38c3..de73ddb77a1f5563a7f253624f2999801b173759 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -17,6 +17,7 @@ #define ZCLIP_PLANE 4.0f // Used for the actual game drawing #define NZCLIP_PLANE 0.9f // Seems to be only used for the HUD and screen textures +#define FAR_ZCLIP_DEFAULT 32768.0f // The width/height/depth of the palette lookup table used by palette rendering. // Changing this also requires changing the shader code! diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index a5fdc00a47c17e6b5cbeba5d074554a66672cde7..4588e724bd2f8b3e83f636d8303fc5e498cef01e 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -41,7 +41,7 @@ EXPORT void HWRAPI(SetTexture) (GLMipmap_t *TexInfo); EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *TexInfo); EXPORT void HWRAPI(DeleteTexture) (GLMipmap_t *TexInfo); EXPORT void HWRAPI(ReadScreenTexture) (int tex, UINT8 *dst_data); -EXPORT void HWRAPI(GClipRect) (INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip); +EXPORT void HWRAPI(GClipRect) (INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip, float farclip); EXPORT void HWRAPI(ClearMipMapCache) (void); EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value); diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 708b3cdf4459941b5f48425d712d592e96378ae7..78b4d057c3ab3197e46517e0c42085a864b76155 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -102,6 +102,15 @@ boolean gl_shadersavailable = false; // Whether the internal state is set to palette rendering or not. static boolean gl_palette_rendering_state = false; +// values for the far clipping plane +static float clipping_distances[] = {1024.0f, 2048.0f, 4096.0f, 6144.0f, 8192.0f, 12288.0f, 16384.0f}; +// values for bsp culling +// slightly higher than the far clipping plane to compensate for impreciseness +static INT32 bsp_culling_distances[] = {(1024+512)*FRACUNIT, (2048+512)*FRACUNIT, (4096+512)*FRACUNIT, + (6144+512)*FRACUNIT, (8192+512)*FRACUNIT, (12288+512)*FRACUNIT, (16384+512)*FRACUNIT}; + +static INT32 current_bsp_culling_distance = 0; + // -------------------------------------------------------------------------- // STUFF FOR THE PROJECTION CODE // -------------------------------------------------------------------------- @@ -2110,6 +2119,70 @@ static boolean HWR_CheckBBox(fixed_t *bspcoord) px2 = bspcoord[checkcoord[boxpos][2]]; py2 = bspcoord[checkcoord[boxpos][3]]; + if (current_bsp_culling_distance) + { + //fixed_t midx = (px1 >> 1) + (px2 >> 1); + //fixed_t midy = (py1 >> 1) + (py2 >> 1); + //fixed_t mindist = min(min(R_PointToDist(px1, py1), R_PointToDist(px2, py2)), R_PointToDist(midx, midy)); + + //fixed_t mindist = ClosestPointOnLineDistance(px1, py1, px2, py2); + + //fixed_t mindist1 = ClosestPointOnLineDistance(bspcoord[BOXLEFT], bspcoord[BOXTOP], bspcoord[BOXRIGHT], bspcoord[BOXTOP]); // top line + //fixed_t mindist2 = ClosestPointOnLineDistance(bspcoord[BOXLEFT], bspcoord[BOXTOP], bspcoord[BOXLEFT], bspcoord[BOXBOTTOM]); // left line + //fixed_t mindist3 = ClosestPointOnLineDistance(bspcoord[BOXLEFT], bspcoord[BOXBOTTOM], bspcoord[BOXRIGHT], bspcoord[BOXBOTTOM]); // bottom line + //fixed_t mindist4 = ClosestPointOnLineDistance(bspcoord[BOXRIGHT], bspcoord[BOXTOP], bspcoord[BOXRIGHT], bspcoord[BOXBOTTOM]); // right line + // this one seems too lax.. maybe closestpointonlinedistance is glitchy and returns points that are not on the line segment? + // could try building an if-else structure that determines what point or line is closest + // 1 | 2 | 3 + //-------------- + // 4 |node| 5 + //-------------- + // 6 | 7 | 8 + // y + // ^ + // | + // -----> x + // inside node: always inside draw distance. the above boxpos thing might have returned true already? + // 1. check top left corner 2. check top line 3. check top right corner + // 4. check left line 5. check right line + // 6. check bottom left corner 7. check bottom line 8. check bottom right corner + // one if statement will split the space in two for one coordinate + // for example: + // x < BOXLEFT || BOXLEFT || !(x < BOXLEFT) <-- (same as x >= BOXLEFT) + fixed_t mindist;// = min(min(mindist1, mindist2), min(mindist3, mindist4)); + + // new thing + // calculate distance to axis aligned bounding box. + if (viewx < bspcoord[BOXLEFT]) // 1,4,6 + { + if (viewy > bspcoord[BOXTOP]) // 1 + mindist = R_PointToDist(bspcoord[BOXLEFT], bspcoord[BOXTOP]); + else if (viewy < bspcoord[BOXBOTTOM]) // 6 + mindist = R_PointToDist(bspcoord[BOXLEFT], bspcoord[BOXBOTTOM]); + else // 4 + mindist = bspcoord[BOXLEFT] - viewx; + } + else if (viewx > bspcoord[BOXRIGHT]) // 3,5,8 + { + if (viewy > bspcoord[BOXTOP]) // 3 + mindist = R_PointToDist(bspcoord[BOXRIGHT], bspcoord[BOXTOP]); + else if (viewy < bspcoord[BOXBOTTOM]) // 8 + mindist = R_PointToDist(bspcoord[BOXRIGHT], bspcoord[BOXBOTTOM]); + else // 5 + mindist = viewx - bspcoord[BOXRIGHT]; + } + else // 2,node,7 + { + if (viewy > bspcoord[BOXTOP]) // 2 + mindist = viewy - bspcoord[BOXTOP]; + else if (viewy < bspcoord[BOXBOTTOM]) // 7 + mindist = bspcoord[BOXBOTTOM] - viewy; + else // node + mindist = 0; + } + if (mindist > current_bsp_culling_distance) return false; + } + angle1 = R_PointToAngle64(px1, py1); angle2 = R_PointToAngle64(px2, py2); return gld_clipper_SafeCheckRange(angle2, angle1); @@ -4319,7 +4392,7 @@ static void HWR_AddSprites(sector_t *sec) { mobj_t *thing; precipmobj_t *precipthing; - fixed_t limit_dist, hoop_limit_dist; + fixed_t limit_dist, hoop_limit_dist, precip_limit_dist; // BSP is traversed by subsector. // A sector might have been split into several @@ -4331,13 +4404,28 @@ static void HWR_AddSprites(sector_t *sec) // Well, now it will be done. sec->validcount = validcount; + if (current_bsp_culling_distance) + { + // Use the smaller setting + if (cv_drawdist.value) + limit_dist = min((fixed_t)current_bsp_culling_distance, (fixed_t)(cv_drawdist.value) << FRACBITS); + else + limit_dist = (fixed_t)current_bsp_culling_distance; + precip_limit_dist = min((fixed_t)current_bsp_culling_distance, (fixed_t)(cv_drawdist_precip.value) << FRACBITS); + hoop_limit_dist = min((fixed_t)current_bsp_culling_distance, (fixed_t)(cv_drawdist_nights.value) << FRACBITS); + } + else + { + limit_dist = (fixed_t)(cv_drawdist.value) << FRACBITS; + precip_limit_dist = (fixed_t)cv_drawdist_precip.value << FRACBITS; + hoop_limit_dist = (fixed_t)(cv_drawdist_nights.value) << FRACBITS; + } + // sprite lighting sectorlight = sec->lightlevel & 0xff; // Handle all things in sector. - // If a limit exists, handle things a tiny bit different. - limit_dist = (fixed_t)(cv_drawdist.value) << FRACBITS; - hoop_limit_dist = (fixed_t)(cv_drawdist_nights.value) << FRACBITS; + // If a limit exists, handle things a tiny bit different for (thing = sec->thinglist; thing; thing = thing->snext) { if (R_ThingWithinDist(thing, limit_dist, hoop_limit_dist)) @@ -4352,11 +4440,11 @@ static void HWR_AddSprites(sector_t *sec) } // no, no infinite draw distance for precipitation. this option at zero is supposed to turn it off - if ((limit_dist = (fixed_t)cv_drawdist_precip.value << FRACBITS)) + if (precip_limit_dist) { for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext) { - if (R_PrecipThingVisible(precipthing, limit_dist)) + if (R_PrecipThingVisible(precipthing, precip_limit_dist)) HWR_ProjectPrecipitationSprite(precipthing); } } @@ -5321,7 +5409,7 @@ static inline void HWR_ClearView(void) (INT32)viewwindowy, (INT32)(viewwindowx + viewwidth), (INT32)(viewwindowy + viewheight), - ZCLIP_PLANE); + ZCLIP_PLANE, FAR_ZCLIP_DEFAULT); HWD.pfnClearBuffer(false, true, 0); //disable clip window - set to full size @@ -5399,6 +5487,18 @@ static void HWR_SetupView(player_t *player, INT32 viewnumber, float fpov, boolea else R_SetupFrame(player); + current_bsp_culling_distance = 0; + + if (!skybox && cv_glrenderdistance.value) + { + HWD.pfnGClipRect((INT32)viewwindowx, + (INT32)viewwindowy, + (INT32)(viewwindowx + viewwidth), + (INT32)(viewwindowy + viewheight), + ZCLIP_PLANE, clipping_distances[cv_glrenderdistance.value - 1]); + current_bsp_culling_distance = bsp_culling_distances[cv_glrenderdistance.value - 1]; + } + gl_viewx = FixedToFloat(viewx); gl_viewy = FixedToFloat(viewy); gl_viewz = FixedToFloat(viewz); @@ -5494,6 +5594,8 @@ static void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) HWR_RenderBSPNode((INT32)numnodes-1); + current_bsp_culling_distance = 0; + if (cv_glbatching.value) HWR_RenderBatches(); @@ -5531,7 +5633,7 @@ static void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) // added by Hurdler for correct splitscreen // moved here by hurdler so it works with the new near clipping plane - HWD.pfnGClipRect(0, 0, vid.width, vid.height, NZCLIP_PLANE); + HWD.pfnGClipRect(0, 0, vid.width, vid.height, NZCLIP_PLANE, FAR_ZCLIP_DEFAULT); } // ========================================================================== @@ -5612,6 +5714,8 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) HWR_RenderBSPNode((INT32)numnodes-1); + current_bsp_culling_distance = 0; + PS_STOP_TIMING(ps_bsptime); if (cv_glbatching.value) @@ -5661,7 +5765,7 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) // added by Hurdler for correct splitscreen // moved here by hurdler so it works with the new near clipping plane - HWD.pfnGClipRect(0, 0, vid.width, vid.height, NZCLIP_PLANE); + HWD.pfnGClipRect(0, 0, vid.width, vid.height, NZCLIP_PLANE, FAR_ZCLIP_DEFAULT); } // Returns whether palette rendering is "actually enabled." @@ -5756,6 +5860,9 @@ static CV_PossibleValue_t glfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSA {0, NULL}}; CV_PossibleValue_t glanisotropicmode_cons_t[] = {{1, "MIN"}, {16, "MAX"}, {0, NULL}}; static CV_PossibleValue_t glsecbright_cons_t[] = {{0, "MIN"}, {255, "MAX"}, {0, NULL}}; +static CV_PossibleValue_t glrenderdistance_cons_t[] = { + {0, "Max"}, {1, "1024"}, {2, "2048"}, {3, "4096"}, {4, "6144"}, {5, "8192"}, + {6, "12288"}, {7, "16384"}, {0, NULL}}; consvar_t cv_glshaders = CVAR_INIT ("gr_shaders", "On", "Enables additional visual effects in OpenGL", CV_SAVE|CV_CALL, glshaders_cons_t, CV_glshaders_OnChange); @@ -5785,6 +5892,8 @@ consvar_t cv_glsolvetjoin = CVAR_INIT ("gr_solvetjoin", "On", NULL, 0, CV_OnOff, consvar_t cv_glbatching = CVAR_INIT ("gr_batching", "On", "Whetever to send polygons in batches to the GPU or not", 0, CV_OnOff, NULL); +consvar_t cv_glrenderdistance = CVAR_INIT("gr_renderdistance", "Max", "Changes how far level geometry is rendered", CV_SAVE, glrenderdistance_cons_t, NULL); + static CV_PossibleValue_t glpalettedepth_cons_t[] = {{16, "16 bits"}, {24, "24 bits"}, {0, NULL}}; consvar_t cv_glpaletterendering = CVAR_INIT ("gr_paletterendering", "On", "Emulate Software's coloring graphics (requires shaders)", CV_SAVE|CV_CALL, CV_OnOff, CV_glpaletterendering_OnChange); @@ -5869,6 +5978,8 @@ void HWR_AddCommands(void) CV_RegisterVar(&cv_glsolvetjoin); CV_RegisterVar(&cv_glbatching); + CV_RegisterVar(&cv_glrenderdistance); + CV_RegisterVar(&cv_glpaletterendering); CV_RegisterVar(&cv_glpalettedepth); diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 22ea3f24c73fb37b514a4e3ae07c13510c0b73f0..093cbe9693ed4c5addc0f492a9a5474a2597af01 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -96,6 +96,7 @@ extern consvar_t cv_glslopecontrast; extern consvar_t cv_glbatching; extern consvar_t cv_glpaletterendering; extern consvar_t cv_glpalettedepth; +extern consvar_t cv_glrenderdistance; extern consvar_t cv_glwireframe; diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index db9fa17884e00779d8df9c37c3469707f798fbe7..bfdcb3e8e59c608829e6fd9dcf10107709d4e896 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -57,7 +57,9 @@ static GLuint NOTEXTURE_NUM = 0; #define N_PI_DEMI (M_PIl/2.0f) //(1.5707963268f) #define ASPECT_RATIO (1.0f) //(320.0f/200.0f) -#define FAR_CLIPPING_PLANE 32768.0f // Draw further! Tails 01-21-2001 +//#define FAR_CLIPPING_PLANE 32768.0f // Draw further! Tails 01-21-2001 +//#define FAR_CLIPPING_PLANE (4096.0f - 512.0f) +static float FAR_CLIPPING_PLANE = 32768.0f; static float NEAR_CLIPPING_PLANE = NZCLIP_PLANE; // ************************************************************************** @@ -1206,12 +1208,13 @@ EXPORT void HWRAPI(ReadScreenTexture) (int tex, UINT8 *dst_data) // -----------------+ // GClipRect : Defines the 2D hardware clipping window // -----------------+ -EXPORT void HWRAPI(GClipRect) (INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip) +EXPORT void HWRAPI(GClipRect) (INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip, float farclip) { // GL_DBG_Printf ("GClipRect(%d, %d, %d, %d)\n", minx, miny, maxx, maxy); pglViewport(minx, screen_height-maxy, maxx-minx, maxy-miny); NEAR_CLIPPING_PLANE = nearclip; + FAR_CLIPPING_PLANE = farclip; //pglScissor(minx, screen_height-maxy, maxx-minx, maxy-miny); pglMatrixMode(GL_PROJECTION); diff --git a/src/m_menu.c b/src/m_menu.c index 60a52052983a866ee28c9cee687f7796c86116c5..6a1a3ade9c4db441dcbac2490552925612c133fd 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1415,12 +1415,14 @@ static menuitem_t OP_OpenGLOptionsMenu[] = {IT_STRING|IT_CVAR, NULL, "Bit depth", NULL, &cv_scr_depth, 124}, {IT_STRING|IT_CVAR, NULL, "Texture filter", NULL, &cv_glfiltermode, 134}, {IT_STRING|IT_CVAR, NULL, "Anisotropic", NULL, &cv_glanisotropicmode, 144}, + {IT_STRING|IT_CVAR, NULL, "Render distance", NULL, &cv_glrenderdistance, 154}, #ifdef ALAM_LIGHTING - {IT_SUBMENU|IT_STRING, NULL, "Lighting...", NULL, &OP_OpenGLLightingDef, 154}, + {IT_SUBMENU|IT_STRING, NULL, "Lighting...", NULL, &OP_OpenGLLightingDef, 164}, #endif #if defined (_WINDOWS) && (!(defined (__unix__) || defined (UNIXCOMMON) || defined (HAVE_SDL))) - {IT_STRING|IT_CVAR, NULL, "Fullscreen", NULL, &cv_fullscreen, 164}, + {IT_STRING|IT_CVAR, NULL, "Fullscreen", NULL, &cv_fullscreen, 174}, #endif + }; #ifdef ALAM_LIGHTING diff --git a/src/sdl/ogl_sdl.c b/src/sdl/ogl_sdl.c index c78b43ec4097cafad8420ceb7497e2883220a67e..0445338792c2cf0201db34123fe53315e6145434 100644 --- a/src/sdl/ogl_sdl.c +++ b/src/sdl/ogl_sdl.c @@ -189,7 +189,7 @@ void OglSdlFinishUpdate(boolean waitvbl) HWR_DrawScreenFinalTexture(sdlw, sdlh); SDL_GL_SwapWindow(window); - GClipRect(0, 0, realwidth, realheight, NZCLIP_PLANE); + GClipRect(0, 0, realwidth, realheight, NZCLIP_PLANE, FAR_ZCLIP_DEFAULT); // Sryder: We need to draw the final screen texture again into the other buffer in the original position so that // effects that want to take the old screen can do so after this