X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fgame%2Fg_game.pas;h=05b824ac9f1f9814b59f80fd244e7436b037c116;hb=7a37d93e41daf0b467ff616e493db79d90882085;hp=e02fbd6471f871a4cd8fec4432aace4086e30783;hpb=44b1b8d4008737947a55103121e2a607a1927a88;p=d2df-sdl.git diff --git a/src/game/g_game.pas b/src/game/g_game.pas index e02fbd6..05b824a 100644 --- a/src/game/g_game.pas +++ b/src/game/g_game.pas @@ -324,8 +324,6 @@ var g_rlayer_water: Boolean = true; g_rlayer_fore: Boolean = true; - g_dbg_scale: Single = 1.0; - procedure g_ResetDynlights (); procedure g_AddDynLight (x, y, radius: Integer; r, g, b, a: Single); @@ -337,7 +335,7 @@ function conIsCheatsEnabled (): Boolean; implementation uses - g_textures, g_main, g_window, g_menu, + e_texture, g_textures, g_main, g_window, g_menu, e_input, e_log, g_console, g_items, g_map, g_panel, g_playermodel, g_gfx, g_options, g_weapons, Math, g_triggers, g_monsters, e_sound, CONFIG, @@ -2714,15 +2712,57 @@ begin end; +procedure renderAmbientQuad (hasAmbient: Boolean; constref ambColor: TDFColor); +begin + if not hasAmbient then exit; + e_AmbientQuad(sX, sY, sWidth, sHeight, ambColor.r, ambColor.g, ambColor.b, ambColor.a); +end; + + // setup sX, sY, sWidth, sHeight, and transformation matrix before calling this! +//FIXME: broken for splitscreen mode procedure renderDynLightsInternal (); var + //hasAmbient: Boolean; + //ambColor: TDFColor; lln: Integer; lx, ly, lrad: Integer; + scxywh: array[0..3] of GLint; + wassc: Boolean; begin + if e_NoGraphics then exit; + //TODO: lights should be in separate grid, i think // but on the other side: grid may be slower for dynlights, as their lifetime is short - if not gwin_has_stencil or (g_dynLightCount < 1) then exit; + if (not g_playerLight) or (not gwin_has_stencil) or (g_dynLightCount < 1) then exit; + + // rendering mode + //ambColor := gCurrentMap['light_ambient'].rgba; + //hasAmbient := (not ambColor.isOpaque) or (not ambColor.isBlack); + + { // this will multiply incoming color to alpha from framebuffer + glEnable(GL_BLEND); + glBlendFunc(GL_DST_ALPHA, GL_ONE); + } + + (* + * light rendering: (INVALID!) + * glStencilFunc(GL_EQUAL, 0, $ff); + * for each light: + * glClear(GL_STENCIL_BUFFER_BIT); + * glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); + * draw shadow volume into stencil buffer + * glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // modify color buffer + * glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // don't modify stencil buffer + * turn off blending + * draw color-less quad with light alpha (WARNING! don't touch color!) + * glEnable(GL_BLEND); + * glBlendFunc(GL_DST_ALPHA, GL_ONE); + * draw all geometry up to and including walls (with alpha-testing, probably) -- this does lighting + *) + + wassc := (glIsEnabled(GL_SCISSOR_TEST) <> 0); + if wassc then glGetIntegerv(GL_SCISSOR_BOX, @scxywh[0]) else glGetIntegerv(GL_VIEWPORT, @scxywh[0]); // setup OpenGL parameters glStencilMask($FFFFFFFF); @@ -2737,17 +2777,24 @@ begin lx := g_dynLights[lln].x; ly := g_dynLights[lln].y; lrad := g_dynLights[lln].radius; - if lrad < 3 then continue; + if (lrad < 3) then continue; - if lx-sX+lrad < 0 then continue; - if ly-sY+lrad < 0 then continue; - if lx-sX-lrad >= gPlayerScreenSize.X then continue; - if ly-sY-lrad >= gPlayerScreenSize.Y then continue; + if (lx-sX+lrad < 0) then continue; + if (ly-sY+lrad < 0) then continue; + if (lx-sX-lrad >= gPlayerScreenSize.X) then continue; + if (ly-sY-lrad >= gPlayerScreenSize.Y) then continue; // set scissor to optimize drawing - //FIXME: broken for splitscreen mode - glScissor((lx-sX)-lrad+2, gPlayerScreenSize.Y-(ly-sY)-lrad-1+2, lrad*2-4, lrad*2-4); - // no need to clear stencil buffer, light blitting will do it for us + if (g_dbg_scale = 1.0) then + begin + glScissor((lx-sX)-lrad+2, gPlayerScreenSize.Y-(ly-sY)-lrad-1+2, lrad*2-4, lrad*2-4); + end + else + begin + glScissor(0, 0, gWinSizeX, gWinSizeY); + end; + // no need to clear stencil buffer, light blitting will do it for us... but only for normal scale + if (g_dbg_scale <> 1.0) then glClear(GL_STENCIL_BUFFER_BIT); glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); // draw extruded panels glDisable(GL_TEXTURE_2D); @@ -2776,7 +2823,10 @@ begin glDisable(GL_STENCIL_TEST); glDisable(GL_BLEND); glDisable(GL_SCISSOR_TEST); - glScissor(0, 0, sWidth, sHeight); + //glScissor(0, 0, sWidth, sHeight); + + glScissor(scxywh[0], scxywh[1], scxywh[2], scxywh[3]); + if wassc then glEnable(GL_SCISSOR_TEST) else glDisable(GL_SCISSOR_TEST); end; @@ -2806,6 +2856,11 @@ procedure renderMapInternal (backXOfs, backYOfs: Integer; setTransMatrix: Boolea type TDrawCB = procedure (); +var + hasAmbient: Boolean; + ambColor: TDFColor; + doAmbient: Boolean = false; + procedure drawPanelType (profname: AnsiString; panType: DWord; doDraw: Boolean); var tagmask: Integer; @@ -2819,13 +2874,13 @@ type begin pan := TPanel(gDrawPanelList.front()); if ((pan.tag and tagmask) = 0) then break; - if doDraw then pan.Draw(); + if doDraw then pan.Draw(doAmbient, ambColor); gDrawPanelList.popFront(); end; end else begin - if doDraw then g_Map_DrawPanels(panType); + if doDraw then g_Map_DrawPanels(panType, hasAmbient, ambColor); end; profileFrameDraw.sectionEnd(); end; @@ -2855,10 +2910,26 @@ begin if setTransMatrix then begin + //if (g_dbg_scale <> 1.0) then glTranslatef(0.0, -0.375/2, 0); glScalef(g_dbg_scale, g_dbg_scale, 1.0); glTranslatef(-sX, -sY, 0); end; + // rendering mode + ambColor := gCurrentMap['light_ambient'].rgba; + hasAmbient := (not ambColor.isOpaque) or (not ambColor.isBlack); + + { + if hasAmbient then + begin + //writeln('color: (', ambColor.r, ',', ambColor.g, ',', ambColor.b, ',', ambColor.a, ')'); + glColor4ub(ambColor.r, ambColor.g, ambColor.b, ambColor.a); + glClear(GL_COLOR_BUFFER_BIT); + end; + } + //writeln('color: (', ambColor.r, ',', ambColor.g, ',', ambColor.b, ',', ambColor.a, ')'); + + drawPanelType('*back', PANEL_BACK, g_rlayer_back); drawPanelType('*step', PANEL_STEP, g_rlayer_step); drawOther('items', @g_Items_Draw); @@ -2875,8 +2946,16 @@ begin drawPanelType('*acid2', PANEL_ACID2, g_rlayer_acid2); drawPanelType('*water', PANEL_WATER, g_rlayer_water); drawOther('dynlights', @renderDynLightsInternal); + + if hasAmbient {and ((not g_playerLight) or (not gwin_has_stencil) or (g_dynLightCount < 1))} then + begin + renderAmbientQuad(hasAmbient, ambColor); + end; + + doAmbient := true; drawPanelType('*fore', PANEL_FORE, g_rlayer_fore); + if g_debug_HealthBar then begin g_Monsters_DrawHealth(); @@ -7088,5 +7167,5 @@ begin conRegVar('dbg_holmes', @g_holmes_enabled, 'enable/disable Holmes', 'Holmes', true); - conRegVar('dbg_scale', @g_dbg_scale, 0.01, 5.0, 'experimental deBUG scale mode', '', true); + conRegVar('dbg_scale', @g_dbg_scale, 0.01, 100.0, 'experimental deBUG scale mode', '', false); end.