diff --git a/docs/licenses/mpl.txt b/docs/licenses/mpl.txt deleted file mode 100644 index 14e2f777f6..0000000000 --- a/docs/licenses/mpl.txt +++ /dev/null @@ -1,373 +0,0 @@ -Mozilla Public License Version 2.0 -================================== - -1. Definitions --------------- - -1.1. "Contributor" - means each individual or legal entity that creates, contributes to - the creation of, or owns Covered Software. - -1.2. "Contributor Version" - means the combination of the Contributions of others (if any) used - by a Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - means Source Code Form to which the initial Contributor has attached - the notice in Exhibit A, the Executable Form of such Source Code - Form, and Modifications of such Source Code Form, in each case - including portions thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - (a) that the initial Contributor has attached the notice described - in Exhibit B to the Covered Software; or - - (b) that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the - terms of a Secondary License. - -1.6. "Executable Form" - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - means a work that combines Covered Software with other material, in - a separate file or files, that is not Covered Software. - -1.8. "License" - means this document. - -1.9. "Licensable" - means having the right to grant, to the maximum extent possible, - whether at the time of the initial grant or subsequently, any and - all of the rights conveyed by this License. - -1.10. "Modifications" - means any of the following: - - (a) any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered - Software; or - - (b) any new file in Source Code Form that contains any Covered - Software. - -1.11. "Patent Claims" of a Contributor - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the - License, by the making, using, selling, offering for sale, having - made, import, or transfer of either its Contributions or its - Contributor Version. - -1.12. "Secondary License" - means either the GNU General Public License, Version 2.0, the GNU - Lesser General Public License, Version 2.1, the GNU Affero General - Public License, Version 3.0, or any later versions of those - licenses. - -1.13. "Source Code Form" - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that - controls, is controlled by, or is under common control with You. For - purposes of this definition, "control" means (a) the power, direct - or indirect, to cause the direction or management of such entity, - whether by contract or otherwise, or (b) ownership of more than - fifty percent (50%) of the outstanding shares or beneficial - ownership of such entity. - -2. License Grants and Conditions --------------------------------- - -2.1. Grants - -Each Contributor hereby grants You a world-wide, royalty-free, -non-exclusive license: - -(a) under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - -(b) under Patent Claims of such Contributor to make, use, sell, offer - for sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - -The licenses granted in Section 2.1 with respect to any Contribution -become effective for each Contribution on the date the Contributor first -distributes such Contribution. - -2.3. Limitations on Grant Scope - -The licenses granted in this Section 2 are the only rights granted under -this License. No additional rights or licenses will be implied from the -distribution or licensing of Covered Software under this License. -Notwithstanding Section 2.1(b) above, no patent license is granted by a -Contributor: - -(a) for any code that a Contributor has removed from Covered Software; - or - -(b) for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - -(c) under Patent Claims infringed by Covered Software in the absence of - its Contributions. - -This License does not grant any rights in the trademarks, service marks, -or logos of any Contributor (except as may be necessary to comply with -the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - -No Contributor makes additional grants as a result of Your choice to -distribute the Covered Software under a subsequent version of this -License (see Section 10.2) or under the terms of a Secondary License (if -permitted under the terms of Section 3.3). - -2.5. Representation - -Each Contributor represents that the Contributor believes its -Contributions are its original creation(s) or it has sufficient rights -to grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - -This License is not intended to limit any rights You have under -applicable copyright doctrines of fair use, fair dealing, or other -equivalents. - -2.7. Conditions - -Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted -in Section 2.1. - -3. Responsibilities -------------------- - -3.1. Distribution of Source Form - -All distribution of Covered Software in Source Code Form, including any -Modifications that You create or to which You contribute, must be under -the terms of this License. You must inform recipients that the Source -Code Form of the Covered Software is governed by the terms of this -License, and how they can obtain a copy of this License. You may not -attempt to alter or restrict the recipients' rights in the Source Code -Form. - -3.2. Distribution of Executable Form - -If You distribute Covered Software in Executable Form then: - -(a) such Covered Software must also be made available in Source Code - Form, as described in Section 3.1, and You must inform recipients of - the Executable Form how they can obtain a copy of such Source Code - Form by reasonable means in a timely manner, at a charge no more - than the cost of distribution to the recipient; and - -(b) You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter - the recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - -You may create and distribute a Larger Work under terms of Your choice, -provided that You also comply with the requirements of this License for -the Covered Software. If the Larger Work is a combination of Covered -Software with a work governed by one or more Secondary Licenses, and the -Covered Software is not Incompatible With Secondary Licenses, this -License permits You to additionally distribute such Covered Software -under the terms of such Secondary License(s), so that the recipient of -the Larger Work may, at their option, further distribute the Covered -Software under the terms of either this License or such Secondary -License(s). - -3.4. Notices - -You may not remove or alter the substance of any license notices -(including copyright notices, patent notices, disclaimers of warranty, -or limitations of liability) contained within the Source Code Form of -the Covered Software, except that You may alter any license notices to -the extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - -You may choose to offer, and to charge a fee for, warranty, support, -indemnity or liability obligations to one or more recipients of Covered -Software. However, You may do so only on Your own behalf, and not on -behalf of any Contributor. You must make it absolutely clear that any -such warranty, support, indemnity, or liability obligation is offered by -You alone, and You hereby agree to indemnify every Contributor for any -liability incurred by such Contributor as a result of warranty, support, -indemnity or liability terms You offer. You may include additional -disclaimers of warranty and limitations of liability specific to any -jurisdiction. - -4. Inability to Comply Due to Statute or Regulation ---------------------------------------------------- - -If it is impossible for You to comply with any of the terms of this -License with respect to some or all of the Covered Software due to -statute, judicial order, or regulation then You must: (a) comply with -the terms of this License to the maximum extent possible; and (b) -describe the limitations and the code they affect. Such description must -be placed in a text file included with all distributions of the Covered -Software under this License. Except to the extent prohibited by statute -or regulation, such description must be sufficiently detailed for a -recipient of ordinary skill to be able to understand it. - -5. Termination --------------- - -5.1. The rights granted under this License will terminate automatically -if You fail to comply with any of its terms. However, if You become -compliant, then the rights granted under this License from a particular -Contributor are reinstated (a) provisionally, unless and until such -Contributor explicitly and finally terminates Your grants, and (b) on an -ongoing basis, if such Contributor fails to notify You of the -non-compliance by some reasonable means prior to 60 days after You have -come back into compliance. Moreover, Your grants from a particular -Contributor are reinstated on an ongoing basis if such Contributor -notifies You of the non-compliance by some reasonable means, this is the -first time You have received notice of non-compliance with this License -from such Contributor, and You become compliant prior to 30 days after -Your receipt of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent -infringement claim (excluding declaratory judgment actions, -counter-claims, and cross-claims) alleging that a Contributor Version -directly or indirectly infringes any patent, then the rights granted to -You by any and all Contributors for the Covered Software under Section -2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all -end user license agreements (excluding distributors and resellers) which -have been validly granted by You or Your distributors under this License -prior to termination shall survive termination. - -************************************************************************ -* * -* 6. Disclaimer of Warranty * -* ------------------------- * -* * -* Covered Software is provided under this License on an "as is" * -* basis, without warranty of any kind, either expressed, implied, or * -* statutory, including, without limitation, warranties that the * -* Covered Software is free of defects, merchantable, fit for a * -* particular purpose or non-infringing. The entire risk as to the * -* quality and performance of the Covered Software is with You. * -* Should any Covered Software prove defective in any respect, You * -* (not any Contributor) assume the cost of any necessary servicing, * -* repair, or correction. This disclaimer of warranty constitutes an * -* essential part of this License. No use of any Covered Software is * -* authorized under this License except under this disclaimer. * -* * -************************************************************************ - -************************************************************************ -* * -* 7. Limitation of Liability * -* -------------------------- * -* * -* Under no circumstances and under no legal theory, whether tort * -* (including negligence), contract, or otherwise, shall any * -* Contributor, or anyone who distributes Covered Software as * -* permitted above, be liable to You for any direct, indirect, * -* special, incidental, or consequential damages of any character * -* including, without limitation, damages for lost profits, loss of * -* goodwill, work stoppage, computer failure or malfunction, or any * -* and all other commercial damages or losses, even if such party * -* shall have been informed of the possibility of such damages. This * -* limitation of liability shall not apply to liability for death or * -* personal injury resulting from such party's negligence to the * -* extent applicable law prohibits such limitation. Some * -* jurisdictions do not allow the exclusion or limitation of * -* incidental or consequential damages, so this exclusion and * -* limitation may not apply to You. * -* * -************************************************************************ - -8. Litigation -------------- - -Any litigation relating to this License may be brought only in the -courts of a jurisdiction where the defendant maintains its principal -place of business and such litigation shall be governed by laws of that -jurisdiction, without reference to its conflict-of-law provisions. -Nothing in this Section shall prevent a party's ability to bring -cross-claims or counter-claims. - -9. Miscellaneous ----------------- - -This License represents the complete agreement concerning the subject -matter hereof. If any provision of this License is held to be -unenforceable, such provision shall be reformed only to the extent -necessary to make it enforceable. Any law or regulation which provides -that the language of a contract shall be construed against the drafter -shall not be used to construe this License against a Contributor. - -10. Versions of the License ---------------------------- - -10.1. New Versions - -Mozilla Foundation is the license steward. Except as provided in Section -10.3, no one other than the license steward has the right to modify or -publish new versions of this License. Each version will be given a -distinguishing version number. - -10.2. Effect of New Versions - -You may distribute the Covered Software under the terms of the version -of the License under which You originally received the Covered Software, -or under the terms of any subsequent version published by the license -steward. - -10.3. Modified Versions - -If you create software not governed by this License, and you want to -create a new license for such software, you may create and use a -modified version of this License if you rename the license and remove -any references to the name of the license steward (except to note that -such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary -Licenses - -If You choose to distribute Source Code Form that is Incompatible With -Secondary Licenses under the terms of this version of the License, the -notice described in Exhibit B of this License must be attached. - -Exhibit A - Source Code Form License Notice -------------------------------------------- - - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - -If it is not possible or desirable to put the notice in a particular -file, then You may include the notice in a location (such as a LICENSE -file in a relevant directory) where a recipient would be likely to look -for such a notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice ---------------------------------------------------------- - - This Source Code Form is "Incompatible With Secondary Licenses", as - defined by the Mozilla Public License, v. 2.0. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 198384a5a9..2397b0dc02 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -409,8 +409,7 @@ CHECK_CXX_SOURCE_COMPILES("thread_local int i; int main() { i = 0; }" HAVE_THREAD_LOCAL) if( NOT HAVE_THREAD_LOCAL ) - message( WARNING "C++ compiler doesn't support thread_local storage duration specifier" ) - add_definitions( -Dthread_local= ) + message( SEND_ERROR "C++ compiler doesn't support thread_local storage duration specifier" ) endif() # Check for functions that may or may not exist. @@ -491,9 +490,6 @@ endif() set( PLAT_WIN32_SOURCES sound/mididevices/music_win_mididevice.cpp win32/critsec.cpp - win32/fb_d3d9.cpp - win32/fb_d3d9_wipe.cpp - win32/fb_ddraw.cpp win32/hardware.cpp win32/helperthread.cpp win32/i_cd.cpp @@ -522,7 +518,6 @@ set( PLAT_SDL_SOURCES posix/sdl/i_joystick.cpp posix/sdl/i_main.cpp posix/sdl/i_system.cpp - posix/sdl/sdlvideo.cpp posix/sdl/sdlglvideo.cpp posix/sdl/st_start.cpp ) set( PLAT_UNIX_SOURCES @@ -575,17 +570,17 @@ if( HAVE_MMX ) add_definitions( -DHAVE_MMX=1 ) set( SYSTEM_SOURCES ${SYSTEM_SOURCES} - gl/hqnx_asm/hq2x_asm.cpp - gl/hqnx_asm/hq3x_asm.cpp - gl/hqnx_asm/hq4x_asm.cpp - gl/hqnx_asm/hqnx_asm_Image.cpp) + textures/hires/hqnx_asm/hq2x_asm.cpp + textures/hires/hqnx_asm/hq3x_asm.cpp + textures/hires/hqnx_asm/hq4x_asm.cpp + textures/hires/hqnx_asm/hqnx_asm_Image.cpp) if( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) set_source_files_properties( - gl/hqnx_asm/hq2x_asm.cpp - gl/hqnx_asm/hq3x_asm.cpp - gl/hqnx_asm/hq4x_asm.cpp - gl/textures/gl_hqresize.cpp + textures/hires/hqnx_asm/hq2x_asm.cpp + textures/hires/hqnx_asm/hq3x_asm.cpp + textures/hires/hqnx_asm/hq4x_asm.cpp + textures/hires/gl_hqresize.cpp PROPERTIES COMPILE_FLAGS "-mmmx" ) endif( ZD_CMAKE_COMPILER_IS_GNUCXX_COMPATIBLE ) endif( HAVE_MMX ) @@ -690,6 +685,9 @@ file( GLOB HEADER_FILES sfmt/*.h sound/*.h textures/*.h + textures/hires/hqnx/*.h + textures/hires/hqnx_asm/*.h + textures/hires/xbr/*.h scripting/*.h scripting/backend/*.h scripting/decorate/*.h @@ -719,9 +717,6 @@ file( GLOB HEADER_FILES gl/api/*.h gl/data/*.h gl/dynlights/*.h - gl/hqnx/*.h - gl/hqnx_asm/*.h - gl/xbr/*.h gl/models/*.h gl/renderer/*.h gl/scene/*.h @@ -730,11 +725,11 @@ file( GLOB HEADER_FILES gl/system/*.h gl/textures/*.h gl/utility/*.h + gl_load/*.h *.h ) set ( SWRENDER_SOURCES - swrenderer/r_swcanvas.cpp swrenderer/r_swcolormaps.cpp swrenderer/r_swrenderer.cpp swrenderer/r_memory.cpp @@ -837,13 +832,12 @@ set( FASTMATH_SOURCES sound/timiditypp/fft4g.cpp sound/timiditypp/reverb.cpp gl/utility/gl_clock.cpp - gl/renderer/gl_2ddrawer.cpp - gl/hqnx/init.cpp - gl/hqnx/hq2x.cpp - gl/hqnx/hq3x.cpp - gl/hqnx/hq4x.cpp - gl/xbr/xbrz.cpp - gl/xbr/xbrz_old.cpp + textures/hires/hqnx/init.cpp + textures/hires/hqnx/hq2x.cpp + textures/hires/hqnx/hq3x.cpp + textures/hires/hqnx/hq4x.cpp + textures/hires/xbr/xbrz.cpp + textures/hires/xbr/xbrz_old.cpp gl/scene/gl_bsp.cpp gl/scene/gl_fakeflat.cpp gl/scene/gl_clipper.cpp @@ -856,13 +850,14 @@ set( FASTMATH_SOURCES gl/scene/gl_renderhacks.cpp gl/scene/gl_weapon.cpp gl/scene/gl_scene.cpp + gl/scene/gl_swscene.cpp gl/scene/gl_sky.cpp gl/scene/gl_portal.cpp gl/scene/gl_walls_draw.cpp gl/scene/gl_vertex.cpp gl/scene/gl_spritelight.cpp gl/dynlights/gl_dynlight1.cpp - gl/system/gl_load.c + gl_load/gl_load.c gl/models/gl_models.cpp r_data/models/models.cpp r_data/matrix.cpp @@ -1017,6 +1012,7 @@ set (PCH_SOURCES stringtable.cpp teaminfo.cpp umapinfo.cpp + v_2ddrawer.cpp v_blend.cpp v_collection.cpp v_draw.cpp @@ -1034,7 +1030,6 @@ set (PCH_SOURCES g_shared/a_action.cpp g_shared/a_decals.cpp g_shared/a_dynlight.cpp - g_shared/a_dynlightdata.cpp g_shared/a_flashfader.cpp g_shared/a_lightning.cpp g_shared/a_morph.cpp @@ -1046,13 +1041,9 @@ set (PCH_SOURCES g_statusbar/sbar_mugshot.cpp g_statusbar/shared_sbar.cpp gl/compatibility/gl_20.cpp - gl/data/gl_data.cpp - gl/data/gl_portaldata.cpp - gl/data/gl_setup.cpp + gl/compatibility/gl_swshader20.cpp gl/data/gl_vertexbuffer.cpp - gl/dynlights/gl_glow.cpp gl/dynlights/gl_lightbuffer.cpp - gl/dynlights/gl_aabbtree.cpp gl/dynlights/gl_shadowmap.cpp gl/renderer/gl_quaddrawer.cpp gl/renderer/gl_renderer.cpp @@ -1062,7 +1053,6 @@ set (PCH_SOURCES gl/renderer/gl_postprocess.cpp gl/renderer/gl_postprocessstate.cpp gl/shaders/gl_shader.cpp - gl/shaders/gl_texshader.cpp gl/shaders/gl_shaderprogram.cpp gl/shaders/gl_postprocessshader.cpp gl/shaders/gl_shadowmapshader.cpp @@ -1085,18 +1075,15 @@ set (PCH_SOURCES gl/stereo3d/gl_interleaved3d.cpp gl/system/gl_interface.cpp gl/system/gl_framebuffer.cpp - gl/system/gl_swframebuffer.cpp - gl/system/gl_swwipe.cpp gl/system/gl_debug.cpp gl/system/gl_menu.cpp gl/system/gl_wipe.cpp gl/textures/gl_hwtexture.cpp gl/textures/gl_texture.cpp gl/textures/gl_material.cpp - gl/textures/gl_hirestex.cpp gl/textures/gl_samplers.cpp - gl/textures/gl_translate.cpp - gl/textures/gl_hqresize.cpp + hwrenderer/dynlights/hw_aabbtree.cpp + menu/joystickmenu.cpp menu/loadsavemenu.cpp menu/menu.cpp @@ -1117,29 +1104,32 @@ set (PCH_SOURCES resourcefiles/resourcefile.cpp textures/animations.cpp textures/anim_switches.cpp - textures/automaptexture.cpp textures/bitmap.cpp - textures/buildtexture.cpp - textures/canvastexture.cpp - textures/ddstexture.cpp - textures/flattexture.cpp - textures/imgztexture.cpp - textures/jpegtexture.cpp - textures/md5check.cpp - textures/multipatchtexture.cpp - textures/patchtexture.cpp - textures/pcxtexture.cpp - textures/pngtexture.cpp - textures/rawpagetexture.cpp - textures/emptytexture.cpp - textures/backdroptexture.cpp - textures/shadertexture.cpp textures/texture.cpp textures/texturemanager.cpp - textures/tgatexture.cpp - textures/warptexture.cpp textures/skyboxtexture.cpp - textures/worldtexture.cpp + textures/formats/automaptexture.cpp + textures/formats/brightmaptexture.cpp + textures/formats/buildtexture.cpp + textures/formats/canvastexture.cpp + textures/formats/ddstexture.cpp + textures/formats/flattexture.cpp + textures/formats/imgztexture.cpp + textures/formats/jpegtexture.cpp + textures/formats/md5check.cpp + textures/formats/multipatchtexture.cpp + textures/formats/patchtexture.cpp + textures/formats/pcxtexture.cpp + textures/formats/pngtexture.cpp + textures/formats/rawpagetexture.cpp + textures/formats/emptytexture.cpp + textures/formats/backdroptexture.cpp + textures/formats/shadertexture.cpp + textures/formats/tgatexture.cpp + textures/formats/worldtexture.cpp + textures/formats/warptexture.cpp + textures/hires/hqresize.cpp + textures/hires/hirestex.cpp xlat/parse_xlat.cpp fragglescript/t_func.cpp fragglescript/t_load.cpp @@ -1153,9 +1143,13 @@ set (PCH_SOURCES intermission/intermission.cpp intermission/intermission_parse.cpp r_data/colormaps.cpp + r_data/gldefs.cpp + r_data/a_dynlightdata.cpp r_data/r_translate.cpp r_data/sprites.cpp + r_data/portalgroups.cpp r_data/voxels.cpp + r_data/renderinfo.cpp r_data/renderstyle.cpp r_data/r_interpolate.cpp r_data/r_vanillatrans.cpp @@ -1417,12 +1411,21 @@ source_group("FraggleScript" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/fr source_group("Intermission" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/intermission/.+") source_group("Inventory" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/g_inventory/.+") source_group("Menu" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/menu/.+") +source_group("Hardware Renderer" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/.+") +source_group("Hardware Renderer\\Data" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/hwrenderer/data/.+") +source_group("Hardware Renderer\\Dynamic Lights" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/hwrenderer/dynlights/.+") +source_group("Hardware Renderer\\Models" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/hwrenderer/models/.+") +source_group("Hardware Renderer\\Renderer" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/hwrenderer/renderer/.+") +source_group("Hardware Renderer\\Scene" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/hwrenderer/scene/.+") +source_group("Hardware Renderer\\Stereo3D" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/hwrenderer/stereo3d/.+") +source_group("Hardware Renderer\\Shaders" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/hwrenderer/shaders/.+") +source_group("Hardware Renderer\\System" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/hwrenderer/system/.+") +source_group("Hardware Renderer\\Textures" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/hwrenderer/textures/.+") +source_group("Hardware Renderer\\Utilities" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/hwrenderer/utility/.+") +source_group("OpenGL Loader" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl_load/.+") source_group("OpenGL Renderer" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/.+") source_group("OpenGL Renderer\\Data" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/data/.+") source_group("OpenGL Renderer\\Dynamic Lights" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/dynlights/.+") -source_group("OpenGL Renderer\\HQ Resize" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/hqnx/.+") -source_group("OpenGL Renderer\\HQ Resize MMX version" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/hqnx_asm/.+") -source_group("OpenGL Renderer\\XBRZ" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/hqnx_asm/.+") source_group("OpenGL Renderer\\Models" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/models/.+") source_group("OpenGL Renderer\\Renderer" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/renderer/.+") source_group("OpenGL Renderer\\Scene" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/scene/.+") @@ -1445,6 +1448,11 @@ source_group("Poly Renderer\\Drawers" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURC source_group("Poly Renderer\\Scene" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/polyrenderer/scene/.+") source_group("Render Data" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/r_data/.+") source_group("Render Data\\Textures" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/textures/.+") +source_group("Render Data\\Textures\\Hires" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/textures/hires/.+") +source_group("Render Data\\Textures\\Hires\\HQ Resize" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/textures/hires/hqnx/.+") +source_group("Render Data\\Textures\\Hires\\HQ Resize MMX version" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/textures/hires/hqnx_asm/.+") +source_group("Render Data\\Textures\\Hires\\XBRZ" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/textures/hires/xbr/.+") +source_group("Render Data\\Textures\\Formats" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/textures/formats/.+") source_group("Render Data\\Models" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/r_data/models/.+") source_group("Render Interface" FILES r_defs.h r_renderer.h r_sky.cpp r_sky.h r_state.h r_utility.cpp r_utility.h) source_group("Resource Files" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/resourcefiles/.+") diff --git a/src/actorinlines.h b/src/actorinlines.h index d55ca1b55c..10c0ad6158 100644 --- a/src/actorinlines.h +++ b/src/actorinlines.h @@ -2,31 +2,32 @@ #include "actor.h" #include "r_defs.h" -// These depend on both actor.h and r_defs.h so they cannot be in either file without creating a cross dependency. +#include "g_levellocals.h" +// These depend on both actor.h and r_defs.h so they cannot be in either file without creating a circular dependency. inline DVector3 AActor::PosRelative(int portalgroup) const { - return Pos() + Displacements.getOffset(Sector->PortalGroup, portalgroup); + return Pos() + level.Displacements.getOffset(Sector->PortalGroup, portalgroup); } inline DVector3 AActor::PosRelative(const AActor *other) const { - return Pos() + Displacements.getOffset(Sector->PortalGroup, other->Sector->PortalGroup); + return Pos() + level.Displacements.getOffset(Sector->PortalGroup, other->Sector->PortalGroup); } inline DVector3 AActor::PosRelative(sector_t *sec) const { - return Pos() + Displacements.getOffset(Sector->PortalGroup, sec->PortalGroup); + return Pos() + level.Displacements.getOffset(Sector->PortalGroup, sec->PortalGroup); } inline DVector3 AActor::PosRelative(line_t *line) const { - return Pos() + Displacements.getOffset(Sector->PortalGroup, line->frontsector->PortalGroup); + return Pos() + level.Displacements.getOffset(Sector->PortalGroup, line->frontsector->PortalGroup); } inline DVector3 PosRelative(const DVector3 &pos, line_t *line, sector_t *refsec = NULL) { - return pos + Displacements.getOffset(refsec->PortalGroup, line->frontsector->PortalGroup); + return pos + level.Displacements.getOffset(refsec->PortalGroup, line->frontsector->PortalGroup); } diff --git a/src/am_map.cpp b/src/am_map.cpp index df4b79b76b..7e6e7546d0 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -771,7 +771,6 @@ static int f_y; // size of window on screen static int f_w; static int f_h; -static int f_p; // [RH] # of bytes from start of a line to start of next static int amclock; @@ -1384,7 +1383,6 @@ void AM_Stop () { automapactive = false; stopped = true; - V_SetBorderNeedRefresh(); viewactive = true; } @@ -2134,7 +2132,7 @@ void AM_drawSubsectors() { F3DFloor *rover = sec->e->XFloor.ffloors[i]; if (!(rover->flags & FF_EXISTS)) continue; - if (rover->flags & FF_FOG) continue; + if (rover->flags & (FF_FOG|FF_THISINSIDE)) continue; if (!(rover->flags & FF_RENDERPLANES)) continue; if (rover->alpha == 0) continue; double roverz = rover->top.plane->ZatPoint(secx, secy); @@ -2192,6 +2190,11 @@ void AM_drawSubsectors() (colormap.LightColor.b + 160) / 2); colormap.Desaturation = 255 - (255 - colormap.Desaturation) / 4; } + // make table based fog visible on the automap as well. + if (level.flags & LEVEL_HASFADETABLE) + { + colormap.FadeColor = PalEntry(0, 128, 128, 128); + } // Draw the polygon. FTexture *pic = TexMan(maptex); @@ -2336,6 +2339,7 @@ bool AM_Check3DFloors(line_t *line) for(unsigned i=0;iflags & FF_THISINSIDE) continue; if (!(rover->flags & FF_EXISTS)) continue; if (rover->alpha == 0) continue; realfrontcount++; @@ -2344,6 +2348,7 @@ bool AM_Check3DFloors(line_t *line) for(unsigned i=0;iflags & FF_THISINSIDE) continue; if (!(rover->flags & FF_EXISTS)) continue; if (rover->alpha == 0) continue; realbackcount++; @@ -2354,6 +2359,7 @@ bool AM_Check3DFloors(line_t *line) for(unsigned i=0;iflags & FF_THISINSIDE) continue; // only relevant for software rendering. if (!(rover->flags & FF_EXISTS)) continue; if (rover->alpha == 0) continue; @@ -2361,6 +2367,7 @@ bool AM_Check3DFloors(line_t *line) for(unsigned j=0;jflags & FF_THISINSIDE) continue; // only relevant for software rendering. if (!(rover2->flags & FF_EXISTS)) continue; if (rover2->alpha == 0) continue; if (rover->model == rover2->model && rover->flags == rover2->flags) @@ -2536,7 +2543,7 @@ void AM_drawWalls (bool allmap) static mline_t l; int lock, color; - int numportalgroups = am_portaloverlay ? Displacements.size : 0; + int numportalgroups = am_portaloverlay ? level.Displacements.size : 0; for (int p = numportalgroups - 1; p >= -1; p--) { @@ -2560,7 +2567,7 @@ void AM_drawWalls (bool allmap) bool portalmode = numportalgroups > 0 && pg != MapPortalGroup; if (pg == p) { - offset = Displacements.getOffset(pg, MapPortalGroup); + offset = level.Displacements.getOffset(pg, MapPortalGroup); } else if (p == -1 && (pg == MapPortalGroup || !am_portaloverlay)) { @@ -3222,7 +3229,6 @@ void AM_Drawer (int bottom) f_x = f_y = 0; f_w = screen->GetWidth (); f_h = bottom; - f_p = screen->GetPitch (); AM_clearFB(AMColors[AMColors.Background]); } @@ -3232,7 +3238,6 @@ void AM_Drawer (int bottom) f_y = viewwindowy; f_w = viewwidth; f_h = viewheight; - f_p = screen->GetPitch (); } AM_activateNewScale(); diff --git a/src/c_console.cpp b/src/c_console.cpp index bebd6a52cf..3cddf41604 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -516,31 +516,6 @@ CUSTOM_CVAR (Int, msgmidcolor2, 4, CVAR_ARCHIVE) setmsgcolor (PRINTLEVELS+1, self); } -static void maybedrawnow (bool tick, bool force) -{ - // FIXME: Does not work right with hw2d - if (ConsoleDrawing || screen == NULL || screen->IsLocked () || screen->Accel2D || ConFont == NULL) - { - return; - } - - if (vidactive && - (((tick || gameaction != ga_nothing) && ConsoleState == c_down) - || gamestate == GS_STARTUP)) - { - static size_t lastprinttime = 0; - size_t nowtime = I_GetTime(); - - if (nowtime - lastprinttime > 1 || force) - { - screen->Lock (false); - C_DrawConsole (false); - screen->Update (); - lastprinttime = nowtime; - } - } -} - struct TextQueue { TextQueue (bool notify, int printlevel, const char *text) @@ -857,7 +832,6 @@ int PrintString (int printlevel, const char *outline) if (vidactive && screen && SmallFont) { NotifyStrings.AddString(printlevel, outline); - maybedrawnow (false, false); } } else if (Logfile != NULL) @@ -1026,8 +1000,6 @@ void FNotifyBuffer::Draw() lineadv = SmallFont->GetHeight (); - BorderTopRefresh = screen->GetPageCount (); - for (unsigned i = 0; i < Text.Size(); ++ i) { FNotifyText ¬ify = Text[i]; @@ -1088,16 +1060,14 @@ void C_InitTicker (const char *label, unsigned int max, bool showpercent) TickerMax = max; TickerLabel = label; TickerAt = 0; - maybedrawnow (true, false); } void C_SetTicker (unsigned int at, bool forceUpdate) { TickerAt = at > TickerMax ? TickerMax : at; - maybedrawnow (true, TickerVisible ? forceUpdate : false); } -void C_DrawConsole (bool hw2d) +void C_DrawConsole () { static int oldbottom = 0; int lines, left, offset; @@ -1116,14 +1086,6 @@ void C_DrawConsole (bool hw2d) offset = -ConFont->GetHeight(); } - if ((ConBottom < oldbottom) && - (gamestate == GS_LEVEL || gamestate == GS_TITLELEVEL) && - (viewwindowx || viewwindowy) && - viewactive) - { - V_SetBorderNeedRefresh(); - } - oldbottom = ConBottom; if (ConsoleState == c_up) @@ -1142,7 +1104,7 @@ void C_DrawConsole (bool hw2d) DTA_DestWidth, screen->GetWidth(), DTA_DestHeight, screen->GetHeight(), DTA_ColorOverlay, conshade, - DTA_Alpha, (hw2d && gamestate != GS_FULLCONSOLE) ? (double)con_alpha : 1., + DTA_Alpha, (gamestate != GS_FULLCONSOLE) ? (double)con_alpha : 1., DTA_Masked, false, TAG_DONE); if (conline && visheight < screen->GetHeight()) @@ -1220,21 +1182,6 @@ void C_DrawConsole (bool hw2d) } } - // Apply palette blend effects - if (StatusBar != NULL && !hw2d) - { - player_t *player = StatusBar->CPlayer; - if (player->camera != NULL && player->camera->player != NULL) - { - player = player->camera->player; - } - if (player->BlendA != 0 && (gamestate == GS_LEVEL || gamestate == GS_TITLELEVEL)) - { - screen->Dim (PalEntry ((unsigned char)(player->BlendR*255), (unsigned char)(player->BlendG*255), (unsigned char)(player->BlendB*255)), - player->BlendA, 0, ConBottom, screen->GetWidth(), screen->GetHeight() - ConBottom); - V_SetBorderNeedRefresh(); - } - } } if (menuactive != MENU_Off) diff --git a/src/c_console.h b/src/c_console.h index f88af41753..9e563b3eff 100644 --- a/src/c_console.h +++ b/src/c_console.h @@ -67,7 +67,7 @@ void AddToConsole (int printlevel, const char *string); int PrintString (int printlevel, const char *string); int VPrintf (int printlevel, const char *format, va_list parms) GCCFORMAT(2); -void C_DrawConsole (bool hw2d); +void C_DrawConsole (); void C_ToggleConsole (void); void C_FullConsole (void); void C_HideConsole (void); diff --git a/src/compatibility.cpp b/src/compatibility.cpp index ff36f9434b..74b0354d8a 100644 --- a/src/compatibility.cpp +++ b/src/compatibility.cpp @@ -54,6 +54,7 @@ #include "w_wad.h" #include "textures.h" #include "g_levellocals.h" +#include "vm.h" // MACROS ------------------------------------------------------------------ @@ -103,6 +104,7 @@ enum // EXTERNAL DATA DECLARATIONS ---------------------------------------------- extern TArray MapThingsConverted; +extern bool ForceNodeBuild; // PUBLIC DATA DEFINITIONS ------------------------------------------------- @@ -177,10 +179,6 @@ static const char *const SectorPlanes[] = "floor", "ceil", NULL }; -static TArray CompatParams; -static int ii_compatparams; -static TArray TexNames; - // CODE -------------------------------------------------------------------- //========================================================================== @@ -198,7 +196,6 @@ void ParseCompatibility() unsigned int j; BCompatMap.Clear(); - CompatParams.Clear(); // The contents of this file are not cumulative, as it should not // be present in user-distributed maps. @@ -251,205 +248,12 @@ void ParseCompatibility() { flags.CompatFlags[Options[i].WhichSlot] |= Options[i].CompatFlags; } - else if (sc.Compare("clearlineflags")) - { - if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size(); - CompatParams.Push(CP_CLEARFLAGS); - sc.MustGetNumber(); - CompatParams.Push(sc.Number); - sc.MustGetNumber(); - CompatParams.Push(sc.Number); - } - else if (sc.Compare("setlineflags")) - { - if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size(); - CompatParams.Push(CP_SETFLAGS); - sc.MustGetNumber(); - CompatParams.Push(sc.Number); - sc.MustGetNumber(); - CompatParams.Push(sc.Number); - } - else if (sc.Compare("setlinespecial")) - { - if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size(); - CompatParams.Push(CP_SETSPECIAL); - sc.MustGetNumber(); - CompatParams.Push(sc.Number); - - sc.MustGetString(); - CompatParams.Push(P_FindLineSpecial(sc.String, NULL, NULL)); - for (int i = 0; i < 5; i++) - { - sc.MustGetNumber(); - CompatParams.Push(sc.Number); - } - } - else if (sc.Compare("setlinesectorref")) - { - if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size(); - CompatParams.Push(CP_SETLINESECTORREF); - sc.MustGetNumber(); - CompatParams.Push(sc.Number); - sc.MustGetString(); - CompatParams.Push(sc.MustMatchString(LineSides)); - sc.MustGetNumber(); - CompatParams.Push(sc.Number); - flags.CompatFlags[SLOT_BCOMPAT] |= BCOMPATF_REBUILDNODES; - } - else if (sc.Compare("clearlinespecial")) - { - if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size(); - CompatParams.Push(CP_CLEARSPECIAL); - sc.MustGetNumber(); - CompatParams.Push(sc.Number); - } - else if (sc.Compare("setactivation")) - { - if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size(); - CompatParams.Push(CP_SETACTIVATION); - sc.MustGetNumber(); - CompatParams.Push(sc.Number); - sc.MustGetNumber(); - CompatParams.Push(sc.Number); - } - else if (sc.Compare("setsectoroffset")) - { - if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size(); - CompatParams.Push(CP_SETSECTOROFFSET); - sc.MustGetNumber(); - CompatParams.Push(sc.Number); - sc.MustGetString(); - CompatParams.Push(sc.MustMatchString(SectorPlanes)); - sc.MustGetFloat(); - CompatParams.Push(int(sc.Float*65536.)); - } - else if (sc.Compare("setsectorspecial")) - { - if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size(); - CompatParams.Push(CP_SETSECTORSPECIAL); - sc.MustGetNumber(); - CompatParams.Push(sc.Number); - sc.MustGetNumber(); - CompatParams.Push(sc.Number); - } - else if (sc.Compare("setwallyscale")) - { - if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size(); - CompatParams.Push(CP_SETWALLYSCALE); - sc.MustGetNumber(); - CompatParams.Push(sc.Number); - sc.MustGetString(); - CompatParams.Push(sc.MustMatchString(LineSides)); - sc.MustGetString(); - CompatParams.Push(sc.MustMatchString(WallTiers)); - sc.MustGetFloat(); - CompatParams.Push(int(sc.Float*65536.)); - } - else if (sc.Compare("setwalltexture")) - { - if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size(); - CompatParams.Push(CP_SETWALLTEXTURE); - sc.MustGetNumber(); - CompatParams.Push(sc.Number); - sc.MustGetString(); - CompatParams.Push(sc.MustMatchString(LineSides)); - sc.MustGetString(); - CompatParams.Push(sc.MustMatchString(WallTiers)); - sc.MustGetString(); - const FString texName = sc.String; - const unsigned int texIndex = TexNames.Find(texName); - const unsigned int texCount = TexNames.Size(); - if (texIndex == texCount) - { - TexNames.Push(texName); - } - CompatParams.Push(texIndex); - } - else if (sc.Compare("setthingz")) - { - if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size(); - CompatParams.Push(CP_SETTHINGZ); - sc.MustGetNumber(); - CompatParams.Push(sc.Number); - sc.MustGetFloat(); - CompatParams.Push(int(sc.Float*256)); // do not use full fixed here so that it can eventually handle larger levels - } - else if (sc.Compare("setsectortag")) - { - if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size(); - CompatParams.Push(CP_SETTAG); - sc.MustGetNumber(); - CompatParams.Push(sc.Number); - sc.MustGetNumber(); - CompatParams.Push(sc.Number); - } - else if (sc.Compare("setthingflags")) - { - if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size(); - CompatParams.Push(CP_SETTHINGFLAGS); - sc.MustGetNumber(); - CompatParams.Push(sc.Number); - sc.MustGetNumber(); - CompatParams.Push(sc.Number); - } - else if (sc.Compare("setvertex")) - { - if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size(); - CompatParams.Push(CP_SETVERTEX); - sc.MustGetNumber(); - CompatParams.Push(sc.Number); - sc.MustGetFloat(); - CompatParams.Push(int(sc.Float * 256)); // do not use full fixed here so that it can eventually handle larger levels - sc.MustGetFloat(); - CompatParams.Push(int(sc.Float * 256)); // do not use full fixed here so that it can eventually handle larger levels - flags.CompatFlags[SLOT_BCOMPAT] |= BCOMPATF_REBUILDNODES; - } - else if (sc.Compare("setthingskills")) - { - if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size(); - CompatParams.Push(CP_SETTHINGSKILLS); - sc.MustGetNumber(); - CompatParams.Push(sc.Number); - sc.MustGetNumber(); - CompatParams.Push(sc.Number); - } - else if (sc.Compare("setsectortexture")) - { - if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size(); - CompatParams.Push(CP_SETSECTORTEXTURE); - sc.MustGetNumber(); - CompatParams.Push(sc.Number); - sc.MustGetString(); - CompatParams.Push(sc.MustMatchString(SectorPlanes)); - sc.MustGetString(); - const FString texName = sc.String; - const unsigned int texIndex = TexNames.Find(texName); - const unsigned int texCount = TexNames.Size(); - if (texIndex == texCount) - { - TexNames.Push(texName); - } - CompatParams.Push(texIndex); - } - else if (sc.Compare("setsectorlight")) - { - if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size(); - CompatParams.Push(CP_SETSECTORLIGHT); - sc.MustGetNumber(); - CompatParams.Push(sc.Number); - sc.MustGetNumber(); - CompatParams.Push(sc.Number); - } else { sc.UnGet(); break; } } - if (flags.ExtCommandIndex != ~0u) - { - CompatParams.Push(CP_END); - } sc.MustGetStringName("}"); for (j = 0; j < md5array.Size(); ++j) { @@ -465,7 +269,7 @@ void ParseCompatibility() // //========================================================================== -void CheckCompatibility(MapData *map) +FName CheckCompatibility(MapData *map) { FMD5Holder md5; FCompatValues *flags; @@ -473,7 +277,6 @@ void CheckCompatibility(MapData *map) ii_compatflags = 0; ii_compatflags2 = 0; ib_compatflags = 0; - ii_compatparams = -1; // When playing Doom IWAD levels force COMPAT_SHORTTEX and COMPATF_LIGHT. // I'm not sure if the IWAD maps actually need COMPATF_LIGHT but it certainly does not hurt. @@ -488,13 +291,16 @@ void CheckCompatibility(MapData *map) flags = BCompatMap.CheckKey(md5); + FString hash; + + for (size_t j = 0; j < sizeof(md5.Bytes); ++j) + { + hash.AppendFormat("%02X", md5.Bytes[j]); + } + if (developer >= DMSG_NOTIFY) { - Printf("MD5 = "); - for (size_t j = 0; j < sizeof(md5.Bytes); ++j) - { - Printf("%02X", md5.Bytes[j]); - } + Printf("MD5 = %s", hash.GetChars()); if (flags != NULL) { Printf(", cflags = %08x, cflags2 = %08x, bflags = %08x\n", @@ -511,7 +317,6 @@ void CheckCompatibility(MapData *map) ii_compatflags |= flags->CompatFlags[SLOT_COMPAT]; ii_compatflags2 |= flags->CompatFlags[SLOT_COMPAT2]; ib_compatflags |= flags->CompatFlags[SLOT_BCOMPAT]; - ii_compatparams = flags->ExtCommandIndex; } // Reset i_compatflags @@ -522,6 +327,7 @@ void CheckCompatibility(MapData *map) { ib_compatflags |= BCOMPATF_FLOATBOB; } + return FName(hash, true); // if this returns NAME_None it means there is no scripted compatibility handler. } //========================================================================== @@ -530,229 +336,130 @@ void CheckCompatibility(MapData *map) // //========================================================================== -void SetCompatibilityParams() +void SetCompatibilityParams(FName checksum) { - if (ii_compatparams != -1) + if (checksum != NAME_None) { - unsigned i = ii_compatparams; - - while (i < CompatParams.Size() && CompatParams[i] != CP_END) + PClass *const cls = PClass::FindClass("LevelCompatibility"); + if (cls != nullptr) { - switch (CompatParams[i]) + PFunction *const func = dyn_cast(cls->FindSymbol("Apply", true)); + if (func != nullptr) { - case CP_CLEARFLAGS: - { - if ((unsigned)CompatParams[i+1] < level.lines.Size()) - { - line_t *line = &level.lines[CompatParams[i+1]]; - line->flags &= ~CompatParams[i+2]; - } - i+=3; - break; - } - case CP_SETFLAGS: - { - if ((unsigned)CompatParams[i+1] < level.lines.Size()) - { - line_t *line = &level.lines[CompatParams[i+1]]; - line->flags |= CompatParams[i+2]; - } - i+=3; - break; - } - case CP_SETSPECIAL: - { - if ((unsigned)CompatParams[i+1] < level.lines.Size()) - { - line_t *line = &level.lines[CompatParams[i+1]]; - line->special = CompatParams[i+2]; - for(int ii=0;ii<5;ii++) - { - line->args[ii] = CompatParams[i+ii+3]; - } - } - i+=8; - break; - } - case CP_CLEARSPECIAL: - { - if ((unsigned)CompatParams[i+1] < level.lines.Size()) - { - line_t *line = &level.lines[CompatParams[i+1]]; - line->special = 0; - memset(line->args, 0, sizeof(line->args)); - } - i += 2; - break; - } - case CP_SETACTIVATION: - { - if ((unsigned)CompatParams[i+1] < level.lines.Size()) - { - line_t *line = &level.lines[CompatParams[i+1]]; - line->activation = CompatParams[i+2]; - } - i += 3; - break; - } - case CP_SETSECTOROFFSET: - { - if ((unsigned)CompatParams[i+1] < level.sectors.Size()) - { - sector_t *sec = &level.sectors[CompatParams[i+1]]; - const double delta = CompatParams[i + 3] / 65536.0; - secplane_t& plane = sector_t::floor == CompatParams[i + 2] - ? sec->floorplane - : sec->ceilingplane; - plane.ChangeHeight(delta); - sec->ChangePlaneTexZ(CompatParams[i + 2], delta); - } - i += 4; - break; - } - case CP_SETSECTORSPECIAL: - { - const unsigned index = CompatParams[i + 1]; - if (index < level.sectors.Size()) - { - level.sectors[index].special = CompatParams[i + 2]; - } - i += 3; - break; - } - case CP_SETWALLYSCALE: - { - if ((unsigned)CompatParams[i+1] < level.lines.Size()) - { - side_t *side = level.lines[CompatParams[i+1]].sidedef[CompatParams[i+2]]; - if (side != NULL) - { - side->SetTextureYScale(CompatParams[i+3], CompatParams[i+4] / 65536.); - } - } - i += 5; - break; - } - case CP_SETWALLTEXTURE: - { - if ((unsigned)CompatParams[i + 1] < level.lines.Size()) - { - side_t *side = level.lines[CompatParams[i + 1]].sidedef[CompatParams[i + 2]]; - if (side != NULL) - { - assert(TexNames.Size() > (unsigned int)CompatParams[i + 4]); - const FTextureID texID = TexMan.GetTexture(TexNames[CompatParams[i + 4]], ETextureType::Any); - side->SetTexture(CompatParams[i + 3], texID); - } - } - i += 5; - break; - } - case CP_SETTHINGZ: - { - // When this is called, the things haven't been spawned yet so we can alter the position inside the MapThings array. - if ((unsigned)CompatParams[i+1] < MapThingsConverted.Size()) - { - MapThingsConverted[CompatParams[i+1]].pos.Z = CompatParams[i+2]/256.; - } - i += 3; - break; - } - case CP_SETTAG: - { - if ((unsigned)CompatParams[i + 1] < level.sectors.Size()) - { - // this assumes that the sector does not have any tags yet! - if (CompatParams[i + 2] == 0) - { - tagManager.RemoveSectorTags(CompatParams[i + 1]); - } - else - { - tagManager.AddSectorTag(CompatParams[i + 1], CompatParams[i + 2]); - } - } - i += 3; - break; - } - case CP_SETTHINGFLAGS: - { - if ((unsigned)CompatParams[i + 1] < MapThingsConverted.Size()) - { - MapThingsConverted[CompatParams[i + 1]].flags = CompatParams[i + 2]; - } - i += 3; - break; - } - case CP_SETVERTEX: - { - if ((unsigned)CompatParams[i + 1] < level.vertexes.Size()) - { - level.vertexes[CompatParams[i + 1]].p.X = CompatParams[i + 2] / 256.; - level.vertexes[CompatParams[i + 1]].p.Y = CompatParams[i + 3] / 256.; - } - i += 4; - break; - } - case CP_SETTHINGSKILLS: - { - if ((unsigned)CompatParams[i + 1] < MapThingsConverted.Size()) - { - MapThingsConverted[CompatParams[i + 1]].SkillFilter = CompatParams[i + 2]; - } - i += 3; - break; - } - case CP_SETSECTORTEXTURE: - { - if ((unsigned)CompatParams[i + 1] < level.sectors.Size()) - { - sector_t *sec = &level.sectors[CompatParams[i+1]]; - assert (sec != nullptr); - secplane_t& plane = sector_t::floor == CompatParams[i + 2] - ? sec->floorplane - : sec->ceilingplane; - assert(TexNames.Size() > (unsigned int)CompatParams[i + 3]); - const FTextureID texID = TexMan.GetTexture(TexNames[CompatParams[i + 3]], ETextureType::Any); - - sec->SetTexture(CompatParams[i + 2], texID); - } - i += 4; - break; - } - case CP_SETSECTORLIGHT: - { - if ((unsigned)CompatParams[i + 1] < level.sectors.Size()) - { - sector_t *sec = &level.sectors[CompatParams[i+1]]; - assert (sec != nullptr); - - sec->SetLightLevel((unsigned)CompatParams[i + 2]); - } - i += 3; - break; - } - case CP_SETLINESECTORREF: - { - if ((unsigned)CompatParams[i + 1] < level.lines.Size()) - { - line_t *line = &level.lines[CompatParams[i + 1]]; - assert(line != nullptr); - side_t *side = line->sidedef[CompatParams[i + 2]]; - if (side != nullptr && (unsigned)CompatParams[i + 3] < level.sectors.Size()) - { - side->sector = &level.sectors[CompatParams[i + 3]]; - } - } - i += 4; - break; - } - + VMValue param = { (int)checksum }; + VMCall(func->Variants[0].Implementation, ¶m, 1, nullptr, 0); } } } } +DEFINE_ACTION_FUNCTION(DLevelCompatibility, OffsetSectorPlane) +{ + PARAM_PROLOGUE; + PARAM_INT(sector); + PARAM_INT(planeval); + PARAM_FLOAT(delta); + + sector_t *sec = &level.sectors[sector]; + secplane_t& plane = sector_t::floor == planeval? sec->floorplane : sec->ceilingplane; + plane.ChangeHeight(delta); + sec->ChangePlaneTexZ(planeval, delta); + return 0; +} + +DEFINE_ACTION_FUNCTION(DLevelCompatibility, ClearSectorTags) +{ + PARAM_PROLOGUE; + PARAM_INT(sector); + tagManager.RemoveSectorTags(sector); + return 0; +} + +DEFINE_ACTION_FUNCTION(DLevelCompatibility, AddSectorTag) +{ + PARAM_PROLOGUE; + PARAM_INT(sector); + PARAM_INT(tag); + tagManager.AddSectorTag(sector, tag); + return 0; +} + +DEFINE_ACTION_FUNCTION(DLevelCompatibility, SetThingSkills) +{ + PARAM_PROLOGUE; + PARAM_INT(thing); + PARAM_INT(skillmask); + + if ((unsigned)thing < MapThingsConverted.Size()) + { + MapThingsConverted[thing].SkillFilter = skillmask; + } + return 0; +} + +DEFINE_ACTION_FUNCTION(DLevelCompatibility, SetThingZ) +{ + PARAM_PROLOGUE; + PARAM_INT(thing); + PARAM_FLOAT(z); + + if ((unsigned)thing < MapThingsConverted.Size()) + { + MapThingsConverted[thing].pos.Z = z; + } + return 0; +} + +DEFINE_ACTION_FUNCTION(DLevelCompatibility, SetThingFlags) +{ + PARAM_PROLOGUE; + PARAM_INT(thing); + PARAM_INT(flags); + + if ((unsigned)thing < MapThingsConverted.Size()) + { + MapThingsConverted[thing].flags = flags; + } + return 0; +} + +DEFINE_ACTION_FUNCTION(DLevelCompatibility, SetVertex) +{ + PARAM_PROLOGUE; + PARAM_UINT(vertex); + PARAM_FLOAT(x); + PARAM_FLOAT(y); + + if (vertex < level.vertexes.Size()) + { + level.vertexes[vertex].p = DVector2(x, y); + } + ForceNodeBuild = true; + return 0; +} + +DEFINE_ACTION_FUNCTION(DLevelCompatibility, SetLineSectorRef) +{ + PARAM_PROLOGUE; + PARAM_UINT(lineidx); + PARAM_UINT(sideidx); + PARAM_UINT(sectoridx); + + if ( sideidx < 2 + && lineidx < level.lines.Size() + && sectoridx < level.sectors.Size()) + { + line_t *line = &level.lines[lineidx]; + side_t *side = line->sidedef[sideidx]; + side->sector = &level.sectors[sectoridx]; + if (sideidx == 0) line->frontsector = side->sector; + else line->backsector = side->sector; + } + ForceNodeBuild = true; + return 0; +} + + //========================================================================== // // CCMD mapchecksum @@ -799,3 +506,4 @@ CCMD (hiddencompatflags) { Printf("%08x %08x %08x\n", ii_compatflags, ii_compatflags2, ib_compatflags); } + diff --git a/src/compatibility.h b/src/compatibility.h index 125f83f34c..e219f5d0a0 100644 --- a/src/compatibility.h +++ b/src/compatibility.h @@ -36,7 +36,7 @@ struct FMD5HashTraits extern TMap BCompatMap; void ParseCompatibility(); -void CheckCompatibility(MapData *map); -void SetCompatibilityParams(); +FName CheckCompatibility(MapData *map); +void SetCompatibilityParams(FName); #endif diff --git a/src/ct_chat.cpp b/src/ct_chat.cpp index 34a5ee9703..baaa34db56 100644 --- a/src/ct_chat.cpp +++ b/src/ct_chat.cpp @@ -274,8 +274,6 @@ void CT_Drawer (void) screen->DrawText (SmallFont, CR_GREY, promptwidth, y, (char *)(ChatQueue + i), DTA_VirtualWidth, screen_width, DTA_VirtualHeight, screen_height, DTA_KeepRatio, true, TAG_DONE); ChatQueue[len] = '\0'; - - BorderTopRefresh = screen->GetPageCount (); } if (players[consoleplayer].camera != NULL && diff --git a/src/d_main.cpp b/src/d_main.cpp index 69298aa4d4..92086e18b9 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -176,6 +176,7 @@ extern bool gameisdead; extern bool demorecording; extern bool M_DemoNoPlay; // [RH] if true, then skip any demos in the loop extern bool insave; +extern TDeletingArray LightDefaults; // PUBLIC DATA DEFINITIONS ------------------------------------------------- @@ -669,7 +670,6 @@ CVAR (Flag, compat_pushwindow, compatflags2, COMPATF2_PUSHWINDOW); void D_Display () { bool wipe; - bool hw2d; if (nodrawers || screen == NULL) return; // for comparative timing / profiling @@ -680,7 +680,7 @@ void D_Display () cycles.Clock(); r_UseVanillaTransparency = UseVanillaTransparency(); // [SP] Cache UseVanillaTransparency() call - r_renderercaps = Renderer->GetCaps(); // [SP] Get the current capabilities of the renderer + r_renderercaps = screen->GetCaps(); // [SP] Get the current capabilities of the renderer if (players[consoleplayer].camera == NULL) { @@ -703,13 +703,6 @@ void D_Display () // [RH] change the screen mode if needed if (setmodeneeded) { - int oldrenderer; - extern int currentrenderer; - EXTERN_CVAR(Int, vid_renderer) - oldrenderer = vid_renderer; // [SP] Save pending vid_renderer setting (hack) - if (currentrenderer != vid_renderer) - vid_renderer = currentrenderer; - // Change screen mode. if (Video->SetResolution (NewWidth, NewHeight, NewBits)) { @@ -728,7 +721,6 @@ void D_Display () // Reset the mouse cursor in case the bit depth changed vid_cursor.Callback(); } - vid_renderer = oldrenderer; // [SP] Restore pending vid_renderer setting } // change the view size if needed @@ -738,22 +730,15 @@ void D_Display () } setmodeneeded = false; - if (screen->Lock (false)) - { - V_SetBorderNeedRefresh(); - } - // [RH] Allow temporarily disabling wipes if (NoWipe) { - V_SetBorderNeedRefresh(); NoWipe--; wipe = false; wipegamestate = gamestate; } else if (gamestate != wipegamestate && gamestate != GS_FULLCONSOLE && gamestate != GS_TITLELEVEL) { // save the current screen if about to wipe - V_SetBorderNeedRefresh(); switch (wipegamestate) { default: @@ -779,9 +764,6 @@ void D_Display () wipe = false; } - hw2d = false; - - { screen->FrameTime = I_msTimeFS(); TexMan.UpdateAnimations(screen->FrameTime); @@ -790,8 +772,8 @@ void D_Display () { case GS_FULLCONSOLE: screen->SetBlendingRect(0,0,0,0); - hw2d = screen->Begin2D(false); - C_DrawConsole (false); + screen->Begin2D(false); + C_DrawConsole (); M_Drawer (); screen->Update (); return; @@ -800,40 +782,22 @@ void D_Display () case GS_TITLELEVEL: if (!gametic) { - if (!screen->HasBegun2D()) - { - screen->Begin2D(false); - } + screen->Begin2D(false); break; } - if (StatusBar != NULL) - { - float blend[4] = { 0, 0, 0, 0 }; - StatusBar->BlendView (blend); - } - screen->SetBlendingRect(viewwindowx, viewwindowy, - viewwindowx + viewwidth, viewwindowy + viewheight); - // [ZZ] execute event hook that we just started the frame //E_RenderFrame(); // - Renderer->RenderView(&players[consoleplayer]); - - if ((hw2d = screen->Begin2D(viewactive))) - { - // Redraw everything every frame when using 2D accel - V_SetBorderNeedRefresh(); - } - Renderer->DrawRemainingPlayerSprites(); - screen->DrawBlendingRect(); + screen->RenderView(&players[consoleplayer]); + // returns with 2S mode set. if (automapactive) { AM_Drawer (hud_althud? viewheight : StatusBar->GetTopOfStatusbar()); } if (!automapactive || viewactive) { - V_RefreshViewBorder (); + screen->RefreshViewBorder (); } // for timing the statusbar code. @@ -872,21 +836,21 @@ void D_Display () case GS_INTERMISSION: screen->SetBlendingRect(0,0,0,0); - hw2d = screen->Begin2D(false); + screen->Begin2D(false); WI_Drawer (); CT_Drawer (); break; case GS_FINALE: screen->SetBlendingRect(0,0,0,0); - hw2d = screen->Begin2D(false); + screen->Begin2D(false); F_Drawer (); CT_Drawer (); break; case GS_DEMOSCREEN: screen->SetBlendingRect(0,0,0,0); - hw2d = screen->Begin2D(false); + screen->Begin2D(false); D_PageDrawer (); CT_Drawer (); break; @@ -904,7 +868,7 @@ void D_Display () tex = TexMan(gameinfo.PauseSign); x = (SCREENWIDTH - tex->GetScaledWidth() * CleanXfac)/2 + - tex->GetScaledLeftOffset() * CleanXfac; + tex->GetScaledLeftOffset(0) * CleanXfac; screen->DrawTexture (tex, x, 4, DTA_CleanNoMove, true, TAG_DONE); if (paused && multiplayer) { @@ -940,7 +904,7 @@ void D_Display () NetUpdate (); // send out any new accumulation // normal update // draw ZScript UI stuff - C_DrawConsole (hw2d); // draw console + C_DrawConsole (); // draw console M_Drawer (); // menu is drawn even on top of everything FStat::PrintStat (); screen->Update (); // page flip or blit buffer @@ -968,7 +932,7 @@ void D_Display () } while (diff < 1); wipestart = nowtime; done = screen->WipeDo (1); - C_DrawConsole (hw2d); // console and + C_DrawConsole (); // console and M_Drawer (); // menu are drawn even on top of wipes screen->Update (); // page flip or blit buffer NetUpdate (); // [RH] not sure this is needed anymore @@ -992,7 +956,6 @@ void D_Display () void D_ErrorCleanup () { savegamerestore = false; - screen->Unlock (); bglobal.RemoveAllBots (true); D_QuitNetGame (); if (demorecording || demoplayback) @@ -1326,7 +1289,6 @@ void D_DoAdvanceDemo (void) Advisory = NULL; if (!M_DemoNoPlay) { - V_SetBorderNeedRefresh(); democount++; mysnprintf (demoname + 4, countof(demoname) - 4, "%d", democount); if (Wads.CheckNumForName (demoname) < 0) @@ -2293,6 +2255,7 @@ static void CheckCmdLine() } } + //========================================================================== // // D_DoomMain @@ -2477,7 +2440,6 @@ void D_DoomMain (void) { if (!batchrun) Printf ("I_Init: Setting up machine state.\n"); I_Init (); - I_CreateRenderer(); } if (!batchrun) Printf ("V_Init: allocate screen.\n"); @@ -2675,7 +2637,7 @@ void D_DoomMain (void) } V_Init2(); - gl_PatchMenu(); + gl_PatchMenu(); // removes unapplicable entries for old hardware. This cannot be done in MENUDEF because at the point it gets parsed it doesn't have the needed info. UpdateJoystickMenu(NULL); v = Args->CheckValue ("-loadgame"); @@ -2744,7 +2706,6 @@ void D_DoomMain (void) // These calls from inside V_Init2 are still necessary C_NewModeAdjust(); M_InitVideoModesMenu(); - Renderer->RemapVoxels(); D_StartTitle (); // start up intro loop setmodeneeded = false; // This may be set to true here, but isn't needed for a restart } @@ -2777,6 +2738,7 @@ void D_DoomMain (void) M_SaveDefaults(NULL); // save config before the restart // delete all data that cannot be left until reinitialization + screen->CleanForRestart(); V_ClearFonts(); // must clear global font pointers ColorSets.Clear(); PainFlashes.Clear(); @@ -2788,6 +2750,7 @@ void D_DoomMain (void) DestroyCVarsFlagged(CVAR_MOD); // Delete any cvar left by mods FS_Close(); // destroy the global FraggleScript. DeinitMenus(); + LightDefaults.Clear(); // this can leak heap memory if it isn't cleared. // delete DoomStartupInfo data DoomStartupInfo.Name = (const char*)0; diff --git a/src/d_net.cpp b/src/d_net.cpp index 7681626d0e..ec26da5847 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -2412,7 +2412,6 @@ void Net_DoCommand (int type, uint8_t **stream, int player) paused = player + 1; S_PauseSound (false, false); } - V_SetBorderNeedRefresh(); } break; diff --git a/src/d_stats.cpp b/src/d_stats.cpp index c4fb6d1a59..dbc0a1e5db 100644 --- a/src/d_stats.cpp +++ b/src/d_stats.cpp @@ -1,4 +1,4 @@ - +#define NO_SEND_STATS #ifdef NO_SEND_STATS void D_DoAnonStats() @@ -36,8 +36,6 @@ extern int sys_ostype; #include "version.h" #include "v_video.h" -EXTERN_CVAR(Bool, vid_glswfb) -extern int currentrenderer; CVAR(Int, sys_statsenabled, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOSET) CVAR(String, sys_statshost, "gzstats.drdteam.org", CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOSET) CVAR(Int, sys_statsport, 80, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOSET) @@ -252,34 +250,17 @@ static int GetCoreInfo() static int GetRenderInfo() { - if (currentrenderer == 0) - { - if (!screen->Accel2D) return 0; - if (vid_glswfb) return 2; - if (screen->LegacyHardware()) return 6; - return 1; - } - else - { - auto info = gl_getInfo(); - if (info.first < 3.3) return 3; // Legacy OpenGL. Don't care about Intel HD 3000 on Windows being run in 'risky' mode. - if (!info.second) return 4; - return 5; - } + auto info = gl_getInfo(); + if (info.first < 3.3) return 3; // Legacy OpenGL. Don't care about Intel HD 3000 on Windows being run in 'risky' mode. + if (!info.second) return 4; + return 5; } static void D_DoHTTPRequest(const char *request) { if (I_HTTPRequest(request)) { - if (currentrenderer == 0) - { - cvar_forceset("sentstats_swr_done", CHECKVERSIONSTR); - } - else - { - cvar_forceset("sentstats_hwr_done", CHECKVERSIONSTR); - } + cvar_forceset("sentstats_hwr_done", CHECKVERSIONSTR); } } @@ -295,12 +276,11 @@ void D_DoAnonStats() done = true; // Do not repeat if already sent. - if (currentrenderer == 0 && sentstats_swr_done >= CHECKVERSION) return; - if (currentrenderer == 1 && sentstats_hwr_done >= CHECKVERSION) return; + if (sentstats_hwr_done >= CHECKVERSION) return; static char requeststring[1024]; mysnprintf(requeststring, sizeof requeststring, "GET /stats.py?render=%i&cores=%i&os=%i&renderconfig=%i HTTP/1.1\nHost: %s\nConnection: close\nUser-Agent: %s %s\n\n", - GetRenderInfo(), GetCoreInfo(), GetOSVersion(), currentrenderer, sys_statshost.GetHumanString(), GAMENAME, VERSIONSTR); + GetRenderInfo(), GetCoreInfo(), GetOSVersion(), V_IsHardwareRenderer(), sys_statshost.GetHumanString(), GAMENAME, VERSIONSTR); DPrintf(DMSG_NOTIFY, "Sending %s", requeststring); std::thread t1(D_DoHTTPRequest, requeststring); t1.detach(); diff --git a/src/doomstat.cpp b/src/doomstat.cpp index e02dc44579..01cfea36a6 100644 --- a/src/doomstat.cpp +++ b/src/doomstat.cpp @@ -70,6 +70,5 @@ int NextSkill = -1; int SinglePlayerClass[MAXPLAYERS]; bool ToggleFullscreen; -int BorderTopRefresh; FString LumpFilterIWAD; diff --git a/src/doomstat.h b/src/doomstat.h index 3e76d7f2f7..e0cd34b48b 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -192,9 +192,6 @@ extern bool precache; extern bool setsizeneeded; extern bool setmodeneeded; -extern int BorderNeedRefresh; -extern int BorderTopRefresh; - EXTERN_CVAR (Float, mouse_sensitivity) //? diff --git a/src/doomtype.h b/src/doomtype.h index 8235e08f3e..da2620a7cb 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -196,6 +196,7 @@ enum class ETextureType : uint8_t SkinGraphic, Null, FirstDefined, + SWCanvas, }; class FTextureID diff --git a/src/f_wipe.cpp b/src/f_wipe.cpp index 02a9268e7d..f47106839f 100644 --- a/src/f_wipe.cpp +++ b/src/f_wipe.cpp @@ -32,148 +32,6 @@ #include "templates.h" #include "v_palette.h" -EXTERN_CVAR(Bool, r_blendmethod) - -// -// SCREEN WIPE PACKAGE -// - -static int CurrentWipeType; - -static short *wipe_scr_start; -static short *wipe_scr_end; -static int *y; - -// [RH] Fire Wipe -#define FIREWIDTH 64 -#define FIREHEIGHT 64 -static uint8_t *burnarray; -static int density; -static int burntime; - -// [RH] Crossfade -static int fade; - - -// Melt ------------------------------------------------------------- - -// Match the strip sizes that oldschool Doom used on a 320x200 screen. -#define MELT_WIDTH 160 -#define MELT_HEIGHT 200 - -void wipe_shittyColMajorXform (short *array) -{ - int x, y; - short *dest; - int width = SCREENWIDTH / 2; - - dest = new short[width*SCREENHEIGHT*2]; - - for(y = 0; y < SCREENHEIGHT; y++) - for(x = 0; x < width; x++) - dest[x*SCREENHEIGHT+y] = array[y*width+x]; - - memcpy(array, dest, SCREENWIDTH*SCREENHEIGHT); - - delete[] dest; -} - -bool wipe_initMelt (int ticks) -{ - int i, r; - - // copy start screen to main screen - screen->DrawBlock (0, 0, SCREENWIDTH, SCREENHEIGHT, (uint8_t *)wipe_scr_start); - - // makes this wipe faster (in theory) - // to have stuff in column-major format - wipe_shittyColMajorXform (wipe_scr_start); - wipe_shittyColMajorXform (wipe_scr_end); - - // setup initial column positions - // (y<0 => not ready to scroll yet) - y = new int[MELT_WIDTH]; - y[0] = -(M_Random() & 15); - for (i = 1; i < MELT_WIDTH; i++) - { - r = (M_Random()%3) - 1; - y[i] = clamp(y[i-1] + r, -15, 0); - } - - return 0; -} - -bool wipe_doMelt (int ticks) -{ - int i, j, dy, x; - const short *s; - short *d; - bool done = true; - - while (ticks--) - { - done = true; - for (i = 0; i < MELT_WIDTH; i++) - { - if (y[i] < 0) - { - y[i]++; - done = false; - } - else if (y[i] < MELT_HEIGHT) - { - dy = (y[i] < 16) ? y[i]+1 : 8; - y[i] = MIN(y[i] + dy, MELT_HEIGHT); - done = false; - } - if (ticks == 0 && y[i] >= 0) - { // Only draw for the final tick. - const int pitch = screen->GetPitch() / 2; - int sy = y[i] * SCREENHEIGHT / MELT_HEIGHT; - - for (x = i * (SCREENWIDTH/2) / MELT_WIDTH; x < (i + 1) * (SCREENWIDTH/2) / MELT_WIDTH; ++x) - { - s = &wipe_scr_end[x*SCREENHEIGHT]; - d = &((short *)screen->GetBuffer())[x]; - - for (j = sy; j != 0; --j) - { - *d = *(s++); - d += pitch; - } - - s = &wipe_scr_start[x*SCREENHEIGHT]; - - for (j = SCREENHEIGHT - sy; j != 0; --j) - { - *d = *(s++); - d += pitch; - } - } - } - } - } - - return done; -} - -bool wipe_exitMelt (int ticks) -{ - delete[] y; - return 0; -} - -// Burn ------------------------------------------------------------- - -bool wipe_initBurn (int ticks) -{ - burnarray = new uint8_t[FIREWIDTH * (FIREHEIGHT+5)]; - memset (burnarray, 0, FIREWIDTH * (FIREHEIGHT+5)); - density = 4; - burntime = 0; - return 0; -} - int wipe_CalcBurn (uint8_t *burnarray, int width, int height, int density) { // This is a modified version of the fire that was once used @@ -258,263 +116,3 @@ int wipe_CalcBurn (uint8_t *burnarray, int width, int height, int density) return -1; } -bool wipe_doBurn (int ticks) -{ - bool done; - - burntime += ticks; - ticks *= 2; - - // Make the fire burn - done = false; - while (!done && ticks--) - { - density = wipe_CalcBurn(burnarray, FIREWIDTH, FIREHEIGHT, density); - done = (density < 0); - } - - // Draw the screen - int xstep, ystep, firex, firey; - int x, y; - uint8_t *to, *fromold, *fromnew; - const int SHIFT = 16; - - xstep = (FIREWIDTH << SHIFT) / SCREENWIDTH; - ystep = (FIREHEIGHT << SHIFT) / SCREENHEIGHT; - to = screen->GetBuffer(); - fromold = (uint8_t *)wipe_scr_start; - fromnew = (uint8_t *)wipe_scr_end; - - if (!r_blendmethod) - { - for (y = 0, firey = 0; y < SCREENHEIGHT; y++, firey += ystep) - { - for (x = 0, firex = 0; x < SCREENWIDTH; x++, firex += xstep) - { - int fglevel; - - fglevel = burnarray[(firex>>SHIFT)+(firey>>SHIFT)*FIREWIDTH] / 2; - if (fglevel >= 63) - { - to[x] = fromnew[x]; - } - else if (fglevel == 0) - { - to[x] = fromold[x]; - done = false; - } - else - { - int bglevel = 64-fglevel; - uint32_t *fg2rgb = Col2RGB8[fglevel]; - uint32_t *bg2rgb = Col2RGB8[bglevel]; - uint32_t fg = fg2rgb[fromnew[x]]; - uint32_t bg = bg2rgb[fromold[x]]; - fg = (fg+bg) | 0x1f07c1f; - to[x] = RGB32k.All[fg & (fg>>15)]; - done = false; - } - } - fromold += SCREENWIDTH; - fromnew += SCREENWIDTH; - to += SCREENPITCH; - } - - } - else - { - for (y = 0, firey = 0; y < SCREENHEIGHT; y++, firey += ystep) - { - for (x = 0, firex = 0; x < SCREENWIDTH; x++, firex += xstep) - { - int fglevel; - - fglevel = burnarray[(firex>>SHIFT)+(firey>>SHIFT)*FIREWIDTH] / 2; - if (fglevel >= 63) - { - to[x] = fromnew[x]; - } - else if (fglevel == 0) - { - to[x] = fromold[x]; - done = false; - } - else - { - int bglevel = 64-fglevel; - - const PalEntry* pal = GPalette.BaseColors; - - uint32_t fg = fromnew[x]; - uint32_t bg = fromold[x]; - int r = MIN((pal[fg].r * fglevel + pal[bg].r * bglevel) >> 8, 63); - int g = MIN((pal[fg].g * fglevel + pal[bg].g * bglevel) >> 8, 63); - int b = MIN((pal[fg].b * fglevel + pal[bg].b * bglevel) >> 8, 63); - to[x] = RGB256k.RGB[r][g][b]; - done = false; - } - } - fromold += SCREENWIDTH; - fromnew += SCREENWIDTH; - to += SCREENPITCH; - } - } - return done || (burntime > 40); -} - -bool wipe_exitBurn (int ticks) -{ - delete[] burnarray; - return 0; -} - -// Crossfade -------------------------------------------------------- - -bool wipe_initFade (int ticks) -{ - fade = 0; - return 0; -} - -bool wipe_doFade (int ticks) -{ - fade += ticks * 2; - if (fade > 64) - { - screen->DrawBlock (0, 0, SCREENWIDTH, SCREENHEIGHT, (uint8_t *)wipe_scr_end); - return true; - } - else - { - int x, y; - int bglevel = 64 - fade; - uint32_t *fg2rgb = Col2RGB8[fade]; - uint32_t *bg2rgb = Col2RGB8[bglevel]; - uint8_t *fromnew = (uint8_t *)wipe_scr_end; - uint8_t *fromold = (uint8_t *)wipe_scr_start; - uint8_t *to = screen->GetBuffer(); - const PalEntry *pal = GPalette.BaseColors; - - if (!r_blendmethod) - { - for (y = 0; y < SCREENHEIGHT; y++) - { - for (x = 0; x < SCREENWIDTH; x++) - { - uint32_t fg = fg2rgb[fromnew[x]]; - uint32_t bg = bg2rgb[fromold[x]]; - fg = (fg+bg) | 0x1f07c1f; - to[x] = RGB32k.All[fg & (fg>>15)]; - } - fromnew += SCREENWIDTH; - fromold += SCREENWIDTH; - to += SCREENPITCH; - } - } - else - { - for (y = 0; y < SCREENHEIGHT; y++) - { - for (x = 0; x < SCREENWIDTH; x++) - { - uint32_t fg = fromnew[x]; - uint32_t bg = fromold[x]; - int r = MIN((pal[fg].r * (64-bglevel) + pal[bg].r * bglevel) >> 8, 63); - int g = MIN((pal[fg].g * (64-bglevel) + pal[bg].g * bglevel) >> 8, 63); - int b = MIN((pal[fg].b * (64-bglevel) + pal[bg].b * bglevel) >> 8, 63); - to[x] = RGB256k.RGB[r][g][b]; - } - fromnew += SCREENWIDTH; - fromold += SCREENWIDTH; - to += SCREENPITCH; - } - } - } - return false; -} - -bool wipe_exitFade (int ticks) -{ - return 0; -} - -// General Wipe Functions ------------------------------------------- - -static bool (*wipes[])(int) = -{ - wipe_initMelt, wipe_doMelt, wipe_exitMelt, - wipe_initBurn, wipe_doBurn, wipe_exitBurn, - wipe_initFade, wipe_doFade, wipe_exitFade -}; - -// Returns true if the wipe should be performed. -bool wipe_StartScreen (int type) -{ - if (screen->IsBgra()) - return false; - - CurrentWipeType = clamp(type, 0, wipe_NUMWIPES - 1); - - if (CurrentWipeType) - { - wipe_scr_start = new short[SCREENWIDTH * SCREENHEIGHT / 2]; - screen->GetBlock (0, 0, SCREENWIDTH, SCREENHEIGHT, (uint8_t *)wipe_scr_start); - return true; - } - return false; -} - -void wipe_EndScreen (void) -{ - if (screen->IsBgra()) - return; - - if (CurrentWipeType) - { - wipe_scr_end = new short[SCREENWIDTH * SCREENHEIGHT / 2]; - screen->GetBlock (0, 0, SCREENWIDTH, SCREENHEIGHT, (uint8_t *)wipe_scr_end); - screen->DrawBlock (0, 0, SCREENWIDTH, SCREENHEIGHT, (uint8_t *)wipe_scr_start); // restore start scr. - - // Initialize the wipe - (*wipes[(CurrentWipeType-1)*3])(0); - } -} - -// Returns true if the wipe is done. -bool wipe_ScreenWipe (int ticks) -{ - bool rc; - - if (screen->IsBgra()) - return true; - - if (CurrentWipeType == wipe_None) - return true; - - // do a piece of wipe-in - rc = (*wipes[(CurrentWipeType-1)*3+1])(ticks); - - return rc; -} - -// Final things for the wipe -void wipe_Cleanup() -{ - if (screen->IsBgra()) - return; - - if (wipe_scr_start != NULL) - { - delete[] wipe_scr_start; - wipe_scr_start = NULL; - } - if (wipe_scr_end != NULL) - { - delete[] wipe_scr_end; - wipe_scr_end = NULL; - } - if (CurrentWipeType > 0) - { - (*wipes[(CurrentWipeType-1)*3+2])(0); - } -} diff --git a/src/f_wipe.h b/src/f_wipe.h index a9296745d2..dc4cfb8cc4 100644 --- a/src/f_wipe.h +++ b/src/f_wipe.h @@ -30,6 +30,7 @@ // SCREEN WIPE PACKAGE // +#if 0 bool wipe_StartScreen (int type); void wipe_EndScreen (void); bool wipe_ScreenWipe (int ticks); @@ -37,7 +38,8 @@ void wipe_Cleanup (); // The buffer must have an additional 5 rows not included in height // to use for a seeding area. -int wipe_CalcBurn (uint8_t *buffer, int width, int height, int density); +#endif +int wipe_CalcBurn(uint8_t *buffer, int width, int height, int density); enum { diff --git a/src/g_game.cpp b/src/g_game.cpp index 2f539b48e5..3fdf551005 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -2247,7 +2247,7 @@ static void PutSavePic (FileWriter *file, int width, int height) } else { - Renderer->WriteSavePic(&players[consoleplayer], file, width, height); + screen->WriteSavePic(&players[consoleplayer], file, width, height); } } diff --git a/src/g_level.cpp b/src/g_level.cpp index 59ba0a07b3..095e8cd2cf 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -117,6 +117,31 @@ EXTERN_CVAR (String, playerclass) void G_VerifySkill(); +CUSTOM_CVAR(Bool, gl_brightfog, false, CVAR_ARCHIVE | CVAR_NOINITCALL) +{ + if (level.info->brightfog == -1) level.brightfog = self; +} + +CUSTOM_CVAR(Bool, gl_lightadditivesurfaces, false, CVAR_ARCHIVE | CVAR_NOINITCALL) +{ + if (level.info->lightadditivesurfaces == -1) level.lightadditivesurfaces = self; +} + +CUSTOM_CVAR(Bool, gl_notexturefill, false, CVAR_NOINITCALL) +{ + if (level.info->notexturefill == -1) level.notexturefill = self; +} + +CUSTOM_CVAR(Int, gl_lightmode, 3, CVAR_ARCHIVE | CVAR_NOINITCALL) +{ + int newself = self; + if (newself > 4) newself = 8; // use 8 for software lighting to avoid conflicts with the bit mask + if (newself < 0) newself = 0; + if (self != newself) self = newself; + else if ((level.info == nullptr || level.info->lightmode == -1)) level.lightmode = self; +} + + static FRandom pr_classchoice ("RandomPlayerClassChoice"); @@ -498,7 +523,6 @@ void G_InitNew (const char *mapname, bool bTitleLevel) demoplayback = false; automapactive = false; viewactive = true; - V_SetBorderNeedRefresh(); //Added by MC: Initialize bots. if (!deathmatch) @@ -1491,6 +1515,12 @@ void G_InitLevelLocals () compatflags2.Callback(); level.DefaultEnvironment = info->DefaultEnvironment; + + level.lightmode = info->lightmode < 0? gl_lightmode : info->lightmode; + level.brightfog = info->brightfog < 0? gl_brightfog : !!info->brightfog; + level.lightadditivesurfaces = info->lightadditivesurfaces < 0 ? gl_lightadditivesurfaces : !!info->lightadditivesurfaces; + level.notexturefill = info->notexturefill < 0 ? gl_notexturefill : !!info->notexturefill; + } //========================================================================== @@ -1986,7 +2016,7 @@ inline T VecDiff(const T& v1, const T& v2) if (nullptr != sec1 && nullptr != sec2) { - result += Displacements.getOffset(sec2->PortalGroup, sec1->PortalGroup); + result += level.Displacements.getOffset(sec2->PortalGroup, sec1->PortalGroup); } } diff --git a/src/g_level.h b/src/g_level.h index 78dcd55b11..b717bdbcfe 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -35,6 +35,7 @@ #define __G_LEVEL_H__ #include "doomtype.h" +#include "vectors.h" #include "sc_man.h" #include "resourcefiles/file_zip.h" @@ -395,6 +396,14 @@ struct level_info_t TArray EventHandlers; + int8_t lightmode; + int8_t brightfog; + int8_t lightadditivesurfaces; + int8_t notexturefill; + FVector3 skyrotatevector; + FVector3 skyrotatevector2; + + level_info_t() { Reset(); diff --git a/src/g_levellocals.h b/src/g_levellocals.h index 868423491f..183005c533 100644 --- a/src/g_levellocals.h +++ b/src/g_levellocals.h @@ -84,6 +84,16 @@ struct FLevelLocals TArray rejectmatrix; TArray sectorPortals; + TArray linePortals; + + // Portal information. + FDisplacementTable Displacements; + FPortalBlockmap PortalBlockmap; + TArray linkedPortals; // only the linked portals, this is used to speed up looking for them in P_CollectConnectedGroups. + TArray portalGroups; + TArray linePortalSpans; + int NumMapSections; + TArray Zones; FBlockmap blockmap; @@ -152,6 +162,12 @@ struct FLevelLocals float pixelstretch; float MusicVolume; + // Hardware render stuff that can either be set via CVAR or MAPINFO + int lightmode; + bool brightfog; + bool lightadditivesurfaces; + bool notexturefill; + bool IsJumpingAllowed() const; bool IsCrouchingAllowed() const; bool IsFreelookAllowed() const; @@ -262,27 +278,27 @@ inline bool sector_t::PortalIsLinked(int plane) inline FLinePortal *line_t::getPortal() const { - return portalindex >= linePortals.Size() ? (FLinePortal*)NULL : &linePortals[portalindex]; + return portalindex >= level.linePortals.Size() ? (FLinePortal*)NULL : &level.linePortals[portalindex]; } // returns true if the portal is crossable by actors inline bool line_t::isLinePortal() const { - return portalindex >= linePortals.Size() ? false : !!(linePortals[portalindex].mFlags & PORTF_PASSABLE); + return portalindex >= level.linePortals.Size() ? false : !!(level.linePortals[portalindex].mFlags & PORTF_PASSABLE); } // returns true if the portal needs to be handled by the renderer inline bool line_t::isVisualPortal() const { - return portalindex >= linePortals.Size() ? false : !!(linePortals[portalindex].mFlags & PORTF_VISIBLE); + return portalindex >= level.linePortals.Size() ? false : !!(level.linePortals[portalindex].mFlags & PORTF_VISIBLE); } inline line_t *line_t::getPortalDestination() const { - return portalindex >= linePortals.Size() ? (line_t*)NULL : linePortals[portalindex].mDestination; + return portalindex >= level.linePortals.Size() ? (line_t*)NULL : level.linePortals[portalindex].mDestination; } inline int line_t::getPortalAlignment() const { - return portalindex >= linePortals.Size() ? 0 : linePortals[portalindex].mAlign; + return portalindex >= level.linePortals.Size() ? 0 : level.linePortals[portalindex].mAlign; } diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index 325f6c2d2a..914dad912f 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -283,6 +283,14 @@ void level_info_t::Reset() specialactions.Clear(); DefaultEnvironment = 0; PrecacheSounds.Clear(); + + brightfog = -1; + lightmode = -1; + notexturefill = -1; + lightadditivesurfaces = -1; + skyrotatevector = FVector3(0, 0, 1); + skyrotatevector2 = FVector3(0, 0, 1); + } @@ -1362,6 +1370,82 @@ DEFINE_MAP_OPTION(pixelratio, false) } +DEFINE_MAP_OPTION(brightfog, false) +{ + parse.ParseAssign(); + parse.sc.MustGetNumber(); + info->brightfog = parse.sc.Number; +} + +DEFINE_MAP_OPTION(lightmode, false) +{ + parse.ParseAssign(); + parse.sc.MustGetNumber(); + + if ((parse.sc.Number >= 0 && parse.sc.Number <= 4) || parse.sc.Number == 8) + { + info->lightmode = uint8_t(parse.sc.Number); + } + else + { + parse.sc.ScriptMessage("Invalid light mode %d", parse.sc.Number); + } +} + +DEFINE_MAP_OPTION(notexturefill, false) +{ + if (parse.CheckAssign()) + { + parse.sc.MustGetNumber(); + info->notexturefill = !!parse.sc.Number; + } + else + { + info->notexturefill = true; + } +} + +DEFINE_MAP_OPTION(lightadditivesurfaces, false) +{ + if (parse.CheckAssign()) + { + parse.sc.MustGetNumber(); + info->lightadditivesurfaces = !!parse.sc.Number; + } + else + { + info->lightadditivesurfaces = true; + } +} + +DEFINE_MAP_OPTION(skyrotate, false) +{ + parse.ParseAssign(); + parse.sc.MustGetFloat(); + info->skyrotatevector.X = (float)parse.sc.Float; + if (parse.format_type == FMapInfoParser::FMT_New) parse.sc.MustGetStringName(","); + parse.sc.MustGetFloat(); + info->skyrotatevector.Y = (float)parse.sc.Float; + if (parse.format_type == FMapInfoParser::FMT_New) parse.sc.MustGetStringName(","); + parse.sc.MustGetFloat(); + info->skyrotatevector.Z = (float)parse.sc.Float; + info->skyrotatevector.MakeUnit(); +} + +DEFINE_MAP_OPTION(skyrotate2, false) +{ + parse.ParseAssign(); + parse.sc.MustGetFloat(); + info->skyrotatevector2.X = (float)parse.sc.Float; + if (parse.format_type == FMapInfoParser::FMT_New) parse.sc.MustGetStringName(","); + parse.sc.MustGetFloat(); + info->skyrotatevector2.Y = (float)parse.sc.Float; + if (parse.format_type == FMapInfoParser::FMT_New) parse.sc.MustGetStringName(","); + parse.sc.MustGetFloat(); + info->skyrotatevector2.Z = (float)parse.sc.Float; + info->skyrotatevector2.MakeUnit(); +} + //========================================================================== // // All flag based map options diff --git a/src/g_shared/a_decals.cpp b/src/g_shared/a_decals.cpp index edc170294a..29807f5b36 100644 --- a/src/g_shared/a_decals.cpp +++ b/src/g_shared/a_decals.cpp @@ -504,7 +504,7 @@ void DBaseDecal::Spread (const FDecalTemplate *tpl, side_t *wall, double x, doub int dwidth = tex->GetWidth (); DecalWidth = dwidth * ScaleX; - DecalLeft = tex->LeftOffset * ScaleX; + DecalLeft = tex->GetLeftOffset(0) * ScaleX; DecalRight = DecalWidth - DecalLeft; SpreadSource = this; SpreadTemplate = tpl; diff --git a/src/g_shared/a_dynlight.cpp b/src/g_shared/a_dynlight.cpp index 1858a9a929..69c798fd2c 100644 --- a/src/g_shared/a_dynlight.cpp +++ b/src/g_shared/a_dynlight.cpp @@ -76,8 +76,6 @@ #include "gl/system//gl_interface.h" #include "vm.h" -extern int currentrenderer; - CUSTOM_CVAR (Bool, gl_lights, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) { @@ -181,12 +179,6 @@ void ADynamicLight::BeginPlay() specialf1 = DAngle(double(SpawnAngle)).Normalized360().Degrees; visibletoplayer = true; - - if (currentrenderer == 1 && gl.legacyMode && (lightflags & LF_ATTENUATE)) - { - args[LIGHT_INTENSITY] = args[LIGHT_INTENSITY] * 2 / 3; - args[LIGHT_SECONDARY_INTENSITY] = args[LIGHT_SECONDARY_INTENSITY] * 2 / 3; - } } //========================================================================== @@ -793,6 +785,147 @@ void ADynamicLight::OnDestroy() } +//========================================================================== +// +// +// +//========================================================================== + +void AActor::AttachLight(unsigned int count, const FLightDefaults *lightdef) +{ + ADynamicLight *light; + + if (count < AttachedLights.Size()) + { + light = barrier_cast(AttachedLights[count]); + assert(light != NULL); + } + else + { + light = Spawn(Pos(), NO_REPLACE); + light->target = this; + light->owned = true; + light->ObjectFlags |= OF_Transient; + //light->lightflags |= LF_ATTENUATE; + AttachedLights.Push(light); + } + light->flags2&=~MF2_DORMANT; + lightdef->ApplyProperties(light); +} + +//========================================================================== +// +// per-state light adjustment +// +//========================================================================== +extern TArray StateLights; + +void AActor::SetDynamicLights() +{ + TArray & LightAssociations = GetInfo()->LightAssociations; + unsigned int count = 0; + + if (state == NULL) return; + if (LightAssociations.Size() > 0) + { + ADynamicLight *lights, *tmpLight; + unsigned int i; + + lights = tmpLight = NULL; + + for (i = 0; i < LightAssociations.Size(); i++) + { + if (LightAssociations[i]->Sprite() == sprite && + (LightAssociations[i]->Frame()==frame || LightAssociations[i]->Frame()==-1)) + { + AttachLight(count++, LightAssociations[i]->Light()); + } + } + } + if (count == 0 && state->Light > 0) + { + for(int i= state->Light; StateLights[i] != NULL; i++) + { + if (StateLights[i] != (FLightDefaults*)-1) + { + AttachLight(count++, StateLights[i]); + } + } + } + + for(;countflags2 |= MF2_DORMANT; + memset(AttachedLights[count]->args, 0, 3*sizeof(args[0])); + } +} + +//========================================================================== +// +// Needed for garbage collection +// +//========================================================================== + +size_t AActor::PropagateMark() +{ + for (unsigned i = 0; i it; + AActor * a; + ADynamicLight * l; + + while ((a=it.Next())) + { + a->AttachedLights.Clear(); + } + + TThinkerIterator it2; + + l=it2.Next(); + while (l) + { + ADynamicLight * ll = it2.Next(); + if (l->owned) l->Destroy(); + l=ll; + } +} + +//========================================================================== +// +// +// +//========================================================================== + +void AActor::RecreateAllAttachedLights() +{ + TThinkerIterator it; + AActor * a; + + while ((a=it.Next())) + { + a->SetDynamicLights(); + } +} + +//========================================================================== +// +// CCMDs +// +//========================================================================== + CCMD(listlights) { int walls, sectors, subsecs; diff --git a/src/g_shared/a_dynlight.h b/src/g_shared/a_dynlight.h index b659507d12..adfaa3a4f0 100644 --- a/src/g_shared/a_dynlight.h +++ b/src/g_shared/a_dynlight.h @@ -8,17 +8,28 @@ EXTERN_CVAR(Bool, gl_attachedlights) class ADynamicLight; class FSerializer; -class FLightDefaults; +enum ELightType +{ + PointLight, + PulseLight, + FlickerLight, + RandomFlickerLight, + SectorLight, + DummyLight, + ColorPulseLight, + ColorFlickerLight, + RandomColorFlickerLight +}; enum { - LIGHT_RED = 0, - LIGHT_GREEN = 1, - LIGHT_BLUE = 2, - LIGHT_INTENSITY = 3, - LIGHT_SECONDARY_INTENSITY = 4, - LIGHT_SCALE = 3, + LIGHT_RED = 0, + LIGHT_GREEN = 1, + LIGHT_BLUE = 2, + LIGHT_INTENSITY = 3, + LIGHT_SECONDARY_INTENSITY = 4, + LIGHT_SCALE = 3, }; enum LightFlag @@ -32,24 +43,111 @@ enum LightFlag LF_SPOT = 64 }; +//========================================================================== +// +// Light definitions +// +//========================================================================== +class FLightDefaults +{ +public: + FLightDefaults(FName name, ELightType type); + + void ApplyProperties(ADynamicLight * light) const; + FName GetName() const { return m_Name; } + void SetParameter(double p) { m_Param = p; } + void SetArg(int arg, int val) { m_Args[arg] = val; } + int GetArg(int arg) { return m_Args[arg]; } + uint8_t GetAttenuate() const { return m_attenuate; } + void SetOffset(float* ft) { m_Pos.X = ft[0]; m_Pos.Z = ft[1]; m_Pos.Y = ft[2]; } + void SetSubtractive(bool subtract) { m_subtractive = subtract; } + void SetAdditive(bool add) { m_additive = add; } + void SetDontLightSelf(bool add) { m_dontlightself = add; } + void SetAttenuate(bool on) { m_attenuate = on; } + void SetHalo(bool halo) { m_halo = halo; } + void SetDontLightActors(bool on) { m_dontlightactors = on; } + void SetSpot(bool spot) { m_spot = spot; } + void SetSpotInnerAngle(double angle) { m_spotInnerAngle = angle; } + void SetSpotOuterAngle(double angle) { m_spotOuterAngle = angle; } + + void OrderIntensities() + { + if (m_Args[LIGHT_INTENSITY] > m_Args[LIGHT_SECONDARY_INTENSITY]) + { + std::swap(m_Args[LIGHT_INTENSITY], m_Args[LIGHT_SECONDARY_INTENSITY]); + m_swapped = true; + } + } + +protected: + FName m_Name; + int m_Args[5] = { 0,0,0,0,0 }; + double m_Param = 0; + DVector3 m_Pos = { 0,0,0 }; + ELightType m_type; + int8_t m_attenuate = -1; + bool m_subtractive = false; + bool m_additive = false; + bool m_halo = false; + bool m_dontlightself = false; + bool m_dontlightactors = false; + bool m_swapped = false; + bool m_spot = false; + double m_spotInnerAngle = 10.0; + double m_spotOuterAngle = 25.0; +}; + +//========================================================================== +// +// Light associations (intermediate parser data) +// +//========================================================================== + +class FLightAssociation +{ +public: + //FLightAssociation(); + FLightAssociation(FName actorName, const char *frameName, FName lightName) + : m_ActorName(actorName), m_AssocLight(lightName) + { + strncpy(m_FrameName, frameName, 8); + } + + FName ActorName() { return m_ActorName; } + const char *FrameName() { return m_FrameName; } + FName Light() { return m_AssocLight; } + void ReplaceLightName(FName newName) { m_AssocLight = newName; } +protected: + char m_FrameName[8]; + FName m_ActorName, m_AssocLight; +}; + + +//========================================================================== +// +// Light associations per actor class +// +//========================================================================== + +class FInternalLightAssociation +{ +public: + FInternalLightAssociation(FLightAssociation * asso); + int Sprite() const { return m_sprite; } + int Frame() const { return m_frame; } + const FLightDefaults *Light() const { return m_AssocLight; } +protected: + int m_sprite; + int m_frame; + FLightDefaults * m_AssocLight; +}; + + + typedef TFlags LightFlags; DEFINE_TFLAGS_OPERATORS(LightFlags) -enum ELightType -{ - PointLight, - PulseLight, - FlickerLight, - RandomFlickerLight, - SectorLight, - DummyLight, - ColorPulseLight, - ColorFlickerLight, - RandomColorFlickerLight -}; - - struct FLightNode { FLightNode ** prevTarget; diff --git a/src/g_shared/a_dynlightdata.cpp b/src/g_shared/a_dynlightdata.cpp deleted file mode 100644 index 320f51019c..0000000000 --- a/src/g_shared/a_dynlightdata.cpp +++ /dev/null @@ -1,1448 +0,0 @@ -/* -** _gl_dynlight.cpp -** Light definitions for actors. -** -**--------------------------------------------------------------------------- -** Copyright 2003 Timothy Stump -** Copyright 2005 Christoph Oelckers -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - - -#include -#include "i_system.h" -#include "doomtype.h" -#include "c_cvars.h" -#include "c_dispatch.h" -#include "m_random.h" -#include "sc_man.h" -#include "templates.h" -#include "w_wad.h" -#include "gi.h" -#include "r_state.h" -#include "stats.h" -#include "zstring.h" -#include "d_dehacked.h" -#include "v_text.h" -#include "g_levellocals.h" -#include "a_dynlight.h" -#include "textures/skyboxtexture.h" - -int ScriptDepth; -void gl_InitGlow(FScanner &sc); -void gl_ParseBrightmap(FScanner &sc, int); -void gl_ParseMaterial(FScanner &sc, int); -void gl_DestroyUserShaders(); -void gl_ParseHardwareShader(FScanner &sc, int deflump); -void gl_ParseDetailTexture(FScanner &sc); - -//========================================================================== -// -// Dehacked aliasing -// -//========================================================================== - -inline PClassActor * GetRealType(PClassActor * ti) -{ - PClassActor *rep = ti->GetReplacement(false); - if (rep != ti && rep != NULL && rep->IsDescendantOf(NAME_DehackedPickup)) - { - return rep; - } - return ti; -} - - - -//========================================================================== -// -// Light associations -// -//========================================================================== -class FLightAssociation -{ -public: - //FLightAssociation(); - FLightAssociation(FName actorName, const char *frameName, FName lightName) - : m_ActorName(actorName), m_AssocLight(lightName) - { - strncpy(m_FrameName, frameName, 8); - } - - FName ActorName() { return m_ActorName; } - const char *FrameName() { return m_FrameName; } - FName Light() { return m_AssocLight; } - void ReplaceLightName(FName newName) { m_AssocLight = newName; } -protected: - char m_FrameName[8]; - FName m_ActorName, m_AssocLight; -}; - -TArray LightAssociations; - - -//========================================================================== -// -// Light definitions -// -//========================================================================== -class FLightDefaults -{ -public: - FLightDefaults(FName name, ELightType type); - - void ApplyProperties(ADynamicLight * light) const; - FName GetName() const { return m_Name; } - void SetParameter(double p) { m_Param = p; } - void SetArg(int arg, int val) { m_Args[arg] = val; } - int GetArg(int arg) { return m_Args[arg]; } - uint8_t GetAttenuate() const { return m_attenuate; } - void SetOffset(float* ft) { m_Pos.X = ft[0]; m_Pos.Z = ft[1]; m_Pos.Y = ft[2]; } - void SetSubtractive(bool subtract) { m_subtractive = subtract; } - void SetAdditive(bool add) { m_additive = add; } - void SetDontLightSelf(bool add) { m_dontlightself = add; } - void SetAttenuate(bool on) { m_attenuate = on; } - void SetHalo(bool halo) { m_halo = halo; } - void SetDontLightActors(bool on) { m_dontlightactors = on; } - void SetSpot(bool spot) { m_spot = spot; } - void SetSpotInnerAngle(double angle) { m_spotInnerAngle = angle; } - void SetSpotOuterAngle(double angle) { m_spotOuterAngle = angle; } - - void OrderIntensities() - { - if (m_Args[LIGHT_INTENSITY] > m_Args[LIGHT_SECONDARY_INTENSITY]) - { - std::swap(m_Args[LIGHT_INTENSITY], m_Args[LIGHT_SECONDARY_INTENSITY]); - m_swapped = true; - } - } - -protected: - FName m_Name; - int m_Args[5] = { 0,0,0,0,0 }; - double m_Param = 0; - DVector3 m_Pos = { 0,0,0 }; - ELightType m_type; - int8_t m_attenuate = -1; - bool m_subtractive = false; - bool m_additive = false; - bool m_halo = false; - bool m_dontlightself = false; - bool m_dontlightactors = false; - bool m_swapped = false; - bool m_spot = false; - double m_spotInnerAngle = 10.0; - double m_spotOuterAngle = 25.0; -}; - -TDeletingArray LightDefaults; - -//----------------------------------------------------------------------------- -// -// -// -//----------------------------------------------------------------------------- - -FLightDefaults::FLightDefaults(FName name, ELightType type) -{ - m_Name = name; - m_type = type; -} - -void FLightDefaults::ApplyProperties(ADynamicLight * light) const -{ - auto oldtype = light->lighttype; - - light->lighttype = m_type; - light->specialf1 = m_Param; - light->SetOffset(m_Pos); - light->halo = m_halo; - for (int a = 0; a < 3; a++) light->args[a] = clamp((int)(m_Args[a]), 0, 255); - light->args[LIGHT_INTENSITY] = m_Args[LIGHT_INTENSITY]; - light->args[LIGHT_SECONDARY_INTENSITY] = m_Args[LIGHT_SECONDARY_INTENSITY]; - light->lightflags &= ~(LF_ADDITIVE | LF_SUBTRACTIVE | LF_DONTLIGHTSELF); - if (m_subtractive) light->lightflags |= LF_SUBTRACTIVE; - if (m_additive) light->lightflags |= LF_ADDITIVE; - if (m_dontlightself) light->lightflags |= LF_DONTLIGHTSELF; - if (m_dontlightactors) light->lightflags |= LF_DONTLIGHTACTORS; - if (m_spot) - light->lightflags |= LF_SPOT; - light->SpotInnerAngle = m_spotInnerAngle; - light->SpotOuterAngle = m_spotOuterAngle; - light->m_tickCount = 0; - if (m_type == PulseLight) - { - float pulseTime = float(m_Param / TICRATE); - - light->m_lastUpdate = level.maptime; - if (m_swapped) light->m_cycler.SetParams(float(light->args[LIGHT_SECONDARY_INTENSITY]), float(light->args[LIGHT_INTENSITY]), pulseTime, oldtype == PulseLight); - else light->m_cycler.SetParams(float(light->args[LIGHT_INTENSITY]), float(light->args[LIGHT_SECONDARY_INTENSITY]), pulseTime, oldtype == PulseLight); - light->m_cycler.ShouldCycle(true); - light->m_cycler.SetCycleType(CYCLE_Sin); - light->m_currentRadius = (float)light->m_cycler.GetVal(); - if (light->m_currentRadius <= 0) light->m_currentRadius = 1; - light->swapped = m_swapped; - } - - switch (m_attenuate) - { - case 0: light->lightflags &= ~LF_ATTENUATE; break; - case 1: light->lightflags |= LF_ATTENUATE; break; - default: if (level.flags3 & LEVEL3_ATTENUATE) light->lightflags |= LF_ATTENUATE; else light->lightflags &= ~LF_ATTENUATE; break; - } - } - - -//========================================================================== -// -// light definition file parser -// -//========================================================================== - - -static const char *LightTags[]= -{ - "color", - "size", - "secondarySize", - "offset", - "chance", - "interval", - "scale", - "frame", - "light", - "{", - "}", - "subtractive", - "additive", - "halo", - "dontlightself", - "attenuate", - "dontlightactors", - "spot", - nullptr -}; - - -enum { - LIGHTTAG_COLOR, - LIGHTTAG_SIZE, - LIGHTTAG_SECSIZE, - LIGHTTAG_OFFSET, - LIGHTTAG_CHANCE, - LIGHTTAG_INTERVAL, - LIGHTTAG_SCALE, - LIGHTTAG_FRAME, - LIGHTTAG_LIGHT, - LIGHTTAG_OPENBRACE, - LIGHTTAG_CLOSEBRACE, - LIGHTTAG_SUBTRACTIVE, - LIGHTTAG_ADDITIVE, - LIGHTTAG_HALO, - LIGHTTAG_DONTLIGHTSELF, - LIGHTTAG_ATTENUATE, - LIGHTTAG_DONTLIGHTACTORS, - LIGHTTAG_SPOT -}; - - -extern int ScriptDepth; - - -//========================================================================== -// -// -// -//========================================================================== - -inline float ParseFloat(FScanner &sc) -{ - sc.MustGetFloat(); - - return float(sc.Float); -} - - -inline int ParseInt(FScanner &sc) -{ - sc.MustGetNumber(); - - return sc.Number; -} - - -inline char *ParseString(FScanner &sc) -{ - sc.GetString(); - - return sc.String; -} - - -static void ParseTriple(FScanner &sc, float floatVal[3]) -{ - for (int i = 0; i < 3; i++) - { - floatVal[i] = ParseFloat(sc); - } -} - - -static void AddLightDefaults(FLightDefaults *defaults) -{ - FLightDefaults *temp; - unsigned int i; - - // remove duplicates - for (i = 0; i < LightDefaults.Size(); i++) - { - temp = LightDefaults[i]; - if (temp->GetName() == defaults->GetName()) - { - delete temp; - LightDefaults.Delete(i); - break; - } - } - - // If the current renderer cannot handle attenuated lights we need to reduce the radius here to account for the far more bright lights this would create. - if (/*!Renderer->CanAttenuate() &&*/ (defaults->GetAttenuate())) - { - defaults->SetArg(LIGHT_INTENSITY, defaults->GetArg(LIGHT_INTENSITY) * 2 / 3); - defaults->SetArg(LIGHT_SECONDARY_INTENSITY, defaults->GetArg(LIGHT_SECONDARY_INTENSITY) * 2 / 3); - } - - LightDefaults.Push(defaults); -} - - -//----------------------------------------------------------------------------- -// -// -// -//----------------------------------------------------------------------------- - -static void ParsePointLight(FScanner &sc) -{ - int type; - float floatTriple[3]; - int intVal; - FLightDefaults *defaults; - - // get name - sc.GetString(); - FName name = sc.String; - - // check for opening brace - sc.GetString(); - if (sc.Compare("{")) - { - defaults = new FLightDefaults(name, PointLight); - ScriptDepth++; - while (ScriptDepth) - { - sc.GetString(); - type = sc.MatchString(LightTags); - switch (type) - { - case LIGHTTAG_OPENBRACE: - ScriptDepth++; - break; - case LIGHTTAG_CLOSEBRACE: - ScriptDepth--; - break; - case LIGHTTAG_COLOR: - ParseTriple(sc, floatTriple); - defaults->SetArg(LIGHT_RED, clamp((int)(floatTriple[0] * 255), 0, 255)); - defaults->SetArg(LIGHT_GREEN, clamp((int)(floatTriple[1] * 255), 0, 255)); - defaults->SetArg(LIGHT_BLUE, clamp((int)(floatTriple[2] * 255), 0, 255)); - break; - case LIGHTTAG_OFFSET: - ParseTriple(sc, floatTriple); - defaults->SetOffset(floatTriple); - break; - case LIGHTTAG_SIZE: - intVal = clamp(ParseInt(sc), 1, 1024); - defaults->SetArg(LIGHT_INTENSITY, intVal); - break; - case LIGHTTAG_SUBTRACTIVE: - defaults->SetSubtractive(ParseInt(sc) != 0); - break; - case LIGHTTAG_ADDITIVE: - defaults->SetAdditive(ParseInt(sc) != 0); - break; - case LIGHTTAG_HALO: - defaults->SetHalo(ParseInt(sc) != 0); - break; - case LIGHTTAG_DONTLIGHTSELF: - defaults->SetDontLightSelf(ParseInt(sc) != 0); - break; - case LIGHTTAG_ATTENUATE: - defaults->SetAttenuate(ParseInt(sc) != 0); - break; - case LIGHTTAG_DONTLIGHTACTORS: - defaults->SetDontLightActors(ParseInt(sc) != 0); - break; - case LIGHTTAG_SPOT: - { - float innerAngle = ParseFloat(sc); - float outerAngle = ParseFloat(sc); - defaults->SetSpot(true); - defaults->SetSpotInnerAngle(innerAngle); - defaults->SetSpotOuterAngle(outerAngle); - } - break; - default: - sc.ScriptError("Unknown tag: %s\n", sc.String); - } - } - AddLightDefaults(defaults); - } - else - { - sc.ScriptError("Expected '{'.\n"); - } -} - - -//----------------------------------------------------------------------------- -// -// -// -//----------------------------------------------------------------------------- - -static void ParsePulseLight(FScanner &sc) -{ - int type; - float floatVal, floatTriple[3]; - int intVal; - FLightDefaults *defaults; - - // get name - sc.GetString(); - FName name = sc.String; - - // check for opening brace - sc.GetString(); - if (sc.Compare("{")) - { - defaults = new FLightDefaults(name, PulseLight); - ScriptDepth++; - while (ScriptDepth) - { - sc.GetString(); - type = sc.MatchString(LightTags); - switch (type) - { - case LIGHTTAG_OPENBRACE: - ScriptDepth++; - break; - case LIGHTTAG_CLOSEBRACE: - ScriptDepth--; - break; - case LIGHTTAG_COLOR: - ParseTriple(sc, floatTriple); - defaults->SetArg(LIGHT_RED, clamp((int)(floatTriple[0] * 255), 0, 255)); - defaults->SetArg(LIGHT_GREEN, clamp((int)(floatTriple[1] * 255), 0, 255)); - defaults->SetArg(LIGHT_BLUE, clamp((int)(floatTriple[2] * 255), 0, 255)); - break; - case LIGHTTAG_OFFSET: - ParseTriple(sc, floatTriple); - defaults->SetOffset(floatTriple); - break; - case LIGHTTAG_SIZE: - intVal = clamp(ParseInt(sc), 1, 1024); - defaults->SetArg(LIGHT_INTENSITY, intVal); - break; - case LIGHTTAG_SECSIZE: - intVal = clamp(ParseInt(sc), 1, 1024); - defaults->SetArg(LIGHT_SECONDARY_INTENSITY, intVal); - break; - case LIGHTTAG_INTERVAL: - floatVal = ParseFloat(sc); - defaults->SetParameter(floatVal * TICRATE); - break; - case LIGHTTAG_SUBTRACTIVE: - defaults->SetSubtractive(ParseInt(sc) != 0); - break; - case LIGHTTAG_HALO: - defaults->SetHalo(ParseInt(sc) != 0); - break; - case LIGHTTAG_DONTLIGHTSELF: - defaults->SetDontLightSelf(ParseInt(sc) != 0); - break; - case LIGHTTAG_ATTENUATE: - defaults->SetAttenuate(ParseInt(sc) != 0); - break; - case LIGHTTAG_DONTLIGHTACTORS: - defaults->SetDontLightActors(ParseInt(sc) != 0); - break; - case LIGHTTAG_SPOT: - { - float innerAngle = ParseFloat(sc); - float outerAngle = ParseFloat(sc); - defaults->SetSpot(true); - defaults->SetSpotInnerAngle(innerAngle); - defaults->SetSpotOuterAngle(outerAngle); - } - break; - default: - sc.ScriptError("Unknown tag: %s\n", sc.String); - } - } - defaults->OrderIntensities(); - - AddLightDefaults(defaults); - } - else - { - sc.ScriptError("Expected '{'.\n"); - } -} - - -//----------------------------------------------------------------------------- -// -// -// -//----------------------------------------------------------------------------- - -void ParseFlickerLight(FScanner &sc) -{ - int type; - float floatVal, floatTriple[3]; - int intVal; - FLightDefaults *defaults; - - // get name - sc.GetString(); - FName name = sc.String; - - // check for opening brace - sc.GetString(); - if (sc.Compare("{")) - { - defaults = new FLightDefaults(name, FlickerLight); - ScriptDepth++; - while (ScriptDepth) - { - sc.GetString(); - type = sc.MatchString(LightTags); - switch (type) - { - case LIGHTTAG_OPENBRACE: - ScriptDepth++; - break; - case LIGHTTAG_CLOSEBRACE: - ScriptDepth--; - break; - case LIGHTTAG_COLOR: - ParseTriple(sc, floatTriple); - defaults->SetArg(LIGHT_RED, clamp((int)(floatTriple[0] * 255), 0, 255)); - defaults->SetArg(LIGHT_GREEN, clamp((int)(floatTriple[1] * 255), 0, 255)); - defaults->SetArg(LIGHT_BLUE, clamp((int)(floatTriple[2] * 255), 0, 255)); - break; - case LIGHTTAG_OFFSET: - ParseTriple(sc, floatTriple); - defaults->SetOffset(floatTriple); - break; - case LIGHTTAG_SIZE: - intVal = clamp(ParseInt(sc), 1, 1024); - defaults->SetArg(LIGHT_INTENSITY, intVal); - break; - case LIGHTTAG_SECSIZE: - intVal = clamp(ParseInt(sc), 1, 1024); - defaults->SetArg(LIGHT_SECONDARY_INTENSITY, intVal); - break; - case LIGHTTAG_CHANCE: - floatVal = ParseFloat(sc); - defaults->SetParameter(floatVal*360.); - break; - case LIGHTTAG_SUBTRACTIVE: - defaults->SetSubtractive(ParseInt(sc) != 0); - break; - case LIGHTTAG_HALO: - defaults->SetHalo(ParseInt(sc) != 0); - break; - case LIGHTTAG_DONTLIGHTSELF: - defaults->SetDontLightSelf(ParseInt(sc) != 0); - break; - case LIGHTTAG_ATTENUATE: - defaults->SetAttenuate(ParseInt(sc) != 0); - break; - case LIGHTTAG_DONTLIGHTACTORS: - defaults->SetDontLightActors(ParseInt(sc) != 0); - break; - case LIGHTTAG_SPOT: - { - float innerAngle = ParseFloat(sc); - float outerAngle = ParseFloat(sc); - defaults->SetSpot(true); - defaults->SetSpotInnerAngle(innerAngle); - defaults->SetSpotOuterAngle(outerAngle); - } - break; - default: - sc.ScriptError("Unknown tag: %s\n", sc.String); - } - } - defaults->OrderIntensities(); - AddLightDefaults(defaults); - } - else - { - sc.ScriptError("Expected '{'.\n"); - } -} - - -//----------------------------------------------------------------------------- -// -// -// -//----------------------------------------------------------------------------- - -void ParseFlickerLight2(FScanner &sc) -{ - int type; - float floatVal, floatTriple[3]; - int intVal; - FLightDefaults *defaults; - - // get name - sc.GetString(); - FName name = sc.String; - - // check for opening brace - sc.GetString(); - if (sc.Compare("{")) - { - defaults = new FLightDefaults(name, RandomFlickerLight); - ScriptDepth++; - while (ScriptDepth) - { - sc.GetString(); - type = sc.MatchString(LightTags); - switch (type) - { - case LIGHTTAG_OPENBRACE: - ScriptDepth++; - break; - case LIGHTTAG_CLOSEBRACE: - ScriptDepth--; - break; - case LIGHTTAG_COLOR: - ParseTriple(sc, floatTriple); - defaults->SetArg(LIGHT_RED, clamp((int)(floatTriple[0] * 255), 0, 255)); - defaults->SetArg(LIGHT_GREEN, clamp((int)(floatTriple[1] * 255), 0, 255)); - defaults->SetArg(LIGHT_BLUE, clamp((int)(floatTriple[2] * 255), 0, 255)); - break; - case LIGHTTAG_OFFSET: - ParseTriple(sc, floatTriple); - defaults->SetOffset(floatTriple); - break; - case LIGHTTAG_SIZE: - intVal = clamp(ParseInt(sc), 1, 1024); - defaults->SetArg(LIGHT_INTENSITY, intVal); - break; - case LIGHTTAG_SECSIZE: - intVal = clamp(ParseInt(sc), 1, 1024); - defaults->SetArg(LIGHT_SECONDARY_INTENSITY, intVal); - break; - case LIGHTTAG_INTERVAL: - floatVal = ParseFloat(sc); - defaults->SetParameter(floatVal * 360.); - break; - case LIGHTTAG_SUBTRACTIVE: - defaults->SetSubtractive(ParseInt(sc) != 0); - break; - case LIGHTTAG_HALO: - defaults->SetHalo(ParseInt(sc) != 0); - break; - case LIGHTTAG_DONTLIGHTSELF: - defaults->SetDontLightSelf(ParseInt(sc) != 0); - break; - case LIGHTTAG_ATTENUATE: - defaults->SetAttenuate(ParseInt(sc) != 0); - break; - case LIGHTTAG_DONTLIGHTACTORS: - defaults->SetDontLightActors(ParseInt(sc) != 0); - break; - case LIGHTTAG_SPOT: - { - float innerAngle = ParseFloat(sc); - float outerAngle = ParseFloat(sc); - defaults->SetSpot(true); - defaults->SetSpotInnerAngle(innerAngle); - defaults->SetSpotOuterAngle(outerAngle); - } - break; - default: - sc.ScriptError("Unknown tag: %s\n", sc.String); - } - } - if (defaults->GetArg(LIGHT_SECONDARY_INTENSITY) < defaults->GetArg(LIGHT_INTENSITY)) - { - int v = defaults->GetArg(LIGHT_SECONDARY_INTENSITY); - defaults->SetArg(LIGHT_SECONDARY_INTENSITY, defaults->GetArg(LIGHT_INTENSITY)); - defaults->SetArg(LIGHT_INTENSITY, v); - } - AddLightDefaults(defaults); - } - else - { - sc.ScriptError("Expected '{'.\n"); - } -} - - -//----------------------------------------------------------------------------- -// -// -// -//----------------------------------------------------------------------------- - -static void ParseSectorLight(FScanner &sc) -{ - int type; - float floatVal; - float floatTriple[3]; - FLightDefaults *defaults; - - // get name - sc.GetString(); - FName name = sc.String; - - // check for opening brace - sc.GetString(); - if (sc.Compare("{")) - { - defaults = new FLightDefaults(name, SectorLight); - ScriptDepth++; - while (ScriptDepth) - { - sc.GetString(); - type = sc.MatchString(LightTags); - switch (type) - { - case LIGHTTAG_OPENBRACE: - ScriptDepth++; - break; - case LIGHTTAG_CLOSEBRACE: - ScriptDepth--; - break; - case LIGHTTAG_COLOR: - ParseTriple(sc, floatTriple); - defaults->SetArg(LIGHT_RED, clamp((int)(floatTriple[0] * 255), 0, 255)); - defaults->SetArg(LIGHT_GREEN, clamp((int)(floatTriple[1] * 255), 0, 255)); - defaults->SetArg(LIGHT_BLUE, clamp((int)(floatTriple[2] * 255), 0, 255)); - break; - case LIGHTTAG_OFFSET: - ParseTriple(sc, floatTriple); - defaults->SetOffset(floatTriple); - break; - case LIGHTTAG_SCALE: - floatVal = ParseFloat(sc); - defaults->SetArg(LIGHT_SCALE, clamp((int)(floatVal * 255), 1, 1024)); - break; - case LIGHTTAG_SUBTRACTIVE: - defaults->SetSubtractive(ParseInt(sc) != 0); - break; - case LIGHTTAG_HALO: - defaults->SetHalo(ParseInt(sc) != 0); - break; - case LIGHTTAG_DONTLIGHTSELF: - defaults->SetDontLightSelf(ParseInt(sc) != 0); - break; - case LIGHTTAG_ATTENUATE: - defaults->SetAttenuate(ParseInt(sc) != 0); - break; - case LIGHTTAG_DONTLIGHTACTORS: - defaults->SetDontLightActors(ParseInt(sc) != 0); - break; - case LIGHTTAG_SPOT: - { - float innerAngle = ParseFloat(sc); - float outerAngle = ParseFloat(sc); - defaults->SetSpot(true); - defaults->SetSpotInnerAngle(innerAngle); - defaults->SetSpotOuterAngle(outerAngle); - } - break; - default: - sc.ScriptError("Unknown tag: %s\n", sc.String); - } - } - AddLightDefaults(defaults); - } - else - { - sc.ScriptError("Expected '{'.\n"); - } -} - - -//----------------------------------------------------------------------------- -// -// -// -//----------------------------------------------------------------------------- - -static void AddLightAssociation(const char *actor, const char *frame, const char *light) -{ - FLightAssociation *temp; - unsigned int i; - FLightAssociation assoc(actor, frame, light); - - for (i = 0; i < LightAssociations.Size(); i++) - { - temp = &LightAssociations[i]; - if (temp->ActorName() == assoc.ActorName()) - { - if (strcmp(temp->FrameName(), assoc.FrameName()) == 0) - { - temp->ReplaceLightName(assoc.Light()); - return; - } - } - } - - LightAssociations.Push(assoc); -} - - -//----------------------------------------------------------------------------- -// -// -// -//----------------------------------------------------------------------------- - -static void ParseFrame(FScanner &sc, FString name) -{ - int type, startDepth; - FString frameName; - - // get name - sc.GetString(); - if (strlen(sc.String) > 8) - { - sc.ScriptError("Name longer than 8 characters: %s\n", sc.String); - } - frameName = sc.String; - - startDepth = ScriptDepth; - - // check for opening brace - sc.GetString(); - if (sc.Compare("{")) - { - ScriptDepth++; - while (ScriptDepth > startDepth) - { - sc.GetString(); - type = sc.MatchString(LightTags); - switch (type) - { - case LIGHTTAG_OPENBRACE: - ScriptDepth++; - break; - case LIGHTTAG_CLOSEBRACE: - ScriptDepth--; - break; - case LIGHTTAG_LIGHT: - ParseString(sc); - AddLightAssociation(name, frameName, sc.String); - break; - default: - sc.ScriptError("Unknown tag: %s\n", sc.String); - } - } - } - else - { - sc.ScriptError("Expected '{'.\n"); - } -} - - -//----------------------------------------------------------------------------- -// -// -// -//----------------------------------------------------------------------------- - -void ParseObject(FScanner &sc) -{ - int type; - FString name; - - // get name - sc.GetString(); - name = sc.String; - if (!PClass::FindActor(name)) - sc.ScriptMessage("Warning: dynamic lights attached to non-existent actor %s\n", name.GetChars()); - - // check for opening brace - sc.GetString(); - if (sc.Compare("{")) - { - ScriptDepth++; - while (ScriptDepth) - { - sc.GetString(); - type = sc.MatchString(LightTags); - switch (type) - { - case LIGHTTAG_OPENBRACE: - ScriptDepth++; - break; - case LIGHTTAG_CLOSEBRACE: - ScriptDepth--; - break; - case LIGHTTAG_FRAME: - ParseFrame(sc, name); - break; - default: - sc.ScriptError("Unknown tag: %s\n", sc.String); - } - } - } - else - { - sc.ScriptError("Expected '{'.\n"); - } -} - - -//========================================================================== -// -// -// -//========================================================================== - -// these are the core types available in the *DEFS lump -static const char *CoreKeywords[]= -{ - "pointlight", - "pulselight", - "flickerlight", - "flickerlight2", - "sectorlight", - "object", - "clearlights", - "shader", - "clearshaders", - "skybox", - "glow", - "brightmap", - "disable_fullbright", - "hardwareshader", - "detail", - "#include", - "material", - nullptr -}; - - -enum -{ - LIGHT_POINT, - LIGHT_PULSE, - LIGHT_FLICKER, - LIGHT_FLICKER2, - LIGHT_SECTOR, - LIGHT_OBJECT, - LIGHT_CLEAR, - TAG_SHADER, - TAG_CLEARSHADERS, - TAG_SKYBOX, - TAG_GLOW, - TAG_BRIGHTMAP, - TAG_DISABLE_FB, - TAG_HARDWARESHADER, - TAG_DETAIL, - TAG_INCLUDE, - TAG_MATERIAL -}; - - -//========================================================================== -// -// This is only here so any shader definition for ZDoomGL can be skipped -// There is no functionality for this stuff! -// -//========================================================================== -bool ParseShader(FScanner &sc) -{ - int ShaderDepth = 0; - - if (sc.GetString()) - { - char *tmp; - - tmp = strstr(sc.String, "{"); - while (tmp) - { - ShaderDepth++; - tmp++; - tmp = strstr(tmp, "{"); - } - - tmp = strstr(sc.String, "}"); - while (tmp) - { - ShaderDepth--; - tmp++; - tmp = strstr(tmp, "}"); - } - - if (ShaderDepth == 0) return true; - } - return false; -} - -//========================================================================== -// -// Light associations per actor class -// -//========================================================================== - -class FInternalLightAssociation -{ -public: - FInternalLightAssociation(FLightAssociation * asso); - int Sprite() const { return m_sprite; } - int Frame() const { return m_frame; } - const FLightDefaults *Light() const { return m_AssocLight; } -protected: - int m_sprite; - int m_frame; - FLightDefaults * m_AssocLight; -}; - -//========================================================================== -// -// -// -//========================================================================== - -FInternalLightAssociation::FInternalLightAssociation(FLightAssociation * asso) -{ - - m_AssocLight=NULL; - for(unsigned int i=0;iGetName() == asso->Light()) - { - m_AssocLight = LightDefaults[i]; - break; - } - } - - m_sprite=-1; - m_frame = -1; - for (unsigned i = 0; i < sprites.Size (); ++i) - { - if (strncmp (sprites[i].name, asso->FrameName(), 4) == 0) - { - m_sprite = (int)i; - break; - } - } - - // Only handle lights for full frames. - // I won't bother with special lights for single rotations - // because there is no decent use for them! - if (strlen(asso->FrameName())==5 || asso->FrameName()[5]=='0') - { - m_frame = toupper(asso->FrameName()[4])-'A'; - } -} - -//========================================================================== -// -// State lights -// -//========================================================================== -TArray ParsedStateLights; -TArray StateLights; - - - -//========================================================================== -// -// -// -//========================================================================== - -void InitializeActorLights() -{ - for(unsigned int i=0;iLight() != nullptr) - ti->ActorInfo()->LightAssociations.Push(iasso); - } - } - // we don't need the parser data for the light associations anymore - LightAssociations.Clear(); - LightAssociations.ShrinkToFit(); - - StateLights.Resize(ParsedStateLights.Size()+1); - for(unsigned i=0; iGetName() == ParsedStateLights[i]) - { - StateLights[i] = LightDefaults[j]; - break; - } - } - } - else StateLights[i] = NULL; - } - StateLights[StateLights.Size()-1] = NULL; // terminator - ParsedStateLights.Clear(); - ParsedStateLights.ShrinkToFit(); -} - - -//========================================================================== -// -// -// -//========================================================================== - -void AActor::AttachLight(unsigned int count, const FLightDefaults *lightdef) -{ - ADynamicLight *light; - - if (count < AttachedLights.Size()) - { - light = barrier_cast(AttachedLights[count]); - assert(light != NULL); - } - else - { - light = Spawn(Pos(), NO_REPLACE); - light->target = this; - light->owned = true; - light->ObjectFlags |= OF_Transient; - //light->lightflags |= LF_ATTENUATE; - AttachedLights.Push(light); - } - light->flags2&=~MF2_DORMANT; - lightdef->ApplyProperties(light); -} - -//========================================================================== -// -// per-state light adjustment -// -//========================================================================== - -void AActor::SetDynamicLights() -{ - TArray & LightAssociations = GetInfo()->LightAssociations; - unsigned int count = 0; - - if (state == NULL) return; - if (LightAssociations.Size() > 0) - { - ADynamicLight *lights, *tmpLight; - unsigned int i; - - lights = tmpLight = NULL; - - for (i = 0; i < LightAssociations.Size(); i++) - { - if (LightAssociations[i]->Sprite() == sprite && - (LightAssociations[i]->Frame()==frame || LightAssociations[i]->Frame()==-1)) - { - AttachLight(count++, LightAssociations[i]->Light()); - } - } - } - if (count == 0 && state->Light > 0) - { - for(int i= state->Light; StateLights[i] != NULL; i++) - { - if (StateLights[i] != (FLightDefaults*)-1) - { - AttachLight(count++, StateLights[i]); - } - } - } - - for(;countflags2 |= MF2_DORMANT; - memset(AttachedLights[count]->args, 0, 3*sizeof(args[0])); - } -} - -//========================================================================== -// -// Needed for garbage collection -// -//========================================================================== - -size_t AActor::PropagateMark() -{ - for (unsigned i = 0; i it; - AActor * a; - ADynamicLight * l; - - while ((a=it.Next())) - { - a->AttachedLights.Clear(); - } - - TThinkerIterator it2; - - l=it2.Next(); - while (l) - { - ADynamicLight * ll = it2.Next(); - if (l->owned) l->Destroy(); - l=ll; - } -} - -//========================================================================== -// -// -// -//========================================================================== - -void AActor::RecreateAllAttachedLights() -{ - TThinkerIterator it; - AActor * a; - - while ((a=it.Next())) - { - a->SetDynamicLights(); - } -} - - -//========================================================================== -// -// -// -//========================================================================== -static void DoParseDefs(FScanner &sc, int workingLump) -{ - int recursion=0; - int lump, type; - - // Get actor class name. - while (true) - { - sc.SavePos(); - if (!sc.GetToken ()) - { - return; - } - type = sc.MatchString(CoreKeywords); - switch (type) - { - case TAG_INCLUDE: - { - sc.MustGetString(); - // This is not using sc.Open because it can print a more useful error message when done here - lump = Wads.CheckNumForFullName(sc.String, true); - if (lump==-1) - sc.ScriptError("Lump '%s' not found", sc.String); - - FScanner newscanner(lump); - DoParseDefs(newscanner, lump); - break; - } - case LIGHT_POINT: - ParsePointLight(sc); - break; - case LIGHT_PULSE: - ParsePulseLight(sc); - break; - case LIGHT_FLICKER: - ParseFlickerLight(sc); - break; - case LIGHT_FLICKER2: - ParseFlickerLight2(sc); - break; - case LIGHT_SECTOR: - ParseSectorLight(sc); - break; - case LIGHT_OBJECT: - ParseObject(sc); - break; - case LIGHT_CLEAR: - // This has been intentionally removed - break; - case TAG_SHADER: - ParseShader(sc); - break; - case TAG_CLEARSHADERS: - break; - case TAG_SKYBOX: - ParseGldefSkybox(sc); - break; - case TAG_GLOW: - gl_InitGlow(sc); - break; - case TAG_BRIGHTMAP: - gl_ParseBrightmap(sc, workingLump); - break; - case TAG_MATERIAL: - gl_ParseMaterial(sc, workingLump); - break; - case TAG_HARDWARESHADER: - gl_ParseHardwareShader(sc, workingLump); - break; - case TAG_DETAIL: - gl_ParseDetailTexture(sc); - break; - case TAG_DISABLE_FB: - { - /* not implemented. - sc.MustGetString(); - const PClass *cls = PClass::FindClass(sc.String); - if (cls) GetDefaultByType(cls)->renderflags |= RF_NEVERFULLBRIGHT; - */ - } - break; - default: - sc.ScriptError("Error parsing defs. Unknown tag: %s.\n", sc.String); - break; - } - } -} - -//========================================================================== -// -// -// -//========================================================================== - -static void LoadGLDefs(const char *defsLump) -{ - int workingLump, lastLump; - static const char *gldefsnames[] = { "GLDEFS", defsLump, nullptr }; - - lastLump = 0; - while ((workingLump = Wads.FindLumpMulti(gldefsnames, &lastLump)) != -1) - { - FScanner sc(workingLump); - DoParseDefs(sc, workingLump); - } -} - - -//========================================================================== -// -// -// -//========================================================================== - -void ParseGLDefs() -{ - const char *defsLump = NULL; - - LightAssociations.Clear(); - LightDefaults.Clear(); - gl_DestroyUserShaders(); - switch (gameinfo.gametype) - { - case GAME_Heretic: - defsLump = "HTICDEFS"; - break; - case GAME_Hexen: - defsLump = "HEXNDEFS"; - break; - case GAME_Strife: - defsLump = "STRFDEFS"; - break; - case GAME_Doom: - defsLump = "DOOMDEFS"; - break; - case GAME_Chex: - defsLump = "CHEXDEFS"; - break; - default: // silence GCC - break; - } - ParseVavoomSkybox(); - LoadGLDefs(defsLump); - InitializeActorLights(); -} - -//========================================================================== -// -// -// -//========================================================================== - -void AddStateLight(FState *State, const char *lname) -{ - if (State->Light == 0) - { - ParsedStateLights.Push(NAME_None); - State->Light = ParsedStateLights.Push(FName(lname)); - } - else - { - ParsedStateLights.Push(FName(lname)); - } -} diff --git a/src/g_shared/hudmessages.cpp b/src/g_shared/hudmessages.cpp index f2fa20854d..0299a0b932 100644 --- a/src/g_shared/hudmessages.cpp +++ b/src/g_shared/hudmessages.cpp @@ -220,10 +220,6 @@ void DHUDMessage::OnDestroy() { V_FreeBrokenLines (Lines); Lines = NULL; - if (screen != NULL) - { - V_SetBorderNeedRefresh(); - } } if (SourceText != NULL) { @@ -618,7 +614,6 @@ void DHUDMessageFadeOut::DoDraw (int linenum, int x, int y, bool clean, int hudh DTA_RenderStyle, Style, TAG_DONE); } - V_SetBorderNeedRefresh(); } } @@ -708,7 +703,6 @@ void DHUDMessageFadeInOut::DoDraw (int linenum, int x, int y, bool clean, int hu DTA_RenderStyle, Style, TAG_DONE); } - V_SetBorderNeedRefresh(); } else { diff --git a/src/g_shared/shared_hud.cpp b/src/g_shared/shared_hud.cpp index 34f5c3b65a..da66b9205e 100644 --- a/src/g_shared/shared_hud.cpp +++ b/src/g_shared/shared_hud.cpp @@ -178,8 +178,8 @@ static void DrawHudText(FFont *font, int color, char * text, int x, int y, doubl FTexture *texc = font->GetChar(text[i], &width); if (texc != NULL) { - double offset = texc->GetScaledTopOffsetDouble() - - tex_zero->GetScaledTopOffsetDouble() + double offset = texc->GetScaledTopOffsetDouble(0) + - tex_zero->GetScaledTopOffsetDouble(0) + tex_zero->GetScaledHeightDouble(); screen->DrawChar(font, color, x, y, text[i], diff --git a/src/g_statusbar/sbar.h b/src/g_statusbar/sbar.h index 31a33a99f1..a0f8edbdaf 100644 --- a/src/g_statusbar/sbar.h +++ b/src/g_statusbar/sbar.h @@ -405,7 +405,6 @@ public: void AttachToPlayer(player_t *player); DVector2 GetHUDScale() const; virtual void FlashCrosshair (); - virtual void BlendView (float blend[4]); void NewGame (); virtual void ScreenSizeChanged (); void CallScreenSizeChanged(); diff --git a/src/g_statusbar/sbarinfo.cpp b/src/g_statusbar/sbarinfo.cpp index d048ffc0e4..277684a6a5 100644 --- a/src/g_statusbar/sbarinfo.cpp +++ b/src/g_statusbar/sbarinfo.cpp @@ -1199,12 +1199,12 @@ public: if((offsetflags & SBarInfoCommand::CENTER) == SBarInfoCommand::CENTER) { - if (forceWidth < 0) dx -= (texture->GetScaledWidthDouble()/2.0)-texture->GetScaledLeftOffsetDouble(); - else dx -= forceWidth*(0.5-(texture->GetScaledLeftOffsetDouble()/texture->GetScaledWidthDouble())); + if (forceWidth < 0) dx -= (texture->GetScaledWidthDouble()/2.0)-texture->GetScaledLeftOffsetDouble(0); + else dx -= forceWidth*(0.5-(texture->GetScaledLeftOffsetDouble(0)/texture->GetScaledWidthDouble())); //Unoptimalized ^^formula is dx -= forceWidth/2.0-(texture->GetScaledLeftOffsetDouble()*forceWidth/texture->GetScaledWidthDouble()); - if (forceHeight < 0) dy -= (texture->GetScaledHeightDouble()/2.0)-texture->GetScaledTopOffsetDouble(); - else dy -= forceHeight*(0.5-(texture->GetScaledTopOffsetDouble()/texture->GetScaledHeightDouble())); + if (forceHeight < 0) dy -= (texture->GetScaledHeightDouble()/2.0)-texture->GetScaledTopOffsetDouble(0); + else dy -= forceHeight*(0.5-(texture->GetScaledTopOffsetDouble(0)/texture->GetScaledHeightDouble())); } dx += xOffset; @@ -1215,10 +1215,10 @@ public: double tmp = 0; w = forceWidth < 0 ? texture->GetScaledWidthDouble() : forceWidth; h = forceHeight < 0 ? texture->GetScaledHeightDouble() : forceHeight; - double dcx = clip[0] == 0 ? 0 : dx + clip[0] - texture->GetScaledLeftOffsetDouble(); - double dcy = clip[1] == 0 ? 0 : dy + clip[1] - texture->GetScaledTopOffsetDouble(); - double dcr = clip[2] == 0 ? INT_MAX : dx + w - clip[2] - texture->GetScaledLeftOffsetDouble(); - double dcb = clip[3] == 0 ? INT_MAX : dy + h - clip[3] - texture->GetScaledTopOffsetDouble(); + double dcx = clip[0] == 0 ? 0 : dx + clip[0] - texture->GetScaledLeftOffsetDouble(0); + double dcy = clip[1] == 0 ? 0 : dy + clip[1] - texture->GetScaledTopOffsetDouble(0); + double dcr = clip[2] == 0 ? INT_MAX : dx + w - clip[2] - texture->GetScaledLeftOffsetDouble(0); + double dcb = clip[3] == 0 ? INT_MAX : dy + h - clip[3] - texture->GetScaledTopOffsetDouble(0); if(clip[0] != 0 || clip[1] != 0) { @@ -1300,10 +1300,10 @@ public: // Check for clipping if(clip[0] != 0 || clip[1] != 0 || clip[2] != 0 || clip[3] != 0) { - rcx = clip[0] == 0 ? 0 : rx+((clip[0] - texture->GetScaledLeftOffsetDouble())*Scale.X); - rcy = clip[1] == 0 ? 0 : ry+((clip[1] - texture->GetScaledTopOffsetDouble())*Scale.Y); - rcr = clip[2] == 0 ? INT_MAX : rx+w-((clip[2] + texture->GetScaledLeftOffsetDouble())*Scale.X); - rcb = clip[3] == 0 ? INT_MAX : ry+h-((clip[3] + texture->GetScaledTopOffsetDouble())*Scale.Y); + rcx = clip[0] == 0 ? 0 : rx+((clip[0] - texture->GetScaledLeftOffsetDouble(0))*Scale.X); + rcy = clip[1] == 0 ? 0 : ry+((clip[1] - texture->GetScaledTopOffsetDouble(0))*Scale.Y); + rcr = clip[2] == 0 ? INT_MAX : rx+w-((clip[2] + texture->GetScaledLeftOffsetDouble(0))*Scale.X); + rcb = clip[3] == 0 ? INT_MAX : ry+h-((clip[3] + texture->GetScaledTopOffsetDouble(0))*Scale.Y); } if(clearDontDraw) @@ -1399,8 +1399,8 @@ public: } int character = (unsigned char)*str; - if(script->spacingCharacter == '\0') //If we are monospaced lets use the offset - ax += (c->LeftOffset+1); //ignore x offsets since we adapt to character size + if (script->spacingCharacter == '\0') //If we are monospaced lets use the offset + ax += (c->GetLeftOffset(0) + 1); //ignore x offsets since we adapt to character size double rx, ry, rw, rh; rx = ax + xOffset; @@ -1463,8 +1463,8 @@ public: DTA_DestHeightF, rh, DTA_Alpha, Alpha, TAG_DONE); - if(script->spacingCharacter == '\0') - ax += width + spacing - (c->LeftOffset+1); + if (script->spacingCharacter == '\0') + ax += width + spacing - (c->GetLeftOffset(0) + 1); else //width gets changed at the call to GetChar() ax += font->GetCharWidth((unsigned char) script->spacingCharacter) + spacing; str++; diff --git a/src/g_statusbar/shared_sbar.cpp b/src/g_statusbar/shared_sbar.cpp index ecbf2bd51a..6ea45eda59 100644 --- a/src/g_statusbar/shared_sbar.cpp +++ b/src/g_statusbar/shared_sbar.cpp @@ -95,10 +95,6 @@ extern int setblocks; FTexture *CrosshairImage; static int CrosshairNum; -// [RH] Base blending values (for e.g. underwater) -int BaseBlendR, BaseBlendG, BaseBlendB; -float BaseBlendA; - CVAR (Int, paletteflash, 0, CVAR_ARCHIVE) CVAR (Flag, pf_hexenweaps, paletteflash, PF_HEXENWEAPONS) CVAR (Flag, pf_poison, paletteflash, PF_POISON) @@ -197,10 +193,6 @@ void ST_LoadCrosshair(bool alwaysload) return; } - if (CrosshairImage != NULL) - { - CrosshairImage->Unload (); - } if (num == 0) { CrosshairNum = 0; @@ -835,8 +827,8 @@ void DBaseStatusBar::RefreshBackground () const { if(y < SCREENHEIGHT) { - V_DrawBorder (x+1, y, SCREENWIDTH, y+1); - V_DrawBorder (x+1, SCREENHEIGHT-1, SCREENWIDTH, SCREENHEIGHT); + screen->DrawBorder (x+1, y, SCREENWIDTH, y+1); + screen->DrawBorder (x+1, SCREENHEIGHT-1, SCREENWIDTH, SCREENHEIGHT); } } else @@ -855,8 +847,8 @@ void DBaseStatusBar::RefreshBackground () const x2 = SCREENWIDTH; } - V_DrawBorder (0, y, x+1, SCREENHEIGHT); - V_DrawBorder (x2-1, y, SCREENWIDTH, SCREENHEIGHT); + screen->DrawBorder (0, y, x+1, SCREENHEIGHT); + screen->DrawBorder (x2-1, y, SCREENWIDTH, SCREENHEIGHT); if (setblocks >= 10) { @@ -1017,7 +1009,6 @@ void DBaseStatusBar::Draw (EHudState state) VMValue params[] = { (DObject*)this }; VMCall(func, params, countof(params), nullptr, 0); } - V_SetBorderNeedRefresh(); } if (viewactive) @@ -1197,29 +1188,6 @@ void DBaseStatusBar::DrawTopStuff (EHudState state) } } -//--------------------------------------------------------------------------- -// -// BlendView -// -//--------------------------------------------------------------------------- - -void DBaseStatusBar::BlendView (float blend[4]) -{ - // [Nash] Allow user to set blend intensity - float cnt = (BaseBlendA * underwater_fade_scalar); - - V_AddBlend (BaseBlendR / 255.f, BaseBlendG / 255.f, BaseBlendB / 255.f, cnt, blend); - V_AddPlayerBlend(CPlayer, blend, 1.0f, 228); - - if (screen->Accel2D || (CPlayer->camera != NULL && menuactive == MENU_Off && ConsoleState == c_up)) - { - player_t *player = (CPlayer->camera != NULL && CPlayer->camera->player != NULL) ? CPlayer->camera->player : CPlayer; - V_AddBlend (player->BlendR, player->BlendG, player->BlendB, player->BlendA, blend); - } - - V_SetBlend ((int)(blend[0] * 255.0f), (int)(blend[1] * 255.0f), - (int)(blend[2] * 255.0f), (int)(blend[3] * 256.0f)); -} void DBaseStatusBar::DrawConsistancy () const { @@ -1261,7 +1229,6 @@ void DBaseStatusBar::DrawConsistancy () const screen->DrawText (SmallFont, CR_GREEN, (screen->GetWidth() - SmallFont->StringWidth (conbuff)*CleanXfac) / 2, 0, conbuff, DTA_CleanNoMove, true, TAG_DONE); - BorderTopRefresh = screen->GetPageCount (); } } @@ -1294,7 +1261,6 @@ void DBaseStatusBar::DrawWaiting () const screen->DrawText (SmallFont, CR_ORANGE, (screen->GetWidth() - SmallFont->StringWidth (conbuff)*CleanXfac) / 2, SmallFont->GetHeight()*CleanYfac, conbuff, DTA_CleanNoMove, true, TAG_DONE); - BorderTopRefresh = screen->GetPageCount (); } } @@ -1581,14 +1547,14 @@ void DBaseStatusBar::DrawGraphic(FTextureID texture, double x, double y, int fla { case DI_ITEM_HCENTER: x -= boxwidth / 2; break; case DI_ITEM_RIGHT: x -= boxwidth; break; - case DI_ITEM_HOFFSET: x -= tex->GetScaledLeftOffsetDouble() * boxwidth / texwidth; break; + case DI_ITEM_HOFFSET: x -= tex->GetScaledLeftOffsetDouble(0) * boxwidth / texwidth; break; } switch (flags & DI_ITEM_VMASK) { case DI_ITEM_VCENTER: y -= boxheight / 2; break; case DI_ITEM_BOTTOM: y -= boxheight; break; - case DI_ITEM_VOFFSET: y -= tex->GetScaledTopOffsetDouble() * boxheight / texheight; break; + case DI_ITEM_VOFFSET: y -= tex->GetScaledTopOffsetDouble(0) * boxheight / texheight; break; } if (!fullscreenOffsets) @@ -1795,7 +1761,7 @@ void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, d } if (!monospaced) //If we are monospaced lets use the offset - x += (c->LeftOffset + 1); //ignore x offsets since we adapt to character size + x += (c->GetLeftOffset(0) + 1); //ignore x offsets since we adapt to character size double rx, ry, rw, rh; rx = x + drawOffset.X; @@ -1835,7 +1801,7 @@ void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, d TAG_DONE); if (!monospaced) - x += width + spacing - (c->LeftOffset + 1); + x += width + spacing - (c->GetLeftOffset(0) + 1); else x += spacing; } diff --git a/src/gl/compatibility/gl_20.cpp b/src/gl/compatibility/gl_20.cpp index e5f097228e..28ceb6be65 100644 --- a/src/gl/compatibility/gl_20.cpp +++ b/src/gl/compatibility/gl_20.cpp @@ -41,7 +41,6 @@ #include "actorinlines.h" #include "g_levellocals.h" #include "gl/dynlights/gl_dynlight.h" -#include "gl/utility/gl_geometric.h" #include "gl/renderer/gl_renderer.h" #include "gl/renderer/gl_lightdata.h" #include "gl/system/gl_interface.h" @@ -53,7 +52,6 @@ CVAR(Bool, gl_lights_additive, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -CVAR(Bool, gl_legacy_mode, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOSET) //========================================================================== // @@ -65,7 +63,7 @@ CVAR(Bool, gl_legacy_mode, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOSET) void gl_PatchMenu() { // Radial fog and Doom lighting are not available without full shader support. - if (!gl_legacy_mode) return; + if (!gl.legacyMode) return; FOptionValues **opt = OptionValues.CheckKey("LightingModes"); if (opt != NULL) @@ -132,6 +130,31 @@ void gl_PatchMenu() void gl_SetTextureMode(int type) { + if (type == TM_SWCANVAS) + { + int shader = V_IsTrueColor() ? 2 : 0; + float c1[4], c2[4]; + if (gl_RenderState.mColormapState > CM_DEFAULT && gl_RenderState.mColormapState < CM_MAXCOLORMAP) + { + FSpecialColormap *scm = &SpecialColormaps[gl_RenderState.mColormapState - CM_FIRSTSPECIALCOLORMAP]; + for (int i = 0; i < 3; i++) + { + c1[i] = scm->ColorizeStart[i]; + c2[i] = scm->ColorizeEnd[i] - scm->ColorizeStart[i]; + } + c1[3] = 0; + c2[3] = 0; + shader++; + } + // Type 2 (unaltered true color) can be done without activating the shader. + if (shader != 2) + { + GLRenderer->legacyShaders->BindShader(shader, c1, c2); + return; + } + else type = TM_MODULATE; + } + glUseProgram(0); if (type == TM_MASK) { glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); @@ -209,7 +232,7 @@ static bool currentModelMatrixState; void FRenderState::ApplyFixedFunction() { - int thistm = mTextureMode == TM_MODULATE && mTempTM == TM_OPAQUE ? TM_OPAQUE : mTextureMode; + int thistm = mTextureMode == TM_MODULATE && (mTempTM == TM_OPAQUE || mSpecialEffect == EFF_SWQUAD) ? TM_OPAQUE : mTextureMode; if (thistm != ffTextureMode) { ffTextureMode = thistm; @@ -407,6 +430,12 @@ bool gl_SetupLight(int group, Plane & p, ADynamicLight * light, FVector3 & nearP float dist = fabsf(p.DistToPoint(lpos.X, lpos.Z, lpos.Y)); float radius = light->GetRadius(); + if (V_IsHardwareRenderer() && gl.legacyMode && (light->lightflags & LF_ATTENUATE)) + { + radius *= 0.66f; + } + + if (radius <= 0.f) return false; if (dist > radius) return false; if (checkside && gl_lights_checkside && p.PointOnSide(lpos.X, lpos.Z, lpos.Y)) @@ -486,7 +515,7 @@ static bool gl_CheckFog(FColormap *cm, int lightlevel) { frontfog = true; } - else if (level.fogdensity != 0 || (glset.lightmode & 4) || cm->FogDensity > 0) + else if (level.fogdensity != 0 || (level.lightmode & 4) || cm->FogDensity > 0) { // case 3: level has fog density set frontfog = true; @@ -641,7 +670,7 @@ void GLFlat::DrawSubsectorLights(subsector_t * sub, int pass) continue; } - p.Set(plane.plane); + p.Set(plane.plane.Normal(), plane.plane.fD()); if (!gl_SetupLight(sub->sector->PortalGroup, p, light, nearPt, up, right, scale, false, pass != GLPASS_LIGHTTEX)) { node = node->nextLight; @@ -715,7 +744,8 @@ bool GLWall::PrepareLight(ADynamicLight * light, int pass) FVector3 nearPt, up, right; float scale; - p.Set(&glseg); + auto normal = glseg.Normal(); + p.Set(normal, -normal.X * glseg.x1 - normal.Y * glseg.y1); if (!p.ValidNormal()) { @@ -849,7 +879,7 @@ void GLSceneDrawer::RenderMultipassStuff() { gl_RenderState.BlendFunc(GL_ONE, GL_ONE); glDepthFunc(GL_EQUAL); - if (glset.lightmode == 8) gl_RenderState.SetSoftLightLevel(255); + if (level.lightmode == 8) gl_RenderState.SetSoftLightLevel(255); gl_drawinfo->dldrawlists[GLLDL_WALLS_PLAIN].DrawWalls(GLPASS_LIGHTTEX); gl_drawinfo->dldrawlists[GLLDL_WALLS_MASKED].DrawWalls(GLPASS_LIGHTTEX); gl_drawinfo->dldrawlists[GLLDL_FLATS_PLAIN].DrawFlats(GLPASS_LIGHTTEX); @@ -896,3 +926,79 @@ void GLSceneDrawer::RenderMultipassStuff() } + +//========================================================================== +// +// Draws a color overlay for Legacy OpenGL +// +//========================================================================== + +void LegacyColorOverlay(F2DDrawer *drawer, F2DDrawer::RenderCommand & cmd) +{ + if (cmd.mDrawMode == F2DDrawer::DTM_Opaque || cmd.mDrawMode == F2DDrawer::DTM_InvertOpaque) + { + gl_RenderState.EnableTexture(false); + } + else + { + gl_RenderState.SetTextureMode(TM_MASK); + } + // Draw this the old fashioned way, there really is no point setting up a buffer for it. + glBegin(GL_TRIANGLES); + for (int i = 0; i < cmd.mIndexCount; i++) + { + auto &vertex = drawer->mVertices[drawer->mIndices[i + cmd.mIndexIndex]]; + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + glBlendEquation(GL_FUNC_ADD); + glColor4ub(cmd.mColor1.r, cmd.mColor1.g, cmd.mColor1.b, vertex.color0.a); + glTexCoord2f(vertex.u, vertex.v); + glVertex3f(vertex.x, vertex.y, vertex.z); + } + glEnd(); +} + +//========================================================================== +// +// Desaturation with translations. +// Let's keep this fallback crap strictly out of the main code, +// including the data it creates! +// +//========================================================================== + +struct DesaturatedTranslations +{ + FRemapTable *tables[32] = { nullptr }; +}; + +static TMap DesaturatedTranslationTable; +static TDeletingArray DesaturatedRemaps; // This is only here to delete the remap tables without infesting other code. + + +int LegacyDesaturation(F2DDrawer::RenderCommand &cmd) +{ + int desat = cmd.mDesaturate / 8; + if (desat <= 0 || desat >= 32) return -1; + if(cmd.mTranslation == nullptr) return desat - 1 + STRange_Desaturate; + // Now it gets nasty. We got a combination of translation and desaturation. + + // The easy case: It was already done. + auto find = DesaturatedTranslationTable.CheckKey(cmd.mTranslation); + if (find != nullptr && find->tables[desat] != nullptr) return find->tables[desat]->GetUniqueIndex(); + + // To handle this case for the legacy renderer a desaturated variant of the translation needs to be built. + auto newremap = new FRemapTable(*cmd.mTranslation); + DesaturatedRemaps.Push(newremap); + for (int i = 0; i < newremap->NumEntries; i++) + { + // This is used for true color texture creation, so the remap table can be left alone. + auto &p = newremap->Palette[i]; + auto gray = p.Luminance(); + + p.r = (p.r * (31 - desat) + gray * (1 + desat)) / 32; + p.g = (p.g * (31 - desat) + gray * (1 + desat)) / 32; + p.b = (p.b * (31 - desat) + gray * (1 + desat)) / 32; + } + auto &tbl = DesaturatedTranslationTable[cmd.mTranslation]; + tbl.tables[desat] = newremap; + return newremap->GetUniqueIndex(); +} \ No newline at end of file diff --git a/src/gl/compatibility/gl_swshader20.cpp b/src/gl/compatibility/gl_swshader20.cpp new file mode 100644 index 0000000000..334a09612c --- /dev/null +++ b/src/gl/compatibility/gl_swshader20.cpp @@ -0,0 +1,220 @@ +// +//--------------------------------------------------------------------------- +// +// Copyright(C) 2018 Christoph Oelckers +// All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see http://www.gnu.org/licenses/ +// +//-------------------------------------------------------------------------- +// +/* +** gl_swshader20.cpp +** +** Implements the shaders used to render the software renderer's +** 3D output to the screen, +** +*/ + +#include "gl/system/gl_system.h" +#include "tarray.h" +#include "doomtype.h" +#include "zstring.h" +#include "i_system.h" +#include "r_utility.h" +#include "w_wad.h" +#include "gl/dynlights/gl_dynlight.h" +#include "gl/renderer/gl_renderer.h" +#include "gl/system/gl_interface.h" +#include "gl/renderer/gl_renderstate.h" + + +class LegacyShader +{ +public: + ~LegacyShader() + { + if (Program != 0) glDeleteProgram(Program); + if (VertexShader != 0) glDeleteShader(VertexShader); + if (FragmentShader != 0) glDeleteShader(FragmentShader); + } + + int Program = 0; + int VertexShader = 0; + int FragmentShader = 0; + + int ConstantLocations[2]; + int ImageLocation = -1; + int PaletteLocation = -1; +}; + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +LegacyShaderContainer::LegacyShaderContainer() +{ + if (!LoadShaders()) + { + Printf("Unable to compile shaders for software rendering\n"); + } +} + +LegacyShaderContainer::~LegacyShaderContainer() +{ + for (auto p : Shaders) if (p) delete p; +} + +LegacyShader* LegacyShaderContainer::CreatePixelShader(const FString& vertex, const FString& fragment, const FString &defines) +{ + auto shader = new LegacyShader(); + char buffer[10000]; + + shader->Program = glCreateProgram(); + if (shader->Program == 0) { Printf("glCreateProgram failed. Disabling OpenGL hardware acceleration.\n"); return nullptr; } + shader->VertexShader = glCreateShader(GL_VERTEX_SHADER); + if (shader->VertexShader == 0) { Printf("glCreateShader(GL_VERTEX_SHADER) failed. Disabling OpenGL hardware acceleration.\n"); return nullptr; } + shader->FragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + if (shader->FragmentShader == 0) { Printf("glCreateShader(GL_FRAGMENT_SHADER) failed. Disabling OpenGL hardware acceleration.\n"); return nullptr; } + + { + FString vertexsrc = defines + vertex; + int lengths[1] = { (int)vertexsrc.Len() }; + const char *sources[1] = { vertexsrc.GetChars() }; + glShaderSource(shader->VertexShader, 1, sources, lengths); + glCompileShader(shader->VertexShader); + } + + { + FString fragmentsrc = defines + fragment; + int lengths[1] = { (int)fragmentsrc.Len() }; + const char *sources[1] = { fragmentsrc.GetChars() }; + glShaderSource(shader->FragmentShader, 1, sources, lengths); + glCompileShader(shader->FragmentShader); + } + + GLint status = 0; + int errorShader = shader->VertexShader; + glGetShaderiv(shader->VertexShader, GL_COMPILE_STATUS, &status); + if (status != GL_FALSE) + { + errorShader = shader->FragmentShader; + glGetShaderiv(shader->FragmentShader, GL_COMPILE_STATUS, &status); + } + if (status == GL_FALSE) + { + GLsizei length = 0; + buffer[0] = 0; + glGetShaderInfoLog(errorShader, 10000, &length, buffer); + Printf("Shader compile failed: %s", buffer); + delete shader; + return nullptr; + } + + glAttachShader(shader->Program, shader->VertexShader); + glAttachShader(shader->Program, shader->FragmentShader); + glLinkProgram(shader->Program); + glGetProgramiv(shader->Program, GL_LINK_STATUS, &status); + if (status == GL_FALSE) + { + GLsizei length = 0; + buffer[0] = 0; + glGetProgramInfoLog(shader->Program, 10000, &length, buffer); + Printf("Shader link failed: %s", buffer); + delete shader; + return nullptr; + } + + shader->ConstantLocations[0] = glGetUniformLocation(shader->Program, "uColor1"); + shader->ConstantLocations[1] = glGetUniformLocation(shader->Program, "uColor2"); + shader->ImageLocation = glGetUniformLocation(shader->Program, "tex"); + shader->PaletteLocation = glGetUniformLocation(shader->Program, "palette"); + + return shader; +} + +//========================================================================== +// +// SWSceneDrawer :: LoadShaders +// +// Returns true if all required shaders were loaded. (Gamma and burn wipe +// are the only ones not considered "required".) +// +//========================================================================== + +static const char * const ShaderDefines[] = { + "#define PAL_TEX\n", + "#define PAL_TEX\n#define SPECIALCM\n", + "", + "#define SPECIALCM\n", +}; + +bool LegacyShaderContainer::LoadShaders() +{ + int lumpvert = Wads.CheckNumForFullName("shaders/swgl/swshadergl2.vp"); + int lumpfrag = Wads.CheckNumForFullName("shaders/swgl/swshadergl2.fp"); + if (lumpvert < 0 || lumpfrag < 0) + return false; + + FString vertsource = Wads.ReadLump(lumpvert).GetString(); + FString fragsource = Wads.ReadLump(lumpfrag).GetString(); + + FString shaderdir, shaderpath; + unsigned int i; + + for (i = 0; i < NUM_SHADERS; ++i) + { + shaderpath = shaderdir; + Shaders[i] = CreatePixelShader(vertsource, fragsource, ShaderDefines[i]); + if (!Shaders[i]) + { + break; + } + + glUseProgram(Shaders[i]->Program); + if (Shaders[i]->ImageLocation != -1) glUniform1i(Shaders[i]->ImageLocation, 0); + if (Shaders[i]->PaletteLocation != -1) glUniform1i(Shaders[i]->PaletteLocation, 1); + glUseProgram(0); + } + if (i == NUM_SHADERS) + { // Success! + return true; + } + // Failure. Release whatever managed to load (which is probably nothing.) + for (i = 0; i < NUM_SHADERS; ++i) + { + if (Shaders[i]) delete Shaders[i]; + } + return false; +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void LegacyShaderContainer::BindShader(int num, const float *p1, const float *p2) +{ + if (num >= 0 && num < 4) + { + auto shader = Shaders[num]; + glUseProgram(shader->Program); + glUniform4fv(shader->ConstantLocations[0], 1, p1); + glUniform4fv(shader->ConstantLocations[1], 1, p2); + } +} + diff --git a/src/gl/data/gl_data.cpp b/src/gl/data/gl_data.cpp deleted file mode 100644 index 6a7747e365..0000000000 --- a/src/gl/data/gl_data.cpp +++ /dev/null @@ -1,414 +0,0 @@ -// -//--------------------------------------------------------------------------- -// -// Copyright(C) 2005-2016 Christoph Oelckers -// All rights reserved. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with this program. If not, see http://www.gnu.org/licenses/ -// -//-------------------------------------------------------------------------- -// -/* -** gl_data.cpp -** Maintenance data for GL renderer (mostly to handle rendering hacks) -** -**/ - -#include "gl/system/gl_system.h" - -#include "doomtype.h" -#include "colormatcher.h" -#include "i_system.h" -#include "p_local.h" -#include "p_tags.h" -#include "p_lnspec.h" -#include "c_dispatch.h" -#include "r_sky.h" -#include "sc_man.h" -#include "w_wad.h" -#include "gi.h" -#include "g_level.h" -#include "doomstat.h" -#include "d_player.h" -#include "g_levellocals.h" - -#include "gl/system/gl_interface.h" -#include "gl/renderer/gl_renderer.h" -#include "gl/renderer/gl_lightdata.h" -#include "gl/data/gl_data.h" -#include "gl/dynlights/gl_dynlight.h" -#include "gl/dynlights/gl_glow.h" -#include "gl/models/gl_models.h" -#include "gl/utility/gl_clock.h" -#include "gl/shaders/gl_shader.h" -#include "gl/gl_functions.h" - -GLRenderSettings glset; - -EXTERN_CVAR(Int, gl_lightmode) -EXTERN_CVAR(Bool, gl_brightfog) -EXTERN_CVAR(Bool, gl_lightadditivesurfaces) - - -CUSTOM_CVAR(Bool, gl_notexturefill, false, 0) -{ - glset.notexturefill = self; -} - - -void gl_CreateSections(); -void AddAutoMaterials(); - -//----------------------------------------------------------------------------- -// -// Adjust sprite offsets for GL rendering (IWAD resources only) -// -//----------------------------------------------------------------------------- - -void AdjustSpriteOffsets() -{ - int lump, lastlump = 0; - int sprid; - TMap donotprocess; - - int numtex = Wads.GetNumLumps(); - - for (int i = 0; i < numtex; i++) - { - if (Wads.GetLumpFile(i) > Wads.GetIwadNum()) break; // we are past the IWAD - if (Wads.GetLumpNamespace(i) == ns_sprites && Wads.GetLumpFile(i) == Wads.GetIwadNum()) - { - char str[9]; - Wads.GetLumpName(str, i); - str[8] = 0; - FTextureID texid = TexMan.CheckForTexture(str, ETextureType::Sprite, 0); - if (texid.isValid() && Wads.GetLumpFile(TexMan[texid]->SourceLump) > Wads.GetIwadNum()) - { - // This texture has been replaced by some PWAD. - memcpy(&sprid, str, 4); - donotprocess[sprid] = true; - } - } - } - - while ((lump = Wads.FindLump("SPROFS", &lastlump, false)) != -1) - { - FScanner sc; - sc.OpenLumpNum(lump); - sc.SetCMode(true); - GLRenderer->FlushTextures(); - int ofslumpno = Wads.GetLumpFile(lump); - while (sc.GetString()) - { - int x,y; - bool iwadonly = false; - bool forced = false; - FTextureID texno = TexMan.CheckForTexture(sc.String, ETextureType::Sprite); - sc.MustGetStringName(","); - sc.MustGetNumber(); - x=sc.Number; - sc.MustGetStringName(","); - sc.MustGetNumber(); - y=sc.Number; - if (sc.CheckString(",")) - { - sc.MustGetString(); - if (sc.Compare("iwad")) iwadonly = true; - if (sc.Compare("iwadforced")) forced = iwadonly = true; - } - if (texno.isValid()) - { - FTexture * tex = TexMan[texno]; - - int lumpnum = tex->GetSourceLump(); - // We only want to change texture offsets for sprites in the IWAD or the file this lump originated from. - if (lumpnum >= 0 && lumpnum < Wads.GetNumLumps()) - { - int wadno = Wads.GetLumpFile(lumpnum); - if ((iwadonly && wadno==Wads.GetIwadNum()) || (!iwadonly && wadno == ofslumpno)) - { - if (wadno == Wads.GetIwadNum() && !forced && iwadonly) - { - memcpy(&sprid, &tex->Name[0], 4); - if (donotprocess.CheckKey(sprid)) continue; // do not alter sprites that only get partially replaced. - } - tex->LeftOffset=x; - tex->TopOffset=y; - tex->KillNative(); - } - } - } - } - } -} - - - -//========================================================================== -// -// Portal identifier lists -// -//========================================================================== - - -//========================================================================== -// -// MAPINFO stuff -// -//========================================================================== - -struct FGLROptions : public FOptionalMapinfoData -{ - FGLROptions() - { - identifier = "gl_renderer"; - brightfog = false; - lightmode = -1; - notexturefill = -1; - skyrotatevector = FVector3(0,0,1); - skyrotatevector2 = FVector3(0,0,1); - lightadditivesurfaces = false; - } - virtual FOptionalMapinfoData *Clone() const - { - FGLROptions *newopt = new FGLROptions; - newopt->identifier = identifier; - newopt->lightmode = lightmode; - newopt->notexturefill = notexturefill; - newopt->skyrotatevector = skyrotatevector; - newopt->skyrotatevector2 = skyrotatevector2; - newopt->lightadditivesurfaces = lightadditivesurfaces; - return newopt; - } - int lightmode; - int brightfog; - int8_t lightadditivesurfaces; - int8_t notexturefill; - FVector3 skyrotatevector; - FVector3 skyrotatevector2; -}; - -DEFINE_MAP_OPTION(brightfog, false) -{ - FGLROptions *opt = info->GetOptData("gl_renderer"); - parse.ParseAssign(); - parse.sc.MustGetNumber(); - opt->brightfog = parse.sc.Number; -} - -DEFINE_MAP_OPTION(lightmode, false) -{ - FGLROptions *opt = info->GetOptData("gl_renderer"); - parse.ParseAssign(); - parse.sc.MustGetNumber(); - opt->lightmode = uint8_t(parse.sc.Number); -} - -DEFINE_MAP_OPTION(notexturefill, false) -{ - FGLROptions *opt = info->GetOptData("gl_renderer"); - if (parse.CheckAssign()) - { - parse.sc.MustGetNumber(); - opt->notexturefill = !!parse.sc.Number; - } - else - { - opt->notexturefill = true; - } -} - -DEFINE_MAP_OPTION(lightadditivesurfaces, false) -{ - FGLROptions *opt = info->GetOptData("gl_renderer"); - if (parse.CheckAssign()) - { - parse.sc.MustGetNumber(); - opt->lightadditivesurfaces = !!parse.sc.Number; - } - else - { - opt->lightadditivesurfaces = true; - } -} - -DEFINE_MAP_OPTION(skyrotate, false) -{ - FGLROptions *opt = info->GetOptData("gl_renderer"); - - parse.ParseAssign(); - parse.sc.MustGetFloat(); - opt->skyrotatevector.X = (float)parse.sc.Float; - if (parse.format_type == FMapInfoParser::FMT_New) parse.sc.MustGetStringName(","); - parse.sc.MustGetFloat(); - opt->skyrotatevector.Y = (float)parse.sc.Float; - if (parse.format_type == FMapInfoParser::FMT_New) parse.sc.MustGetStringName(","); - parse.sc.MustGetFloat(); - opt->skyrotatevector.Z = (float)parse.sc.Float; - opt->skyrotatevector.MakeUnit(); -} - -DEFINE_MAP_OPTION(skyrotate2, false) -{ - FGLROptions *opt = info->GetOptData("gl_renderer"); - - parse.ParseAssign(); - parse.sc.MustGetFloat(); - opt->skyrotatevector2.X = (float)parse.sc.Float; - if (parse.format_type == FMapInfoParser::FMT_New) parse.sc.MustGetStringName(","); - parse.sc.MustGetFloat(); - opt->skyrotatevector2.Y = (float)parse.sc.Float; - if (parse.format_type == FMapInfoParser::FMT_New) parse.sc.MustGetStringName(","); - parse.sc.MustGetFloat(); - opt->skyrotatevector2.Z = (float)parse.sc.Float; - opt->skyrotatevector2.MakeUnit(); -} - -bool IsLightmodeValid() -{ - return (glset.map_lightmode >= 0 && glset.map_lightmode <= 4) || glset.map_lightmode == 8; -} - -static void ResetOpts() -{ - if (!IsLightmodeValid()) glset.lightmode = gl_lightmode; - else glset.lightmode = glset.map_lightmode; - if (glset.map_notexturefill == -1) glset.notexturefill = gl_notexturefill; - else glset.notexturefill = !!glset.map_notexturefill; - if (glset.map_brightfog == -1) glset.brightfog = gl_brightfog; - else glset.brightfog = !!glset.map_brightfog; - if (glset.map_lightadditivesurfaces == -1) glset.lightadditivesurfaces = gl_lightadditivesurfaces; - else glset.lightadditivesurfaces = !!glset.map_lightadditivesurfaces; -} - -void InitGLRMapinfoData() -{ - FGLROptions *opt = level.info->GetOptData("gl_renderer", false); - - if (opt != NULL) - { - glset.map_lightmode = opt->lightmode; - glset.map_lightadditivesurfaces = opt->lightadditivesurfaces; - glset.map_brightfog = opt->brightfog; - glset.map_notexturefill = opt->notexturefill; - glset.skyrotatevector = opt->skyrotatevector; - glset.skyrotatevector2 = opt->skyrotatevector2; - } - else - { - glset.map_lightmode = -1; - glset.map_lightadditivesurfaces = -1; - glset.map_brightfog = -1; - glset.map_notexturefill = -1; - glset.skyrotatevector = FVector3(0, 0, 1); - glset.skyrotatevector2 = FVector3(0, 0, 1); - } - ResetOpts(); -} -CCMD(gl_resetmap) -{ - ResetOpts(); -} - - -//========================================================================== -// -// Recalculate all heights affecting this vertex. -// -//========================================================================== -void gl_RecalcVertexHeights(vertex_t * v) -{ - int i,j,k; - float height; - - v->numheights=0; - for(i=0;inumsectors;i++) - { - for(j=0;j<2;j++) - { - if (j==0) height=v->sectors[i]->ceilingplane.ZatPoint(v); - else height=v->sectors[i]->floorplane.ZatPoint(v); - - for(k=0;knumheights;k++) - { - if (height == v->heightlist[k]) break; - if (height < v->heightlist[k]) - { - memmove(&v->heightlist[k+1], &v->heightlist[k], sizeof(float) * (v->numheights-k)); - v->heightlist[k]=height; - v->numheights++; - break; - } - } - if (k==v->numheights) v->heightlist[v->numheights++]=height; - } - } - if (v->numheights<=2) v->numheights=0; // is not in need of any special attention - v->dirty = false; -} - - - - -void gl_InitData() -{ - AdjustSpriteOffsets(); - AddAutoMaterials(); -} - -//========================================================================== -// -// dumpgeometry -// -//========================================================================== - -CCMD(dumpgeometry) -{ - for(auto §or : level.sectors) - { - Printf(PRINT_LOG, "Sector %d\n", sector.sectornum); - for(int j=0;jIndex()), sub->sector->sectornum, sub->hacked&1? "hacked":""); - for(uint32_t k=0;knumlines;k++) - { - seg_t * seg = sub->firstline + k; - if (seg->linedef) - { - Printf(PRINT_LOG, " (%4.4f, %4.4f), (%4.4f, %4.4f) - seg %d, linedef %d, side %d", - seg->v1->fX(), seg->v1->fY(), seg->v2->fX(), seg->v2->fY(), - seg->Index(), seg->linedef->Index(), seg->sidedef != seg->linedef->sidedef[0]); - } - else - { - Printf(PRINT_LOG, " (%4.4f, %4.4f), (%4.4f, %4.4f) - seg %d, miniseg", - seg->v1->fX(), seg->v1->fY(), seg->v2->fX(), seg->v2->fY(), seg->Index()); - } - if (seg->PartnerSeg) - { - subsector_t * sub2 = seg->PartnerSeg->Subsector; - Printf(PRINT_LOG, ", back sector = %d, real back sector = %d", sub2->render_sector->sectornum, seg->PartnerSeg->frontsector->sectornum); - } - else if (seg->backsector) - { - Printf(PRINT_LOG, ", back sector = %d (no partnerseg)", seg->backsector->sectornum); - } - - Printf(PRINT_LOG, "\n"); - } - } - } -} diff --git a/src/gl/data/gl_data.h b/src/gl/data/gl_data.h deleted file mode 100644 index 518f330c90..0000000000 --- a/src/gl/data/gl_data.h +++ /dev/null @@ -1,68 +0,0 @@ - -#ifndef __GLC_DATA_H -#define __GLC_DATA_H - -#include "doomtype.h" -#include "vectors.h" -#include "r_utility.h" - -struct GLRenderSettings -{ - int8_t lightmode; - bool notexturefill; - bool brightfog; - bool lightadditivesurfaces; - - int8_t map_lightmode; - int8_t map_notexturefill; - int8_t map_brightfog; - int8_t map_lightadditivesurfaces; - - FVector3 skyrotatevector; - FVector3 skyrotatevector2; -}; - -extern GLRenderSettings glset; - -#include "r_defs.h" -#include "a_sharedglobal.h" -#include "c_cvars.h" - -EXTERN_CVAR(Int, gl_weaponlight); - -inline int getExtraLight() -{ - return r_viewpoint.extralight * gl_weaponlight; -} - -void gl_RecalcVertexHeights(vertex_t * v); - -struct GLSectorStackPortal; - -struct FPortal -{ - DVector2 mDisplacement; - int plane; - GLSectorStackPortal *glportal; // for quick access to the render data. This is only valid during BSP traversal! - - GLSectorStackPortal *GetRenderState(); -}; - -struct FGLLinePortal -{ - // defines the complete span of this portal, if this is of type PORTT_LINKED. - vertex_t *v1 = nullptr, *v2 = nullptr; // vertices, from v1 to v2 - TArray lines; - int validcount = 0; -}; - -extern TArray glSectorPortals; -extern TArray linePortalToGL; - -extern TArray currentmapsection; - -void gl_InitPortals(); -void gl_BuildPortalCoverage(FPortalCoverage *coverage, subsector_t *subsector, const DVector2 &displacement); -void gl_InitData(); - -#endif diff --git a/src/gl/data/gl_vertexbuffer.cpp b/src/gl/data/gl_vertexbuffer.cpp index 4973ad39de..8e9ab5c592 100644 --- a/src/gl/data/gl_vertexbuffer.cpp +++ b/src/gl/data/gl_vertexbuffer.cpp @@ -35,7 +35,6 @@ #include "gl/system/gl_interface.h" #include "gl/renderer/gl_renderer.h" #include "gl/shaders/gl_shader.h" -#include "gl/data/gl_data.h" #include "gl/data/gl_vertexbuffer.h" @@ -170,9 +169,9 @@ FFlatVertexBuffer::FFlatVertexBuffer(int width, int height) // and the second one for the fullscreen quad used for blend overlays. vbo_shadowdata[4].Set(0, 0, 0, 0, 0); - vbo_shadowdata[5].Set(0, (float)height, 0, 0, 0); - vbo_shadowdata[6].Set((float)width, 0, 0, 0, 0); - vbo_shadowdata[7].Set((float)width, (float)height, 0, 0, 0); + vbo_shadowdata[5].Set(0, (float)height, 0, 0, 1); + vbo_shadowdata[6].Set((float)width, 0, 0, 1, 0); + vbo_shadowdata[7].Set((float)width, (float)height, 0, 1, 1); // and this is for the postprocessing copy operation vbo_shadowdata[8].Set(-1.0f, -1.0f, 0, 0.0f, 0.0f); @@ -218,10 +217,10 @@ FFlatVertexBuffer::~FFlatVertexBuffer() void FFlatVertexBuffer::OutputResized(int width, int height) { vbo_shadowdata[4].Set(0, 0, 0, 0, 0); - vbo_shadowdata[5].Set(0, (float)height, 0, 0, 0); - vbo_shadowdata[6].Set((float)width, 0, 0, 0, 0); - vbo_shadowdata[7].Set((float)width, (float)height, 0, 0, 0); - + vbo_shadowdata[5].Set(0, (float)height, 0, 0, 1); + vbo_shadowdata[6].Set((float)width, 0, 0, 1, 0); + vbo_shadowdata[7].Set((float)width, (float)height, 0, 1, 1); + Map(); memcpy(&map[4], &vbo_shadowdata[4], 4 * sizeof(FFlatVertex)); Unmap(); @@ -299,7 +298,7 @@ static F3DFloor *Find3DFloor(sector_t *target, sector_t *model) for(unsigned i=0; ie->XFloor.ffloors.Size(); i++) { F3DFloor *ffloor = target->e->XFloor.ffloors[i]; - if (ffloor->model == model) return ffloor; + if (ffloor->model == model && !(ffloor->flags & FF_THISINSIDE)) return ffloor; } return NULL; } diff --git a/src/gl/dynlights/gl_dynlight.h b/src/gl/dynlights/gl_dynlight.h index 1ecdca4ce7..99979f034a 100644 --- a/src/gl/dynlights/gl_dynlight.h +++ b/src/gl/dynlights/gl_dynlight.h @@ -25,7 +25,6 @@ #include "c_cvars.h" #include "a_dynlight.h" -#include "gl/utility/gl_geometric.h" struct FDynLightData diff --git a/src/gl/dynlights/gl_dynlight1.cpp b/src/gl/dynlights/gl_dynlight1.cpp index 42f1c27cfb..9c3e40ad01 100644 --- a/src/gl/dynlights/gl_dynlight1.cpp +++ b/src/gl/dynlights/gl_dynlight1.cpp @@ -29,7 +29,6 @@ #include "c_dispatch.h" #include "p_local.h" #include "vectors.h" -#include "gl/gl_functions.h" #include "g_level.h" #include "actorinlines.h" #include "a_dynlight.h" @@ -37,7 +36,6 @@ #include "gl/system/gl_interface.h" #include "gl/renderer/gl_renderer.h" #include "gl/renderer/gl_lightdata.h" -#include "gl/data/gl_data.h" #include "gl/dynlights/gl_dynlight.h" #include "gl/scene/gl_drawinfo.h" #include "gl/scene/gl_portal.h" diff --git a/src/gl/dynlights/gl_glow.cpp b/src/gl/dynlights/gl_glow.cpp deleted file mode 100644 index 030ec21885..0000000000 --- a/src/gl/dynlights/gl_glow.cpp +++ /dev/null @@ -1,208 +0,0 @@ -// -//--------------------------------------------------------------------------- -// -// Copyright(C) 2005-2016 Christoph Oelckers -// All rights reserved. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with this program. If not, see http://www.gnu.org/licenses/ -// -//-------------------------------------------------------------------------- -// -/* -** gl_glow.cpp -** Glowing flats like Doomsday -** -**/ - -#include "w_wad.h" -#include "sc_man.h" -#include "v_video.h" -#include "r_defs.h" -#include "textures/textures.h" - -#include "gl/dynlights/gl_glow.h" - -//=========================================================================== -// -// Reads glow definitions from GLDEFS -// -//=========================================================================== -void gl_InitGlow(FScanner &sc) -{ - sc.MustGetStringName("{"); - while (!sc.CheckString("}")) - { - sc.MustGetString(); - if (sc.Compare("FLATS")) - { - sc.MustGetStringName("{"); - while (!sc.CheckString("}")) - { - sc.MustGetString(); - FTextureID flump=TexMan.CheckForTexture(sc.String, ETextureType::Flat,FTextureManager::TEXMAN_TryAny); - FTexture *tex = TexMan[flump]; - if (tex) tex->gl_info.bAutoGlowing = tex->gl_info.bGlowing = tex->gl_info.bFullbright = true; - } - } - else if (sc.Compare("WALLS")) - { - sc.MustGetStringName("{"); - while (!sc.CheckString("}")) - { - sc.MustGetString(); - FTextureID flump=TexMan.CheckForTexture(sc.String, ETextureType::Wall,FTextureManager::TEXMAN_TryAny); - FTexture *tex = TexMan[flump]; - if (tex) tex->gl_info.bAutoGlowing = tex->gl_info.bGlowing = tex->gl_info.bFullbright = true; - } - } - else if (sc.Compare("TEXTURE")) - { - sc.SetCMode(true); - sc.MustGetString(); - FTextureID flump=TexMan.CheckForTexture(sc.String, ETextureType::Flat,FTextureManager::TEXMAN_TryAny); - FTexture *tex = TexMan[flump]; - sc.MustGetStringName(","); - sc.MustGetString(); - PalEntry color = V_GetColor(NULL, sc.String); - //sc.MustGetStringName(","); - //sc.MustGetNumber(); - if (sc.CheckString(",")) - { - if (sc.CheckNumber()) - { - if (tex) tex->gl_info.GlowHeight = sc.Number; - if (!sc.CheckString(",")) goto skip_fb; - } - - sc.MustGetStringName("fullbright"); - if (tex) tex->gl_info.bFullbright = true; - } - skip_fb: - sc.SetCMode(false); - - if (tex && color != 0) - { - tex->gl_info.bAutoGlowing = false; - tex->gl_info.bGlowing = true; - tex->gl_info.GlowColor = color; - } - } - } -} - - -//========================================================================== -// -// Checks whether a sprite should be affected by a glow -// -//========================================================================== -int gl_CheckSpriteGlow(sector_t *sector, int lightlevel, const DVector3 &pos) -{ - float bottomglowcolor[4]; - bottomglowcolor[3] = 0; - auto c = sector->planes[sector_t::floor].GlowColor; - if (c == 0) - { - FTexture *tex = TexMan[sector->GetTexture(sector_t::floor)]; - if (tex != NULL && tex->isGlowing()) - { - if (!tex->gl_info.bAutoGlowing) tex = TexMan(sector->GetTexture(sector_t::floor)); - if (tex->isGlowing()) // recheck the current animation frame. - { - tex->GetGlowColor(bottomglowcolor); - bottomglowcolor[3] = (float)tex->gl_info.GlowHeight; - } - } - } - else if (c != ~0u) - { - bottomglowcolor[0] = c.r / 255.f; - bottomglowcolor[1] = c.g / 255.f; - bottomglowcolor[2] = c.b / 255.f; - bottomglowcolor[3] = sector->planes[sector_t::floor].GlowHeight; - } - - if (bottomglowcolor[3]> 0) - { - double floordiff = pos.Z - sector->floorplane.ZatPoint(pos); - if (floordiff < bottomglowcolor[3]) - { - int maxlight = (255 + lightlevel) >> 1; - double lightfrac = floordiff / bottomglowcolor[3]; - if (lightfrac < 0) lightfrac = 0; - lightlevel = int(lightfrac*lightlevel + maxlight*(1 - lightfrac)); - } - } - return lightlevel; -} - -//========================================================================== -// -// Checks whether a wall should glow -// -//========================================================================== -bool gl_GetWallGlow(sector_t *sector, float *topglowcolor, float *bottomglowcolor) -{ - bool ret = false; - bottomglowcolor[3] = topglowcolor[3] = 0; - auto c = sector->planes[sector_t::ceiling].GlowColor; - if (c == 0) - { - FTexture *tex = TexMan[sector->GetTexture(sector_t::ceiling)]; - if (tex != NULL && tex->isGlowing()) - { - if (!tex->gl_info.bAutoGlowing) tex = TexMan(sector->GetTexture(sector_t::ceiling)); - if (tex->isGlowing()) // recheck the current animation frame. - { - ret = true; - tex->GetGlowColor(topglowcolor); - topglowcolor[3] = (float)tex->gl_info.GlowHeight; - } - } - } - else if (c != ~0u) - { - topglowcolor[0] = c.r / 255.f; - topglowcolor[1] = c.g / 255.f; - topglowcolor[2] = c.b / 255.f; - topglowcolor[3] = sector->planes[sector_t::ceiling].GlowHeight; - ret = topglowcolor[3] > 0; - } - - c = sector->planes[sector_t::floor].GlowColor; - if (c == 0) - { - FTexture *tex = TexMan[sector->GetTexture(sector_t::floor)]; - if (tex != NULL && tex->isGlowing()) - { - if (!tex->gl_info.bAutoGlowing) tex = TexMan(sector->GetTexture(sector_t::floor)); - if (tex->isGlowing()) // recheck the current animation frame. - { - ret = true; - tex->GetGlowColor(bottomglowcolor); - bottomglowcolor[3] = (float)tex->gl_info.GlowHeight; - } - } - } - else if (c != ~0u) - { - bottomglowcolor[0] = c.r / 255.f; - bottomglowcolor[1] = c.g / 255.f; - bottomglowcolor[2] = c.b / 255.f; - bottomglowcolor[3] = sector->planes[sector_t::floor].GlowHeight; - ret = bottomglowcolor[3] > 0; - } - return ret; -} - diff --git a/src/gl/dynlights/gl_glow.h b/src/gl/dynlights/gl_glow.h deleted file mode 100644 index eb433c9996..0000000000 --- a/src/gl/dynlights/gl_glow.h +++ /dev/null @@ -1,11 +0,0 @@ - -#ifndef __GL_GLOW -#define __GL_GLOW - -struct sector_t; - -void gl_InitGlow(const char * lumpnm); -int gl_CheckSpriteGlow(sector_t *sec, int lightlevel, const DVector3 &pos); -bool gl_GetWallGlow(sector_t *sector, float *topglowcolor, float *bottomglowcolor); - -#endif diff --git a/src/gl/dynlights/gl_shadowmap.cpp b/src/gl/dynlights/gl_shadowmap.cpp index 4ef06efa3c..9e6ee4c917 100644 --- a/src/gl/dynlights/gl_shadowmap.cpp +++ b/src/gl/dynlights/gl_shadowmap.cpp @@ -216,18 +216,18 @@ void FShadowMap::UploadAABBTree() if (mAABBTree) return; - mAABBTree.reset(new LevelAABBTree()); + mAABBTree.reset(new hwrenderer::LevelAABBTree()); int oldBinding = 0; glGetIntegerv(GL_SHADER_STORAGE_BUFFER_BINDING, &oldBinding); glGenBuffers(1, (GLuint*)&mNodesBuffer); glBindBuffer(GL_SHADER_STORAGE_BUFFER, mNodesBuffer); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(AABBTreeNode) * mAABBTree->nodes.Size(), &mAABBTree->nodes[0], GL_STATIC_DRAW); + glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(hwrenderer::AABBTreeNode) * mAABBTree->nodes.Size(), &mAABBTree->nodes[0], GL_STATIC_DRAW); glGenBuffers(1, (GLuint*)&mLinesBuffer); glBindBuffer(GL_SHADER_STORAGE_BUFFER, mLinesBuffer); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(AABBTreeLine) * mAABBTree->lines.Size(), &mAABBTree->lines[0], GL_STATIC_DRAW); + glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(hwrenderer::AABBTreeLine) * mAABBTree->lines.Size(), &mAABBTree->lines[0], GL_STATIC_DRAW); glBindBuffer(GL_SHADER_STORAGE_BUFFER, oldBinding); } diff --git a/src/gl/dynlights/gl_shadowmap.h b/src/gl/dynlights/gl_shadowmap.h index 281936f80e..eea0c9f4aa 100644 --- a/src/gl/dynlights/gl_shadowmap.h +++ b/src/gl/dynlights/gl_shadowmap.h @@ -1,7 +1,7 @@ #pragma once -#include "gl/dynlights/gl_aabbtree.h" +#include "hwrenderer/dynlights/hw_aabbtree.h" #include "tarray.h" #include @@ -55,7 +55,7 @@ private: unsigned mLastNumSegs = 0; // AABB-tree of the level, used for ray tests - std::unique_ptr mAABBTree; + std::unique_ptr mAABBTree; FShadowMap(const FShadowMap &) = delete; FShadowMap &operator=(FShadowMap &) = delete; diff --git a/src/gl/gl_functions.h b/src/gl/gl_functions.h deleted file mode 100644 index 2401926fff..0000000000 --- a/src/gl/gl_functions.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __GL_FUNCT -#define __GL_FUNCT - -#include "v_palette.h" - -class AActor; - -void gl_PreprocessLevel(); -void gl_CleanLevelData(); -void gl_LinkLights(); - -#endif diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp index 3bceeedf7b..390664c3d8 100644 --- a/src/gl/models/gl_models.cpp +++ b/src/gl/models/gl_models.cpp @@ -49,14 +49,11 @@ #include "gl/scene/gl_portal.h" #include "gl/models/gl_models.h" #include "gl/textures/gl_material.h" -#include "gl/utility/gl_convert.h" #include "gl/renderer/gl_renderstate.h" #include "gl/shaders/gl_shader.h" CVAR(Bool, gl_light_models, true, CVAR_ARCHIVE) -extern int modellightindex; - VSMatrix FGLModelRenderer::GetViewToWorldMatrix() { VSMatrix objectToWorldMatrix; @@ -360,9 +357,9 @@ void FModelVertexBuffer::SetupFrame(FModelRenderer *renderer, unsigned int frame // //=========================================================================== -void gl_RenderModel(GLSprite * spr) +void gl_RenderModel(GLSprite * spr, int mli) { - FGLModelRenderer renderer; + FGLModelRenderer renderer(mli); renderer.RenderModel(spr->x, spr->y, spr->z, spr->modelframe, spr->actor); } @@ -372,8 +369,8 @@ void gl_RenderModel(GLSprite * spr) // //=========================================================================== -void gl_RenderHUDModel(DPSprite *psp, float ofsX, float ofsY) +void gl_RenderHUDModel(DPSprite *psp, float ofsX, float ofsY, int mli) { - FGLModelRenderer renderer; + FGLModelRenderer renderer(mli); renderer.RenderHUDModel(psp, ofsX, ofsY); } diff --git a/src/gl/models/gl_models.h b/src/gl/models/gl_models.h index 636c1944cd..de3fdfe7e4 100644 --- a/src/gl/models/gl_models.h +++ b/src/gl/models/gl_models.h @@ -32,7 +32,10 @@ class GLSprite; class FGLModelRenderer : public FModelRenderer { + int modellightindex = -1; public: + FGLModelRenderer(int mli) : modellightindex(mli) + {} void BeginDrawModel(AActor *actor, FSpriteModelFrame *smf, const VSMatrix &objectToWorldMatrix) override; void EndDrawModel(AActor *actor, FSpriteModelFrame *smf) override; IModelVertexBuffer *CreateVertexBuffer(bool needindex, bool singleframe) override; @@ -48,5 +51,5 @@ public: double GetTimeFloat() override; }; -void gl_RenderModel(GLSprite * spr); -void gl_RenderHUDModel(DPSprite *psp, float ofsx, float ofsy); +void gl_RenderModel(GLSprite * spr, int mli); +void gl_RenderHUDModel(DPSprite *psp, float ofsx, float ofsy, int mli); diff --git a/src/gl/renderer/gl_2ddrawer.cpp b/src/gl/renderer/gl_2ddrawer.cpp deleted file mode 100644 index 9c89c6f607..0000000000 --- a/src/gl/renderer/gl_2ddrawer.cpp +++ /dev/null @@ -1,492 +0,0 @@ -// -//--------------------------------------------------------------------------- -// -// Copyright(C) 2016 Christoph Oelckers -// All rights reserved. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with this program. If not, see http://www.gnu.org/licenses/ -// -//-------------------------------------------------------------------------- -// -/* -** gl_2ddrawer.h -** Container class for drawing 2d graphics with a vertex buffer -** -**/ - -#include "gl/system/gl_system.h" -#include "gl/system/gl_framebuffer.h" -#include "gl/renderer/gl_renderer.h" -#include "gl/renderer/gl_2ddrawer.h" -#include "gl/textures/gl_material.h" -#include "gl/renderer/gl_renderstate.h" -#include "gl/renderer/gl_lightdata.h" -#include "gl/scene/gl_drawinfo.h" -#include "gl/textures/gl_translate.h" -#include "vectors.h" - -//========================================================================== -// -// -// -//========================================================================== - -int F2DDrawer::AddData(const F2DDrawer::DataGeneric *data) -{ - int addr = mData.Reserve(data->mLen); - memcpy(&mData[addr], data, data->mLen); - mLastLineCmd = -1; - return addr; -} - -//========================================================================== -// -// Draws a texture -// -//========================================================================== - -void F2DDrawer::AddTexture(FTexture *img, DrawParms &parms) -{ - double xscale = parms.destwidth / parms.texwidth; - double yscale = parms.destheight / parms.texheight; - double x = parms.x - parms.left * xscale; - double y = parms.y - parms.top * yscale; - double w = parms.destwidth; - double h = parms.destheight; - float u1, v1, u2, v2; - int light = 255; - - FMaterial * gltex = FMaterial::ValidateTexture(img, false); - if (gltex == nullptr) return; - - DataTexture dg; - - dg.mType = DrawTypeTexture; - dg.mLen = (sizeof(dg) + 7) & ~7; - dg.mVertCount = 4; - dg.mRenderStyle = parms.style; - dg.mMasked = !!parms.masked; - dg.mTexture = gltex; - - if (parms.colorOverlay && (parms.colorOverlay & 0xffffff) == 0) - { - // handle black overlays as reduced light. - light = 255 - APART(parms.colorOverlay); - parms.colorOverlay = 0; - } - dg.mVertIndex = (int)mVertices.Reserve(parms.colorOverlay == 0? 4 : 8); - dg.mColorOverlay = parms.colorOverlay; - dg.mTranslation = 0; - - if (!img->bHasCanvas) - { - dg.mAlphaTexture = !!(parms.style.Flags & STYLEF_RedIsAlpha); - - if (!dg.mAlphaTexture) - { - if (parms.remap != NULL && !parms.remap->Inactive) - { - GLTranslationPalette * pal = static_cast(parms.remap->GetNative()); - if (pal) dg.mTranslation = -pal->GetIndex(); - } - } - u1 = gltex->GetUL(); - v1 = gltex->GetVT(); - u2 = gltex->GetUR(); - v2 = gltex->GetVB(); - - } - else - { - dg.mAlphaTexture = false; - u1 = 0.f; - v1 = 1.f; - u2 = 1.f; - v2 = 0.f; - } - - if (parms.flipX) - std::swap(u1, u2); - - - if (parms.windowleft > 0 || parms.windowright < parms.texwidth) - { - double wi = MIN(parms.windowright, parms.texwidth); - x += parms.windowleft * xscale; - w -= (parms.texwidth - wi + parms.windowleft) * xscale; - - u1 = float(u1 + parms.windowleft / parms.texwidth); - u2 = float(u2 - (parms.texwidth - wi) / parms.texwidth); - } - - PalEntry color; - if (parms.style.Flags & STYLEF_ColorIsFixed) - { - color = parms.fillcolor; - } - else - { - color = PalEntry(light, light, light); - } - color.a = (uint8_t)(parms.Alpha * 255); - // red and blue channels are swapped to use value as vertex color - color = PalEntry((color.a * parms.color.a) / 255, (color.b * parms.color.b) / 255, (color.g * parms.color.g) / 255, (color.r * parms.color.r) / 255); - - // scissor test doesn't use the current viewport for the coordinates, so use real screen coordinates - dg.mScissor[0] = GLRenderer->ScreenToWindowX(parms.lclip); - dg.mScissor[1] = GLRenderer->ScreenToWindowY(parms.dclip); - dg.mScissor[2] = GLRenderer->ScreenToWindowX(parms.rclip) - dg.mScissor[0]; - dg.mScissor[3] = GLRenderer->ScreenToWindowY(parms.uclip) - dg.mScissor[1]; - - FSimpleVertex *ptr = &mVertices[dg.mVertIndex]; - ptr->Set(x, y, 0, u1, v1, color); ptr++; - ptr->Set(x, y + h, 0, u1, v2, color); ptr++; - ptr->Set(x + w, y, 0, u2, v1, color); ptr++; - ptr->Set(x + w, y + h, 0, u2, v2, color); ptr++; - if (parms.colorOverlay != 0) - { - color = parms.colorOverlay; - std::swap(color.r, color.b); - ptr->Set(x, y, 0, u1, v1, color); ptr++; - ptr->Set(x, y + h, 0, u1, v2, color); ptr++; - ptr->Set(x + w, y, 0, u2, v1, color); ptr++; - ptr->Set(x + w, y + h, 0, u2, v2, color); ptr++; - dg.mVertCount = 8; - } - AddData(&dg); -} - - -//========================================================================== -// -// -// -//========================================================================== - -void F2DDrawer::AddPoly(FTexture *texture, FVector2 *points, int npoints, - double originx, double originy, double scalex, double scaley, - DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel) -{ - FMaterial *gltexture = FMaterial::ValidateTexture(texture, false); - - if (gltexture == nullptr) - { - return; - } - DataSimplePoly poly; - - poly.mType = DrawTypePoly; - poly.mLen = (sizeof(poly) + 7) & ~7; - poly.mTexture = gltexture; - poly.mColormap = colormap; - poly.mLightLevel = lightlevel; - poly.mVertCount = npoints; - poly.mVertIndex = (int)mVertices.Reserve(npoints); - poly.mFlatColor = flatcolor; - - bool dorotate = rotation != 0; - - float cosrot = cos(rotation.Radians()); - float sinrot = sin(rotation.Radians()); - - float uscale = float(1.f / (texture->GetScaledWidth() * scalex)); - float vscale = float(1.f / (texture->GetScaledHeight() * scaley)); - if (texture->bHasCanvas) - { - vscale = 0 - vscale; - } - float ox = float(originx); - float oy = float(originy); - - for (int i = 0; i < npoints; ++i) - { - float u = points[i].X - 0.5f - ox; - float v = points[i].Y - 0.5f - oy; - if (dorotate) - { - float t = u; - u = t * cosrot - v * sinrot; - v = v * cosrot + t * sinrot; - } - mVertices[poly.mVertIndex+i].Set(points[i].X, points[i].Y, 0, u*uscale, v*vscale); - } - AddData(&poly); -} - -//=========================================================================== -// -// -// -//=========================================================================== - -void F2DDrawer::AddDim(PalEntry color, float damount, int x1, int y1, int w, int h) -{ - color.a = uint8_t(damount * 255); - std::swap(color.r, color.b); - - DataGeneric dg; - - dg.mType = DrawTypeDim; - dg.mLen = (sizeof(dg) + 7) & ~7; - dg.mVertCount = 4; - dg.mVertIndex = (int)mVertices.Reserve(4); - FSimpleVertex *ptr = &mVertices[dg.mVertIndex]; - ptr->Set(x1, y1, 0, 0, 0, color); ptr++; - ptr->Set(x1, y1 + h, 0, 0, 0, color); ptr++; - ptr->Set(x1 + w, y1 + h, 0, 0, 0, color); ptr++; - ptr->Set(x1 + w, y1, 0, 0, 0, color); ptr++; - AddData(&dg); -} - -//========================================================================== -// -// -// -//========================================================================== - -void F2DDrawer::AddClear(int left, int top, int right, int bottom, int palcolor, uint32_t color) -{ - PalEntry p = palcolor == -1 || color != 0 ? (PalEntry)color : GPalette.BaseColors[palcolor]; - AddDim(p, 1.f, left, top, right - left, bottom - top); -} - -//========================================================================== -// -// -// -//========================================================================== - -void F2DDrawer::AddFlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin) -{ - float fU1, fU2, fV1, fV2; - - FMaterial *gltexture = FMaterial::ValidateTexture(src, false); - - if (!gltexture) return; - - DataFlatFill dg; - - dg.mType = DrawTypeFlatFill; - dg.mLen = (sizeof(dg) + 7) & ~7; - dg.mVertCount = 4; - dg.mVertIndex = (int)mVertices.Reserve(4); - dg.mTexture = gltexture; - - // scaling is not used here. - if (!local_origin) - { - fU1 = float(left) / src->GetWidth(); - fV1 = float(top) / src->GetHeight(); - fU2 = float(right) / src->GetWidth(); - fV2 = float(bottom) / src->GetHeight(); - } - else - { - fU1 = 0; - fV1 = 0; - fU2 = float(right - left) / src->GetWidth(); - fV2 = float(bottom - top) / src->GetHeight(); - } - FSimpleVertex *ptr = &mVertices[dg.mVertIndex]; - ptr->Set(left, top, 0, fU1, fV1); ptr++; - ptr->Set(left, bottom, 0, fU1, fV2); ptr++; - ptr->Set(right, top, 0, fU2, fV1); ptr++; - ptr->Set(right, bottom, 0, fU2, fV2); ptr++; - AddData(&dg); -} - - -//========================================================================== -// -// -// -//========================================================================== - -void F2DDrawer::AddLine(int x1, int y1, int x2, int y2, int palcolor, uint32_t color) -{ - PalEntry p = color ? (PalEntry)color : GPalette.BaseColors[palcolor]; - p.a = 255; - std::swap(p.r, p.b); - - DataGeneric dg; - - dg.mType = DrawTypeLine; - dg.mLen = (sizeof(dg) + 7) & ~7; - dg.mVertCount = 2; - dg.mVertIndex = (int)mVertices.Reserve(2); - mVertices[dg.mVertIndex].Set(x1, y1, 0, 0, 0, p); - mVertices[dg.mVertIndex+1].Set(x2, y2, 0, 0, 0, p); - - // Test if we can batch multiple line commands - if (mLastLineCmd == -1) - { - mLastLineCmd = AddData(&dg); - } - else - { - DataGeneric *dg = (DataGeneric *)&mData[mLastLineCmd]; - dg->mVertCount += 2; - } -} - -//========================================================================== -// -// -// -//========================================================================== - -void F2DDrawer::AddPixel(int x1, int y1, int palcolor, uint32_t color) -{ - PalEntry p = color ? (PalEntry)color : GPalette.BaseColors[palcolor]; - p.a = 255; - std::swap(p.r, p.b); - - DataGeneric dg; - - dg.mType = DrawTypePixel; - dg.mLen = (sizeof(dg) + 7) & ~7; - dg.mVertCount = 2; - dg.mVertIndex = (int)mVertices.Reserve(1); - mVertices[dg.mVertIndex].Set(x1, y1, 0, 0, 0, p); - AddData(&dg); -} - - -//========================================================================== -// -// -// -//========================================================================== - -void F2DDrawer::Draw() -{ - F2DDrawer::EDrawType lasttype = DrawTypeTexture; - - if (mData.Size() == 0) return; - int8_t savedlightmode = glset.lightmode; - // lightmode is only relevant for automap subsectors, - // but We cannot use the software light mode here because it doesn't properly calculate the light for 2D rendering. - if (glset.lightmode == 8) glset.lightmode = 0; - - set(&mVertices[0], mVertices.Size()); - for (unsigned i = 0; i < mData.Size();) - { - DataGeneric *dg = (DataGeneric *)&mData[i]; - // DrawTypePoly may not use the color part of the vertex buffer because it needs to use gl_SetColor to produce proper output. - if (lasttype == DrawTypePoly && dg->mType != DrawTypePoly) - { - gl_RenderState.ResetColor(); // this is needed to reset the desaturation. - EnableColorArray(true); - } - else if (lasttype != DrawTypePoly && dg->mType == DrawTypePoly) - { - EnableColorArray(false); - } - lasttype = dg->mType; - - switch (dg->mType) - { - default: - break; - - case DrawTypeTexture: - { - DataTexture *dt = static_cast(dg); - - gl_SetRenderStyle(dt->mRenderStyle, !dt->mMasked, false); - gl_RenderState.SetMaterial(dt->mTexture, CLAMP_XY_NOMIP, dt->mTranslation, -1, dt->mAlphaTexture); - - glEnable(GL_SCISSOR_TEST); - glScissor(dt->mScissor[0], dt->mScissor[1], dt->mScissor[2], dt->mScissor[3]); - - gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); - gl_RenderState.Apply(); - - glDrawArrays(GL_TRIANGLE_STRIP, dt->mVertIndex, 4); - - gl_RenderState.BlendEquation(GL_FUNC_ADD); - if (dt->mVertCount > 4) - { - gl_RenderState.SetTextureMode(TM_MASK); - gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl_RenderState.Apply(); - glDrawArrays(GL_TRIANGLE_STRIP, dt->mVertIndex + 4, 4); - } - - const auto &viewport = GLRenderer->mScreenViewport; - glScissor(viewport.left, viewport.top, viewport.width, viewport.height); - glDisable(GL_SCISSOR_TEST); - gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl_RenderState.SetTextureMode(TM_MODULATE); - break; - } - - case DrawTypePoly: - { - DataSimplePoly *dsp = static_cast(dg); - - gl_SetColor(dsp->mLightLevel, 0, false, dsp->mColormap, 1.f); - gl_RenderState.SetMaterial(dsp->mTexture, CLAMP_NONE, 0, -1, false); - gl_RenderState.SetObjectColor(dsp->mFlatColor|0xff000000); - gl_RenderState.Apply(); - glDrawArrays(GL_TRIANGLE_FAN, dsp->mVertIndex, dsp->mVertCount); - gl_RenderState.SetObjectColor(0xffffffff); - break; - } - - case DrawTypeFlatFill: - { - DataFlatFill *dff = static_cast(dg); - gl_RenderState.SetMaterial(dff->mTexture, CLAMP_NONE, 0, -1, false); - gl_RenderState.Apply(); - glDrawArrays(GL_TRIANGLE_STRIP, dg->mVertIndex, dg->mVertCount); - break; - } - - case DrawTypeDim: - gl_RenderState.EnableTexture(false); - gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl_RenderState.AlphaFunc(GL_GREATER, 0); - gl_RenderState.Apply(); - glDrawArrays(GL_TRIANGLE_FAN, dg->mVertIndex, dg->mVertCount); - gl_RenderState.EnableTexture(true); - break; - - case DrawTypeLine: - gl_RenderState.EnableTexture(false); - gl_RenderState.Apply(); - glDrawArrays(GL_LINES, dg->mVertIndex, dg->mVertCount); - gl_RenderState.EnableTexture(true); - break; - - case DrawTypePixel: - gl_RenderState.EnableTexture(false); - gl_RenderState.Apply(); - glDrawArrays(GL_POINTS, dg->mVertIndex, dg->mVertCount); - gl_RenderState.EnableTexture(true); - break; - - } - i += dg->mLen; - } - gl_RenderState.SetVertexBuffer(GLRenderer->mVBO); - glset.lightmode = savedlightmode; -} - -void F2DDrawer::Clear() -{ - mVertices.Clear(); - mData.Clear(); - mLastLineCmd = -1; -} diff --git a/src/gl/renderer/gl_2ddrawer.h b/src/gl/renderer/gl_2ddrawer.h deleted file mode 100644 index 417f06ceba..0000000000 --- a/src/gl/renderer/gl_2ddrawer.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef __2DDRAWER_H -#define __2DDRAWER_H - -#include "tarray.h" -#include "gl/data/gl_vertexbuffer.h" - -class F2DDrawer : public FSimpleVertexBuffer -{ - enum EDrawType - { - DrawTypeTexture, - DrawTypeDim, - DrawTypeFlatFill, - DrawTypePoly, - DrawTypeLine, - DrawTypePixel - }; - - struct DataGeneric - { - EDrawType mType; - uint32_t mLen; - int mVertIndex; - int mVertCount; - }; - - struct DataTexture : public DataGeneric - { - FMaterial *mTexture; - int mScissor[4]; - uint32_t mColorOverlay; - int mTranslation; - FRenderStyle mRenderStyle; - bool mMasked; - bool mAlphaTexture; - }; - - struct DataFlatFill : public DataGeneric - { - FMaterial *mTexture; - }; - - struct DataSimplePoly : public DataGeneric - { - FMaterial *mTexture; - int mLightLevel; - FColormap mColormap; - PalEntry mFlatColor; - }; - - TArray mVertices; - TArray mData; - int mLastLineCmd = -1; // consecutive lines can be batched into a single draw call so keep this info around. - - int AddData(const DataGeneric *data); - -public: - void AddTexture(FTexture *img, DrawParms &parms); - void AddDim(PalEntry color, float damount, int x1, int y1, int w, int h); - void AddClear(int left, int top, int right, int bottom, int palcolor, uint32_t color); - void AddFlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin); - - void AddPoly(FTexture *texture, FVector2 *points, int npoints, - double originx, double originy, double scalex, double scaley, - DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel); - - void AddLine(int x1, int y1, int x2, int y2, int palcolor, uint32_t color); - void AddPixel(int x1, int y1, int palcolor, uint32_t color); - - void Draw(); - void Clear(); -}; - - -#endif diff --git a/src/gl/renderer/gl_colormap.h b/src/gl/renderer/gl_colormap.h index 85988e0b85..46e36431e8 100644 --- a/src/gl/renderer/gl_colormap.h +++ b/src/gl/renderer/gl_colormap.h @@ -9,10 +9,12 @@ struct lightlist_t; enum EColorManipulation { - + CM_SPECIAL2D = -3, // the special colormaps get passed as color pair from the 2D drawer so they need a different value here. + CM_PLAIN2D = -2, // regular 2D drawing. CM_INVALID=-1, CM_DEFAULT=0, // untranslated CM_FIRSTSPECIALCOLORMAP, // first special fixed colormap + CM_FIRSTSPECIALCOLORMAPFORCED= 0x08000000, // first special fixed colormap, application forced (for 2D overlays) CM_FOGLAYER = 0x10000000, // Sprite shaped fog layer @@ -22,6 +24,7 @@ enum EColorManipulation }; #define CM_MAXCOLORMAP int(CM_FIRSTSPECIALCOLORMAP + SpecialColormaps.Size()) +#define CM_MAXCOLORMAPFORCED int(CM_FIRSTSPECIALCOLORMAPFORCED + SpecialColormaps.Size()) #endif diff --git a/src/gl/renderer/gl_lightdata.cpp b/src/gl/renderer/gl_lightdata.cpp index b1960c91f5..0e994abf91 100644 --- a/src/gl/renderer/gl_lightdata.cpp +++ b/src/gl/renderer/gl_lightdata.cpp @@ -28,7 +28,6 @@ #include "gl/system/gl_system.h" #include "gl/system/gl_interface.h" #include "gl/system/gl_cvars.h" -#include "gl/data/gl_data.h" #include "gl/renderer/gl_colormap.h" #include "gl/renderer/gl_lightdata.h" #include "gl/renderer/gl_renderstate.h" @@ -53,8 +52,6 @@ CUSTOM_CVAR(Bool, gl_enhanced_nightvision, true, CVAR_ARCHIVE|CVAR_NOINITCALL) GLRenderer->mShaderManager->ResetFixedColormap(); } } -CVAR(Bool, gl_brightfog, false, CVAR_ARCHIVE); -CVAR(Bool, gl_lightadditivesurfaces, false, CVAR_ARCHIVE); @@ -97,14 +94,6 @@ CUSTOM_CVAR(Int,gl_fogmode,1,CVAR_ARCHIVE|CVAR_NOINITCALL) if (self<0) self=0; } -CUSTOM_CVAR(Int, gl_lightmode, 3 ,CVAR_ARCHIVE|CVAR_NOINITCALL) -{ - int newself = self; - if (newself > 4) newself=8; // use 8 for software lighting to avoid conflicts with the bit mask - if (newself < 0) newself=0; - if (self != newself) self = newself; - glset.lightmode = newself; -} @@ -119,12 +108,12 @@ CUSTOM_CVAR(Int, gl_lightmode, 3 ,CVAR_ARCHIVE|CVAR_NOINITCALL) void gl_GetRenderStyle(FRenderStyle style, bool drawopaque, bool allowcolorblending, int *tm, int *sb, int *db, int *be) { - static int blendstyles[] = { GL_ZERO, GL_ONE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA }; + static int blendstyles[] = { GL_ZERO, GL_ONE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_DST_COLOR, GL_ONE_MINUS_DST_COLOR, }; static int renderops[] = { 0, GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; - int srcblend = blendstyles[style.SrcAlpha&3]; - int dstblend = blendstyles[style.DestAlpha&3]; + int srcblend = blendstyles[style.SrcAlpha%STYLEALPHA_MAX]; + int dstblend = blendstyles[style.DestAlpha%STYLEALPHA_MAX]; int blendequation = renderops[style.BlendOp&15]; int texturemode = drawopaque? TM_OPAQUE : TM_MODULATE; @@ -138,7 +127,6 @@ void gl_GetRenderStyle(FRenderStyle style, bool drawopaque, bool allowcolorblend } else if (style.Flags & STYLEF_InvertSource) { - // The only place where InvertSource is used is for inverted sprites with the infrared powerup. texturemode = TM_INVERSE; } @@ -173,7 +161,7 @@ int gl_CalcLightLevel(int lightlevel, int rellight, bool weapon) if (lightlevel == 0) return 0; - if ((glset.lightmode & 2) && lightlevel < 192 && !weapon) + if ((level.lightmode & 2) && lightlevel < 192 && !weapon) { if (lightlevel > 100) { @@ -211,7 +199,7 @@ static PalEntry gl_CalcLightColor(int light, PalEntry pe, int blendfactor) { int r,g,b; - if (glset.lightmode == 8) + if (level.lightmode == 8) { return pe; } @@ -277,7 +265,7 @@ float gl_GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity) { float density; - if (glset.lightmode & 4) + if (level.lightmode & 4) { // uses approximations of Legacy's default settings. density = level.fogdensity ? level.fogdensity : 18; @@ -290,9 +278,9 @@ float gl_GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity) else if ((fogcolor.d & 0xffffff) == 0) { // case 2: black fog - if (glset.lightmode != 8 && !(level.flags3 & LEVEL3_NOLIGHTFADE)) + if (level.lightmode != 8 && !(level.flags3 & LEVEL3_NOLIGHTFADE)) { - density = distfogtable[glset.lightmode != 0][gl_ClampLight(lightlevel)]; + density = distfogtable[level.lightmode != 0][gl_ClampLight(lightlevel)]; } else { @@ -351,7 +339,7 @@ bool gl_CheckFog(sector_t *frontsector, sector_t *backsector) else if (level.outsidefogdensity != 0 && APART(level.info->outsidefog) != 0xff && (fogcolor.d & 0xffffff) == (level.info->outsidefog & 0xffffff)) { } - else if (level.fogdensity!=0 || (glset.lightmode & 4)) + else if (level.fogdensity!=0 || (level.lightmode & 4)) { // case 3: level has fog density set } @@ -370,7 +358,7 @@ bool gl_CheckFog(sector_t *frontsector, sector_t *backsector) { return false; } - else if (level.fogdensity!=0 || (glset.lightmode & 4)) + else if (level.fogdensity!=0 || (level.lightmode & 4)) { // case 3: level has fog density set return false; @@ -460,7 +448,7 @@ void gl_SetFog(int lightlevel, int rellight, bool fullbright, const FColormap *c } else { - if (glset.lightmode == 2 && fogcolor == 0) + if (level.lightmode == 2 && fogcolor == 0) { float light = gl_CalcLightLevel(lightlevel, rellight, false); gl_SetShaderLight(light, lightlevel); @@ -481,7 +469,7 @@ void gl_SetFog(int lightlevel, int rellight, bool fullbright, const FColormap *c gl_RenderState.SetFog(fogcolor, fogdensity); // Korshun: fullbright fog like in software renderer. - if (glset.lightmode == 8 && glset.brightfog && fogdensity != 0 && fogcolor != 0) + if (level.lightmode == 8 && level.brightfog && fogdensity != 0 && fogcolor != 0) { gl_RenderState.SetSoftLightLevel(255); } diff --git a/src/gl/renderer/gl_postprocess.cpp b/src/gl/renderer/gl_postprocess.cpp index 463895e8ca..72e30f27ae 100644 --- a/src/gl/renderer/gl_postprocess.cpp +++ b/src/gl/renderer/gl_postprocess.cpp @@ -42,7 +42,6 @@ #include "r_utility.h" #include "p_local.h" #include "colormatcher.h" -#include "gl/gl_functions.h" #include "gl/system/gl_interface.h" #include "gl/system/gl_framebuffer.h" #include "gl/system/gl_cvars.h" @@ -52,7 +51,6 @@ #include "gl/renderer/gl_renderbuffers.h" #include "gl/renderer/gl_renderer.h" #include "gl/renderer/gl_postprocessstate.h" -#include "gl/data/gl_data.h" #include "gl/data/gl_vertexbuffer.h" #include "gl/shaders/gl_ambientshader.h" #include "gl/shaders/gl_bloomshader.h" @@ -63,7 +61,7 @@ #include "gl/shaders/gl_fxaashader.h" #include "gl/shaders/gl_presentshader.h" #include "gl/shaders/gl_postprocessshader.h" -#include "gl/renderer/gl_2ddrawer.h" +#include "gl/shaders/gl_postprocessshaderinstance.h" #include "gl/stereo3d/gl_stereo3d.h" #include "r_videoscale.h" @@ -626,7 +624,7 @@ void FGLRenderer::CreateTonemapPalette() } } - mTonemapPalette = new FHardwareTexture(512, 512, true); + mTonemapPalette = new FHardwareTexture(true); mTonemapPalette->CreateTexture(&lut[0], 512, 512, 0, false, 0, "mTonemapPalette"); } } @@ -798,10 +796,10 @@ void FGLRenderer::Flush() mBuffers->BindEyeFB(eye_ix); glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height); glScissor(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height); - m2DDrawer->Draw(); + screen->Draw2D(); FGLDebug::PopGroup(); } - m2DDrawer->Clear(); + screen->Clear2D(); FGLPostProcessState savedState; FGLDebug::PushGroup("PresentEyes"); @@ -818,8 +816,8 @@ void FGLRenderer::Flush() void FGLRenderer::CopyToBackbuffer(const GL_IRECT *bounds, bool applyGamma) { - m2DDrawer->Draw(); // draw all pending 2D stuff before copying the buffer - m2DDrawer->Clear(); + screen->Draw2D(); // draw all pending 2D stuff before copying the buffer + screen->Clear2D(); mCustomPostProcessShaders->Run("screen"); diff --git a/src/gl/renderer/gl_postprocessstate.cpp b/src/gl/renderer/gl_postprocessstate.cpp index fead1435aa..4fbe04a768 100644 --- a/src/gl/renderer/gl_postprocessstate.cpp +++ b/src/gl/renderer/gl_postprocessstate.cpp @@ -28,7 +28,6 @@ #include "templates.h" #include "gl/system/gl_system.h" #include "gl/system/gl_interface.h" -#include "gl/data/gl_data.h" #include "gl/data/gl_vertexbuffer.h" #include "gl/system/gl_cvars.h" #include "gl/shaders/gl_shader.h" diff --git a/src/gl/renderer/gl_postprocessstate.h b/src/gl/renderer/gl_postprocessstate.h index cd45915aac..8e8b24b610 100644 --- a/src/gl/renderer/gl_postprocessstate.h +++ b/src/gl/renderer/gl_postprocessstate.h @@ -3,7 +3,6 @@ #include #include "gl/system/gl_interface.h" -#include "gl/data/gl_data.h" #include "r_data/matrix.h" #include "c_cvars.h" #include "r_defs.h" diff --git a/src/gl/renderer/gl_renderbuffers.cpp b/src/gl/renderer/gl_renderbuffers.cpp index d60045f3e3..acc2d5c0de 100644 --- a/src/gl/renderer/gl_renderbuffers.cpp +++ b/src/gl/renderer/gl_renderbuffers.cpp @@ -28,7 +28,6 @@ #include "gl/system/gl_system.h" #include "m_swap.h" #include "v_video.h" -#include "gl/gl_functions.h" #include "vectors.h" #include "gl/system/gl_interface.h" #include "gl/system/gl_framebuffer.h" diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index 1c0cf40acf..6f89d176f0 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -33,10 +33,12 @@ #include "m_png.h" #include "m_crc32.h" #include "w_wad.h" -//#include "gl/gl_intern.h" -#include "gl/gl_functions.h" #include "vectors.h" #include "doomstat.h" +#include "i_time.h" +#include "p_effect.h" +#include "d_player.h" +#include "a_dynlight.h" #include "gl/system/gl_interface.h" #include "gl/system/gl_framebuffer.h" @@ -46,10 +48,10 @@ #include "gl/renderer/gl_lightdata.h" #include "gl/renderer/gl_renderstate.h" #include "gl/renderer/gl_renderbuffers.h" -#include "gl/renderer/gl_2ddrawer.h" -#include "gl/data/gl_data.h" #include "gl/data/gl_vertexbuffer.h" #include "gl/scene/gl_drawinfo.h" +#include "gl/scene/gl_scenedrawer.h" +#include "gl/scene/gl_swscene.h" #include "gl/scene/gl_portal.h" #include "gl/shaders/gl_shader.h" #include "gl/shaders/gl_ambientshader.h" @@ -63,20 +65,21 @@ #include "gl/shaders/gl_present3dRowshader.h" #include "gl/shaders/gl_shadowmapshader.h" #include "gl/shaders/gl_postprocessshader.h" +#include "gl/shaders/gl_postprocessshaderinstance.h" #include "gl/stereo3d/gl_stereo3d.h" -#include "gl/textures/gl_texture.h" -#include "gl/textures/gl_translate.h" #include "gl/textures/gl_material.h" #include "gl/textures/gl_samplers.h" #include "gl/utility/gl_clock.h" -#include "gl/utility/gl_templates.h" #include "gl/models/gl_models.h" #include "gl/dynlights/gl_lightbuffer.h" #include "r_videoscale.h" EXTERN_CVAR(Int, screenblocks) +EXTERN_CVAR(Bool, cl_capfps) +EXTERN_CVAR(Float, underwater_fade_scalar) CVAR(Bool, gl_scale_viewport, true, CVAR_ARCHIVE); +extern bool NoInterpolateView; //=========================================================================== // @@ -105,7 +108,6 @@ FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb) gl_spriteindex = 0; mShaderManager = nullptr; mLights = nullptr; - m2DDrawer = nullptr; mTonemapPalette = nullptr; mBuffers = nullptr; mPresentShader = nullptr; @@ -160,7 +162,11 @@ void FGLRenderer::Initialize(int width, int height) mPresent3dRowShader = new FPresent3DRowShader(); mShadowMapShader = new FShadowMapShader(); mCustomPostProcessShaders = new FCustomPostProcessShaders(); - m2DDrawer = new F2DDrawer; + + if (gl.legacyMode) + { + legacyShaders = new LegacyShaderContainer; + } GetSpecialTextures(); @@ -196,7 +202,7 @@ FGLRenderer::~FGLRenderer() gl_FlushModels(); AActor::DeleteAllAttachedLights(); FMaterial::FlushAll(); - if (m2DDrawer != nullptr) delete m2DDrawer; + if (legacyShaders) delete legacyShaders; if (mShaderManager != NULL) delete mShaderManager; if (mSamplerManager != NULL) delete mSamplerManager; if (mVBO != NULL) delete mVBO; @@ -208,6 +214,7 @@ FGLRenderer::~FGLRenderer() glBindVertexArray(0); glDeleteVertexArrays(1, &mVAOID); } + if (swdrawer) delete swdrawer; if (mBuffers) delete mBuffers; if (mPresentShader) delete mPresentShader; if (mLinearDepthShader) delete mLinearDepthShader; @@ -360,6 +367,13 @@ int FGLRenderer::ScreenToWindowY(int y) // //=========================================================================== +void FGLRenderer::ResetSWScene() +{ + // force recreation of the SW scene drawer to ensure it gets a new set of resources. + if (swdrawer != nullptr) delete swdrawer; + swdrawer = nullptr; +} + void FGLRenderer::SetupLevel() { mVBO->CreateVBO(); @@ -420,18 +434,462 @@ void FGLRenderer::EndOffscreen() glBindFramebuffer(GL_FRAMEBUFFER, mOldFBID); } -//=========================================================================== -// +//----------------------------------------------------------------------------- // +// renders the view +// +//----------------------------------------------------------------------------- + +void FGLRenderer::RenderView(player_t* player) +{ + gl_RenderState.SetVertexBuffer(mVBO); + mVBO->Reset(); + + if (!V_IsHardwareRenderer()) + { + if (swdrawer == nullptr) swdrawer = new SWSceneDrawer; + swdrawer->RenderView(player); + } + else + { + checkBenchActive(); + + // reset statistics counters + ResetProfilingData(); + + // Get this before everything else + if (cl_capfps || r_NoInterpolate) r_viewpoint.TicFrac = 1.; + else r_viewpoint.TicFrac = I_GetTimeFrac(); + + P_FindParticleSubsectors(); + + if (!gl.legacyMode) mLights->Clear(); + + // NoInterpolateView should have no bearing on camera textures, but needs to be preserved for the main view below. + bool saved_niv = NoInterpolateView; + NoInterpolateView = false; + // prepare all camera textures that have been used in the last frame + FCanvasTextureInfo::UpdateAll(); + NoInterpolateView = saved_niv; + + + // now render the main view + float fovratio; + float ratio = r_viewwindow.WidescreenRatio; + if (r_viewwindow.WidescreenRatio >= 1.3f) + { + fovratio = 1.333333f; + } + else + { + fovratio = ratio; + } + // Check if there's some lights. If not some code can be skipped. + TThinkerIterator it(STAT_DLIGHT); + mLightCount = ((it.Next()) != NULL); + + GLSceneDrawer drawer; + + drawer.SetFixedColormap(player); + + mShadowMap.Update(); + sector_t * viewsector = drawer.RenderViewpoint(player->camera, NULL, r_viewpoint.FieldOfView.Degrees, ratio, fovratio, true, true); + } + + All.Unclock(); +} + +//=========================================================================== +// +// Camera texture rendering // //=========================================================================== -unsigned char *FGLRenderer::GetTextureBuffer(FTexture *tex, int &w, int &h) +void FGLRenderer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV) { FMaterial * gltex = FMaterial::ValidateTexture(tex, false); - if (gltex) + + int width = gltex->TextureWidth(); + int height = gltex->TextureHeight(); + + if (gl.legacyMode) { - return gltex->CreateTexBuffer(0, w, h); + // In legacy mode, fail if the requested texture is too large. + if (gltex->GetWidth() > screen->GetWidth() || gltex->GetHeight() > screen->GetHeight()) return; + glFlush(); } - return NULL; + else + { + StartOffscreen(); + gltex->BindToFrameBuffer(); + } + + GL_IRECT bounds; + bounds.left = bounds.top = 0; + bounds.width = FHardwareTexture::GetTexDimension(gltex->GetWidth()); + bounds.height = FHardwareTexture::GetTexDimension(gltex->GetHeight()); + + GLSceneDrawer drawer; + drawer.FixedColormap = CM_DEFAULT; + gl_RenderState.SetFixedColormap(CM_DEFAULT); + drawer.RenderViewpoint(Viewpoint, &bounds, FOV, (float)width / height, (float)width / height, false, false); + + if (gl.legacyMode) + { + glFlush(); + gl_RenderState.SetMaterial(gltex, 0, 0, -1, false); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, bounds.width, bounds.height); + } + else + { + EndOffscreen(); + } + + tex->SetUpdated(); +} + +void FGLRenderer::WriteSavePic(player_t *player, FileWriter *file, int width, int height) +{ + // Todo: This needs to call the software renderer and process the returned image, if so desired. + // This also needs to take out parts of the scene drawer so they can be shared between renderers. + GLSceneDrawer drawer; + drawer.WriteSavePic(player, file, width, height); +} + + +void gl_FillScreen() +{ + gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); + gl_RenderState.EnableTexture(false); + gl_RenderState.Apply(); + // The fullscreen quad is stored at index 4 in the main vertex buffer. + GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, FFlatVertexBuffer::FULLSCREEN_INDEX, 4); +} + +//========================================================================== +// +// Draws a blend over the entire view +// +//========================================================================== +void FGLRenderer::DrawBlend(sector_t * viewsector, bool FixedColormap, bool docolormap, bool in2d) +{ + float blend[4] = { 0,0,0,0 }; + PalEntry blendv = 0; + float extra_red; + float extra_green; + float extra_blue; + player_t *player = NULL; + + if (players[consoleplayer].camera != NULL) + { + player = players[consoleplayer].camera->player; + } + + // don't draw sector based blends when an invulnerability colormap is active + if (!FixedColormap) + { + if (!viewsector->e->XFloor.ffloors.Size()) + { + if (viewsector->heightsec && !(viewsector->MoreFlags&SECF_IGNOREHEIGHTSEC)) + { + auto s = viewsector->heightsec; + blendv = s->floorplane.PointOnSide(r_viewpoint.Pos) < 0? s->bottommap : s->ceilingplane.PointOnSide(r_viewpoint.Pos) < 0 ? s->topmap : s->midmap; + } + } + else + { + TArray & lightlist = viewsector->e->XFloor.lightlist; + + for (unsigned int i = 0; i < lightlist.Size(); i++) + { + double lightbottom; + if (i < lightlist.Size() - 1) + lightbottom = lightlist[i + 1].plane.ZatPoint(r_viewpoint.Pos); + else + lightbottom = viewsector->floorplane.ZatPoint(r_viewpoint.Pos); + + if (lightbottom < r_viewpoint.Pos.Z && (!lightlist[i].caster || !(lightlist[i].caster->flags&FF_FADEWALLS))) + { + // 3d floor 'fog' is rendered as a blending value + blendv = lightlist[i].blend; + // If this is the same as the sector's it doesn't apply! + if (blendv == viewsector->Colormap.FadeColor) blendv = 0; + // a little hack to make this work for Legacy maps. + if (blendv.a == 0 && blendv != 0) blendv.a = 128; + break; + } + } + } + + if (blendv.a == 0 && docolormap) + { + blendv = R_BlendForColormap(blendv); + } + + if (blendv.a == 255) + { + + extra_red = blendv.r / 255.0f; + extra_green = blendv.g / 255.0f; + extra_blue = blendv.b / 255.0f; + + // If this is a multiplicative blend do it separately and add the additive ones on top of it. + + // black multiplicative blends are ignored + if (extra_red || extra_green || extra_blue) + { + if (!in2d) + { + gl_RenderState.BlendFunc(GL_DST_COLOR, GL_ZERO); + gl_RenderState.SetColor(extra_red, extra_green, extra_blue, 1.0f); + gl_FillScreen(); + } + else + { + screen->Dim(blendv, 1, 0, 0, screen->GetWidth(), screen->GetHeight(), &LegacyRenderStyles[STYLE_Multiply]); + } + } + blendv = 0; + } + else if (blendv.a) + { + // [Nash] allow user to set blend intensity + int cnt = blendv.a; + cnt = (int)(cnt * underwater_fade_scalar); + + V_AddBlend(blendv.r / 255.f, blendv.g / 255.f, blendv.b / 255.f, cnt / 255.0f, blend); + } + } + + if (player) + { + V_AddPlayerBlend(player, blend, 0.5, 175); + } + + if (players[consoleplayer].camera != NULL) + { + // except for fadeto effects + player_t *player = (players[consoleplayer].camera->player != NULL) ? players[consoleplayer].camera->player : &players[consoleplayer]; + V_AddBlend(player->BlendR, player->BlendG, player->BlendB, player->BlendA, blend); + } + + if (!in2d) + { + gl_RenderState.SetTextureMode(TM_MODULATE); + gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + if (blend[3] > 0.0f) + { + gl_RenderState.SetColor(blend[0], blend[1], blend[2], blend[3]); + gl_FillScreen(); + } + gl_RenderState.ResetColor(); + gl_RenderState.EnableTexture(true); + } + else + { + screen->Dim(PalEntry(255, blend[0] * 255, blend[1] * 255, blend[2] * 255), blend[3], 0, 0, screen->GetWidth(), screen->GetHeight()); + } +} + + +//=========================================================================== +// +// Vertex buffer for 2D drawer +// +//=========================================================================== + +class F2DVertexBuffer : public FSimpleVertexBuffer +{ + uint32_t ibo_id; + + // Make sure we can build upon FSimpleVertexBuffer. + static_assert(offsetof(FSimpleVertex, x) == offsetof(F2DDrawer::TwoDVertex, x), "x not aligned"); + static_assert(offsetof(FSimpleVertex, u) == offsetof(F2DDrawer::TwoDVertex, u), "u not aligned"); + static_assert(offsetof(FSimpleVertex, color) == offsetof(F2DDrawer::TwoDVertex, color0), "color not aligned"); + +public: + + F2DVertexBuffer() + { + glGenBuffers(1, &ibo_id); + } + ~F2DVertexBuffer() + { + if (ibo_id != 0) + { + glDeleteBuffers(1, &ibo_id); + } + } + void UploadData(F2DDrawer::TwoDVertex *vertices, int vertcount, int *indices, int indexcount) + { + glBindBuffer(GL_ARRAY_BUFFER, vbo_id); + glBufferData(GL_ARRAY_BUFFER, vertcount * sizeof(vertices[0]), vertices, GL_STREAM_DRAW); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexcount * sizeof(indices[0]), indices, GL_STREAM_DRAW); + } + + void BindVBO() override + { + FSimpleVertexBuffer::BindVBO(); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id); + } +}; + +//=========================================================================== +// +// Draws the 2D stuff. This is the version for OpenGL 3 and later. +// +//=========================================================================== + +void LegacyColorOverlay(F2DDrawer *drawer, F2DDrawer::RenderCommand & cmd); +int LegacyDesaturation(F2DDrawer::RenderCommand &cmd); + +void FGLRenderer::Draw2D(F2DDrawer *drawer) +{ + + + auto &vertices = drawer->mVertices; + auto &indices = drawer->mIndices; + auto &commands = drawer->mData; + + if (commands.Size() == 0) return; + + for (auto &v : vertices) + { + // Change from BGRA to RGBA + std::swap(v.color0.r, v.color0.b); + } + auto vb = new F2DVertexBuffer; + vb->UploadData(&vertices[0], vertices.Size(), &indices[0], indices.Size()); + gl_RenderState.SetVertexBuffer(vb); + gl_RenderState.SetFixedColormap(CM_DEFAULT); + + for(auto &cmd : commands) + { + + int gltrans = -1; + int tm, sb, db, be; + // The texture mode being returned here cannot be used, because the higher level code + // already manipulated the data so that some cases will not be handled correctly. + // Since we already get a proper mode from the calling code this doesn't really matter. + gl_GetRenderStyle(cmd.mRenderStyle, false, false, &tm, &sb, &db, &be); + gl_RenderState.BlendEquation(be); + gl_RenderState.BlendFunc(sb, db); + + // Rather than adding remapping code, let's enforce that the constants here are equal. + static_assert(int(F2DDrawer::DTM_Normal) == int(TM_MODULATE), "DTM_Normal != TM_MODULATE"); + static_assert(int(F2DDrawer::DTM_Opaque) == int(TM_OPAQUE), "DTM_Opaque != TM_OPAQUE"); + static_assert(int(F2DDrawer::DTM_Invert) == int(TM_INVERSE), "DTM_Invert != TM_INVERSE"); + static_assert(int(F2DDrawer::DTM_InvertOpaque) == int(TM_INVERTOPAQUE), "DTM_InvertOpaque != TM_INVERTOPAQUE"); + static_assert(int(F2DDrawer::DTM_Stencil) == int(TM_MASK), "DTM_Stencil != TM_MASK"); + static_assert(int(F2DDrawer::DTM_AlphaTexture) == int(TM_REDTOALPHA), "DTM_AlphaTexture != TM_REDTOALPHA"); + gl_RenderState.SetTextureMode(cmd.mDrawMode); + if (cmd.mFlags & F2DDrawer::DTF_Scissor) + { + glEnable(GL_SCISSOR_TEST); + // scissor test doesn't use the current viewport for the coordinates, so use real screen coordinates + // Note that the origin here is the lower left corner! + auto sciX = ScreenToWindowX(cmd.mScissor[0]); + auto sciY = ScreenToWindowY(cmd.mScissor[3]); + auto sciW = ScreenToWindowX(cmd.mScissor[2]) - sciX; + auto sciH = ScreenToWindowY(cmd.mScissor[1]) - sciY; + glScissor(sciX, sciY, sciW, sciH); + } + else glDisable(GL_SCISSOR_TEST); + + if (cmd.mSpecialColormap != nullptr) + { + auto index = cmd.mSpecialColormap - &SpecialColormaps[0]; + if (index < 0 || (unsigned)index >= SpecialColormaps.Size()) index = 0; // if it isn't in the table FBitmap cannot use it. Shouldn't happen anyway. + if (!gl.legacyMode || cmd.mTexture->UseType == ETextureType::SWCanvas) + { + gl_RenderState.SetFixedColormap(CM_FIRSTSPECIALCOLORMAPFORCED + int(index)); + } + else + { + // map the special colormap to a translation for the legacy renderer. + // This only gets used on the software renderer's weapon sprite. + gltrans = STRange_Specialcolormap + index; + } + } + else + { + if (!gl.legacyMode) + { + gl_RenderState.Set2DOverlayColor(cmd.mColor1); + gl_RenderState.SetFixedColormap(CM_PLAIN2D); + } + else if (cmd.mDesaturate > 0) + { + gltrans = LegacyDesaturation(cmd); + } + } + + gl_RenderState.SetColor(1, 1, 1, 1, cmd.mDesaturate); + + gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); + + if (cmd.mTexture != nullptr) + { + auto mat = FMaterial::ValidateTexture(cmd.mTexture, false); + if (mat == nullptr) continue; + + // This requires very special handling + if (gl.legacyMode && cmd.mTexture->UseType == ETextureType::SWCanvas) + { + gl_RenderState.SetTextureMode(TM_SWCANVAS); + } + + if (gltrans == -1 && cmd.mTranslation != nullptr) gltrans = cmd.mTranslation->GetUniqueIndex(); + gl_RenderState.SetMaterial(mat, cmd.mFlags & F2DDrawer::DTF_Wrap ? CLAMP_NONE : CLAMP_XY_NOMIP, -gltrans, -1, cmd.mDrawMode == F2DDrawer::DTM_AlphaTexture); + gl_RenderState.EnableTexture(true); + + // Canvas textures are stored upside down + if (cmd.mTexture->bHasCanvas) + { + gl_RenderState.mTextureMatrix.loadIdentity(); + gl_RenderState.mTextureMatrix.scale(1.f, -1.f, 1.f); + gl_RenderState.mTextureMatrix.translate(0.f, 1.f, 0.0f); + gl_RenderState.EnableTextureMatrix(true); + } + } + else + { + gl_RenderState.EnableTexture(false); + } + gl_RenderState.Apply(); + + switch (cmd.mType) + { + case F2DDrawer::DrawTypeTriangles: + glDrawElements(GL_TRIANGLES, cmd.mIndexCount, GL_UNSIGNED_INT, (const void *)(cmd.mIndexIndex * sizeof(unsigned int))); + if (gl.legacyMode && cmd.mColor1 != 0) + { + // Draw the overlay as a separate operation. + LegacyColorOverlay(drawer, cmd); + } + break; + + case F2DDrawer::DrawTypeLines: + glDrawArrays(GL_LINES, cmd.mVertIndex, cmd.mVertCount); + break; + + case F2DDrawer::DrawTypePoints: + glDrawArrays(GL_POINTS, cmd.mVertIndex, cmd.mVertCount); + break; + + } + gl_RenderState.SetEffect(EFF_NONE); + gl_RenderState.EnableTextureMatrix(false); + } + glDisable(GL_SCISSOR_TEST); + + gl_RenderState.SetVertexBuffer(GLRenderer->mVBO); + gl_RenderState.EnableTexture(true); + gl_RenderState.SetTextureMode(TM_MODULATE); + gl_RenderState.SetFixedColormap(CM_DEFAULT); + gl_RenderState.ResetColor(); + gl_RenderState.Apply(); + delete vb; } diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index 1f68fe57e4..fa87ada0af 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -40,11 +40,12 @@ class FPresentShader; class FPresent3DCheckerShader; class FPresent3DColumnShader; class FPresent3DRowShader; -class F2DDrawer; +class FGL2DDrawer; class FHardwareTexture; class FShadowMapShader; class FCustomPostProcessShaders; class GLSceneDrawer; +class SWSceneDrawer; inline float DEG2RAD(float deg) { @@ -88,6 +89,29 @@ enum DM_SKYPORTAL }; + +// Helper baggage to draw the paletted software renderer output on old hardware. +// This must be here because the 2D drawer needs to access it, not the scene drawer. +class LegacyShader; +struct LegacyShaderContainer +{ + enum + { + NUM_SHADERS = 4 + }; + + LegacyShader *Shaders[NUM_SHADERS]; + + LegacyShader* CreatePixelShader(const FString& vertexsrc, const FString& fragmentsrc, const FString &defines); + LegacyShaderContainer(); + ~LegacyShaderContainer(); + bool LoadShaders(); + void BindShader(int num, const float *p1, const float *p2); +}; + + + + class FGLRenderer { public: @@ -146,7 +170,8 @@ public: FFlatVertexBuffer *mVBO; FSkyVertexBuffer *mSkyVBO; FLightBuffer *mLights; - F2DDrawer *m2DDrawer; + SWSceneDrawer *swdrawer = nullptr; + LegacyShaderContainer *legacyShaders = nullptr; GL_IRECT mScreenViewport; GL_IRECT mSceneViewport; @@ -170,10 +195,8 @@ public: void ClearBorders(); void FlushTextures(); - unsigned char *GetTextureBuffer(FTexture *tex, int &w, int &h); void SetupLevel(); - - void RenderView(player_t* player); + void ResetSWScene(); void RenderScreenQuad(); void PostProcessScene(int fixedcm, const std::function &afterBloomDrawEndScene2D); @@ -191,6 +214,11 @@ public: void DrawPresentTexture(const GL_IRECT &box, bool applyGamma); void Flush(); void GetSpecialTextures(); + void Draw2D(F2DDrawer *data); + void RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV); + void WriteSavePic(player_t *player, FileWriter *file, int width, int height); + void RenderView(player_t *player); + void DrawBlend(sector_t * viewsector, bool FixedColormap, bool docolormap, bool in2d = false); bool StartOffscreen(); diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index b27a5de599..2d02742f65 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -26,9 +26,9 @@ */ #include "templates.h" +#include "doomstat.h" #include "gl/system/gl_system.h" #include "gl/system/gl_interface.h" -#include "gl/data/gl_data.h" #include "gl/data/gl_vertexbuffer.h" #include "gl/system/gl_cvars.h" #include "gl/shaders/gl_shader.h" @@ -159,8 +159,6 @@ bool FRenderState::ApplyShader() glVertexAttrib4fv(VATTR_COLOR, mColor.vec); glVertexAttrib4fv(VATTR_NORMAL, mNormal.vec); - //activeShader->muObjectColor2.Set(mObjectColor2); - activeShader->muObjectColor2.Set(mObjectColor2); activeShader->muDesaturation.Set(mDesaturation / 255.f); activeShader->muFogEnabled.Set(fogset); @@ -171,6 +169,7 @@ bool FRenderState::ApplyShader() activeShader->muLightParms.Set(mLightParms); activeShader->muFogColor.Set(mFogColor); activeShader->muObjectColor.Set(mObjectColor); + activeShader->muObjectColor2.Set(mObjectColor2); activeShader->muDynLightColor.Set(mDynColor.vec); activeShader->muInterpolationFactor.Set(mInterpolationFactor); activeShader->muClipHeight.Set(mClipHeight); @@ -225,7 +224,28 @@ bool FRenderState::ApplyShader() activeShader->currentcliplinestate = 0; } - if (mColormapState != activeShader->currentfixedcolormap) + if (mColormapState < -1) // 2D operations + { + if (mColormapState != CM_SPECIAL2D) + { + activeShader->muColormapStart.Set(m2DColors[0]); + activeShader->muFixedColormap.Set(4); + } + else + { + float startr = m2DColors[0].r / 255.f; + float startg = m2DColors[0].g / 255.f; + float startb = m2DColors[0].b / 255.f; + float ranger = m2DColors[1].r / 255.f - startr; + float rangeg = m2DColors[1].g / 255.f - startg; + float rangeb = m2DColors[1].b / 255.f - startb; + activeShader->muColormapStart.Set(startr, startg, startb, 0.f); + activeShader->muColormapRange.Set(ranger, rangeg, rangeb, 0.f); + activeShader->muFixedColormap.Set(1); + } + activeShader->currentfixedcolormap = mColormapState; + } + else if (mColormapState != activeShader->currentfixedcolormap) { float r, g, b; activeShader->currentfixedcolormap = mColormapState; @@ -233,9 +253,9 @@ bool FRenderState::ApplyShader() { activeShader->muFixedColormap.Set(0); } - else if (mColormapState > CM_DEFAULT && mColormapState < CM_MAXCOLORMAP) + else if ((mColormapState >= CM_FIRSTSPECIALCOLORMAP && mColormapState < CM_MAXCOLORMAPFORCED)) { - if (FGLRenderBuffers::IsEnabled()) + if (FGLRenderBuffers::IsEnabled() && mColormapState < CM_FIRSTSPECIALCOLORMAPFORCED) { // When using postprocessing to apply the colormap, we must render the image fullbright here. activeShader->muFixedColormap.Set(2); @@ -243,13 +263,20 @@ bool FRenderState::ApplyShader() } else { - FSpecialColormap *scm = &SpecialColormaps[mColormapState - CM_FIRSTSPECIALCOLORMAP]; - float m[] = { scm->ColorizeEnd[0] - scm->ColorizeStart[0], - scm->ColorizeEnd[1] - scm->ColorizeStart[1], scm->ColorizeEnd[2] - scm->ColorizeStart[2], 0.f }; + if (mColormapState >= CM_FIRSTSPECIALCOLORMAPFORCED) + { + auto colormapState = mColormapState + CM_FIRSTSPECIALCOLORMAP - CM_FIRSTSPECIALCOLORMAPFORCED; + if (colormapState < CM_MAXCOLORMAP) + { + FSpecialColormap *scm = &SpecialColormaps[colormapState - CM_FIRSTSPECIALCOLORMAP]; + float m[] = { scm->ColorizeEnd[0] - scm->ColorizeStart[0], + scm->ColorizeEnd[1] - scm->ColorizeStart[1], scm->ColorizeEnd[2] - scm->ColorizeStart[2], 0.f }; - activeShader->muFixedColormap.Set(1); - activeShader->muColormapStart.Set(scm->ColorizeStart[0], scm->ColorizeStart[1], scm->ColorizeStart[2], 0.f); - activeShader->muColormapRange.Set(m); + activeShader->muFixedColormap.Set(1); + activeShader->muColormapStart.Set(scm->ColorizeStart[0], scm->ColorizeStart[1], scm->ColorizeStart[2], 0.f); + activeShader->muColormapRange.Set(m); + } + } } } else if (mColormapState == CM_FOGLAYER) diff --git a/src/gl/renderer/gl_renderstate.h b/src/gl/renderer/gl_renderstate.h index 34a030f8a0..54590e9deb 100644 --- a/src/gl/renderer/gl_renderstate.h +++ b/src/gl/renderer/gl_renderstate.h @@ -25,12 +25,12 @@ #include #include "gl/system/gl_interface.h" -#include "gl/data/gl_data.h" #include "r_data/matrix.h" #include "gl/textures/gl_material.h" #include "c_cvars.h" #include "r_defs.h" #include "r_data/r_translate.h" +#include "g_levellocals.h" class FVertexBuffer; class FShader; @@ -59,6 +59,7 @@ enum EEffect EFF_SPHEREMAP, EFF_BURN, EFF_STENCIL, + EFF_SWQUAD, MAX_EFFECTS }; @@ -72,6 +73,7 @@ enum EPassType class FRenderState { + friend void gl_SetTextureMode(int type); bool mTextureEnabled; bool mFogEnabled; bool mGlowEnabled; @@ -108,6 +110,7 @@ class FRenderState PalEntry mFogColor; PalEntry mObjectColor; PalEntry mObjectColor2; + PalEntry m2DColors[2]; // in the shader these will reuse the colormap ramp uniforms. FStateVec4 mDynColor; float mClipSplit[2]; @@ -144,8 +147,8 @@ public: void SetMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader, bool alphatexture) { - // alpha textures need special treatment in the legacy renderer because withouz shaders they need a different texture. - if (alphatexture && gl.legacyMode) translation = INT_MAX; + // alpha textures need special treatment in the legacy renderer because without shaders they need a different texture. This will also override all other translations. + if (alphatexture && gl.legacyMode) translation = -STRange_AlphaTexture; if (mat->tex->bHasCanvas) { @@ -156,8 +159,8 @@ public: mTempTM = TM_MODULATE; } mEffectState = overrideshader >= 0? overrideshader : mat->mShaderIndex; - mShaderTimer = mat->tex->gl_info.shaderspeed; - SetSpecular(mat->tex->gl_info.Glossiness, mat->tex->gl_info.SpecularLevel); + mShaderTimer = mat->tex->shaderspeed; + SetSpecular(mat->tex->Glossiness, mat->tex->SpecularLevel); mat->Bind(clampmode, translation); } @@ -355,9 +358,9 @@ public: mGlowBottom.Set(b[0], b[1], b[2], b[3]); } - void SetSoftLightLevel(int level) + void SetSoftLightLevel(int llevel) { - if (glset.lightmode == 8) mLightParms[3] = level / 255.f; + if (level.lightmode == 8) mLightParms[3] = llevel / 255.f; else mLightParms[3] = -1.f; } @@ -392,6 +395,11 @@ public: mObjectColor2 = pe; } + void Set2DOverlayColor(PalEntry pe) + { + m2DColors[0] = pe; + } + void SetSpecular(float glossiness, float specularLevel) { mGlossiness = glossiness; diff --git a/src/gl/scene/gl_bsp.cpp b/src/gl/scene/gl_bsp.cpp index 8f44b4fb78..f77cfbf085 100644 --- a/src/gl/scene/gl_bsp.cpp +++ b/src/gl/scene/gl_bsp.cpp @@ -36,7 +36,6 @@ #include "g_levellocals.h" #include "gl/renderer/gl_renderer.h" -#include "gl/data/gl_data.h" #include "gl/data/gl_vertexbuffer.h" #include "gl/scene/gl_scenedrawer.h" #include "gl/scene/gl_portal.h" @@ -423,7 +422,7 @@ void GLSceneDrawer::DoSubsector(subsector_t * sub) if (!sector) return; // If the mapsections differ this subsector can't possibly be visible from the current view point - if (!(currentmapsection[sub->mapsection>>3] & (1 << (sub->mapsection & 7)))) return; + if (!CurrentMapSections[sub->mapsection]) return; if (sub->flags & SSECF_POLYORG) return; // never render polyobject origin subsectors because their vertices no longer are where one may expect. if (gl_drawinfo->ss_renderflags[sub->Index()] & SSRF_SEEN) @@ -520,16 +519,16 @@ void GLSceneDrawer::DoSubsector(subsector_t * sub) (sub->numlines > 2) ? SSRF_PROCESSED|SSRF_RENDERALL : SSRF_PROCESSED; if (sub->hacked & 1) gl_drawinfo->AddHackedSubsector(sub); - FPortal *portal; + FSectorPortalGroup *portal; - portal = fakesector->GetGLPortal(sector_t::ceiling); + portal = fakesector->GetPortalGroup(sector_t::ceiling); if (portal != NULL) { GLSectorStackPortal *glportal = portal->GetRenderState(); glportal->AddSubsector(sub); } - portal = fakesector->GetGLPortal(sector_t::floor); + portal = fakesector->GetPortalGroup(sector_t::floor); if (portal != NULL) { GLSectorStackPortal *glportal = portal->GetRenderState(); diff --git a/src/gl/scene/gl_decal.cpp b/src/gl/scene/gl_decal.cpp index 0f3bc7ffb4..64f91b7fe3 100644 --- a/src/gl/scene/gl_decal.cpp +++ b/src/gl/scene/gl_decal.cpp @@ -32,7 +32,6 @@ #include "g_levellocals.h" #include "gl/system/gl_cvars.h" -#include "gl/data/gl_data.h" #include "gl/data/gl_vertexbuffer.h" #include "gl/renderer/gl_renderer.h" #include "gl/renderer/gl_lightdata.h" @@ -40,7 +39,6 @@ #include "gl/scene/gl_drawinfo.h" #include "gl/scene/gl_scenedrawer.h" #include "gl/shaders/gl_shader.h" -#include "gl/textures/gl_texture.h" #include "gl/textures/gl_material.h" #include "gl/utility/gl_clock.h" #include "gl/renderer/gl_quaddrawer.h" diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index c2d79b3ca1..e36d4a487f 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -35,7 +35,6 @@ #include "g_levellocals.h" #include "gl/system/gl_cvars.h" -#include "gl/data/gl_data.h" #include "gl/data/gl_vertexbuffer.h" #include "gl/scene/gl_drawinfo.h" #include "gl/scene/gl_portal.h" @@ -44,12 +43,12 @@ #include "gl/renderer/gl_renderstate.h" #include "gl/textures/gl_material.h" #include "gl/utility/gl_clock.h" -#include "gl/utility/gl_templates.h" #include "gl/shaders/gl_shader.h" #include "gl/stereo3d/scoped_color_mask.h" #include "gl/renderer/gl_quaddrawer.h" FDrawInfo * gl_drawinfo; +FDrawInfoList di_list; //========================================================================== // @@ -607,17 +606,6 @@ inline int GLDrawList::CompareSprites(SortNode * a,SortNode * b) else return (i_compatflags & COMPATF_SPRITESORT)? s1->index-s2->index : s2->index-s1->index; } -//========================================================================== -// -// -// -//========================================================================== -static GLDrawList * gd; -int CompareSprite(const void * a,const void * b) -{ - return gd->CompareSprites(*(SortNode**)a,*(SortNode**)b); -} - //========================================================================== // // @@ -635,8 +623,11 @@ SortNode * GLDrawList::SortSpriteList(SortNode * head) sortspritelist.Clear(); for(count=0,n=head;n;n=n->next) sortspritelist.Push(n); - gd=this; - qsort(&sortspritelist[0],sortspritelist.Size(),sizeof(SortNode *),CompareSprite); + std::sort(sortspritelist.begin(), sortspritelist.end(), [=](SortNode *a, SortNode *b) + { + return CompareSprites(a, b) < 0; + }); + for(i=0;inext=NULL; @@ -910,38 +901,20 @@ void GLDrawList::DrawDecals() // Sorting the drawitems first by texture and then by light level. // //========================================================================== -static GLDrawList * sortinfo; - -static int diwcmp (const void *a, const void *b) -{ - const GLDrawItem * di1 = (const GLDrawItem *)a; - GLWall * w1=&sortinfo->walls[di1->index]; - - const GLDrawItem * di2 = (const GLDrawItem *)b; - GLWall * w2=&sortinfo->walls[di2->index]; - - if (w1->gltexture != w2->gltexture) return w1->gltexture - w2->gltexture; - return ((w1->flags & 3) - (w2->flags & 3)); -} - -static int difcmp (const void *a, const void *b) -{ - const GLDrawItem * di1 = (const GLDrawItem *)a; - GLFlat * w1=&sortinfo->flats[di1->index]; - - const GLDrawItem * di2 = (const GLDrawItem *)b; - GLFlat* w2=&sortinfo->flats[di2->index]; - - return w1->gltexture - w2->gltexture; -} - void GLDrawList::SortWalls() { if (drawitems.Size() > 1) { - sortinfo=this; - qsort(&drawitems[0], drawitems.Size(), sizeof(drawitems[0]), diwcmp); + std::sort(drawitems.begin(), drawitems.end(), [=](const GLDrawItem &a, const GLDrawItem &b) -> bool + { + GLWall * w1 = &walls[a.index]; + GLWall * w2 = &walls[b.index]; + + if (w1->gltexture != w2->gltexture) return w1->gltexture < w2->gltexture; + return (w1->flags & 3) < (w2->flags & 3); + + }); } } @@ -949,8 +922,12 @@ void GLDrawList::SortFlats() { if (drawitems.Size() > 1) { - sortinfo=this; - qsort(&drawitems[0], drawitems.Size(), sizeof(drawitems[0]), difcmp); + std::sort(drawitems.begin(), drawitems.end(), [=](const GLDrawItem &a, const GLDrawItem &b) + { + GLFlat * w1 = &flats[a.index]; + GLFlat* w2 = &flats[b.index]; + return w1->gltexture < w2->gltexture; + }); } } @@ -990,6 +967,8 @@ void GLDrawList::AddSprite(GLSprite * sprite) // Try to reuse the lists as often as possible as they contain resources that // are expensive to create and delete. // +// Note: If multithreading gets used, this class needs synchronization. +// //========================================================================== FDrawInfo *FDrawInfoList::GetNew() @@ -1009,8 +988,6 @@ void FDrawInfoList::Release(FDrawInfo * di) mList.Push(di); } -static FDrawInfoList di_list; - //========================================================================== // // diff --git a/src/gl/scene/gl_fakeflat.cpp b/src/gl/scene/gl_fakeflat.cpp index a8726b273b..14a723d582 100644 --- a/src/gl/scene/gl_fakeflat.cpp +++ b/src/gl/scene/gl_fakeflat.cpp @@ -32,7 +32,6 @@ #include "r_sky.h" #include "gl/renderer/gl_renderer.h" #include "gl/scene/gl_scenedrawer.h" -#include "gl/data/gl_data.h" //========================================================================== diff --git a/src/gl/scene/gl_flats.cpp b/src/gl/scene/gl_flats.cpp index 98f5afa801..a3fe05c10d 100644 --- a/src/gl/scene/gl_flats.cpp +++ b/src/gl/scene/gl_flats.cpp @@ -43,18 +43,14 @@ #include "gl/renderer/gl_renderer.h" #include "gl/renderer/gl_lightdata.h" #include "gl/renderer/gl_renderstate.h" -#include "gl/data/gl_data.h" #include "gl/data/gl_vertexbuffer.h" #include "gl/dynlights/gl_dynlight.h" -#include "gl/dynlights/gl_glow.h" #include "gl/dynlights/gl_lightbuffer.h" #include "gl/scene/gl_drawinfo.h" #include "gl/shaders/gl_shader.h" #include "gl/scene/gl_scenedrawer.h" #include "gl/textures/gl_material.h" #include "gl/utility/gl_clock.h" -#include "gl/utility/gl_convert.h" -#include "gl/utility/gl_templates.h" #include "gl/renderer/gl_quaddrawer.h" #ifdef _DEBUG @@ -112,7 +108,7 @@ void GLFlat::SetupSubsectorLights(int pass, subsector_t * sub, int *dli) { Plane p; - if (renderstyle == STYLE_Add && !glset.lightadditivesurfaces) return; // no lights on additively blended surfaces. + if (renderstyle == STYLE_Add && !level.lightadditivesurfaces) return; // no lights on additively blended surfaces. if (dli != NULL && *dli != -1) { @@ -143,7 +139,7 @@ void GLFlat::SetupSubsectorLights(int pass, subsector_t * sub, int *dli) continue; } - p.Set(plane.plane); + p.Set(plane.plane.Normal(), plane.plane.fD()); gl_GetLight(sub->sector->PortalGroup, p, light, false, lightdata); node = node->nextLight; } @@ -420,7 +416,7 @@ void GLFlat::Draw(int pass, bool trans) // trans only has meaning for GLPASS_LIG } else { - if (!gltexture->GetTransparent()) gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold); + if (!gltexture->tex->GetTranslucency()) gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold); else gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false); gl_SetPlaneTextureRotation(&plane, gltexture); @@ -472,7 +468,7 @@ inline void GLFlat::PutFlat(bool fog) // translucent 3D floors go into the regular translucent list, translucent portals go into the translucent border list. list = (renderflags&SSRF_RENDER3DPLANES) ? GLDL_TRANSLUCENT : GLDL_TRANSLUCENTBORDER; } - else if (gltexture->GetTransparent()) + else if (gltexture->tex->GetTranslucency()) { if (stack) { diff --git a/src/gl/scene/gl_portal.cpp b/src/gl/scene/gl_portal.cpp index ed38127662..130fb263a5 100644 --- a/src/gl/scene/gl_portal.cpp +++ b/src/gl/scene/gl_portal.cpp @@ -45,8 +45,6 @@ #include "gl/renderer/gl_renderer.h" #include "gl/renderer/gl_renderstate.h" #include "gl/renderer/gl_quaddrawer.h" -#include "gl/dynlights/gl_glow.h" -#include "gl/data/gl_data.h" #include "gl/data/gl_vertexbuffer.h" #include "gl/scene/gl_clipper.h" #include "gl/scene/gl_drawinfo.h" @@ -56,7 +54,6 @@ #include "gl/stereo3d/scoped_color_mask.h" #include "gl/textures/gl_material.h" #include "gl/utility/gl_clock.h" -#include "gl/utility/gl_templates.h" //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- @@ -88,7 +85,9 @@ bool GLPortal::inskybox; UniqueList UniqueSkies; UniqueList UniqueHorizons; UniqueList UniquePlaneMirrors; -UniqueList UniqueLineToLines; +UniqueList UniqueLineToLines; + +int skyboxrecursion = 0; //========================================================================== // @@ -463,7 +462,7 @@ void GLPortal::StartFrame() //----------------------------------------------------------------------------- // -// Portal info +// printing portal info // //----------------------------------------------------------------------------- @@ -474,7 +473,7 @@ CCMD(gl_portalinfo) gl_portalinfo = true; } -FString indent; +static FString indent; //----------------------------------------------------------------------------- // @@ -580,20 +579,22 @@ GLPortal * GLPortal::FindPortal(const void * src) //----------------------------------------------------------------------------- // -// +// Save/RestoreMapSection +// +// saves CurrentMapSection for a recursive call of SceneDrawer::DrawScene // //----------------------------------------------------------------------------- void GLPortal::SaveMapSection() { - savedmapsection.Resize(currentmapsection.Size()); - memcpy(&savedmapsection[0], ¤tmapsection[0], currentmapsection.Size()); - memset(¤tmapsection[0], 0, currentmapsection.Size()); + SavedMapSection = std::move(drawer->CurrentMapSections); + drawer->CurrentMapSections.Resize(SavedMapSection.Size()); + drawer->CurrentMapSections.Zero(); } void GLPortal::RestoreMapSection() { - memcpy(¤tmapsection[0], &savedmapsection[0], currentmapsection.Size()); + drawer->CurrentMapSections = std::move(SavedMapSection); } //----------------------------------------------------------------------------- @@ -611,7 +612,7 @@ void GLPortal::RestoreMapSection() // GLSkyboxPortal::DrawContents // //----------------------------------------------------------------------------- -static int skyboxrecursion=0; + void GLSkyboxPortal::DrawContents() { int old_pm = PlaneMirrorMode; @@ -651,7 +652,7 @@ void GLSkyboxPortal::DrawContents() int mapsection = R_PointInSubsector(r_viewpoint.Pos)->mapsection; SaveMapSection(); - currentmapsection[mapsection >> 3] |= 1 << (mapsection & 7); + drawer->CurrentMapSections.Set(mapsection); drawer->DrawScene(DM_SKYPORTAL); portal->mFlags &= ~PORTSF_INSKYBOX; @@ -674,6 +675,22 @@ void GLSkyboxPortal::DrawContents() // //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- + + +//========================================================================== +// +// Fixme: This needs abstraction. +// +//========================================================================== + +GLSectorStackPortal *FSectorPortalGroup::GetRenderState() +{ + if (glportal == NULL) glportal = new GLSectorStackPortal(this); + return glportal; +} + + + GLSectorStackPortal::~GLSectorStackPortal() { if (origin != NULL && origin->glportal == this) @@ -717,7 +734,7 @@ void GLSectorStackPortal::SetupCoverage() for(int j=0;jportalcoverage[plane].sscount; j++) { subsector_t *dsub = &::level.subsectors[sub->portalcoverage[plane].subsectors[j]]; - currentmapsection[dsub->mapsection>>3] |= 1 << (dsub->mapsection&7); + drawer->CurrentMapSections.Set(dsub->mapsection); gl_drawinfo->ss_renderflags[dsub->Index()] |= SSRF_SEEN; } } @@ -731,7 +748,7 @@ void GLSectorStackPortal::SetupCoverage() //----------------------------------------------------------------------------- void GLSectorStackPortal::DrawContents() { - FPortal *portal = origin; + FSectorPortalGroup *portal = origin; r_viewpoint.Pos += origin->mDisplacement; r_viewpoint.ActorPos += origin->mDisplacement; @@ -1040,8 +1057,7 @@ void GLLineToLinePortal::DrawContents() if (line->sidedef[0]->Flags & WALLF_POLYOBJ) sub = R_PointInSubsector(line->v1->fixX(), line->v1->fixY()); else sub = line->frontsector->subsectors[0]; - int mapsection = sub->mapsection; - currentmapsection[mapsection >> 3] |= 1 << (mapsection & 7); + drawer->CurrentMapSections.Set(sub->mapsection); } GLRenderer->mViewActor = nullptr; diff --git a/src/gl/scene/gl_portal.h b/src/gl/scene/gl_portal.h index 4eade59d2c..0e57906a61 100644 --- a/src/gl/scene/gl_portal.h +++ b/src/gl/scene/gl_portal.h @@ -37,11 +37,9 @@ #define __GL_PORTAL_H #include "tarray.h" -//#include "gl/gl_intern.h" +#include "actor.h" #include "gl/renderer/gl_renderer.h" #include "gl/scene/gl_drawinfo.h" -#include "gl/utility/gl_templates.h" -#include "gl/data/gl_data.h" struct GLHorizonInfo { @@ -76,7 +74,7 @@ struct GLSkyInfo extern UniqueList UniqueSkies; extern UniqueList UniqueHorizons; extern UniqueList UniquePlaneMirrors; -extern UniqueList UniqueLineToLines; +extern UniqueList UniqueLineToLines; struct GLEEHorizonPortal; class GLSceneDrawer; @@ -111,7 +109,7 @@ private: ActorRenderFlags savedvisibility; GLPortal *PrevPortal; GLPortal *PrevClipPortal; - TArray savedmapsection; + BitArray SavedMapSection; TArray mPrimIndices; protected: @@ -200,7 +198,7 @@ struct GLLinePortal : public GLPortal CalcDelta(); } - GLLinePortal(FGLLinePortal *line) + GLLinePortal(FLinePortalSpan *line) { if (line->lines[0]->mType != PORTT_LINKED || line->v1 == nullptr) { @@ -260,7 +258,7 @@ public: struct GLLineToLinePortal : public GLLinePortal { - FGLLinePortal *glport; + FLinePortalSpan *glport; protected: virtual void DrawContents(); virtual void * GetSource() const { return glport; } @@ -270,7 +268,7 @@ protected: public: - GLLineToLinePortal(FGLLinePortal *ll) + GLLineToLinePortal(FLinePortalSpan *ll) : GLLinePortal(ll) { glport = ll; @@ -333,11 +331,11 @@ protected: virtual void * GetSource() const { return origin; } virtual bool IsSky() { return true; } // although this isn't a real sky it can be handled as one. virtual const char *GetName(); - FPortal *origin; + FSectorPortalGroup *origin; public: - GLSectorStackPortal(FPortal *pt) + GLSectorStackPortal(FSectorPortalGroup *pt) { origin=pt; } diff --git a/src/gl/scene/gl_renderhacks.cpp b/src/gl/scene/gl_renderhacks.cpp index 827842cfd5..fff839c5ef 100644 --- a/src/gl/scene/gl_renderhacks.cpp +++ b/src/gl/scene/gl_renderhacks.cpp @@ -33,25 +33,27 @@ #include "g_levellocals.h" #include "gl/renderer/gl_renderer.h" -#include "gl/data/gl_data.h" -#include "gl/dynlights/gl_glow.h" #include "gl/scene/gl_drawinfo.h" #include "gl/scene/gl_portal.h" #include "gl/scene/gl_scenedrawer.h" #include "gl/utility/gl_clock.h" -#include "gl/utility/gl_templates.h" // This is for debugging maps. -FreeList SSR_List; - // profiling data static int totalupper, totallower; static int lowershcount, uppershcount; -static glcycle_t totalms, showtotalms; -static glcycle_t totalssms; -static sector_t fakesec; +static glcycle_t totalms, showtotalms, totalssms; + + +static sector_t fakesec; // this is static because it gets used in recursively called functions. + +// Having this static doesn't really matter here because the hack code is not multithreading-capable anyway. +static bool inview; +static subsector_t * viewsubsector; +static TArray lowersegs; + void FDrawInfo::ClearBuffers() { @@ -62,7 +64,7 @@ void FDrawInfo::ClearBuffers() { gl_subsectorrendernode * n = node; node = node->next; - SSR_List.Release(n); + delete n; } } otherfloorplanes.Clear(); @@ -74,7 +76,7 @@ void FDrawInfo::ClearBuffers() { gl_subsectorrendernode * n = node; node = node->next; - SSR_List.Release(n); + delete n; } } otherceilingplanes.Clear(); @@ -507,7 +509,7 @@ void FDrawInfo::HandleMissingTextures() for (unsigned int j = 0; j < HandledSubsectors.Size(); j++) { - gl_subsectorrendernode * node = SSR_List.GetNew(); + gl_subsectorrendernode * node = new gl_subsectorrendernode; node->sub = HandledSubsectors[j]; AddOtherCeilingPlane(sec->sectornum, node); @@ -551,7 +553,7 @@ void FDrawInfo::HandleMissingTextures() for (unsigned int j = 0; j < HandledSubsectors.Size(); j++) { - gl_subsectorrendernode * node = SSR_List.GetNew(); + gl_subsectorrendernode * node = new gl_subsectorrendernode; node->sub = HandledSubsectors[j]; AddOtherCeilingPlane(fakesector->sectornum, node); } @@ -579,7 +581,7 @@ void FDrawInfo::HandleMissingTextures() for (unsigned int j = 0; j < HandledSubsectors.Size(); j++) { - gl_subsectorrendernode * node = SSR_List.GetNew(); + gl_subsectorrendernode * node = new gl_subsectorrendernode; node->sub = HandledSubsectors[j]; AddOtherFloorPlane(sec->sectornum, node); } @@ -622,7 +624,7 @@ void FDrawInfo::HandleMissingTextures() for (unsigned int j = 0; j < HandledSubsectors.Size(); j++) { - gl_subsectorrendernode * node = SSR_List.GetNew(); + gl_subsectorrendernode * node = new gl_subsectorrendernode; node->sub = HandledSubsectors[j]; AddOtherFloorPlane(fakesector->sectornum, node); } @@ -664,7 +666,7 @@ void FDrawInfo::DrawUnhandledMissingTextures() if (seg->backsector->GetTexture(sector_t::ceiling) == skyflatnum) continue; if (seg->backsector->ValidatePortal(sector_t::ceiling) != NULL) continue; - if (!glset.notexturefill) FloodUpperGap(seg); + if (!level.notexturefill) FloodUpperGap(seg); } validcount++; @@ -683,7 +685,7 @@ void FDrawInfo::DrawUnhandledMissingTextures() if (seg->backsector->GetTexture(sector_t::floor) == skyflatnum) continue; if (seg->backsector->ValidatePortal(sector_t::floor) != NULL) continue; - if (!glset.notexturefill) FloodLowerGap(seg); + if (!level.notexturefill) FloodLowerGap(seg); } MissingUpperTextures.Clear(); MissingLowerTextures.Clear(); @@ -765,9 +767,6 @@ bool FDrawInfo::CheckAnchorFloor(subsector_t * sub) // Collect connected subsectors that have to be rendered with the same plane // //========================================================================== -static bool inview; -static subsector_t * viewsubsector; -static TArray lowersegs; bool FDrawInfo::CollectSubsectorsFloor(subsector_t * sub, sector_t * anchor) { @@ -955,7 +954,7 @@ void FDrawInfo::HandleHackedSubsectors() { for(unsigned int j=0;jsub = HandledSubsectors[j]; AddOtherFloorPlane(sub->render_sector->sectornum, node); @@ -985,7 +984,7 @@ void FDrawInfo::HandleHackedSubsectors() { for(unsigned int j=0;jsub = HandledSubsectors[j]; AddOtherCeilingPlane(sub->render_sector->sectornum, node); @@ -1037,7 +1036,7 @@ void FDrawInfo::CollectSectorStacksCeiling(subsector_t * sub, sector_t * anchor) sub->validcount=validcount; // Has a sector stack or skybox itself! - if (sub->render_sector->GetGLPortal(sector_t::ceiling) != nullptr) return; + if (sub->render_sector->GetPortalGroup(sector_t::ceiling) != nullptr) return; // Don't bother processing unrendered subsectors if (sub->numlines>2 && !(ss_renderflags[sub->Index()]&SSRF_PROCESSED)) return; @@ -1081,7 +1080,7 @@ void FDrawInfo::CollectSectorStacksFloor(subsector_t * sub, sector_t * anchor) sub->validcount=validcount; // Has a sector stack or skybox itself! - if (sub->render_sector->GetGLPortal(sector_t::floor) != nullptr) return; + if (sub->render_sector->GetPortalGroup(sector_t::floor) != nullptr) return; // Don't bother processing unrendered subsectors if (sub->numlines>2 && !(ss_renderflags[sub->Index()]&SSRF_PROCESSED)) return; @@ -1122,13 +1121,12 @@ void FDrawInfo::CollectSectorStacksFloor(subsector_t * sub, sector_t * anchor) void FDrawInfo::ProcessSectorStacks() { unsigned int i; - sector_t fake; validcount++; for (i=0;iin_area, false); - FPortal *portal = sec->GetGLPortal(sector_t::ceiling); + sector_t *sec = gl_FakeFlat(CeilingStacks[i], &fakesec, mDrawer->in_area, false); + auto portal = sec->GetPortalGroup(sector_t::ceiling); if (portal != NULL) for(int k=0;ksubsectorcount;k++) { subsector_t * sub = sec->subsectors[k]; @@ -1152,14 +1150,14 @@ void FDrawInfo::ProcessSectorStacks() if (sub->portalcoverage[sector_t::ceiling].subsectors == NULL) { - gl_BuildPortalCoverage(&sub->portalcoverage[sector_t::ceiling], sub, portal->mDisplacement); + BuildPortalCoverage(&sub->portalcoverage[sector_t::ceiling], sub, portal->mDisplacement); } portal->GetRenderState()->AddSubsector(sub); if (sec->GetAlpha(sector_t::ceiling) != 0 && sec->GetTexture(sector_t::ceiling) != skyflatnum) { - gl_subsectorrendernode * node = SSR_List.GetNew(); + gl_subsectorrendernode * node = new gl_subsectorrendernode; node->sub = sub; AddOtherCeilingPlane(sec->sectornum, node); } @@ -1171,8 +1169,8 @@ void FDrawInfo::ProcessSectorStacks() validcount++; for (i=0;iin_area, false); - FPortal *portal = sec->GetGLPortal(sector_t::floor); + sector_t *sec = gl_FakeFlat(FloorStacks[i], &fakesec, mDrawer->in_area, false); + auto portal = sec->GetPortalGroup(sector_t::floor); if (portal != NULL) for(int k=0;ksubsectorcount;k++) { subsector_t * sub = sec->subsectors[k]; @@ -1197,7 +1195,7 @@ void FDrawInfo::ProcessSectorStacks() if (sub->portalcoverage[sector_t::floor].subsectors == NULL) { - gl_BuildPortalCoverage(&sub->portalcoverage[sector_t::floor], sub, portal->mDisplacement); + BuildPortalCoverage(&sub->portalcoverage[sector_t::floor], sub, portal->mDisplacement); } GLSectorStackPortal *glportal = portal->GetRenderState(); @@ -1205,7 +1203,7 @@ void FDrawInfo::ProcessSectorStacks() if (sec->GetAlpha(sector_t::floor) != 0 && sec->GetTexture(sector_t::floor) != skyflatnum) { - gl_subsectorrendernode * node = SSR_List.GetNew(); + gl_subsectorrendernode * node = new gl_subsectorrendernode; node->sub = sub; AddOtherFloorPlane(sec->sectornum, node); } diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 060eaf6a34..1d3524f753 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -42,7 +42,6 @@ #include "po_man.h" #include "r_utility.h" #include "p_local.h" -#include "gl/gl_functions.h" #include "serializer.h" #include "g_levellocals.h" #include "events.h" @@ -54,7 +53,6 @@ #include "gl/renderer/gl_lightdata.h" #include "gl/renderer/gl_renderstate.h" #include "gl/renderer/gl_renderbuffers.h" -#include "gl/data/gl_data.h" #include "gl/data/gl_vertexbuffer.h" #include "gl/dynlights/gl_dynlight.h" #include "gl/models/gl_models.h" @@ -67,8 +65,6 @@ #include "gl/stereo3d/scoped_view_shifter.h" #include "gl/textures/gl_material.h" #include "gl/utility/gl_clock.h" -#include "gl/utility/gl_convert.h" -#include "gl/utility/gl_templates.h" //========================================================================== // @@ -83,17 +79,9 @@ CVAR(Bool, gl_sort_textures, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) EXTERN_CVAR (Bool, cl_capfps) EXTERN_CVAR (Bool, r_deathcamera) -EXTERN_CVAR (Float, underwater_fade_scalar) EXTERN_CVAR (Float, r_visibility) -EXTERN_CVAR (Bool, gl_legacy_mode) EXTERN_CVAR (Bool, r_drawvoxels) -extern bool NoInterpolateView; - -area_t in_area; -TArray currentmapsection; -int camtexcount; - //----------------------------------------------------------------------------- // // R_FrustumAngle @@ -268,7 +256,7 @@ void GLSceneDrawer::CreateScene() ProcessAll.Clock(); // clip the scene and fill the drawlists - for(unsigned i=0;iglportal = NULL; + for(auto p : level.portalGroups) p->glportal = nullptr; GLRenderer->gl_spriteindex=0; Bsp.Clock(); GLRenderer->mVBO->Map(); @@ -278,7 +266,9 @@ void GLSceneDrawer::CreateScene() if (GLRenderer->mCurrentPortal != NULL) GLRenderer->mCurrentPortal->RenderAttached(); Bsp.Unclock(); - // And now the crappy hacks that have to be done to avoid rendering anomalies: + // And now the crappy hacks that have to be done to avoid rendering anomalies. + // These cannot be multithreaded when the time comes because all these depend + // on the global 'validcount' variable. gl_drawinfo->HandleMissingTextures(); // Missing upper/lower textures gl_drawinfo->HandleHackedSubsectors(); // open sector hacks for deep water @@ -464,7 +454,7 @@ void GLSceneDrawer::RenderTranslucent() //----------------------------------------------------------------------------- // // gl_drawscene - this function renders the scene from the current -// viewpoint, including mirrors and skyboxes and other glSectorPortals +// viewpoint, including mirrors and skyboxes and other portals // It is assumed that the GLPortal::EndFrame returns with the // stencil, z-buffer and the projection matrix intact! // @@ -515,7 +505,7 @@ void GLSceneDrawer::DrawScene(int drawmode) gl_RenderState.ApplyMatrices(); } - // Handle all glSectorPortals after rendering the opaque objects but before + // Handle all portals after rendering the opaque objects but before // doing all translucent stuff recursion++; GLPortal::EndFrame(); @@ -523,138 +513,6 @@ void GLSceneDrawer::DrawScene(int drawmode) RenderTranslucent(); } - -void gl_FillScreen() -{ - gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); - gl_RenderState.EnableTexture(false); - gl_RenderState.Apply(); - // The fullscreen quad is stored at index 4 in the main vertex buffer. - GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, FFlatVertexBuffer::FULLSCREEN_INDEX, 4); -} - -//========================================================================== -// -// Draws a blend over the entire view -// -//========================================================================== -void GLSceneDrawer::DrawBlend(sector_t * viewsector) -{ - float blend[4]={0,0,0,0}; - PalEntry blendv=0; - float extra_red; - float extra_green; - float extra_blue; - player_t *player = NULL; - - if (players[consoleplayer].camera != NULL) - { - player=players[consoleplayer].camera->player; - } - - // don't draw sector based blends when an invulnerability colormap is active - if (!FixedColormap) - { - if (!viewsector->e->XFloor.ffloors.Size()) - { - if (viewsector->heightsec && !(viewsector->MoreFlags&SECF_IGNOREHEIGHTSEC)) - { - switch (in_area) - { - default: - case area_normal: blendv = viewsector->heightsec->midmap; break; - case area_above: blendv = viewsector->heightsec->topmap; break; - case area_below: blendv = viewsector->heightsec->bottommap; break; - } - } - } - else - { - TArray & lightlist = viewsector->e->XFloor.lightlist; - - for (unsigned int i = 0; i < lightlist.Size(); i++) - { - double lightbottom; - if (i < lightlist.Size() - 1) - lightbottom = lightlist[i + 1].plane.ZatPoint(r_viewpoint.Pos); - else - lightbottom = viewsector->floorplane.ZatPoint(r_viewpoint.Pos); - - if (lightbottom < r_viewpoint.Pos.Z && (!lightlist[i].caster || !(lightlist[i].caster->flags&FF_FADEWALLS))) - { - // 3d floor 'fog' is rendered as a blending value - blendv = lightlist[i].blend; - // If this is the same as the sector's it doesn't apply! - if (blendv == viewsector->Colormap.FadeColor) blendv = 0; - // a little hack to make this work for Legacy maps. - if (blendv.a == 0 && blendv != 0) blendv.a = 128; - break; - } - } - } - - if (blendv.a == 0) - { - blendv = R_BlendForColormap(blendv); - } - - if (blendv.a == 255) - { - - extra_red = blendv.r / 255.0f; - extra_green = blendv.g / 255.0f; - extra_blue = blendv.b / 255.0f; - - // If this is a multiplicative blend do it separately and add the additive ones on top of it. - blendv = 0; - - // black multiplicative blends are ignored - if (extra_red || extra_green || extra_blue) - { - gl_RenderState.BlendFunc(GL_DST_COLOR, GL_ZERO); - gl_RenderState.SetColor(extra_red, extra_green, extra_blue, 1.0f); - gl_FillScreen(); - } - } - else if (blendv.a) - { - // [Nash] allow user to set blend intensity - int cnt = blendv.a; - cnt = (int)(cnt * underwater_fade_scalar); - - V_AddBlend(blendv.r / 255.f, blendv.g / 255.f, blendv.b / 255.f, cnt / 255.0f, blend); - } - } - - // This mostly duplicates the code in shared_sbar.cpp - // When I was writing this the original was called too late so that I - // couldn't get the blend in time. However, since then I made some changes - // here that would get lost if I switched back so I won't do it. - - if (player) - { - V_AddPlayerBlend(player, blend, 0.5, 175); - } - - if (players[consoleplayer].camera != NULL) - { - // except for fadeto effects - player_t *player = (players[consoleplayer].camera->player != NULL) ? players[consoleplayer].camera->player : &players[consoleplayer]; - V_AddBlend (player->BlendR, player->BlendG, player->BlendB, player->BlendA, blend); - } - - gl_RenderState.SetTextureMode(TM_MODULATE); - gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - if (blend[3]>0.0f) - { - gl_RenderState.SetColor(blend[0], blend[1], blend[2], blend[3]); - gl_FillScreen(); - } - gl_RenderState.ResetColor(); - gl_RenderState.EnableTexture(true); -} - - //----------------------------------------------------------------------------- // // Draws player sprites and color blend @@ -740,8 +598,9 @@ void GLSceneDrawer::ProcessScene(bool toscreen) GLPortal::BeginScene(); int mapsection = R_PointInSubsector(r_viewpoint.Pos)->mapsection; - memset(¤tmapsection[0], 0, currentmapsection.Size()); - currentmapsection[mapsection>>3] |= 1 << (mapsection & 7); + CurrentMapSections.Resize(level.NumMapSections); + CurrentMapSections.Zero(); + CurrentMapSections.Set(mapsection); DrawScene(toscreen ? DM_MAINVIEW : DM_OFFSCREEN); FDrawInfo::EndDrawInfo(); @@ -793,6 +652,17 @@ void GLSceneDrawer::SetFixedColormap (player_t *player) gl_RenderState.SetFixedColormap(FixedColormap); } +//----------------------------------------------------------------------------- +// +// +// +//----------------------------------------------------------------------------- + +void GLSceneDrawer::DrawBlend(sector_t *viewsector) +{ + GLRenderer->DrawBlend(viewsector, !!FixedColormap, true); +} + //----------------------------------------------------------------------------- // // Renders one viewpoint in a scene @@ -892,63 +762,6 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, f return lviewsector; } -//----------------------------------------------------------------------------- -// -// renders the view -// -//----------------------------------------------------------------------------- - -void FGLRenderer::RenderView (player_t* player) -{ - checkBenchActive(); - - gl_RenderState.SetVertexBuffer(mVBO); - mVBO->Reset(); - - // reset statistics counters - ResetProfilingData(); - - // Get this before everything else - if (cl_capfps || r_NoInterpolate) r_viewpoint.TicFrac = 1.; - else r_viewpoint.TicFrac = I_GetTimeFrac (); - - P_FindParticleSubsectors (); - - if (!gl.legacyMode) mLights->Clear(); - - // NoInterpolateView should have no bearing on camera textures, but needs to be preserved for the main view below. - bool saved_niv = NoInterpolateView; - NoInterpolateView = false; - // prepare all camera textures that have been used in the last frame - FCanvasTextureInfo::UpdateAll(); - NoInterpolateView = saved_niv; - - - // now render the main view - float fovratio; - float ratio = r_viewwindow.WidescreenRatio; - if (r_viewwindow.WidescreenRatio >= 1.3f) - { - fovratio = 1.333333f; - } - else - { - fovratio = ratio; - } - GLSceneDrawer drawer; - - drawer.SetFixedColormap (player); - - // Check if there's some lights. If not some code can be skipped. - TThinkerIterator it(STAT_DLIGHT); - mLightCount = ((it.Next()) != NULL); - - mShadowMap.Update(); - sector_t * viewsector = drawer.RenderViewpoint(player->camera, NULL, r_viewpoint.FieldOfView.Degrees, ratio, fovratio, true, true); - - All.Unclock(); -} - //=========================================================================== // // Render the view to a savegame picture @@ -992,231 +805,3 @@ void GLSceneDrawer::WriteSavePic (player_t *player, FileWriter *file, int width, M_CreatePNG (file, scr + ((height-1) * width * 3), NULL, SS_RGB, width, height, -width * 3, Gamma); M_Free(scr); } - - -//=========================================================================== -// -// -// -//=========================================================================== - -struct FGLInterface : public FRenderer -{ - void Precache(uint8_t *texhitlist, TMap &actorhitlist) override; - void RenderView(player_t *player) override; - void WriteSavePic (player_t *player, FileWriter *file, int width, int height) override; - void StartSerialize(FSerializer &arc) override; - void EndSerialize(FSerializer &arc) override; - void RenderTextureView (FCanvasTexture *self, AActor *viewpoint, double fov) override; - void PreprocessLevel() override; - void CleanLevelData() override; - bool RequireGLNodes() override; - - int GetMaxViewPitch(bool down) override; - void SetClearColor(int color) override; - void Init() override; - uint32_t GetCaps() override; -}; - -//========================================================================== -// -// DFrameBuffer :: Precache -// -//========================================================================== -void gl_PrecacheTexture(uint8_t *texhitlist, TMap &actorhitlist); - -void FGLInterface::Precache(uint8_t *texhitlist, TMap &actorhitlist) -{ - gl_PrecacheTexture(texhitlist, actorhitlist); -} - -//=========================================================================== -// -// notify the renderer that serialization of the curent level is about to start/end -// -//=========================================================================== - -void FGLInterface::StartSerialize(FSerializer &arc) -{ -} - -void FGLInterface::EndSerialize(FSerializer &arc) -{ - if (arc.isReading()) - { - // The portal data needs to be recreated after reading a savegame. - gl_InitPortals(); - } -} - -//=========================================================================== -// -// Get max. view angle (renderer specific information so it goes here now) -// -//=========================================================================== - -EXTERN_CVAR(Float, maxviewpitch) - -int FGLInterface::GetMaxViewPitch(bool down) -{ - return int(maxviewpitch); -} - -//=========================================================================== -// -// -// -//=========================================================================== - -void FGLInterface::SetClearColor(int color) -{ - PalEntry pe = GPalette.BaseColors[color]; - GLRenderer->mSceneClearColor[0] = pe.r / 255.f; - GLRenderer->mSceneClearColor[1] = pe.g / 255.f; - GLRenderer->mSceneClearColor[2] = pe.b / 255.f; -} - -//=========================================================================== -// -// Render the view to a savegame picture -// -//=========================================================================== - -void FGLInterface::WriteSavePic (player_t *player, FileWriter *file, int width, int height) -{ - GLSceneDrawer drawer; - drawer.WriteSavePic(player, file, width, height); -} - -//=========================================================================== -// -// -// -//=========================================================================== - -void FGLInterface::RenderView(player_t *player) -{ - GLRenderer->RenderView(player); -} - -//=========================================================================== -// -// -// -//=========================================================================== - -void FGLInterface::Init() -{ - gl_InitData(); -} - -//=========================================================================== -// -// Camera texture rendering -// -//=========================================================================== -CVAR(Bool, gl_usefb, false , CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -extern TexFilter_s TexFilter[]; - -void FGLInterface::RenderTextureView (FCanvasTexture *tex, AActor *Viewpoint, double FOV) -{ - FMaterial * gltex = FMaterial::ValidateTexture(tex, false); - - int width = gltex->TextureWidth(); - int height = gltex->TextureHeight(); - - if (gl.legacyMode) - { - // In legacy mode, fail if the requested texture is too large. - if (gltex->GetWidth() > screen->GetWidth() || gltex->GetHeight() > screen->GetHeight()) return; - glFlush(); - } - else - { - GLRenderer->StartOffscreen(); - gltex->BindToFrameBuffer(); - } - - GL_IRECT bounds; - bounds.left=bounds.top=0; - bounds.width=FHardwareTexture::GetTexDimension(gltex->GetWidth()); - bounds.height=FHardwareTexture::GetTexDimension(gltex->GetHeight()); - - GLSceneDrawer drawer; - drawer.FixedColormap = CM_DEFAULT; - gl_RenderState.SetFixedColormap(CM_DEFAULT); - drawer.RenderViewpoint(Viewpoint, &bounds, FOV, (float)width/height, (float)width/height, false, false); - - if (gl.legacyMode) - { - glFlush(); - gl_RenderState.SetMaterial(gltex, 0, 0, -1, false); - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, bounds.width, bounds.height); - } - else - { - GLRenderer->EndOffscreen(); - } - - tex->SetUpdated(); - camtexcount++; -} - -//=========================================================================== -// -// -// -//=========================================================================== - -void FGLInterface::PreprocessLevel() -{ - gl_PreprocessLevel(); -} - -void FGLInterface::CleanLevelData() -{ - gl_CleanLevelData(); -} - -bool FGLInterface::RequireGLNodes() -{ - return true; -} - -uint32_t FGLInterface::GetCaps() -{ - // describe our basic feature set - ActorRenderFeatureFlags FlagSet = RFF_FLATSPRITES | RFF_MODELS | RFF_SLOPE3DFLOORS | - RFF_TILTPITCH | RFF_ROLLSPRITES | RFF_POLYGONAL; - if (r_drawvoxels) - FlagSet |= RFF_VOXELS; - if (gl_legacy_mode) - { - // legacy mode always has truecolor because palette tonemap is not available - FlagSet |= RFF_TRUECOLOR; - } - else if (!(FGLRenderBuffers::IsEnabled())) - { - // truecolor is always available when renderbuffers are unavailable because palette tonemap is not possible - FlagSet |= RFF_TRUECOLOR | RFF_MATSHADER | RFF_BRIGHTMAP; - } - else - { - if (gl_tonemap != 5) // not running palette tonemap shader - FlagSet |= RFF_TRUECOLOR; - FlagSet |= RFF_MATSHADER | RFF_POSTSHADER | RFF_BRIGHTMAP; - } - return (uint32_t)FlagSet; -} -//=========================================================================== -// -// -// -//=========================================================================== - -FRenderer *gl_CreateInterface() -{ - return new FGLInterface; -} - - diff --git a/src/gl/scene/gl_scenedrawer.h b/src/gl/scene/gl_scenedrawer.h index 9ca7132f1b..4f59120acf 100644 --- a/src/gl/scene/gl_scenedrawer.h +++ b/src/gl/scene/gl_scenedrawer.h @@ -6,6 +6,16 @@ #include "gl_portal.h" #include "gl/renderer/gl_lightdata.h" #include "gl/renderer/gl_renderer.h" +#include "r_utility.h" +#include "c_cvars.h" + +EXTERN_CVAR(Int, gl_weaponlight); + +inline int getExtraLight() +{ + return r_viewpoint.extralight * gl_weaponlight; +} + class GLSceneDrawer { @@ -45,6 +55,7 @@ public: Clipper clipper; int FixedColormap; area_t in_area; + BitArray CurrentMapSections; // this cannot be a single number, because a group of portals with the same displacement may link different sections. angle_t FrustumAngle(); void SetViewMatrix(float vx, float vy, float vz, bool mirror, bool planemirror); @@ -60,7 +71,7 @@ public: void DrawBlend(sector_t * viewsector); void EndDrawScene(sector_t * viewsector); void DrawEndScene2D(sector_t * viewsector); - void RenderActorsInPortal(FGLLinePortal *glport); + void RenderActorsInPortal(FLinePortalSpan *glport); void CheckViewArea(vertex_t *v1, vertex_t *v2, sector_t *frontsector, sector_t *backsector); @@ -71,7 +82,7 @@ public: void DrawPSprite(player_t * player, DPSprite *psp, float sx, float sy, bool hudModelStep, int OverrideShader, bool alphatexture); void DrawPlayerSprites(sector_t * viewsector, bool hudModelStep); void DrawTargeterSprites(); - + void InitClipper(angle_t a1, angle_t a2) { clipper.Clear(); diff --git a/src/gl/scene/gl_sky.cpp b/src/gl/scene/gl_sky.cpp index d1781dacce..9abd693980 100644 --- a/src/gl/scene/gl_sky.cpp +++ b/src/gl/scene/gl_sky.cpp @@ -29,14 +29,11 @@ #include "doomdata.h" #include "portal.h" #include "g_levellocals.h" -#include "gl/gl_functions.h" -#include "gl/data/gl_data.h" #include "gl/renderer/gl_lightdata.h" #include "gl/scene/gl_drawinfo.h" #include "gl/scene/gl_portal.h" #include "gl/textures/gl_material.h" -#include "gl/utility/gl_convert.h" CVAR(Bool,gl_noskyboxes, false, 0) @@ -136,7 +133,7 @@ void GLWall::SkyPlane(sector_t *sector, int plane, bool allowreflect) case PORTS_PORTAL: case PORTS_LINKEDPORTAL: { - FPortal *glport = sector->GetGLPortal(plane); + auto glport = sector->GetPortalGroup(plane); if (glport != NULL) { if (sector->PortalBlocksView(plane)) return; @@ -299,8 +296,8 @@ void GLWall::SkyTop(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,vertex int type = fs->GetPortalType(sector_t::ceiling); if (type == PORTS_STACKEDSECTORTHING || type == PORTS_PORTAL || type == PORTS_LINKEDPORTAL) { - FPortal *pfront = fs->GetGLPortal(sector_t::ceiling); - FPortal *pback = bs->GetGLPortal(sector_t::ceiling); + auto pfront = fs->GetPortalGroup(sector_t::ceiling); + auto pback = bs->GetPortalGroup(sector_t::ceiling); if (pfront == NULL || fs->PortalBlocksView(sector_t::ceiling)) return; if (pfront == pback && !bs->PortalBlocksView(sector_t::ceiling)) return; } @@ -378,8 +375,8 @@ void GLWall::SkyBottom(seg_t * seg,sector_t * fs,sector_t * bs,vertex_t * v1,ver int type = fs->GetPortalType(sector_t::floor); if (type == PORTS_STACKEDSECTORTHING || type == PORTS_PORTAL || type == PORTS_LINKEDPORTAL) { - FPortal *pfront = fs->GetGLPortal(sector_t::floor); - FPortal *pback = bs->GetGLPortal(sector_t::floor); + auto pfront = fs->GetPortalGroup(sector_t::floor); + auto pback = bs->GetPortalGroup(sector_t::floor); if (pfront == NULL || fs->PortalBlocksView(sector_t::floor)) return; if (pfront == pback && !bs->PortalBlocksView(sector_t::floor)) return; } diff --git a/src/gl/scene/gl_skydome.cpp b/src/gl/scene/gl_skydome.cpp index 9b0073c12b..e40c59468a 100644 --- a/src/gl/scene/gl_skydome.cpp +++ b/src/gl/scene/gl_skydome.cpp @@ -64,7 +64,6 @@ #include "textures/skyboxtexture.h" #include "gl/system/gl_interface.h" -#include "gl/data/gl_data.h" #include "gl/data/gl_vertexbuffer.h" #include "gl/renderer/gl_lightdata.h" #include "gl/renderer/gl_renderstate.h" @@ -72,7 +71,6 @@ #include "gl/scene/gl_scenedrawer.h" #include "gl/scene/gl_portal.h" #include "gl/shaders/gl_shader.h" -#include "gl/textures/gl_texture.h" #include "gl/textures/gl_material.h" @@ -436,9 +434,9 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool gl_RenderState.mModelMatrix.loadIdentity(); if (!sky2) - gl_RenderState.mModelMatrix.rotate(-180.0f+x_offset, glset.skyrotatevector.X, glset.skyrotatevector.Z, glset.skyrotatevector.Y); + gl_RenderState.mModelMatrix.rotate(-180.0f+x_offset, level.info->skyrotatevector.X, level.info->skyrotatevector.Z, level.info->skyrotatevector.Y); else - gl_RenderState.mModelMatrix.rotate(-180.0f+x_offset, glset.skyrotatevector2.X, glset.skyrotatevector2.Z, glset.skyrotatevector2.Y); + gl_RenderState.mModelMatrix.rotate(-180.0f+x_offset, level.info->skyrotatevector2.X, level.info->skyrotatevector2.Z, level.info->skyrotatevector2.Y); if (sb->faces[5]) { @@ -502,10 +500,10 @@ void GLSkyPortal::DrawContents() bool drawBoth = false; // We have no use for Doom lighting special handling here, so disable it for this function. - int oldlightmode = glset.lightmode; - if (glset.lightmode == 8) + int oldlightmode = ::level.lightmode; + if (::level.lightmode == 8) { - glset.lightmode = 2; + ::level.lightmode = 2; gl_RenderState.SetSoftLightLevel(-1); } @@ -520,7 +518,7 @@ void GLSkyPortal::DrawContents() drawer->SetupView(0, 0, 0, r_viewpoint.Angles.Yaw, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1)); gl_RenderState.SetVertexBuffer(GLRenderer->mSkyVBO); - if (origin->texture[0] && origin->texture[0]->tex->gl_info.bSkybox) + if (origin->texture[0] && origin->texture[0]->tex->bSkybox) { RenderBox(origin->skytexno1, origin->texture[0], origin->x_offset[0], origin->sky2); } @@ -558,7 +556,7 @@ void GLSkyPortal::DrawContents() gl_RenderState.SetVertexBuffer(GLRenderer->mVBO); gl_MatrixStack.Pop(gl_RenderState.mViewMatrix); gl_RenderState.ApplyMatrices(); - glset.lightmode = oldlightmode; + ::level.lightmode = oldlightmode; gl_RenderState.SetDepthClamp(oldClamp); } diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index c7efe1eb8d..939a109f7c 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -30,7 +30,6 @@ #include "p_effect.h" #include "g_level.h" #include "doomstat.h" -#include "gl/gl_functions.h" #include "r_defs.h" #include "r_sky.h" #include "r_utility.h" @@ -48,8 +47,6 @@ #include "gl/renderer/gl_lightdata.h" #include "gl/renderer/gl_renderstate.h" #include "gl/renderer/gl_renderer.h" -#include "gl/data/gl_data.h" -#include "gl/dynlights/gl_glow.h" #include "gl/scene/gl_drawinfo.h" #include "gl/scene/gl_scenedrawer.h" #include "gl/scene/gl_portal.h" @@ -82,7 +79,6 @@ EXTERN_CVAR (Bool, r_debug_disable_vis_filter) extern TArray sprites; extern TArray SpriteFrames; extern uint32_t r_renderercaps; -extern int modellightindex; enum HWRenderStyle { @@ -301,7 +297,7 @@ void GLSprite::Draw(int pass) gl_SetRenderStyle(RenderStyle, false, // The rest of the needed checks are done inside gl_SetRenderStyle trans > 1.f - FLT_EPSILON && gl_usecolorblending && mDrawer->FixedColormap == CM_DEFAULT && actor && - fullbright && gltexture && !gltexture->GetTransparent()); + fullbright && gltexture && !gltexture->tex->GetTranslucency()); if (hw_styleflags == STYLEHW_NoAlphaTest) { @@ -426,7 +422,7 @@ void GLSprite::Draw(int pass) secplane_t *lowplane = i == (*lightlist).Size() - 1 ? &bottomp : &(*lightlist)[i + 1].plane; int thislight = (*lightlist)[i].caster != NULL ? gl_ClampLight(*(*lightlist)[i].p_lightlevel) : lightlevel; - int thisll = actor == nullptr? thislight : (uint8_t)gl_CheckSpriteGlow(actor->Sector, thislight, actor->InterpolatedPosition(r_viewpoint.TicFrac)); + int thisll = actor == nullptr? thislight : (uint8_t)actor->Sector->CheckSpriteGlow(thislight, actor->InterpolatedPosition(r_viewpoint.TicFrac)); FColormap thiscm; thiscm.CopyFog(Colormap); @@ -477,7 +473,7 @@ void GLSprite::Draw(int pass) } else { - gl_RenderModel(this); + gl_RenderModel(this, dynlightindex); } } @@ -601,6 +597,7 @@ void GLSprite::PerformSpriteClipAdjustment(AActor *thing, const DVector2 &thingp for (unsigned int i = 0; i < x.ffloors.Size(); i++) { F3DFloor * ff = x.ffloors[i]; + if (ff->flags & FF_THISINSIDE) continue; // only relevant for software rendering. float floorh = ff->top.plane->ZatPoint(thingpos); float ceilingh = ff->bottom.plane->ZatPoint(thingpos); if (floorh == thing->floorz) @@ -722,17 +719,17 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal) } // If this thing is in a map section that's not in view it can't possibly be visible - if (!thruportal && !(currentmapsection[thing->subsector->mapsection >> 3] & (1 << (thing->subsector->mapsection & 7)))) return; + if (!thruportal && !mDrawer->CurrentMapSections[thing->subsector->mapsection]) return; // [RH] Interpolate the sprite's position to make it look smooth DVector3 thingpos = thing->InterpolatedPosition(r_viewpoint.TicFrac); - if (thruportal == 1) thingpos += Displacements.getOffset(thing->Sector->PortalGroup, sector->PortalGroup); + if (thruportal == 1) thingpos += level.Displacements.getOffset(thing->Sector->PortalGroup, sector->PortalGroup); // Some added checks if the camera actor is not supposed to be seen. It can happen that some portal setup has this actor in view in which case it may not be skipped here if (thing == camera && !r_viewpoint.showviewer) { DVector3 thingorigin = thing->Pos(); - if (thruportal == 1) thingorigin += Displacements.getOffset(thing->Sector->PortalGroup, sector->PortalGroup); + if (thruportal == 1) thingorigin += level.Displacements.getOffset(thing->Sector->PortalGroup, sector->PortalGroup); if (fabs(thingorigin.X - r_viewpoint.ActorPos.X) < 2 && fabs(thingorigin.Y - r_viewpoint.ActorPos.Y) < 2) return; } // Thing is invisible if close to the camera. @@ -941,14 +938,14 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal) // allow disabling of the fullbright flag by a brightmap definition // (e.g. to do the gun flashes of Doom's zombies correctly. fullbright = (thing->flags5 & MF5_BRIGHT) || - ((thing->renderflags & RF_FULLBRIGHT) && (!gltexture || !gltexture->tex->gl_info.bDisableFullbright)); + ((thing->renderflags & RF_FULLBRIGHT) && (!gltexture || !gltexture->tex->bDisableFullbright)); lightlevel = fullbright ? 255 : gl_ClampLight(rendersector->GetTexture(sector_t::ceiling) == skyflatnum ? rendersector->GetCeilingLight() : rendersector->GetFloorLight()); foglevel = (uint8_t)clamp(rendersector->lightlevel, 0, 255); - lightlevel = gl_CheckSpriteGlow(rendersector, lightlevel, thingpos); + lightlevel = rendersector->CheckSpriteGlow(lightlevel, thingpos); ThingColor = (thing->RenderStyle.Flags & STYLEF_ColorIsFixed) ? thing->fillcolor : 0xffffff; ThingColor.a = 255; @@ -1063,7 +1060,7 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal) RenderStyle.DestAlpha = STYLEALPHA_InvSrc; } } - if ((gltexture && gltexture->GetTransparent()) || (RenderStyle.Flags & STYLEF_RedIsAlpha)) + if ((gltexture && gltexture->tex->GetTranslucency()) || (RenderStyle.Flags & STYLEF_RedIsAlpha)) { if (hw_styleflags == STYLEHW_Solid) { @@ -1284,7 +1281,7 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s // //========================================================================== -void GLSceneDrawer::RenderActorsInPortal(FGLLinePortal *glport) +void GLSceneDrawer::RenderActorsInPortal(FLinePortalSpan *glport) { TMap processcheck; if (glport->validcount == validcount) return; // only process once per frame diff --git a/src/gl/scene/gl_spritelight.cpp b/src/gl/scene/gl_spritelight.cpp index 72f69cb7de..d25339b946 100644 --- a/src/gl/scene/gl_spritelight.cpp +++ b/src/gl/scene/gl_spritelight.cpp @@ -30,7 +30,6 @@ #include "p_local.h" #include "p_effect.h" #include "vectors.h" -#include "gl/gl_functions.h" #include "g_level.h" #include "g_levellocals.h" #include "actorinlines.h" @@ -38,7 +37,6 @@ #include "gl/system/gl_cvars.h" #include "gl/renderer/gl_renderer.h" #include "gl/renderer/gl_lightdata.h" -#include "gl/data/gl_data.h" #include "gl/dynlights/gl_dynlight.h" #include "gl/scene/gl_drawinfo.h" #include "gl/scene/gl_portal.h" @@ -46,8 +44,6 @@ #include "gl/textures/gl_material.h" #include "gl/dynlights/gl_lightbuffer.h" -FDynLightData modellightdata; -int modellightindex = -1; template T smoothstep(const T edge0, const T edge1, const T x) @@ -81,13 +77,13 @@ void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t * // This is a performance critical section of code where we cannot afford to let the compiler decide whether to inline the function or not. // This will do the calculations explicitly rather than calling one of AActor's utility functions. - if (Displacements.size > 0) + if (level.Displacements.size > 0) { int fromgroup = light->Sector->PortalGroup; int togroup = subsec->sector->PortalGroup; if (fromgroup == togroup || fromgroup == 0 || togroup == 0) goto direct; - DVector2 offset = Displacements.getOffset(fromgroup, togroup); + DVector2 offset = level.Displacements.getOffset(fromgroup, togroup); L = FVector3(x - light->X() - offset.X, y - light->Y() - offset.Y, z - light->Z()); } else @@ -140,7 +136,6 @@ void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t * node = node->nextLight; } gl_RenderState.SetDynLight(out[0], out[1], out[2]); - modellightindex = -1; } void gl_SetDynSpriteLight(AActor *thing, particle_t *particle) @@ -200,11 +195,12 @@ void BSPWalkCircle(float x, float y, float radiusSquared, const Callback &callba int gl_SetDynModelLight(AActor *self, int dynlightindex) { + static FDynLightData modellightdata; // If this ever gets multithreaded, this variable must either be made non-static or thread_local. + // For deferred light mode this function gets called twice. First time for list upload, and second for draw. if (gl.lightmethod == LM_DEFERRED && dynlightindex != -1) { gl_RenderState.SetDynLight(0, 0, 0); - modellightindex = dynlightindex; return dynlightindex; } @@ -262,7 +258,6 @@ int gl_SetDynModelLight(AActor *self, int dynlightindex) if (gl.lightmethod != LM_DEFERRED) { gl_RenderState.SetDynLight(0, 0, 0); - modellightindex = dynlightindex; } return dynlightindex; } diff --git a/src/gl/scene/gl_swscene.cpp b/src/gl/scene/gl_swscene.cpp new file mode 100644 index 0000000000..2015ed4d2b --- /dev/null +++ b/src/gl/scene/gl_swscene.cpp @@ -0,0 +1,128 @@ +// +//--------------------------------------------------------------------------- +// +// Copyright(C) 2004-2018 Christoph Oelckers +// All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see http://www.gnu.org/licenses/ +// +//-------------------------------------------------------------------------- +// +/* +** gl_swscene.cpp +** common overlay code for software and hardware renderer +** +*/ + +#include "gl/system/gl_system.h" +#include "gl/system/gl_interface.h" +#include "gl/system/gl_debug.h" +#include "gl/data/gl_vertexbuffer.h" +#include "gl/shaders/gl_shader.h" +#include "gl/renderer/gl_renderstate.h" +#include "v_palette.h" +#include "v_video.h" +#include "gl_swscene.h" +#include "w_wad.h" +#include "d_player.h" +#include "textures/bitmap.h" +#include "swrenderer/scene/r_light.h" + +// [RH] Base blending values (for e.g. underwater) +int BaseBlendR, BaseBlendG, BaseBlendB; +float BaseBlendA; + + + +class FSWPaletteTexture : public FTexture +{ +public: + FSWPaletteTexture() + { + Width = 256; + Height = 1; + UseType = ETextureType::MiscPatch; + } + + int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) + { + PalEntry *pe = (PalEntry*)bmp->GetPixels(); + for (int i = 0; i < 256; i++) + { + pe[i] = GPalette.BaseColors[i].d | 0xff000000; + } + return 0; + } +}; + +class FSWSceneTexture : public FTexture +{ +public: + FHardwareTexture *hwtex; + + FSWSceneTexture(int w, int h, int bits) + { + Width = w; + Height = h; + WidthBits = bits; + UseType = ETextureType::SWCanvas; + + hwtex = new FHardwareTexture(true); + new FGLTexture(this, hwtex); + } + + // This is just a wrapper around the hardware texture and should never call the bitmap getters - if it does, something is wrong. +}; + +//========================================================================== +// +// SWSceneDrawer :: CreateResources +// +//========================================================================== + +SWSceneDrawer::SWSceneDrawer() +{ + PaletteTexture = new FSWPaletteTexture; +} + +SWSceneDrawer::~SWSceneDrawer() +{ + if (PaletteTexture != nullptr) delete PaletteTexture; + if (FBTexture != nullptr) delete FBTexture; +} + +void SWSceneDrawer::RenderView(player_t *player) +{ + DCanvas buffer(screen->GetWidth(), screen->GetHeight(), V_IsTrueColor()); + if (FBTexture == nullptr || FBTexture->hwtex == nullptr || FBTexture->GetWidth() != screen->GetWidth() || FBTexture->GetHeight() != screen->GetHeight() || (V_IsTrueColor() ? 1:0) != FBTexture->WidthBits) + { + // This manually constructs its own material here. + if (FBTexture != nullptr) delete FBTexture; + FBTexture = new FSWSceneTexture(screen->GetWidth(), screen->GetHeight(), V_IsTrueColor()); + FBTexture->hwtex->AllocateBuffer(screen->GetWidth(), screen->GetHeight(), V_IsTrueColor() ? 4 : 1); + auto mat = FMaterial::ValidateTexture(FBTexture, false); + mat->AddTextureLayer(PaletteTexture); + } + auto buf = FBTexture->hwtex->MapBuffer(); + if (!buf) I_FatalError("Unable to map buffer for software rendering"); + buffer.SetBuffer(screen->GetWidth(), screen->GetHeight(), screen->GetWidth(), buf); + SWRenderer->RenderView(player, &buffer); + FBTexture->hwtex->CreateTexture(nullptr, screen->GetWidth(), screen->GetHeight(), 0, false, 0, "swbuffer"); + + auto map = swrenderer::CameraLight::Instance()->ShaderColormap(); + screen->Begin2D(false); + screen->DrawTexture(FBTexture, 0, 0, DTA_SpecialColormap, map, TAG_DONE); + SWRenderer->DrawRemainingPlayerSprites(); + GLRenderer->DrawBlend(r_viewpoint.sector, !!map, V_IsTrueColor(), true); +} diff --git a/src/gl/scene/gl_swscene.h b/src/gl/scene/gl_swscene.h new file mode 100644 index 0000000000..67be5974fe --- /dev/null +++ b/src/gl/scene/gl_swscene.h @@ -0,0 +1,33 @@ +#pragma once +#pragma once + +#include "r_defs.h" +#include "m_fixed.h" +#include "gl_clipper.h" +#include "gl_portal.h" +#include "gl/renderer/gl_lightdata.h" +#include "gl/renderer/gl_renderer.h" +#include "r_utility.h" +#include "c_cvars.h" + +class FSWSceneTexture; + +class SWSceneDrawer +{ + FTexture *PaletteTexture = nullptr; + FSWSceneTexture *FBTexture = nullptr; + bool FBIsTruecolor = false; + + + void BlendView (player_t *CPlayer, float blend[4]); + bool CreateResources(); + void BindFBBuffer(); + + +public: + SWSceneDrawer(); + ~SWSceneDrawer(); + + void RenderView(player_t *player); +}; + diff --git a/src/gl/scene/gl_vertex.cpp b/src/gl/scene/gl_vertex.cpp index d693227d50..ea1fe007cc 100644 --- a/src/gl/scene/gl_vertex.cpp +++ b/src/gl/scene/gl_vertex.cpp @@ -23,18 +23,14 @@ #include "gl/system/gl_system.h" -#include "gl/gl_functions.h" #include "gl/renderer/gl_renderer.h" #include "gl/renderer/gl_lightdata.h" -#include "gl/data/gl_data.h" #include "gl/data/gl_vertexbuffer.h" -#include "gl/dynlights/gl_glow.h" #include "gl/scene/gl_drawinfo.h" #include "gl/scene/gl_portal.h" #include "gl/shaders/gl_shader.h" #include "gl/textures/gl_material.h" -#include "gl/utility/gl_templates.h" EXTERN_CVAR(Bool, gl_seamless) diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index 5d041a55ff..7151b18095 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -20,9 +20,9 @@ class FMaterial; struct GLDrawList; struct GLSkyInfo; struct FTexCoordInfo; -struct FPortal; +struct FSectorPortalGroup; struct FFlatVertex; -struct FGLLinePortal; +struct FLinePortalSpan; class GLSceneDrawer; enum @@ -171,9 +171,9 @@ public: FSectorPortal *secportal; // sector portal (formerly skybox) GLSkyInfo * sky; // for normal sky GLHorizonInfo * horizon; // for horizon information - FPortal * portal; // stacked sector portals + FSectorPortalGroup * portal; // stacked sector portals secplane_t * planemirror; // for plane mirrors - FGLLinePortal *lineportal; // line-to-line portals + FLinePortalSpan *lineportal; // line-to-line portals }; diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index c78c23eff1..b7eb403930 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -37,15 +37,12 @@ #include "gl/system/gl_cvars.h" #include "gl/renderer/gl_lightdata.h" -#include "gl/data/gl_data.h" #include "gl/dynlights/gl_dynlight.h" -#include "gl/dynlights/gl_glow.h" #include "gl/scene/gl_drawinfo.h" #include "gl/scene/gl_portal.h" #include "gl/scene/gl_scenedrawer.h" #include "gl/textures/gl_material.h" #include "gl/utility/gl_clock.h" -#include "gl/utility/gl_templates.h" #include "gl/shaders/gl_shader.h" @@ -72,7 +69,7 @@ void GLWall::PutWall(bool translucent) }; - if (gltexture && gltexture->GetTransparent() && passflag[type] == 2) + if (gltexture && gltexture->tex->GetTranslucency() && passflag[type] == 2) { translucent = true; } @@ -178,9 +175,9 @@ void GLWall::PutPortal(int ptype) if (!portal) { line_t *otherside = lineportal->lines[0]->mDestination; - if (otherside != NULL && otherside->portalindex < linePortals.Size()) + if (otherside != NULL && otherside->portalindex < level.linePortals.Size()) { - mDrawer->RenderActorsInPortal(linePortalToGL[otherside->portalindex]); + mDrawer->RenderActorsInPortal(otherside->getPortal()->mGroup); } portal = new GLLineToLinePortal(lineportal); } @@ -995,7 +992,7 @@ void GLWall::DoMidTexture(seg_t * seg, bool drawfogboundary, case 0: RenderStyle=STYLE_Translucent; alpha = seg->linedef->alpha; - translucent =alpha < 1. || (gltexture && gltexture->GetTransparent()); + translucent =alpha < 1. || (gltexture && gltexture->tex->GetTranslucency()); break; case ML_ADDTRANS: @@ -1221,6 +1218,7 @@ void GLWall::InverseFloors(seg_t * seg, sector_t * frontsector, for (unsigned int i = 0; i < frontffloors.Size(); i++) { F3DFloor * rover = frontffloors[i]; + if (rover->flags & FF_THISINSIDE) continue; // only relevant for software rendering. if (!(rover->flags&FF_EXISTS)) continue; if (!(rover->flags&FF_RENDERSIDES)) continue; if (!(rover->flags&(FF_INVERTSIDES | FF_ALLSIDES))) continue; @@ -1273,6 +1271,7 @@ void GLWall::ClipFFloors(seg_t * seg, F3DFloor * ffloor, sector_t * frontsector, for (unsigned int i = 0; i < frontffloors.Size(); i++) { F3DFloor * rover = frontffloors[i]; + if (rover->flags & FF_THISINSIDE) continue; // only relevant for software rendering. if (!(rover->flags&FF_EXISTS)) continue; if (!(rover->flags&FF_RENDERSIDES)) continue; if ((rover->flags&(FF_SWIMMABLE | FF_TRANSLUCENT)) != flags) continue; @@ -1372,6 +1371,7 @@ void GLWall::DoFFloorBlocks(seg_t * seg, sector_t * frontsector, sector_t * back for (unsigned int i = 0; i < backffloors.Size(); i++) { F3DFloor * rover = backffloors[i]; + if (rover->flags & FF_THISINSIDE) continue; // only relevant for software rendering. if (!(rover->flags&FF_EXISTS)) continue; if (!(rover->flags&FF_RENDERSIDES) || (rover->flags&FF_INVERTSIDES)) continue; @@ -1483,8 +1483,8 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) glseg.fracright = 1; if (gl_seamless) { - if (v1->dirty) gl_RecalcVertexHeights(v1); - if (v2->dirty) gl_RecalcVertexHeights(v2); + if (v1->dirty) v1->RecalcVertexHeights(); + if (v2->dirty) v2->RecalcVertexHeights(); } } else // polyobjects must be rendered per seg. @@ -1538,7 +1538,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) gltexture = NULL; - if (gl_GetWallGlow(frontsector, topglowcolor, bottomglowcolor)) flags |= GLWF_GLOW; + if (frontsector->GetWallGlow(topglowcolor, bottomglowcolor)) flags |= GLWF_GLOW; topplane = frontsector->ceilingplane; bottomplane = frontsector->floorplane; @@ -1563,7 +1563,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) if (seg->linedef->isVisualPortal()) { - lineportal = linePortalToGL[seg->linedef->portalindex]; + lineportal = seg->linedef->getPortal()->mGroup; ztop[0] = zceil[0]; ztop[1] = zceil[1]; zbottom[0] = zfloor[0]; @@ -1670,7 +1670,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector) if (isportal) { - lineportal = linePortalToGL[seg->linedef->portalindex]; + lineportal = seg->linedef->getPortal()->mGroup; ztop[0] = bch1; ztop[1] = bch2; zbottom[0] = bfh1; @@ -1774,7 +1774,7 @@ void GLWall::ProcessLowerMiniseg(seg_t *seg, sector_t * frontsector, sector_t * RenderStyle = STYLE_Normal; Colormap = frontsector->Colormap; - if (gl_GetWallGlow(frontsector, topglowcolor, bottomglowcolor)) flags |= GLWF_GLOW; + if (frontsector->GetWallGlow(topglowcolor, bottomglowcolor)) flags |= GLWF_GLOW; topplane = frontsector->ceilingplane; bottomplane = frontsector->floorplane; dynlightindex = -1; diff --git a/src/gl/scene/gl_walls_draw.cpp b/src/gl/scene/gl_walls_draw.cpp index beeb103a0f..0fb2e38bf7 100644 --- a/src/gl/scene/gl_walls_draw.cpp +++ b/src/gl/scene/gl_walls_draw.cpp @@ -27,17 +27,14 @@ #include "g_levellocals.h" #include "actor.h" #include "actorinlines.h" -#include "gl/gl_functions.h" #include "gl/system/gl_interface.h" #include "gl/system/gl_cvars.h" #include "gl/renderer/gl_lightdata.h" #include "gl/renderer/gl_renderstate.h" #include "gl/renderer/gl_renderer.h" -#include "gl/data/gl_data.h" #include "gl/data/gl_vertexbuffer.h" #include "gl/dynlights/gl_dynlight.h" -#include "gl/dynlights/gl_glow.h" #include "gl/dynlights/gl_lightbuffer.h" #include "gl/scene/gl_drawinfo.h" #include "gl/scene/gl_portal.h" @@ -45,7 +42,6 @@ #include "gl/shaders/gl_shader.h" #include "gl/textures/gl_material.h" #include "gl/utility/gl_clock.h" -#include "gl/utility/gl_templates.h" #include "gl/renderer/gl_quaddrawer.h" EXTERN_CVAR(Bool, gl_seamless) @@ -60,7 +56,7 @@ FDynLightData lightdata; void GLWall::SetupLights() { - if (RenderStyle == STYLE_Add && !glset.lightadditivesurfaces) return; // no lights on additively blended surfaces. + if (RenderStyle == STYLE_Add && !level.lightadditivesurfaces) return; // no lights on additively blended surfaces. // check for wall types which cannot have dynamic lights on them (portal types never get here so they don't need to be checked.) switch (type) @@ -75,14 +71,10 @@ void GLWall::SetupLights() Plane p; lightdata.Clear(); - p.Set(&glseg); - /* - if (!p.ValidNormal()) - { - return; - } - */ + auto normal = glseg.Normal(); + p.Set(normal, -normal.X * glseg.x1 - normal.Y * glseg.y1); + FLightNode *node; if (seg->sidedef == NULL) { @@ -403,7 +395,7 @@ void GLWall::RenderTranslucentWall() { SetupLights(); } - if (!gltexture->GetTransparent()) gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold); + if (!gltexture->tex->GetTranslucency()) gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold); else gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); if (RenderStyle == STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA,GL_ONE); RenderTextured(RWF_TEXTURED | RWF_NOSPLIT); diff --git a/src/gl/scene/gl_weapon.cpp b/src/gl/scene/gl_weapon.cpp index 421517a26d..3915c25e6a 100644 --- a/src/gl/scene/gl_weapon.cpp +++ b/src/gl/scene/gl_weapon.cpp @@ -39,9 +39,7 @@ #include "gl/renderer/gl_renderer.h" #include "gl/renderer/gl_lightdata.h" #include "gl/renderer/gl_renderstate.h" -#include "gl/data/gl_data.h" #include "gl/data/gl_vertexbuffer.h" -#include "gl/dynlights/gl_glow.h" #include "gl/scene/gl_drawinfo.h" #include "gl/scene/gl_scenedrawer.h" #include "gl/models/gl_models.h" @@ -75,7 +73,7 @@ void GLSceneDrawer::DrawPSprite (player_t * player,DPSprite *psp, float sx, floa // [BB] In the HUD model step we just render the model and break out. if ( hudModelStep ) { - gl_RenderHUDModel(psp, sx, sy); + gl_RenderHUDModel(psp, sx, sy, weapondynlightindex[psp]); return; } @@ -146,7 +144,7 @@ void GLSceneDrawer::DrawPSprite (player_t * player,DPSprite *psp, float sx, floa } - if (tex->GetTransparent() || OverrideShader != -1) + if (tex->tex->GetTranslucency() || OverrideShader != -1) { gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f); } @@ -176,7 +174,7 @@ static bool isBright(DPSprite *psp) { FMaterial * tex = FMaterial::ValidateTexture(lump, false, false); if (tex) - disablefullbright = tex->tex->gl_info.bDisableFullbright; + disablefullbright = tex->tex->bDisableFullbright; } return psp->GetState()->GetFullbright() && !disablefullbright; } @@ -315,7 +313,7 @@ void GLSceneDrawer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) lightlevel = gl_CalcLightLevel(lightlevel, getExtraLight(), true); - if (glset.lightmode == 8 || lightlevel < 92) + if (level.lightmode == 8 || lightlevel < 92) { // Korshun: the way based on max possible light level for sector like in software renderer. float min_L = 36.0 / 31.0 - ((lightlevel / 255.0) * (63.0 / 31.0)); // Lightlevel in range 0-63 @@ -330,12 +328,12 @@ void GLSceneDrawer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) { lightlevel = (2 * lightlevel + 255) / 3; } - lightlevel = gl_CheckSpriteGlow(viewsector, lightlevel, playermo->Pos()); + lightlevel = viewsector->CheckSpriteGlow(lightlevel, playermo->Pos()); } // Korshun: fullbright fog in opengl, render weapon sprites fullbright (but don't cancel out the light color!) - if (glset.brightfog && ((level.flags&LEVEL_HASFADETABLE) || cm.FadeColor != 0)) + if (level.brightfog && ((level.flags&LEVEL_HASFADETABLE) || cm.FadeColor != 0)) { lightlevel = 255; } @@ -344,8 +342,8 @@ void GLSceneDrawer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) // hack alert! Rather than changing everything in the underlying lighting code let's just temporarily change // light mode here to draw the weapon sprite. - int oldlightmode = glset.lightmode; - if (glset.lightmode == 8) glset.lightmode = 2; + int oldlightmode = level.lightmode; + if (level.lightmode == 8) level.lightmode = 2; for(DPSprite *psp = player->psprites; psp != nullptr && psp->GetID() < PSP_TARGETCENTER; psp = psp->GetNext()) { @@ -491,7 +489,7 @@ void GLSceneDrawer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) gl_RenderState.SetObjectColor(0xffffffff); gl_RenderState.SetDynLight(0, 0, 0); gl_RenderState.EnableBrightmap(false); - glset.lightmode = oldlightmode; + level.lightmode = oldlightmode; } //========================================================================== diff --git a/src/gl/shaders/gl_ambientshader.cpp b/src/gl/shaders/gl_ambientshader.cpp index 3d0af2dabd..e433ebd002 100644 --- a/src/gl/shaders/gl_ambientshader.cpp +++ b/src/gl/shaders/gl_ambientshader.cpp @@ -23,7 +23,6 @@ #include "gl/system/gl_system.h" #include "m_swap.h" #include "v_video.h" -#include "gl/gl_functions.h" #include "vectors.h" #include "gl/system/gl_interface.h" #include "gl/system/gl_framebuffer.h" diff --git a/src/gl/shaders/gl_bloomshader.cpp b/src/gl/shaders/gl_bloomshader.cpp index bc7b80b01c..9dbc4ff6ca 100644 --- a/src/gl/shaders/gl_bloomshader.cpp +++ b/src/gl/shaders/gl_bloomshader.cpp @@ -28,7 +28,6 @@ #include "gl/system/gl_system.h" #include "m_swap.h" #include "v_video.h" -#include "gl/gl_functions.h" #include "vectors.h" #include "gl/system/gl_interface.h" #include "gl/system/gl_framebuffer.h" diff --git a/src/gl/shaders/gl_blurshader.cpp b/src/gl/shaders/gl_blurshader.cpp index 56b637f6de..71cf6ffa3d 100644 --- a/src/gl/shaders/gl_blurshader.cpp +++ b/src/gl/shaders/gl_blurshader.cpp @@ -28,7 +28,6 @@ #include "gl/system/gl_system.h" #include "m_swap.h" #include "v_video.h" -#include "gl/gl_functions.h" #include "vectors.h" #include "gl/system/gl_interface.h" #include "gl/system/gl_framebuffer.h" diff --git a/src/gl/shaders/gl_colormapshader.cpp b/src/gl/shaders/gl_colormapshader.cpp index e29b270136..2036599e94 100644 --- a/src/gl/shaders/gl_colormapshader.cpp +++ b/src/gl/shaders/gl_colormapshader.cpp @@ -28,7 +28,6 @@ #include "gl/system/gl_system.h" #include "m_swap.h" #include "v_video.h" -#include "gl/gl_functions.h" #include "vectors.h" #include "gl/system/gl_interface.h" #include "gl/system/gl_framebuffer.h" diff --git a/src/gl/shaders/gl_lensshader.cpp b/src/gl/shaders/gl_lensshader.cpp index c5ec679f3a..a92b2dece3 100644 --- a/src/gl/shaders/gl_lensshader.cpp +++ b/src/gl/shaders/gl_lensshader.cpp @@ -28,7 +28,6 @@ #include "gl/system/gl_system.h" #include "m_swap.h" #include "v_video.h" -#include "gl/gl_functions.h" #include "vectors.h" #include "gl/system/gl_interface.h" #include "gl/system/gl_framebuffer.h" diff --git a/src/gl/shaders/gl_postprocessshader.cpp b/src/gl/shaders/gl_postprocessshader.cpp index 2d96da90cc..1eae66ec2f 100644 --- a/src/gl/shaders/gl_postprocessshader.cpp +++ b/src/gl/shaders/gl_postprocessshader.cpp @@ -23,7 +23,6 @@ #include "gl/system/gl_system.h" #include "m_swap.h" #include "v_video.h" -#include "gl/gl_functions.h" #include "vectors.h" #include "w_wad.h" #include "gl/system/gl_interface.h" @@ -34,6 +33,7 @@ #include "gl/renderer/gl_postprocessstate.h" #include "gl/renderer/gl_renderbuffers.h" #include "gl/shaders/gl_postprocessshader.h" +#include "gl/shaders/gl_postprocessshaderinstance.h" #include "textures/textures.h" #include "textures/bitmap.h" diff --git a/src/gl/shaders/gl_postprocessshader.h b/src/gl/shaders/gl_postprocessshader.h index 23b8c1864e..523b8d8d02 100644 --- a/src/gl/shaders/gl_postprocessshader.h +++ b/src/gl/shaders/gl_postprocessshader.h @@ -1,10 +1,5 @@ #pragma once -#include "gl_shaderprogram.h" -#include - -class PostProcessShaderInstance; - enum class PostProcessUniformType { Undefined, @@ -35,38 +30,3 @@ struct PostProcessShader extern TArray PostProcessShaders; -class PostProcessShaderInstance -{ -public: - PostProcessShaderInstance(PostProcessShader *desc) : Desc(desc) { } - ~PostProcessShaderInstance(); - - void Run(); - - PostProcessShader *Desc; - -private: - bool IsShaderSupported(); - void CompileShader(); - void UpdateUniforms(); - void BindTextures(); - - FShaderProgram mProgram; - FBufferedUniformSampler mInputTexture; - std::map mTextureHandles; -}; - -class FCustomPostProcessShaders -{ -public: - FCustomPostProcessShaders(); - ~FCustomPostProcessShaders(); - - void Run(FString target); - -private: - std::vector> mShaders; - - FCustomPostProcessShaders(const FCustomPostProcessShaders &) = delete; - FCustomPostProcessShaders &operator=(const FCustomPostProcessShaders &) = delete; -}; diff --git a/src/gl/shaders/gl_postprocessshaderinstance.h b/src/gl/shaders/gl_postprocessshaderinstance.h new file mode 100644 index 0000000000..2b3e8e5d9b --- /dev/null +++ b/src/gl/shaders/gl_postprocessshaderinstance.h @@ -0,0 +1,42 @@ +#pragma once + +#include "gl_shaderprogram.h" +#include + +struct PostProcessShader; + +class PostProcessShaderInstance +{ +public: + PostProcessShaderInstance(PostProcessShader *desc) : Desc(desc) { } + ~PostProcessShaderInstance(); + + void Run(); + + PostProcessShader *Desc; + +private: + bool IsShaderSupported(); + void CompileShader(); + void UpdateUniforms(); + void BindTextures(); + + FShaderProgram mProgram; + FBufferedUniformSampler mInputTexture; + std::map mTextureHandles; +}; + +class FCustomPostProcessShaders +{ +public: + FCustomPostProcessShaders(); + ~FCustomPostProcessShaders(); + + void Run(FString target); + +private: + std::vector> mShaders; + + FCustomPostProcessShaders(const FCustomPostProcessShaders &) = delete; + FCustomPostProcessShaders &operator=(const FCustomPostProcessShaders &) = delete; +}; diff --git a/src/gl/shaders/gl_present3dRowshader.cpp b/src/gl/shaders/gl_present3dRowshader.cpp index 94dd7dc796..0b689f5e81 100644 --- a/src/gl/shaders/gl_present3dRowshader.cpp +++ b/src/gl/shaders/gl_present3dRowshader.cpp @@ -30,7 +30,6 @@ #include "gl/system/gl_system.h" #include "m_swap.h" #include "v_video.h" -#include "gl/gl_functions.h" #include "vectors.h" #include "gl/system/gl_interface.h" #include "gl/system/gl_framebuffer.h" diff --git a/src/gl/shaders/gl_presentshader.cpp b/src/gl/shaders/gl_presentshader.cpp index 06056f539e..b3044b7bc3 100644 --- a/src/gl/shaders/gl_presentshader.cpp +++ b/src/gl/shaders/gl_presentshader.cpp @@ -28,7 +28,6 @@ #include "gl/system/gl_system.h" #include "m_swap.h" #include "v_video.h" -#include "gl/gl_functions.h" #include "vectors.h" #include "gl/system/gl_interface.h" #include "gl/system/gl_framebuffer.h" diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index f4ebfa26a4..c174215e97 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -41,7 +41,6 @@ #include "gl/system/gl_interface.h" #include "gl/system/gl_debug.h" -#include "gl/data/gl_data.h" #include "r_data/matrix.h" #include "gl/renderer/gl_renderer.h" #include "gl/renderer/gl_renderstate.h" @@ -587,6 +586,7 @@ static const FDefaultShader defaultshaders[]= {"SpecularBrightmap", "shaders/glsl/func_brightmap.fp", "shaders/glsl/material_specular.fp", "#define SPECULAR\n#define NORMALMAP\n"}, {"PBR","shaders/glsl/func_normal.fp", "shaders/glsl/material_pbr.fp", "#define PBR\n#define NORMALMAP\n"}, {"PBRBrightmap","shaders/glsl/func_brightmap.fp", "shaders/glsl/material_pbr.fp", "#define PBR\n#define NORMALMAP\n"}, + {"Paletted", "shaders/glsl/func_paletted.fp", "shaders/glsl/material_nolight.fp", ""}, {"No Texture", "shaders/glsl/func_notexture.fp", "shaders/glsl/material_normal.fp", ""}, {"Basic Fuzz", "shaders/glsl/fuzz_standard.fp", "shaders/glsl/material_normal.fp", ""}, {"Smooth Fuzz", "shaders/glsl/fuzz_smooth.fp", "shaders/glsl/material_normal.fp", ""}, @@ -599,7 +599,7 @@ static const FDefaultShader defaultshaders[]= {nullptr,nullptr,nullptr,nullptr} }; -static TArray usershaders; +TArray usershaders; struct FEffectShader { @@ -617,6 +617,7 @@ static const FEffectShader effectshaders[]= { "spheremap", "shaders/glsl/main.vp", "shaders/glsl/main.fp", "shaders/glsl/func_normal.fp", "shaders/glsl/material_normal.fp", "#define SPHEREMAP\n#define NO_ALPHATEST\n" }, { "burn", "shaders/glsl/main.vp", "shaders/glsl/burn.fp", nullptr, nullptr, "#define SIMPLE\n#define NO_ALPHATEST\n" }, { "stencil", "shaders/glsl/main.vp", "shaders/glsl/stencil.fp", nullptr, nullptr, "#define SIMPLE\n#define NO_ALPHATEST\n" }, + { "swrquad", "shaders/glsl/main.vp", "shaders/glsl/swshader.fp", nullptr, nullptr, "#define SIMPLE\n" }, }; FShaderManager::FShaderManager() @@ -872,157 +873,6 @@ void gl_DestroyUserShaders() // todo } -//========================================================================== -// -// Parses a shader definition -// -//========================================================================== - -void gl_ParseHardwareShader(FScanner &sc, int deflump) -{ - sc.MustGetString(); - if (sc.Compare("postprocess")) - { - sc.MustGetString(); - - PostProcessShader shaderdesc; - shaderdesc.Target = sc.String; - shaderdesc.Target.ToLower(); - - bool validTarget = false; - if (sc.Compare("beforebloom")) validTarget = true; - if (sc.Compare("scene")) validTarget = true; - if (sc.Compare("screen")) validTarget = true; - if (!validTarget) - sc.ScriptError("Invalid target '%s' for postprocess shader",sc.String); - - sc.MustGetToken('{'); - while (!sc.CheckToken('}')) - { - sc.MustGetString(); - if (sc.Compare("shader")) - { - sc.MustGetString(); - shaderdesc.ShaderLumpName = sc.String; - - sc.MustGetNumber(); - shaderdesc.ShaderVersion = sc.Number; - if (sc.Number > 450 || sc.Number < 330) - sc.ScriptError("Shader version must be in range 330 to 450!"); - } - else if (sc.Compare("name")) - { - sc.MustGetString(); - shaderdesc.Name = sc.String; - } - else if (sc.Compare("uniform")) - { - sc.MustGetString(); - FString uniformType = sc.String; - uniformType.ToLower(); - - sc.MustGetString(); - FString uniformName = sc.String; - - PostProcessUniformType parsedType = PostProcessUniformType::Undefined; - - if (uniformType.Compare("int") == 0) - parsedType = PostProcessUniformType::Int; - else if (uniformType.Compare("float") == 0) - parsedType = PostProcessUniformType::Float; - else if (uniformType.Compare("vec2") == 0) - parsedType = PostProcessUniformType::Vec2; - else if (uniformType.Compare("vec3") == 0) - parsedType = PostProcessUniformType::Vec3; - else - sc.ScriptError("Unrecognized uniform type '%s'", sc.String); - - if (parsedType != PostProcessUniformType::Undefined) - shaderdesc.Uniforms[uniformName].Type = parsedType; - } - else if (sc.Compare("texture")) - { - sc.MustGetString(); - FString textureName = sc.String; - - sc.MustGetString(); - FString textureSource = sc.String; - - shaderdesc.Textures[textureName] = textureSource; - } - else if (sc.Compare("enabled")) - { - shaderdesc.Enabled = true; - } - else - { - sc.ScriptError("Unknown keyword '%s'", sc.String); - } - } - - PostProcessShaders.Push(shaderdesc); - } - else - { - ETextureType type = ETextureType::Any; - - if (sc.Compare("texture")) type = ETextureType::Wall; - else if (sc.Compare("flat")) type = ETextureType::Flat; - else if (sc.Compare("sprite")) type = ETextureType::Sprite; - else sc.UnGet(); - - bool disable_fullbright = false; - bool thiswad = false; - bool iwad = false; - int maplump = -1; - FString maplumpname; - float speed = 1.f; - - sc.MustGetString(); - FTextureID no = TexMan.CheckForTexture(sc.String, type); - FTexture *tex = TexMan[no]; - - sc.MustGetToken('{'); - while (!sc.CheckToken('}')) - { - sc.MustGetString(); - if (sc.Compare("shader")) - { - sc.MustGetString(); - maplumpname = sc.String; - } - else if (sc.Compare("speed")) - { - sc.MustGetFloat(); - speed = float(sc.Float); - } - } - if (!tex) - { - return; - } - - if (maplumpname.IsNotEmpty()) - { - if (tex->bWarped != 0) - { - Printf("Cannot combine warping with hardware shader on texture '%s'\n", tex->Name.GetChars()); - return; - } - tex->gl_info.shaderspeed = speed; - for (unsigned i = 0; i < usershaders.Size(); i++) - { - if (!usershaders[i].CompareNoCase(maplumpname)) - { - tex->gl_info.shaderindex = i + FIRST_USER_SHADER; - return; - } - } - tex->gl_info.shaderindex = usershaders.Push(maplumpname) + FIRST_USER_SHADER; - } - } -} - static bool IsConsolePlayer(player_t *player) { AActor *activator = player ? player->mo : nullptr; diff --git a/src/gl/shaders/gl_shader.h b/src/gl/shaders/gl_shader.h index 8b119aec97..5aa1fdedc2 100644 --- a/src/gl/shaders/gl_shader.h +++ b/src/gl/shaders/gl_shader.h @@ -200,6 +200,12 @@ public: { glUniform4f(mIndex, a, b, c, d); } + + void Set(PalEntry newvalue) + { + glUniform4f(mIndex, newvalue.r / 255.f, newvalue.g / 255.f, newvalue.b / 255.f, newvalue.a / 255.f); + } + }; class FBufferedUniformPE @@ -399,28 +405,6 @@ public: } }; -enum MaterialShaderIndex -{ - SHADER_Default, - SHADER_Warp1, - SHADER_Warp2, - SHADER_Brightmap, - SHADER_Specular, - SHADER_SpecularBrightmap, - SHADER_PBR, - SHADER_PBRBrightmap, - SHADER_NoTexture, - SHADER_BasicFuzz, - SHADER_SmoothFuzz, - SHADER_SwirlyFuzz, - SHADER_TranslucentFuzz, - SHADER_JaggedFuzz, - SHADER_NoiseFuzz, - SHADER_SmoothNoiseFuzz, - SHADER_SoftwareFuzz, - FIRST_USER_SHADER -}; - enum { LIGHTBUF_BINDINGPOINT = 1 diff --git a/src/gl/shaders/gl_shaderprogram.cpp b/src/gl/shaders/gl_shaderprogram.cpp index dfb46c5443..5db66840da 100644 --- a/src/gl/shaders/gl_shaderprogram.cpp +++ b/src/gl/shaders/gl_shaderprogram.cpp @@ -28,7 +28,6 @@ #include "gl/system/gl_system.h" #include "m_swap.h" #include "v_video.h" -#include "gl/gl_functions.h" #include "vectors.h" #include "gl/system/gl_interface.h" #include "gl/system/gl_cvars.h" diff --git a/src/gl/shaders/gl_shadowmapshader.cpp b/src/gl/shaders/gl_shadowmapshader.cpp index 8b81d386ae..41921ef876 100644 --- a/src/gl/shaders/gl_shadowmapshader.cpp +++ b/src/gl/shaders/gl_shadowmapshader.cpp @@ -24,7 +24,6 @@ #include "files.h" #include "m_swap.h" #include "v_video.h" -#include "gl/gl_functions.h" #include "vectors.h" #include "gl/system/gl_interface.h" #include "gl/system/gl_framebuffer.h" diff --git a/src/gl/shaders/gl_tonemapshader.cpp b/src/gl/shaders/gl_tonemapshader.cpp index 5045618beb..eede7e9150 100644 --- a/src/gl/shaders/gl_tonemapshader.cpp +++ b/src/gl/shaders/gl_tonemapshader.cpp @@ -28,7 +28,6 @@ #include "gl/system/gl_system.h" #include "m_swap.h" #include "v_video.h" -#include "gl/gl_functions.h" #include "vectors.h" #include "gl/system/gl_interface.h" #include "gl/system/gl_framebuffer.h" diff --git a/src/gl/stereo3d/gl_interleaved3d.cpp b/src/gl/stereo3d/gl_interleaved3d.cpp index 4729fbf773..bc6a7acd60 100644 --- a/src/gl/stereo3d/gl_interleaved3d.cpp +++ b/src/gl/stereo3d/gl_interleaved3d.cpp @@ -41,6 +41,10 @@ #include "gl/system/gl_framebuffer.h" #include "gl/shaders/gl_present3dRowshader.h" +#ifdef _WIN32 +#include "hardware.h" +#endif // _WIN32 + EXTERN_CVAR(Float, vid_saturation) EXTERN_CVAR(Float, vid_brightness) EXTERN_CVAR(Float, vid_contrast) diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index 8549abb7e6..bdebfff506 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -40,16 +40,13 @@ #include "gl/system/gl_interface.h" #include "gl/system/gl_framebuffer.h" #include "gl/renderer/gl_renderer.h" +#include "gl/renderer/gl_renderbuffers.h" #include "gl/renderer/gl_renderstate.h" #include "gl/renderer/gl_lightdata.h" -#include "gl/data/gl_data.h" #include "gl/textures/gl_hwtexture.h" -#include "gl/textures/gl_texture.h" -#include "gl/textures/gl_translate.h" +#include "gl/textures/gl_samplers.h" #include "gl/utility/gl_clock.h" -#include "gl/utility/gl_templates.h" -#include "gl/gl_functions.h" -#include "gl/renderer/gl_2ddrawer.h" +#include "gl/data/gl_vertexbuffer.h" #include "gl_debug.h" #include "r_videoscale.h" @@ -98,9 +95,7 @@ OpenGLFrameBuffer::OpenGLFrameBuffer(void *hMonitor, int width, int height, int mDebug = std::make_shared(); mDebug->Update(); gl_SetupMenu(); - gl_GenerateGlobalBrightmapFromColormap(); DoSetGamma(); - Accel2D = true; } OpenGLFrameBuffer::~OpenGLFrameBuffer() @@ -178,7 +173,6 @@ void OpenGLFrameBuffer::Update() GLRenderer->Flush(); Swap(); - Unlock(); CheckBench(); int initialWidth = IsFullscreen() ? VideoWidth : GetClientWidth(); @@ -188,7 +182,7 @@ void OpenGLFrameBuffer::Update() if (clientWidth > 0 && clientHeight > 0 && (Width != clientWidth || Height != clientHeight)) { // Do not call Resize here because it's only for software canvases - Pitch = Width = clientWidth; + Width = clientWidth; Height = clientHeight; V_OutputResized(Width, Height); GLRenderer->mVBO->OutputResized(Width, Height); @@ -197,6 +191,91 @@ void OpenGLFrameBuffer::Update() GLRenderer->SetOutputViewport(nullptr); } +//=========================================================================== +// +// +// +//=========================================================================== + +void OpenGLFrameBuffer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV) +{ + if (!V_IsHardwareRenderer()) + { + Super::RenderTextureView(tex, Viewpoint, FOV); + } + else if (GLRenderer != nullptr) + { + GLRenderer->RenderTextureView(tex, Viewpoint, FOV); + camtexcount++; + } +} + +//=========================================================================== +// +// Render the view to a savegame picture +// +//=========================================================================== + +void OpenGLFrameBuffer::WriteSavePic(player_t *player, FileWriter *file, int width, int height) +{ + if (!V_IsHardwareRenderer()) + Super::WriteSavePic(player, file, width, height); + + if (GLRenderer != nullptr) + GLRenderer->WriteSavePic(player, file, width, height); +} + +//=========================================================================== +// +// +// +//=========================================================================== + +void OpenGLFrameBuffer::RenderView(player_t *player) +{ + if (GLRenderer != nullptr) + GLRenderer->RenderView(player); +} + + + +//=========================================================================== +// +// +// +//=========================================================================== + +EXTERN_CVAR(Bool, r_drawvoxels) +EXTERN_CVAR(Int, gl_tonemap) + +uint32_t OpenGLFrameBuffer::GetCaps() +{ + if (!V_IsHardwareRenderer()) + return Super::GetCaps(); + + // describe our basic feature set + ActorRenderFeatureFlags FlagSet = RFF_FLATSPRITES | RFF_MODELS | RFF_SLOPE3DFLOORS | + RFF_TILTPITCH | RFF_ROLLSPRITES | RFF_POLYGONAL; + if (r_drawvoxels) + FlagSet |= RFF_VOXELS; + if (gl.legacyMode) + { + // legacy mode always has truecolor because palette tonemap is not available + FlagSet |= RFF_TRUECOLOR; + } + else if (!(FGLRenderBuffers::IsEnabled())) + { + // truecolor is always available when renderbuffers are unavailable because palette tonemap is not possible + FlagSet |= RFF_TRUECOLOR | RFF_MATSHADER | RFF_BRIGHTMAP; + } + else + { + if (gl_tonemap != 5) // not running palette tonemap shader + FlagSet |= RFF_TRUECOLOR; + FlagSet |= RFF_MATSHADER | RFF_POSTSHADER | RFF_BRIGHTMAP; + } + return (uint32_t)FlagSet; +} //========================================================================== // @@ -205,7 +284,6 @@ void OpenGLFrameBuffer::Update() //========================================================================== CVAR(Bool, gl_finishbeforeswap, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); -extern int camtexcount; void OpenGLFrameBuffer::Swap() { @@ -308,6 +386,17 @@ bool OpenGLFrameBuffer::SetContrast(float contrast) // //=========================================================================== +void OpenGLFrameBuffer::CleanForRestart() +{ + if (GLRenderer) + GLRenderer->ResetSWScene(); +} + +void OpenGLFrameBuffer::SetTextureFilterMode() +{ + if (GLRenderer != nullptr && GLRenderer->mSamplerManager != nullptr) GLRenderer->mSamplerManager->SetTextureFilterMode(); +} + void OpenGLFrameBuffer::UpdatePalette() { if (GLRenderer) @@ -337,25 +426,29 @@ void OpenGLFrameBuffer::GetFlash(PalEntry &rgb, int &amount) amount = Flash.a; } -int OpenGLFrameBuffer::GetPageCount() +void OpenGLFrameBuffer::InitForLevel() { - return 1; + if (GLRenderer != NULL) + { + GLRenderer->SetupLevel(); + } } +//=========================================================================== +// +// +// +//=========================================================================== -//========================================================================== -// -// DFrameBuffer :: CreatePalette -// -// Creates a native palette from a remap table, if supported. -// -//========================================================================== - -FNativePalette *OpenGLFrameBuffer::CreatePalette(FRemapTable *remap) +void OpenGLFrameBuffer::SetClearColor(int color) { - return GLTranslationPalette::CreatePalette(remap); + PalEntry pe = GPalette.BaseColors[color]; + GLRenderer->mSceneClearColor[0] = pe.r / 255.f; + GLRenderer->mSceneClearColor[1] = pe.g / 255.f; + GLRenderer->mSceneClearColor[2] = pe.b / 255.f; } + //========================================================================== // // @@ -386,100 +479,6 @@ bool OpenGLFrameBuffer::Begin2D(bool copy3d) return true; } -//========================================================================== -// -// Draws a texture -// -//========================================================================== - -void OpenGLFrameBuffer::DrawTextureParms(FTexture *img, DrawParms &parms) -{ - if (GLRenderer != nullptr && GLRenderer->m2DDrawer != nullptr) - GLRenderer->m2DDrawer->AddTexture(img, parms); -} - -//========================================================================== -// -// -// -//========================================================================== -void OpenGLFrameBuffer::DrawLine(int x1, int y1, int x2, int y2, int palcolor, uint32_t color) -{ - if (GLRenderer != nullptr && GLRenderer->m2DDrawer != nullptr) - GLRenderer->m2DDrawer->AddLine(x1, y1, x2, y2, palcolor, color); -} - -//========================================================================== -// -// -// -//========================================================================== -void OpenGLFrameBuffer::DrawPixel(int x1, int y1, int palcolor, uint32_t color) -{ - if (GLRenderer != nullptr && GLRenderer->m2DDrawer != nullptr) - GLRenderer->m2DDrawer->AddPixel(x1, y1, palcolor, color); -} - -//========================================================================== -// -// -// -//========================================================================== -void OpenGLFrameBuffer::Dim(PalEntry) -{ - // Unlike in the software renderer the color is being ignored here because - // view blending only affects the actual view with the GL renderer. - Super::Dim(0); -} - -void OpenGLFrameBuffer::DoDim(PalEntry color, float damount, int x1, int y1, int w, int h) -{ - if (GLRenderer != nullptr && GLRenderer->m2DDrawer != nullptr) - GLRenderer->m2DDrawer->AddDim(color, damount, x1, y1, w, h); -} - -//========================================================================== -// -// -// -//========================================================================== -void OpenGLFrameBuffer::FlatFill (int left, int top, int right, int bottom, FTexture *src, bool local_origin) -{ - - if (GLRenderer != nullptr && GLRenderer->m2DDrawer != nullptr) - GLRenderer->m2DDrawer->AddFlatFill(left, top, right, bottom, src, local_origin); -} - -//========================================================================== -// -// -// -//========================================================================== -void OpenGLFrameBuffer::DoClear(int left, int top, int right, int bottom, int palcolor, uint32_t color) -{ - if (GLRenderer != nullptr && GLRenderer->m2DDrawer != nullptr) - GLRenderer->m2DDrawer->AddClear(left, top, right, bottom, palcolor, color); -} - -//========================================================================== -// -// D3DFB :: FillSimplePoly -// -// Here, "simple" means that a simple triangle fan can draw it. -// -//========================================================================== - -void OpenGLFrameBuffer::FillSimplePoly(FTexture *texture, FVector2 *points, int npoints, - double originx, double originy, double scalex, double scaley, - DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel, int bottomclip) -{ - if (GLRenderer != nullptr && GLRenderer->m2DDrawer != nullptr && npoints >= 3) - { - GLRenderer->m2DDrawer->AddPoly(texture, points, npoints, originx, originy, scalex, scaley, rotation, colormap, flatcolor, lightlevel); - } -} - - //=========================================================================== // // Takes a screenshot @@ -550,7 +549,6 @@ void OpenGLFrameBuffer::GameRestart() memcpy (SourcePalette, GPalette.BaseColors, sizeof(PalEntry)*256); UpdatePalette (); ScreenshotBuffer = NULL; - gl_GenerateGlobalBrightmapFromColormap(); GLRenderer->GetSpecialTextures(); } @@ -569,3 +567,14 @@ void OpenGLFrameBuffer::ScaleCoordsFromWindow(int16_t &x, int16_t &y) x = int16_t((x - letterboxX) * Width / letterboxWidth); y = int16_t((y - letterboxY) * Height / letterboxHeight); } + +//=========================================================================== +// +// 2D drawing +// +//=========================================================================== + +void OpenGLFrameBuffer::Draw2D() +{ + if (GLRenderer != nullptr) GLRenderer->Draw2D(&m2DDrawer); +} diff --git a/src/gl/system/gl_framebuffer.h b/src/gl/system/gl_framebuffer.h index 0c7c922aaa..6cd1efc34f 100644 --- a/src/gl/system/gl_framebuffer.h +++ b/src/gl/system/gl_framebuffer.h @@ -1,10 +1,7 @@ #ifndef __GL_FRAMEBUFFER #define __GL_FRAMEBUFFER -#ifdef _WIN32 -#include "win32iface.h" -#include "win32gliface.h" -#endif +#include "gl_sysfb.h" #include @@ -12,17 +9,9 @@ class FHardwareTexture; class FSimpleVertexBuffer; class FGLDebug; -#ifdef _WIN32 -class OpenGLFrameBuffer : public Win32GLFrameBuffer +class OpenGLFrameBuffer : public SystemFrameBuffer { - typedef Win32GLFrameBuffer Super; -#else -#include "sdlglvideo.h" -class OpenGLFrameBuffer : public SDLGLFB -{ - typedef SDLGLFB Super; //[C]commented, DECLARE_CLASS defines this in linux -#endif - + typedef SystemFrameBuffer Super; public: @@ -39,14 +28,21 @@ public: bool SetContrast(float contrast); void DoSetGamma(); - void UpdatePalette(); - void GetFlashedPalette (PalEntry pal[256]); - PalEntry *GetPalette (); - bool SetFlash(PalEntry rgb, int amount); - void GetFlash(PalEntry &rgb, int &amount); - int GetPageCount(); - bool Begin2D(bool copy3d); - void GameRestart(); + void CleanForRestart() override; + void UpdatePalette() override; + void GetFlashedPalette (PalEntry pal[256]) override; + PalEntry *GetPalette () override; + bool SetFlash(PalEntry rgb, int amount) override; + void GetFlash(PalEntry &rgb, int &amount) override; + bool Begin2D(bool copy3d) override; + void GameRestart() override; + void InitForLevel() override; + void SetClearColor(int color) override; + uint32_t GetCaps() override; + void RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV) override; + void WriteSavePic(player_t *player, FileWriter *file, int width, int height) override; + void RenderView(player_t *player) override; + void SetTextureFilterMode() override; // Retrieves a buffer containing image data for a screenshot. // Hint: Pitch can be negative for upside-down images, in which case buffer @@ -56,32 +52,17 @@ public: // Releases the screenshot buffer. virtual void ReleaseScreenshotBuffer(); - // 2D drawing - void DrawTextureParms(FTexture *img, DrawParms &parms); - void DrawLine(int x1, int y1, int x2, int y2, int palcolor, uint32_t color); - void DrawPixel(int x1, int y1, int palcolor, uint32_t color); - void DoClear(int left, int top, int right, int bottom, int palcolor, uint32_t color); - void Dim(PalEntry color=0); - void DoDim (PalEntry color, float damount, int x1, int y1, int w, int h); - void FlatFill (int left, int top, int right, int bottom, FTexture *src, bool local_origin=false); - - void FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, - double originx, double originy, double scalex, double scaley, - DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel, int bottomclip); - - FNativePalette *CreatePalette(FRemapTable *remap); - bool WipeStartScreen(int type); void WipeEndScreen(); bool WipeDo(int ticks); void WipeCleanup(); void Swap(); - bool Is8BitMode() { return false; } bool IsHWGammaActive() const { return HWGammaActive; } void SetVSync(bool vsync); void ScaleCoordsFromWindow(int16_t &x, int16_t &y) override; + void Draw2D() override; bool HWGammaActive = false; // Are we using hardware or software gamma? std::shared_ptr mDebug; // Debug API @@ -89,6 +70,7 @@ private: PalEntry Flash; // Only needed to support some cruft in the interface that only makes sense for the software renderer PalEntry SourcePalette[256]; // This is where unpaletted textures get their palette from uint8_t *ScreenshotBuffer; // What the name says. This must be maintained because the software renderer can return a locked canvas surface which the caller cannot release. + int camtexcount = 0; class Wiper { diff --git a/src/gl/system/gl_interface.cpp b/src/gl/system/gl_interface.cpp index 3f0fe4dbf3..94b28712dc 100644 --- a/src/gl/system/gl_interface.cpp +++ b/src/gl/system/gl_interface.cpp @@ -43,10 +43,6 @@ static TArray m_Extensions; RenderContext gl; static double realglversion; // this is public so the statistics code can access it. -EXTERN_CVAR(Bool, gl_legacy_mode) -extern int currentrenderer; -CVAR(Bool, gl_riskymodernpath, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) - //========================================================================== // // @@ -211,11 +207,7 @@ void gl_LoadExtensions() // The minimum requirement for the modern render path is GL 3.3. // Although some GL 3.1 or 3.2 solutions may theoretically work they are usually too broken or too slow. - // unless, of course, we're simply using this as a software backend... - float minmodernpath = 3.3f; - if (gl_riskymodernpath) - minmodernpath = 3.1f; - if ((gl_version < minmodernpath && (currentrenderer==1)) || gl_version < 3.0f) + if (gl_version < 3.3f) { gl.legacyMode = true; gl.lightmethod = LM_LEGACY; @@ -327,7 +319,6 @@ void gl_LoadExtensions() UCVarValue value; value.Bool = gl.legacyMode; - gl_legacy_mode.ForceSet (value, CVAR_Bool); } //========================================================================== @@ -373,18 +364,6 @@ void gl_PrintStartupLog() glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &v); Printf("Max. vertex shader storage blocks: %d\n", v); } - - // For shader-less, the special alphatexture translation must be changed to actually set the alpha, because it won't get translated by a shader. - if (gl.legacyMode) - { - FRemapTable *remap = translationtables[TRANSLATION_Standard][8]; - for (int i = 0; i < 256; i++) - { - remap->Remap[i] = i; - remap->Palette[i] = PalEntry(i, 255, 255, 255); - } - } - } std::pair gl_getInfo() diff --git a/src/gl/system/gl_interface.h b/src/gl/system/gl_interface.h index a839e13b46..2584517013 100644 --- a/src/gl/system/gl_interface.h +++ b/src/gl/system/gl_interface.h @@ -29,14 +29,14 @@ enum RenderFlags enum TexMode { + TM_SWCANVAS = -1, // special case for the legacy renderer, do not use for anything but the SW renderer's canvas. TM_MODULATE = 0, // (r, g, b, a) TM_MASK, // (1, 1, 1, a) TM_OPAQUE, // (r, g, b, 1) TM_INVERSE, // (1-r, 1-g, 1-b, a) TM_REDTOALPHA, // (1, 1, 1, r) TM_CLAMPY, // (r, g, b, (t >= 0.0 && t <= 1.0)? a:0) - - TM_INVERTOPAQUE, // used by GL 2.x fallback code. + TM_INVERTOPAQUE, // (1-r, 1-g, 1-b, 1) }; enum ELightMethod diff --git a/src/gl/system/gl_swframebuffer.cpp b/src/gl/system/gl_swframebuffer.cpp deleted file mode 100644 index f0baf6f9de..0000000000 --- a/src/gl/system/gl_swframebuffer.cpp +++ /dev/null @@ -1,3825 +0,0 @@ -/* -** gl_swframebuffer.cpp -** Code to let ZDoom use OpenGL as a simple framebuffer -** -**--------------------------------------------------------------------------- -** Copyright 1998-2011 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -** This file does _not_ implement hardware-acclerated 3D rendering. It is -** just a means of getting the pixel data to the screen in a more reliable -** method on modern hardware by copying the entire frame to a texture, -** drawing that to the screen, and presenting. -** -** That said, it does implement hardware-accelerated 2D rendering. -*/ - -#include "gl/system/gl_system.h" -#include "m_swap.h" -#include "v_video.h" -#include "doomstat.h" -#include "m_png.h" -#include "m_crc32.h" -#include "vectors.h" -#include "v_palette.h" -#include "templates.h" - -#include "c_dispatch.h" -#include "templates.h" -#include "i_system.h" -#include "i_video.h" -#include "v_pfx.h" -#include "stats.h" -#include "doomerrors.h" -#include "r_data/r_translate.h" -#include "f_wipe.h" -#include "sbar.h" -#include "w_wad.h" -#include "r_data/colormaps.h" - -#include "gl/system/gl_interface.h" -#include "gl/system/gl_swframebuffer.h" -#include "gl/data/gl_data.h" -#include "gl/utility/gl_clock.h" -#include "gl/utility/gl_templates.h" -#include "gl/gl_functions.h" -#include "gl_debug.h" -#include "r_videoscale.h" - -#include "swrenderer/scene/r_light.h" - -#ifndef NO_SSE -#include -#endif - -CVAR(Int, gl_showpacks, 0, 0) -#ifndef WIN32 // Defined in fb_d3d9 for Windows -CVAR(Bool, vid_hwaalines, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -CUSTOM_CVAR(Bool, vid_hw2d, true, CVAR_NOINITCALL) -{ - V_SetBorderNeedRefresh(); -} -#else -EXTERN_CVAR(Bool, vid_hwaalines) -EXTERN_CVAR(Bool, vid_hw2d) -#endif - -EXTERN_CVAR(Bool, fullscreen) -EXTERN_CVAR(Float, Gamma) -EXTERN_CVAR(Bool, vid_vsync) -EXTERN_CVAR(Float, transsouls) -EXTERN_CVAR(Int, vid_refreshrate) - -#ifdef WIN32 -extern cycle_t BlitCycles; -#endif - -void gl_LoadExtensions(); -void gl_PrintStartupLog(); - -#ifndef WIN32 -// This has to be in this file because system headers conflict Doom headers -DFrameBuffer *CreateGLSWFrameBuffer(int width, int height, bool bgra, bool fullscreen) -{ - return new OpenGLSWFrameBuffer(NULL, width, height, 32, 60, fullscreen, bgra); -} -#endif - -const char *const OpenGLSWFrameBuffer::ShaderDefines[OpenGLSWFrameBuffer::NUM_SHADERS] = -{ - "#define ENORMALCOLOR", // NormalColor - "#define ENORMALCOLOR\n#define PALTEX", // NormalColorPal - "#define ENORMALCOLOR\n#define INVERT", // NormalColorInv - "#define ENORMALCOLOR\n#define PALTEX\n#define INVERT", // NormalColorPalInv - - "#define EREDTOALPHA", // RedToAlpha - "#define EREDTOALPHA\n#define INVERT", // RedToAlphaInv - - "#define EVERTEXCOLOR", // VertexColor - - "#define ESPECIALCOLORMAP\n", // SpecialColormap - "#define ESPECIALCOLORMAP\n#define PALTEX", // SpecialColorMapPal - - "#define EINGAMECOLORMAP", // InGameColormap - "#define EINGAMECOLORMAP\n#define DESAT", // InGameColormapDesat - "#define EINGAMECOLORMAP\n#define INVERT", // InGameColormapInv - "#define EINGAMECOLORMAP\n#define INVERT\n#define DESAT", // InGameColormapInvDesat - "#define EINGAMECOLORMAP\n#define PALTEX\n", // InGameColormapPal - "#define EINGAMECOLORMAP\n#define PALTEX\n#define DESAT", // InGameColormapPalDesat - "#define EINGAMECOLORMAP\n#define PALTEX\n#define INVERT", // InGameColormapPalInv - "#define EINGAMECOLORMAP\n#define PALTEX\n#define INVERT\n#define DESAT", // InGameColormapPalInvDesat - - "#define EBURNWIPE", // BurnWipe - "#define EGAMMACORRECTION", // GammaCorrection -}; - -OpenGLSWFrameBuffer::OpenGLSWFrameBuffer(void *hMonitor, int width, int height, int bits, int refreshHz, bool fullscreen, bool bgra) : - Super(hMonitor, width, height, bits, refreshHz, fullscreen, bgra) -{ - VertexBuffer = nullptr; - IndexBuffer = nullptr; - FBTexture = nullptr; - InitialWipeScreen = nullptr; - ScreenshotTexture = nullptr; - FinalWipeScreen = nullptr; - PaletteTexture = nullptr; - for (int i = 0; i < NUM_SHADERS; ++i) - { - Shaders[i] = nullptr; - } - - BlendingRect.left = 0; - BlendingRect.top = 0; - BlendingRect.right = Width; - BlendingRect.bottom = Height; - In2D = 0; - Palettes = nullptr; - Textures = nullptr; - Accel2D = true; - GatheringWipeScreen = false; - ScreenWipe = nullptr; - InScene = false; - QuadExtra = new BufferedTris[MAX_QUAD_BATCH]; - memset(QuadExtra, 0, sizeof(BufferedTris) * MAX_QUAD_BATCH); - Atlases = nullptr; - PixelDoubling = 0; - - Gamma = 1.0; - FlashColor0 = 0; - FlashColor1 = 0xFFFFFFFF; - FlashColor = 0; - FlashAmount = 0; - - NeedGammaUpdate = false; - NeedPalUpdate = false; - - if (MemBuffer == nullptr) - { - return; - } - - memcpy(SourcePalette, GPalette.BaseColors, sizeof(PalEntry) * 256); - - // To do: this needs to cooperate with the same static in OpenGLFrameBuffer::InitializeState - static bool first = true; - if (first) - { - if (ogl_LoadFunctions() == ogl_LOAD_FAILED) - { - Printf("OpenGL load failed. No OpenGL acceleration will be used.\n"); - return; - } - } - - const char *glversion = (const char*)glGetString(GL_VERSION); - bool isGLES = (glversion && strlen(glversion) > 10 && memcmp(glversion, "OpenGL ES ", 10) == 0); - - if (!isGLES && ogl_IsVersionGEQ(3, 0) == 0) - { - Printf("OpenGL acceleration requires at least OpenGL 3.0. No Acceleration will be used.\n"); - return; - } - gl_LoadExtensions(); - if (gl.legacyMode) - { - Printf("Legacy OpenGL path is active. No Acceleration will be used.\n"); - return; - } - InitializeState(); - if (first) - { - gl_PrintStartupLog(); - first = false; - } - - if (!glGetString) - return; - - // SetVSync needs to be at the very top to workaround a bug in Nvidia's OpenGL driver. - // If wglSwapIntervalEXT is called after glBindFramebuffer in a frame the setting is not changed! - Super::SetVSync(vid_vsync); - - Debug = std::make_shared(); - Debug->Update(); - - //Windowed = !(static_cast(Video)->GoFullscreen(fullscreen)); - - TrueHeight = height; - - Valid = CreateResources(); - if (Valid) - SetInitialState(); -} - -OpenGLSWFrameBuffer::~OpenGLSWFrameBuffer() -{ - ReleaseResources(); - delete[] QuadExtra; -} - -void *OpenGLSWFrameBuffer::MapBuffer(int target, int size) -{ - if (glMapBufferRange) - { - return (FBVERTEX*)glMapBufferRange(target, 0, size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); - } - else - { - glBufferData(target, size, nullptr, GL_STREAM_DRAW); - return glMapBuffer(target, GL_WRITE_ONLY); - } -} - -OpenGLSWFrameBuffer::HWFrameBuffer::~HWFrameBuffer() -{ - if (Framebuffer != 0) glDeleteFramebuffers(1, (GLuint*)&Framebuffer); - Texture.reset(); -} - -OpenGLSWFrameBuffer::HWTexture::~HWTexture() -{ - if (Texture != 0) glDeleteTextures(1, (GLuint*)&Texture); - if (Buffers[0] != 0) glDeleteBuffers(2, (GLuint*)Buffers); -} - -OpenGLSWFrameBuffer::HWVertexBuffer::~HWVertexBuffer() -{ - if (VertexArray != 0) glDeleteVertexArrays(1, (GLuint*)&VertexArray); - if (Buffer != 0) glDeleteBuffers(1, (GLuint*)&Buffer); -} - -OpenGLSWFrameBuffer::FBVERTEX *OpenGLSWFrameBuffer::HWVertexBuffer::Lock() -{ - glBindBuffer(GL_ARRAY_BUFFER, Buffer); - return (FBVERTEX*)MapBuffer(GL_ARRAY_BUFFER, Size); -} - -void OpenGLSWFrameBuffer::HWVertexBuffer::Unlock() -{ - glUnmapBuffer(GL_ARRAY_BUFFER); - glBindBuffer(GL_ARRAY_BUFFER, 0); -} - -OpenGLSWFrameBuffer::HWIndexBuffer::~HWIndexBuffer() -{ - if (Buffer != 0) glDeleteBuffers(1, (GLuint*)&Buffer); -} - -uint16_t *OpenGLSWFrameBuffer::HWIndexBuffer::Lock() -{ - glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &LockedOldBinding); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Buffer); - return (uint16_t*)MapBuffer(GL_ELEMENT_ARRAY_BUFFER, Size); -} - -void OpenGLSWFrameBuffer::HWIndexBuffer::Unlock() -{ - glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, LockedOldBinding); -} - -OpenGLSWFrameBuffer::HWPixelShader::~HWPixelShader() -{ - if (Program != 0) glDeleteProgram(Program); - if (VertexShader != 0) glDeleteShader(VertexShader); - if (FragmentShader != 0) glDeleteShader(FragmentShader); -} - -std::unique_ptr OpenGLSWFrameBuffer::CreateFrameBuffer(const FString &name, int width, int height) -{ - std::unique_ptr fb(new HWFrameBuffer()); - - GLint format = GL_RGBA16F; - if (gl.es) format = GL_RGB; - - fb->Texture = CreateTexture(name, width, height, 1, format); - if (!fb->Texture) - { - return nullptr; - } - - glGenFramebuffers(1, (GLuint*)&fb->Framebuffer); - - GLint oldFramebufferBinding = 0, oldTextureBinding = 0; - glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldFramebufferBinding); - glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTextureBinding); - - glBindFramebuffer(GL_FRAMEBUFFER, fb->Framebuffer); - FGLDebug::LabelObject(GL_FRAMEBUFFER, fb->Framebuffer, name); - - glBindTexture(GL_TEXTURE_2D, fb->Texture->Texture); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fb->Texture->Texture, 0); - - GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER); - - glBindFramebuffer(GL_FRAMEBUFFER, oldFramebufferBinding); - glBindTexture(GL_TEXTURE_2D, oldTextureBinding); - - if (result != GL_FRAMEBUFFER_COMPLETE) - { - Printf("Framebuffer is not complete\n"); - return nullptr; - } - - return fb; -} - -std::unique_ptr OpenGLSWFrameBuffer::CreatePixelShader(FString vertexsrc, FString fragmentsrc, const FString &defines) -{ - std::unique_ptr shader(new HWPixelShader()); - - shader->Program = glCreateProgram(); - if (shader->Program == 0) { Printf("glCreateProgram failed. Disabling OpenGL hardware acceleration.\n"); return nullptr; } - shader->VertexShader = glCreateShader(GL_VERTEX_SHADER); - if (shader->VertexShader == 0) { Printf("glCreateShader(GL_VERTEX_SHADER) failed. Disabling OpenGL hardware acceleration.\n"); return nullptr; } - shader->FragmentShader = glCreateShader(GL_FRAGMENT_SHADER); - if (shader->FragmentShader == 0) { Printf("glCreateShader(GL_FRAGMENT_SHADER) failed. Disabling OpenGL hardware acceleration.\n"); return nullptr; } - - int maxGlslVersion = 330; - int shaderVersion = MIN((int)round(gl.glslversion * 10) * 10, maxGlslVersion); - - FString prefix; - prefix.AppendFormat("#version %d\n%s\n#line 0\n", shaderVersion, defines.GetChars()); - //Printf("Shader prefix: %s", prefix.GetChars()); - - vertexsrc = prefix + vertexsrc; - fragmentsrc = prefix + fragmentsrc; - - { - int lengths[1] = { (int)vertexsrc.Len() }; - const char *sources[1] = { vertexsrc.GetChars() }; - glShaderSource(shader->VertexShader, 1, sources, lengths); - glCompileShader(shader->VertexShader); - } - - { - int lengths[1] = { (int)fragmentsrc.Len() }; - const char *sources[1] = { fragmentsrc.GetChars() }; - glShaderSource(shader->FragmentShader, 1, sources, lengths); - glCompileShader(shader->FragmentShader); - } - - GLint status = 0; - int errorShader = shader->VertexShader; - glGetShaderiv(shader->VertexShader, GL_COMPILE_STATUS, &status); - if (status != GL_FALSE) { errorShader = shader->FragmentShader; glGetShaderiv(shader->FragmentShader, GL_COMPILE_STATUS, &status); } - if (status == GL_FALSE) - { - static char buffer[10000]; - GLsizei length = 0; - buffer[0] = 0; - glGetShaderInfoLog(errorShader, 10000, &length, buffer); - //Printf("Shader compile failed: %s", buffer); - - return nullptr; - } - - glAttachShader(shader->Program, shader->VertexShader); - glAttachShader(shader->Program, shader->FragmentShader); - glBindFragDataLocation(shader->Program, 0, "FragColor"); - glBindAttribLocation(shader->Program, 0, "AttrPosition"); - glBindAttribLocation(shader->Program, 1, "AttrColor0"); - glBindAttribLocation(shader->Program, 2, "AttrColor1"); - glBindAttribLocation(shader->Program, 3, "AttrTexCoord0"); - glLinkProgram(shader->Program); - glGetProgramiv(shader->Program, GL_LINK_STATUS, &status); - if (status == GL_FALSE) - { - static char buffer[10000]; - GLsizei length = 0; - buffer[0] = 0; - glGetProgramInfoLog(shader->Program, 10000, &length, buffer); - //Printf("Shader link failed: %s", buffer); - - return nullptr; - } - - shader->ConstantLocations[PSCONST_Desaturation] = glGetUniformLocation(shader->Program, "Desaturation"); - shader->ConstantLocations[PSCONST_PaletteMod] = glGetUniformLocation(shader->Program, "PaletteMod"); - shader->ConstantLocations[PSCONST_Weights] = glGetUniformLocation(shader->Program, "Weights"); - shader->ConstantLocations[PSCONST_Gamma] = glGetUniformLocation(shader->Program, "Gamma"); - shader->ConstantLocations[PSCONST_ScreenSize] = glGetUniformLocation(shader->Program, "ScreenSize"); - shader->ImageLocation = glGetUniformLocation(shader->Program, "Image"); - shader->PaletteLocation = glGetUniformLocation(shader->Program, "Palette"); - shader->NewScreenLocation = glGetUniformLocation(shader->Program, "NewScreen"); - shader->BurnLocation = glGetUniformLocation(shader->Program, "Burn"); - - return shader; -} - -std::unique_ptr OpenGLSWFrameBuffer::CreateVertexBuffer(int size) -{ - std::unique_ptr obj(new HWVertexBuffer()); - - obj->Size = size; - - GLint oldBinding = 0; - glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &oldBinding); - - glGenVertexArrays(1, (GLuint*)&obj->VertexArray); - glGenBuffers(1, (GLuint*)&obj->Buffer); - glBindVertexArray(obj->VertexArray); - glBindBuffer(GL_ARRAY_BUFFER, obj->Buffer); - FGLDebug::LabelObject(GL_BUFFER, obj->Buffer, "VertexBuffer"); - glBufferData(GL_ARRAY_BUFFER, size, nullptr, GL_STREAM_DRAW); - glEnableVertexAttribArray(0); - glEnableVertexAttribArray(1); - glEnableVertexAttribArray(2); - glEnableVertexAttribArray(3); - glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(FBVERTEX), (const GLvoid*)offsetof(FBVERTEX, x)); - glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(FBVERTEX), (const GLvoid*)offsetof(FBVERTEX, color0)); - glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(FBVERTEX), (const GLvoid*)offsetof(FBVERTEX, color1)); - glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(FBVERTEX), (const GLvoid*)offsetof(FBVERTEX, tu)); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindVertexArray(oldBinding); - - return obj; -} - -std::unique_ptr OpenGLSWFrameBuffer::CreateIndexBuffer(int size) -{ - std::unique_ptr obj(new HWIndexBuffer()); - - obj->Size = size; - - GLint oldBinding = 0; - glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &oldBinding); - - glGenBuffers(1, (GLuint*)&obj->Buffer); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, obj->Buffer); - FGLDebug::LabelObject(GL_BUFFER, obj->Buffer, "IndexBuffer"); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, nullptr, GL_STREAM_DRAW); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oldBinding); - - return obj; -} - -std::unique_ptr OpenGLSWFrameBuffer::CreateTexture(const FString &name, int width, int height, int levels, int format) -{ - std::unique_ptr obj(new HWTexture()); - - obj->Format = format; - - GLint oldBinding = 0; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldBinding); - - glGenTextures(1, (GLuint*)&obj->Texture); - glBindTexture(GL_TEXTURE_2D, obj->Texture); - GLenum srcformat; - switch (format) - { - case GL_RGB: srcformat = GL_RGB; break; - case GL_R8: srcformat = GL_RED; break; - case GL_RGBA8: srcformat = gl.es ? GL_RGBA : GL_BGRA; break; - case GL_RGBA16F: srcformat = GL_RGBA; break; - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: srcformat = GL_RGB; break; - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: srcformat = GL_RGBA; break; - case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: srcformat = GL_RGBA; break; - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: srcformat = GL_RGBA; break; - default: - I_FatalError("Unknown format passed to CreateTexture"); - return nullptr; - } - glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, srcformat, GL_UNSIGNED_BYTE, nullptr); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - FGLDebug::LabelObject(GL_TEXTURE, obj->Texture, name); - - glBindTexture(GL_TEXTURE_2D, oldBinding); - - return obj; -} - -std::unique_ptr OpenGLSWFrameBuffer::CopyCurrentScreen() -{ - std::unique_ptr obj(new HWTexture()); - obj->Format = GL_RGBA16F; - - GLint oldBinding = 0; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldBinding); - - glGenTextures(1, (GLuint*)&obj->Texture); - glBindTexture(GL_TEXTURE_2D, obj->Texture); - - glCopyTexImage2D(GL_TEXTURE_2D, 0, obj->Format, 0, 0, Width, Height, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - FGLDebug::LabelObject(GL_TEXTURE, obj->Texture, "CopyCurrentScreen"); - - glBindTexture(GL_TEXTURE_2D, oldBinding); - - return obj; -} - -void OpenGLSWFrameBuffer::SetGammaRamp(const GammaRamp *ramp) -{ -} - -void OpenGLSWFrameBuffer::SetPixelShaderConstantF(int uniformIndex, const float *data, int vec4fcount) -{ - assert(uniformIndex < NumPSCONST && vec4fcount == 1); // This emulation of d3d9 only works for very simple stuff - for (int i = 0; i < 4; i++) - ShaderConstants[uniformIndex * 4 + i] = data[i]; - if (CurrentShader && CurrentShader->ConstantLocations[uniformIndex] != -1) - glUniform4fv(CurrentShader->ConstantLocations[uniformIndex], vec4fcount, data); -} - -void OpenGLSWFrameBuffer::SetHWPixelShader(HWPixelShader *shader) -{ - if (shader != CurrentShader) - { - if (shader) - { - glUseProgram(shader->Program); - for (int i = 0; i < NumPSCONST; i++) - { - if (shader->ConstantLocations[i] != -1) - glUniform4fv(shader->ConstantLocations[i], 1, &ShaderConstants[i * 4]); - } - } - else - { - glUseProgram(0); - } - } - CurrentShader = shader; -} - -void OpenGLSWFrameBuffer::SetStreamSource(HWVertexBuffer *vertexBuffer) -{ - if (vertexBuffer) - glBindVertexArray(vertexBuffer->VertexArray); - else - glBindVertexArray(0); -} - -void OpenGLSWFrameBuffer::SetIndices(HWIndexBuffer *indexBuffer) -{ - if (indexBuffer) - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer->Buffer); - else - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); -} - -void OpenGLSWFrameBuffer::DrawTriangleFans(int count, const FBVERTEX *vertices) -{ - count = 2 + count; - - GLint oldBinding = 0; - glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &oldBinding); - - if (!StreamVertexBuffer) - { - StreamVertexBuffer.reset(new HWVertexBuffer()); - glGenVertexArrays(1, (GLuint*)&StreamVertexBuffer->VertexArray); - glGenBuffers(1, (GLuint*)&StreamVertexBuffer->Buffer); - glBindVertexArray(StreamVertexBuffer->VertexArray); - glBindBuffer(GL_ARRAY_BUFFER, StreamVertexBuffer->Buffer); - glBufferData(GL_ARRAY_BUFFER, count * sizeof(FBVERTEX), vertices, GL_STREAM_DRAW); - glEnableVertexAttribArray(0); - glEnableVertexAttribArray(1); - glEnableVertexAttribArray(2); - glEnableVertexAttribArray(3); - glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(FBVERTEX), (const GLvoid*)offsetof(FBVERTEX, x)); - glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(FBVERTEX), (const GLvoid*)offsetof(FBVERTEX, color0)); - glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(FBVERTEX), (const GLvoid*)offsetof(FBVERTEX, color1)); - glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(FBVERTEX), (const GLvoid*)offsetof(FBVERTEX, tu)); - } - else - { - glBindVertexArray(StreamVertexBuffer->VertexArray); - glBindBuffer(GL_ARRAY_BUFFER, StreamVertexBuffer->Buffer); - glBufferData(GL_ARRAY_BUFFER, count * sizeof(FBVERTEX), vertices, GL_STREAM_DRAW); - } - - glDrawArrays(GL_TRIANGLE_FAN, 0, count); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindVertexArray(oldBinding); -} - -void OpenGLSWFrameBuffer::DrawTriangleFans(int count, const BURNVERTEX *vertices) -{ - count = 2 + count; - - GLint oldBinding = 0; - glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &oldBinding); - - if (!StreamVertexBufferBurn) - { - StreamVertexBufferBurn.reset(new HWVertexBuffer()); - glGenVertexArrays(1, (GLuint*)&StreamVertexBufferBurn->VertexArray); - glGenBuffers(1, (GLuint*)&StreamVertexBufferBurn->Buffer); - glBindVertexArray(StreamVertexBufferBurn->VertexArray); - glBindBuffer(GL_ARRAY_BUFFER, StreamVertexBufferBurn->Buffer); - glBufferData(GL_ARRAY_BUFFER, count * sizeof(BURNVERTEX), vertices, GL_STREAM_DRAW); - glEnableVertexAttribArray(0); - glEnableVertexAttribArray(1); - glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(BURNVERTEX), (const GLvoid*)offsetof(BURNVERTEX, x)); - glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(BURNVERTEX), (const GLvoid*)offsetof(BURNVERTEX, tu0)); - } - else - { - glBindVertexArray(StreamVertexBufferBurn->VertexArray); - glBindBuffer(GL_ARRAY_BUFFER, StreamVertexBufferBurn->Buffer); - glBufferData(GL_ARRAY_BUFFER, count * sizeof(BURNVERTEX), vertices, GL_STREAM_DRAW); - } - - glDrawArrays(GL_TRIANGLE_FAN, 0, count); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindVertexArray(oldBinding); -} - -void OpenGLSWFrameBuffer::DrawPoints(int count, const FBVERTEX *vertices) -{ - GLint oldBinding = 0; - glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &oldBinding); - - if (!StreamVertexBuffer) - { - StreamVertexBuffer.reset(new HWVertexBuffer()); - glGenVertexArrays(1, (GLuint*)&StreamVertexBuffer->VertexArray); - glGenBuffers(1, (GLuint*)&StreamVertexBuffer->Buffer); - glBindVertexArray(StreamVertexBuffer->VertexArray); - glBindBuffer(GL_ARRAY_BUFFER, StreamVertexBuffer->Buffer); - glBufferData(GL_ARRAY_BUFFER, count * sizeof(FBVERTEX), vertices, GL_STREAM_DRAW); - glEnableVertexAttribArray(0); - glEnableVertexAttribArray(1); - glEnableVertexAttribArray(2); - glEnableVertexAttribArray(3); - glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(FBVERTEX), (const GLvoid*)offsetof(FBVERTEX, x)); - glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(FBVERTEX), (const GLvoid*)offsetof(FBVERTEX, color0)); - glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(FBVERTEX), (const GLvoid*)offsetof(FBVERTEX, color1)); - glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(FBVERTEX), (const GLvoid*)offsetof(FBVERTEX, tu)); - } - else - { - glBindVertexArray(StreamVertexBuffer->VertexArray); - glBindBuffer(GL_ARRAY_BUFFER, StreamVertexBuffer->Buffer); - glBufferData(GL_ARRAY_BUFFER, count * sizeof(FBVERTEX), vertices, GL_STREAM_DRAW); - } - - glDrawArrays(GL_POINTS, 0, count); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindVertexArray(oldBinding); -} - -void OpenGLSWFrameBuffer::DrawLineList(int count) -{ - glDrawArrays(GL_LINES, 0, count * 2); -} - -void OpenGLSWFrameBuffer::DrawTriangleList(int minIndex, int numVertices, int startIndex, int primitiveCount) -{ - glDrawRangeElements(GL_TRIANGLES, minIndex, minIndex + numVertices - 1, primitiveCount * 3, GL_UNSIGNED_SHORT, (const void*)(startIndex * sizeof(uint16_t))); -} - -void OpenGLSWFrameBuffer::GetLetterboxFrame(int &letterboxX, int &letterboxY, int &letterboxWidth, int &letterboxHeight) -{ - int clientWidth = GetClientWidth(); - int clientHeight = GetClientHeight(); - - float scaleX, scaleY; - if (ViewportIsScaled43()) - { - scaleX = MIN(clientWidth / (float)Width, clientHeight / (Height * 1.2f)); - scaleY = scaleX * 1.2f; - } - else - { - scaleX = MIN(clientWidth / (float)Width, clientHeight / (float)Height); - scaleY = scaleX; - } - - letterboxWidth = (int)round(Width * scaleX); - letterboxHeight = (int)round(Height * scaleY); - letterboxX = (clientWidth - letterboxWidth) / 2; - letterboxY = (clientHeight - letterboxHeight) / 2; -} - -void OpenGLSWFrameBuffer::Present() -{ - int clientWidth = GetClientWidth(); - int clientHeight = GetClientHeight(); - if (clientWidth > 0 && clientHeight > 0) - { - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glViewport(0, 0, clientWidth, clientHeight); - - int letterboxX, letterboxY, letterboxWidth, letterboxHeight; - GetLetterboxFrame(letterboxX, letterboxY, letterboxWidth, letterboxHeight); - DrawLetterbox(letterboxX, letterboxY, letterboxWidth, letterboxHeight); - glViewport(letterboxX, letterboxY, letterboxWidth, letterboxHeight); - - FBVERTEX verts[4]; - CalcFullscreenCoords(verts, false, 0, 0xFFFFFFFF); - SetTexture(0, OutputFB->Texture.get()); - - if (ViewportLinearScale()) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } - else - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - } - - SetPixelShader(Shaders[SHADER_GammaCorrection].get()); - SetAlphaBlend(0); - EnableAlphaTest(false); - DrawTriangleFans(2, verts); - } - - SwapBuffers(); - Debug->Update(); - - float screensize[4] = { (float)Width, (float)Height, 1.0f, 1.0f }; - SetPixelShaderConstantF(PSCONST_ScreenSize, screensize, 1); - - glBindFramebuffer(GL_FRAMEBUFFER, OutputFB->Framebuffer); - glViewport(0, 0, Width, Height); -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: SetInitialState -// -// Called after initial device creation and reset, when everything is set -// to OpenGL's defaults. -// -//========================================================================== - -void OpenGLSWFrameBuffer::SetInitialState() -{ - if (gl.es) UseMappedMemBuffer = false; - - AlphaBlendEnabled = false; - AlphaBlendOp = GL_FUNC_ADD; - AlphaSrcBlend = 0; - AlphaDestBlend = 0; - - CurPixelShader = nullptr; - memset(Constant, 0, sizeof(Constant)); - - for (unsigned i = 0; i < countof(Texture); ++i) - { - Texture[i] = nullptr; - SamplerWrapS[i] = GL_CLAMP_TO_EDGE; - SamplerWrapT[i] = GL_CLAMP_TO_EDGE; - } - - NeedGammaUpdate = true; - NeedPalUpdate = true; - - // This constant is used for grayscaling weights (.xyz) and color inversion (.w) - float weights[4] = { 77 / 256.f, 143 / 256.f, 37 / 256.f, 1 }; - SetPixelShaderConstantF(PSCONST_Weights, weights, 1); - - float screensize[4] = { (float)Width, (float)Height, 1.0f, 1.0f }; - SetPixelShaderConstantF(PSCONST_ScreenSize, screensize, 1); - - AlphaTestEnabled = false; - - CurBorderColor = 0; - - // Clear to black, just in case it wasn't done already. - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: CreateResources -// -//========================================================================== - -bool OpenGLSWFrameBuffer::CreateResources() -{ - Atlases = nullptr; - if (!LoadShaders()) - return false; - - OutputFB = CreateFrameBuffer("OutputFB", Width, Height); - if (!OutputFB) - return false; - - glBindFramebuffer(GL_FRAMEBUFFER, OutputFB->Framebuffer); - - if (!CreateFBTexture() || - !CreatePaletteTexture()) - { - return false; - } - if (!CreateVertexes()) - { - return false; - } - return true; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: LoadShaders -// -// Returns true if all required shaders were loaded. (Gamma and burn wipe -// are the only ones not considered "required".) -// -//========================================================================== - -bool OpenGLSWFrameBuffer::LoadShaders() -{ - int lumpvert = Wads.CheckNumForFullName("shaders/glsl/swshader.vp"); - int lumpfrag = Wads.CheckNumForFullName("shaders/glsl/swshader.fp"); - if (lumpvert < 0 || lumpfrag < 0) - return false; - - FString vertsource = Wads.ReadLump(lumpvert).GetString(); - FString fragsource = Wads.ReadLump(lumpfrag).GetString(); - - FString shaderdir, shaderpath; - unsigned int i; - - for (i = 0; i < NUM_SHADERS; ++i) - { - shaderpath = shaderdir; - Shaders[i] = CreatePixelShader(vertsource, fragsource, ShaderDefines[i]); - if (!Shaders[i] && i < SHADER_BurnWipe) - { - break; - } - - glUseProgram(Shaders[i]->Program); - if (Shaders[i]->ImageLocation != -1) glUniform1i(Shaders[i]->ImageLocation, 0); - if (Shaders[i]->PaletteLocation != -1) glUniform1i(Shaders[i]->PaletteLocation, 1); - if (Shaders[i]->NewScreenLocation != -1) glUniform1i(Shaders[i]->NewScreenLocation, 0); - if (Shaders[i]->BurnLocation != -1) glUniform1i(Shaders[i]->BurnLocation, 1); - glUseProgram(0); - } - if (i == NUM_SHADERS) - { // Success! - return true; - } - // Failure. Release whatever managed to load (which is probably nothing.) - for (i = 0; i < NUM_SHADERS; ++i) - { - Shaders[i].reset(); - } - return false; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: ReleaseResources -// -//========================================================================== - -void OpenGLSWFrameBuffer::ReleaseResources() -{ -#ifdef WIN32 - I_SaveWindowedPos(); -#endif - KillNativeTexs(); - KillNativePals(); - ReleaseDefaultPoolItems(); - ScreenshotTexture.reset(); - PaletteTexture.reset(); - for (int i = 0; i < NUM_SHADERS; ++i) - { - Shaders[i].reset(); - } - if (ScreenWipe != nullptr) - { - delete ScreenWipe; - ScreenWipe = nullptr; - } - Atlas *pack, *next; - for (pack = Atlases; pack != nullptr; pack = next) - { - next = pack->Next; - delete pack; - } - GatheringWipeScreen = false; -} - -void OpenGLSWFrameBuffer::ReleaseDefaultPoolItems() -{ - FBTexture.reset(); - FinalWipeScreen.reset(); - InitialWipeScreen.reset(); - VertexBuffer.reset(); - IndexBuffer.reset(); - OutputFB.reset(); -} - -bool OpenGLSWFrameBuffer::Reset() -{ - ReleaseDefaultPoolItems(); - - OutputFB = CreateFrameBuffer("OutputFB", Width, Height); - if (!OutputFB || !CreateFBTexture() || !CreateVertexes()) - { - return false; - } - - glBindFramebuffer(GL_FRAMEBUFFER, OutputFB->Framebuffer); - glViewport(0, 0, Width, Height); - - SetInitialState(); - return true; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: KillNativePals -// -// Frees all native palettes. -// -//========================================================================== - -void OpenGLSWFrameBuffer::KillNativePals() -{ - while (Palettes != nullptr) - { - delete Palettes; - } -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: KillNativeTexs -// -// Frees all native textures. -// -//========================================================================== - -void OpenGLSWFrameBuffer::KillNativeTexs() -{ - while (Textures != nullptr) - { - delete Textures; - } -} - -bool OpenGLSWFrameBuffer::CreateFBTexture() -{ - FBTexture = CreateTexture("FBTexture", Width, Height, 1, IsBgra() ? GL_RGBA8 : GL_R8); - return FBTexture != nullptr; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: CreatePaletteTexture -// -//========================================================================== - -bool OpenGLSWFrameBuffer::CreatePaletteTexture() -{ - PaletteTexture = CreateTexture("PaletteTexture", 256, 1, 1, GL_RGBA8); - return PaletteTexture != nullptr; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: CreateVertexes -// -//========================================================================== - -bool OpenGLSWFrameBuffer::CreateVertexes() -{ - VertexPos = -1; - IndexPos = -1; - QuadBatchPos = -1; - BatchType = BATCH_None; - VertexBuffer = CreateVertexBuffer(sizeof(FBVERTEX)*NUM_VERTS); - if (!VertexBuffer) - { - return false; - } - IndexBuffer = CreateIndexBuffer(sizeof(uint16_t)*NUM_INDEXES); - if (!IndexBuffer) - { - return false; - } - return true; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: CalcFullscreenCoords -// -//========================================================================== - -void OpenGLSWFrameBuffer::CalcFullscreenCoords(FBVERTEX verts[4], bool viewarea_only, uint32_t color0, uint32_t color1) const -{ - float mxl, mxr, myt, myb, tmxl, tmxr, tmyt, tmyb; - - if (viewarea_only) - { // Just calculate vertices for the viewarea/BlendingRect - mxl = float(BlendingRect.left); - mxr = float(BlendingRect.right); - myt = float(BlendingRect.top); - myb = float(BlendingRect.bottom); - tmxl = float(BlendingRect.left) / float(Width); - tmxr = float(BlendingRect.right) / float(Width); - tmyt = float(BlendingRect.top) / float(Height); - tmyb = float(BlendingRect.bottom) / float(Height); - } - else - { // Calculate vertices for the whole screen - mxl = 0.0f; - mxr = float(Width); - myt = 0.0f; - myb = float(Height); - tmxl = 0; - tmxr = 1.0f; - tmyt = 0; - tmyb = 1.0f; - } - - //{ mxl, myt, 0, 1, 0, 0xFFFFFFFF, tmxl, tmyt }, - //{ mxr, myt, 0, 1, 0, 0xFFFFFFFF, tmxr, tmyt }, - //{ mxr, myb, 0, 1, 0, 0xFFFFFFFF, tmxr, tmyb }, - //{ mxl, myb, 0, 1, 0, 0xFFFFFFFF, tmxl, tmyb }, - - verts[0].x = mxl; - verts[0].y = myt; - verts[0].z = 0; - verts[0].rhw = 1; - verts[0].color0 = color0; - verts[0].color1 = color1; - verts[0].tu = tmxl; - verts[0].tv = tmyt; - - verts[1].x = mxr; - verts[1].y = myt; - verts[1].z = 0; - verts[1].rhw = 1; - verts[1].color0 = color0; - verts[1].color1 = color1; - verts[1].tu = tmxr; - verts[1].tv = tmyt; - - verts[2].x = mxr; - verts[2].y = myb; - verts[2].z = 0; - verts[2].rhw = 1; - verts[2].color0 = color0; - verts[2].color1 = color1; - verts[2].tu = tmxr; - verts[2].tv = tmyb; - - verts[3].x = mxl; - verts[3].y = myb; - verts[3].z = 0; - verts[3].rhw = 1; - verts[3].color0 = color0; - verts[3].color1 = color1; - verts[3].tu = tmxl; - verts[3].tv = tmyb; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: GetPageCount -// -//========================================================================== - -int OpenGLSWFrameBuffer::GetPageCount() -{ - return 2; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: IsValid -// -//========================================================================== - -bool OpenGLSWFrameBuffer::IsValid() -{ - return Valid; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: Lock -// -//========================================================================== - -bool OpenGLSWFrameBuffer::Lock(bool buffered) -{ - if (m_Lock++ > 0) - { - return false; - } - assert(!In2D); - Accel2D = vid_hw2d; - if (UseMappedMemBuffer) - { - if (!MappedMemBuffer) - { - BindFBBuffer(); - - MappedMemBuffer = glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE); - Pitch = Width; - if (MappedMemBuffer == nullptr) - return true; - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - } - Buffer = (uint8_t*)MappedMemBuffer; - } - else - { - Buffer = MemBuffer; - } - return false; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: Unlock -// -//========================================================================== - -void OpenGLSWFrameBuffer::Unlock() -{ - if (m_Lock == 0) - { - return; - } - - if (UpdatePending && m_Lock == 1) - { - Update(); - } - else if (--m_Lock == 0) - { - Buffer = nullptr; - - if (MappedMemBuffer) - { - BindFBBuffer(); - glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - MappedMemBuffer = nullptr; - } - } -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: Update -// -// When In2D == 0: Copy buffer to screen and present -// When In2D == 1: Copy buffer to screen but do not present -// When In2D == 2: Set up for 2D drawing but do not draw anything -// When In2D == 3: Present and set In2D to 0 -// -//========================================================================== - -void OpenGLSWFrameBuffer::Update() -{ - if (In2D == 3) - { - if (InScene) - { - DrawRateStuff(); - DrawPackedTextures(gl_showpacks); - EndBatch(); // Make sure all batched primitives are drawn. - Flip(); - } - In2D = 0; - return; - } - - if (m_Lock != 1) - { - I_FatalError("Framebuffer must have exactly 1 lock to be updated"); - if (m_Lock > 0) - { - UpdatePending = true; - --m_Lock; - } - return; - } - - if (In2D == 0) - { - DrawRateStuff(); - } - - if (NeedGammaUpdate) - { - float psgamma[4]; - float igamma; - - NeedGammaUpdate = false; - igamma = 1 / Gamma; - if (IsFullscreen()) - { - GammaRamp ramp; - - for (int i = 0; i < 256; ++i) - { - ramp.blue[i] = ramp.green[i] = ramp.red[i] = uint16_t(65535.f * powf(i / 255.f, igamma)); - } - SetGammaRamp(&ramp); - } - psgamma[2] = psgamma[1] = psgamma[0] = igamma; - psgamma[3] = 0.5; // For SM14 version - SetPixelShaderConstantF(PSCONST_Gamma, psgamma, 1); - } - - if (NeedPalUpdate) - { - UploadPalette(); - NeedPalUpdate = false; - } - -#ifdef WIN32 - BlitCycles.Reset(); - BlitCycles.Clock(); -#endif - - m_Lock = 0; - Draw3DPart(In2D <= 1); - if (In2D == 0) - { - Flip(); - } - -#ifdef WIN32 - BlitCycles.Unclock(); - //LOG1 ("cycles = %d\n", BlitCycles); -#endif - - Buffer = nullptr; - UpdatePending = false; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: Flip -// -//========================================================================== - -void OpenGLSWFrameBuffer::Flip() -{ - assert(InScene); - - Present(); - InScene = false; - - if (!IsFullscreen()) - { - int clientWidth = ViewportScaledWidth(GetClientWidth(), GetClientHeight()); - int clientHeight = ViewportScaledHeight(GetClientWidth(), GetClientHeight()); - if (clientWidth > 0 && clientHeight > 0 && (Width != clientWidth || Height != clientHeight)) - { - Resize(clientWidth, clientHeight); - - TrueHeight = Height; - PixelDoubling = 0; - Reset(); - - V_OutputResized(Width, Height); - } - } -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: PaintToWindow -// -//========================================================================== - -#ifdef WIN32 - -bool OpenGLSWFrameBuffer::PaintToWindow() -{ - if (m_Lock != 0) - { - return false; - } - Draw3DPart(true); - return true; -} - -#endif - -//========================================================================== -// -// OpenGLSWFrameBuffer :: Draw3DPart -// -// The software 3D part, to be exact. -// -//========================================================================== - -void OpenGLSWFrameBuffer::BindFBBuffer() -{ - int usage = UseMappedMemBuffer ? GL_DYNAMIC_DRAW : GL_STREAM_DRAW; - - int pixelsize = IsBgra() ? 4 : 1; - int size = Width * Height * pixelsize; - - if (FBTexture->Buffers[0] == 0) - { - glGenBuffers(2, (GLuint*)FBTexture->Buffers); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, FBTexture->Buffers[1]); - glBufferData(GL_PIXEL_UNPACK_BUFFER, size, nullptr, usage); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, FBTexture->Buffers[0]); - glBufferData(GL_PIXEL_UNPACK_BUFFER, size, nullptr, usage); - } - else - { - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, FBTexture->Buffers[FBTexture->CurrentBuffer]); - } -} - -void OpenGLSWFrameBuffer::BgraToRgba(uint32_t *dest, const uint32_t *src, int width, int height, int srcpitch) -{ - for (int y = 0; y < height; y++) - { - for (int x = 0; x < width; x++) - { - uint32_t r = RPART(src[x]); - uint32_t g = GPART(src[x]); - uint32_t b = BPART(src[x]); - uint32_t a = APART(src[x]); - dest[x] = r | (g << 8) | (b << 16) | (a << 24); - } - dest += width; - src += srcpitch; - } -} - -void OpenGLSWFrameBuffer::Draw3DPart(bool copy3d) -{ - if (copy3d) - { - BindFBBuffer(); - FBTexture->CurrentBuffer = (FBTexture->CurrentBuffer + 1) & 1; - - if (!UseMappedMemBuffer) - { - int pixelsize = IsBgra() ? 4 : 1; - int size = Width * Height * pixelsize; - - uint8_t *dest = (uint8_t*)MapBuffer(GL_PIXEL_UNPACK_BUFFER, size); - if (dest) - { - if (gl.es && pixelsize == 4) - { - BgraToRgba((uint32_t*)dest, (const uint32_t *)MemBuffer, Width, Height, Pitch); - } - else if (Pitch == Width) - { - memcpy(dest, MemBuffer, Width * Height * pixelsize); - } - else - { - uint8_t *src = MemBuffer; - for (int y = 0; y < Height; y++) - { - memcpy(dest, src, Width * pixelsize); - dest += Width * pixelsize; - src += Pitch * pixelsize; - } - } - glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); - } - } - else if (MappedMemBuffer) - { - glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); - MappedMemBuffer = nullptr; - } - - GLint oldBinding = 0; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldBinding); - glBindTexture(GL_TEXTURE_2D, FBTexture->Texture); - if (IsBgra()) - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, Width, Height, gl.es ? GL_RGBA : GL_BGRA, GL_UNSIGNED_BYTE, 0); - else - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, Width, Height, GL_RED, GL_UNSIGNED_BYTE, 0); - glBindTexture(GL_TEXTURE_2D, oldBinding); - - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - } - InScene = true; - if (vid_hwaalines) - glEnable(GL_LINE_SMOOTH); - else - glDisable(GL_LINE_SMOOTH); - - SetTexture(0, FBTexture.get()); - SetPaletteTexture(PaletteTexture.get(), 256, BorderColor); - memset(Constant, 0, sizeof(Constant)); - SetAlphaBlend(0); - EnableAlphaTest(false); - if (IsBgra()) - SetPixelShader(Shaders[SHADER_NormalColor].get()); - else - SetPixelShader(Shaders[SHADER_NormalColorPal].get()); - if (copy3d) - { - FBVERTEX verts[4]; - uint32_t color0, color1; - if (Accel2D) - { - auto map = swrenderer::CameraLight::Instance()->ShaderColormap(); - if (map == nullptr) - { - color0 = 0; - color1 = 0xFFFFFFF; - } - else - { - color0 = ColorValue(map->ColorizeStart[0] / 2, map->ColorizeStart[1] / 2, map->ColorizeStart[2] / 2, 0); - color1 = ColorValue(map->ColorizeEnd[0] / 2, map->ColorizeEnd[1] / 2, map->ColorizeEnd[2] / 2, 1); - if (IsBgra()) - SetPixelShader(Shaders[SHADER_SpecialColormap].get()); - else - SetPixelShader(Shaders[SHADER_SpecialColormapPal].get()); - } - } - else - { - color0 = FlashColor0; - color1 = FlashColor1; - } - CalcFullscreenCoords(verts, Accel2D, color0, color1); - DrawTriangleFans(2, verts); - } - if (IsBgra()) - SetPixelShader(Shaders[SHADER_NormalColor].get()); - else - SetPixelShader(Shaders[SHADER_NormalColorPal].get()); -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: DrawLetterbox -// -// Draws the black bars at the top and bottom of the screen for letterboxed -// modes. -// -//========================================================================== - -void OpenGLSWFrameBuffer::DrawLetterbox(int x, int y, int width, int height) -{ - int clientWidth = GetClientWidth(); - int clientHeight = GetClientHeight(); - if (clientWidth == 0 || clientHeight == 0) - return; - - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glEnable(GL_SCISSOR_TEST); - if (y > 0) - { - glScissor(0, 0, clientWidth, y); - glClear(GL_COLOR_BUFFER_BIT); - } - if (clientHeight - y - height > 0) - { - glScissor(0, y + height, clientWidth, clientHeight - y - height); - glClear(GL_COLOR_BUFFER_BIT); - } - if (x > 0) - { - glScissor(0, y, x, height); - glClear(GL_COLOR_BUFFER_BIT); - } - if (clientWidth - x - width > 0) - { - glScissor(x + width, y, clientWidth - x - width, height); - glClear(GL_COLOR_BUFFER_BIT); - } - glDisable(GL_SCISSOR_TEST); -} - -void OpenGLSWFrameBuffer::UploadPalette() -{ - if (PaletteTexture->Buffers[0] == 0) - { - glGenBuffers(2, (GLuint*)PaletteTexture->Buffers); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, PaletteTexture->Buffers[0]); - glBufferData(GL_PIXEL_UNPACK_BUFFER, 256 * 4, nullptr, GL_STREAM_DRAW); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, PaletteTexture->Buffers[1]); - glBufferData(GL_PIXEL_UNPACK_BUFFER, 256 * 4, nullptr, GL_STREAM_DRAW); - - if (gl.es) PaletteTexture->MapBuffer.resize(256 * 4); - } - else - { - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, PaletteTexture->Buffers[PaletteTexture->CurrentBuffer]); - PaletteTexture->CurrentBuffer = (PaletteTexture->CurrentBuffer + 1) & 1; - } - - uint8_t *pix = gl.es ? PaletteTexture->MapBuffer.data() : (uint8_t*)MapBuffer(GL_PIXEL_UNPACK_BUFFER, 256 * 4); - if (pix) - { - int i; - - for (i = 0; i < 256; ++i, pix += 4) - { - pix[0] = SourcePalette[i].b; - pix[1] = SourcePalette[i].g; - pix[2] = SourcePalette[i].r; - pix[3] = (i == 0 ? 0 : 255); - // To let masked textures work, the first palette entry's alpha is 0. - } - pix += 4; - for (; i < 255; ++i, pix += 4) - { - pix[0] = SourcePalette[i].b; - pix[1] = SourcePalette[i].g; - pix[2] = SourcePalette[i].r; - pix[3] = 255; - } - if (gl.es) - { - uint8_t *tempbuffer = PaletteTexture->MapBuffer.data(); - BgraToRgba((uint32_t*)tempbuffer, (const uint32_t *)tempbuffer, 256, 1, 256); - glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, 256 * 4, tempbuffer); - } - else - { - glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); - } - - GLint oldBinding = 0; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldBinding); - glBindTexture(GL_TEXTURE_2D, PaletteTexture->Texture); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 1, gl.es ? GL_RGBA : GL_BGRA, GL_UNSIGNED_BYTE, 0); - glBindTexture(GL_TEXTURE_2D, oldBinding); - BorderColor = ColorXRGB(SourcePalette[255].r, SourcePalette[255].g, SourcePalette[255].b); - } - - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); -} - -PalEntry *OpenGLSWFrameBuffer::GetPalette() -{ - return SourcePalette; -} - -void OpenGLSWFrameBuffer::UpdatePalette() -{ - NeedPalUpdate = true; -} - -bool OpenGLSWFrameBuffer::SetGamma(float gamma) -{ - Gamma = gamma; - NeedGammaUpdate = true; - return true; -} - -bool OpenGLSWFrameBuffer::SetFlash(PalEntry rgb, int amount) -{ - FlashColor = rgb; - FlashAmount = amount; - - // Fill in the constants for the pixel shader to do linear interpolation between the palette and the flash: - float r = rgb.r / 255.f, g = rgb.g / 255.f, b = rgb.b / 255.f, a = amount / 256.f; - FlashColor0 = ColorValue(r * a, g * a, b * a, 0); - a = 1 - a; - FlashColor1 = ColorValue(a, a, a, 1); - return true; -} - -void OpenGLSWFrameBuffer::GetFlash(PalEntry &rgb, int &amount) -{ - rgb = FlashColor; - amount = FlashAmount; -} - -void OpenGLSWFrameBuffer::GetFlashedPalette(PalEntry pal[256]) -{ - memcpy(pal, SourcePalette, 256 * sizeof(PalEntry)); - if (FlashAmount) - { - DoBlending(pal, pal, 256, FlashColor.r, FlashColor.g, FlashColor.b, FlashAmount); - } -} - -void OpenGLSWFrameBuffer::SetVSync(bool vsync) -{ - // Switch to the default frame buffer because Nvidia's driver associates the vsync state with the bound FB object. - GLint oldDrawFramebufferBinding = 0, oldReadFramebufferBinding = 0; - glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldDrawFramebufferBinding); - glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &oldReadFramebufferBinding); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); - glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); - - Super::SetVSync(vsync); - - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, oldDrawFramebufferBinding); - glBindFramebuffer(GL_READ_FRAMEBUFFER, oldReadFramebufferBinding); -} - -void OpenGLSWFrameBuffer::NewRefreshRate() -{ -} - -void OpenGLSWFrameBuffer::SetBlendingRect(int x1, int y1, int x2, int y2) -{ - BlendingRect.left = x1; - BlendingRect.top = y1; - BlendingRect.right = x2; - BlendingRect.bottom = y2; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: GetScreenshotBuffer -// -// Returns a pointer into a surface holding the current screen data. -// -//========================================================================== - -void OpenGLSWFrameBuffer::GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type, float &gamma) -{ - Super::GetScreenshotBuffer(buffer, pitch, color_type, gamma); - /* - LockedRect lrect; - - if (!Accel2D) - { - Super::GetScreenshotBuffer(buffer, pitch, color_type, gamma); - return; - } - buffer = nullptr; - if ((ScreenshotTexture = GetCurrentScreen()) != nullptr) - { - if (!ScreenshotTexture->GetSurfaceLevel(0, &ScreenshotSurface)) - { - delete ScreenshotTexture; - ScreenshotTexture = nullptr; - } - else if (!ScreenshotSurface->LockRect(&lrect, nullptr, false)) - { - delete ScreenshotSurface; - ScreenshotSurface = nullptr; - delete ScreenshotTexture; - ScreenshotTexture = nullptr; - } - else - { - buffer = (const uint8_t *)lrect.pBits; - pitch = lrect.Pitch; - color_type = SS_BGRA; - gamma = Gamma; - } - } - */ -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: ReleaseScreenshotBuffer -// -//========================================================================== - -void OpenGLSWFrameBuffer::ReleaseScreenshotBuffer() -{ - if (m_Lock > 0) - { - Super::ReleaseScreenshotBuffer(); - } - ScreenshotTexture.reset(); -} - -/**************************************************************************/ -/* 2D Stuff */ -/**************************************************************************/ - -//========================================================================== -// -// OpenGLSWFrameBuffer :: DrawPackedTextures -// -// DEBUG: Draws the texture atlases to the screen, starting with the -// 1-based packnum. Ignores atlases that are flagged for use by one -// texture only. -// -//========================================================================== - -void OpenGLSWFrameBuffer::DrawPackedTextures(int packnum) -{ - uint32_t empty_colors[8] = - { - 0x50FF0000, 0x5000FF00, 0x500000FF, 0x50FFFF00, - 0x50FF00FF, 0x5000FFFF, 0x50FF8000, 0x500080FF - }; - Atlas *pack; - int x = 8, y = 8; - - if (packnum <= 0) - { - return; - } - pack = Atlases; - // Find the first texture atlas that is an actual atlas. - while (pack != nullptr && pack->OneUse) - { // Skip textures that aren't used as atlases - pack = pack->Next; - } - // Skip however many atlases we would have otherwise drawn - // until we've skipped of them. - while (pack != nullptr && packnum != 1) - { - if (!pack->OneUse) - { // Skip textures that aren't used as atlases - packnum--; - } - pack = pack->Next; - } - // Draw atlases until we run out of room on the screen. - while (pack != nullptr) - { - if (pack->OneUse) - { // Skip textures that aren't used as atlases - pack = pack->Next; - continue; - } - - AddColorOnlyRect(x - 1, y - 1, 258, 258, ColorXRGB(255, 255, 0)); - int back = 0; - for (PackedTexture *box = pack->UsedList; box != nullptr; box = box->Next) - { - AddColorOnlyQuad( - x + box->Area.left * 256 / pack->Width, - y + box->Area.top * 256 / pack->Height, - (box->Area.right - box->Area.left) * 256 / pack->Width, - (box->Area.bottom - box->Area.top) * 256 / pack->Height, empty_colors[back]); - back = (back + 1) & 7; - } - // AddColorOnlyQuad(x, y-LBOffsetI, 256, 256, ColorARGB(180,0,0,0)); - - CheckQuadBatch(); - - BufferedTris *quad = &QuadExtra[QuadBatchPos]; - FBVERTEX *vert = &VertexData[VertexPos]; - - quad->ClearSetup(); - if (pack->Format == GL_R8/* && !tex->IsGray*/) - { - quad->Flags = BQF_WrapUV | BQF_GamePalette/* | BQF_DisableAlphaTest*/; - quad->ShaderNum = BQS_PalTex; - } - else - { - quad->Flags = BQF_WrapUV/* | BQF_DisableAlphaTest*/; - quad->ShaderNum = BQS_Plain; - } - quad->Palette = nullptr; - quad->Texture = pack->Tex.get(); - quad->NumVerts = 4; - quad->NumTris = 2; - - float x0 = float(x); - float y0 = float(y); - float x1 = x0 + 256.f; - float y1 = y0 + 256.f; - - vert[0].x = x0; - vert[0].y = y0; - vert[0].z = 0; - vert[0].rhw = 1; - vert[0].color0 = 0; - vert[0].color1 = 0xFFFFFFFF; - vert[0].tu = 0; - vert[0].tv = 0; - - vert[1].x = x1; - vert[1].y = y0; - vert[1].z = 0; - vert[1].rhw = 1; - vert[1].color0 = 0; - vert[1].color1 = 0xFFFFFFFF; - vert[1].tu = 1; - vert[1].tv = 0; - - vert[2].x = x1; - vert[2].y = y1; - vert[2].z = 0; - vert[2].rhw = 1; - vert[2].color0 = 0; - vert[2].color1 = 0xFFFFFFFF; - vert[2].tu = 1; - vert[2].tv = 1; - - vert[3].x = x0; - vert[3].y = y1; - vert[3].z = 0; - vert[3].rhw = 1; - vert[3].color0 = 0; - vert[3].color1 = 0xFFFFFFFF; - vert[3].tu = 0; - vert[3].tv = 1; - - IndexData[IndexPos] = VertexPos; - IndexData[IndexPos + 1] = VertexPos + 1; - IndexData[IndexPos + 2] = VertexPos + 2; - IndexData[IndexPos + 3] = VertexPos; - IndexData[IndexPos + 4] = VertexPos + 2; - IndexData[IndexPos + 5] = VertexPos + 3; - - QuadBatchPos++; - VertexPos += 4; - IndexPos += 6; - - x += 256 + 8; - if (x > Width - 256) - { - x = 8; - y += 256 + 8; - if (y > Height - 256) - { - return; - } - } - pack = pack->Next; - } -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: AllocPackedTexture -// -// Finds space to pack an image inside a texture atlas and returns it. -// Large images and those that need to wrap always get their own textures. -// -//========================================================================== - -OpenGLSWFrameBuffer::PackedTexture *OpenGLSWFrameBuffer::AllocPackedTexture(int w, int h, bool wrapping, int format) -{ - Atlas *pack; - Rect box; - bool padded; - - // The - 2 to account for padding - if (w > 256 - 2 || h > 256 - 2 || wrapping) - { // Create a new texture atlas. - pack = new Atlas(this, w, h, format); - pack->OneUse = true; - box = pack->Packer.Insert(w, h); - padded = false; - } - else - { // Try to find space in an existing texture atlas. - w += 2; // Add padding - h += 2; - for (pack = Atlases; pack != nullptr; pack = pack->Next) - { - // Use the first atlas it fits in. - if (pack->Format == format) - { - box = pack->Packer.Insert(w, h); - if (box.width != 0) - { - break; - } - } - } - if (pack == nullptr) - { // Create a new texture atlas. - pack = new Atlas(this, DEF_ATLAS_WIDTH, DEF_ATLAS_HEIGHT, format); - box = pack->Packer.Insert(w, h); - } - padded = true; - } - assert(box.width != 0 && box.height != 0); - return pack->AllocateImage(box, padded); -} - -//========================================================================== -// -// Atlas Constructor -// -//========================================================================== - -OpenGLSWFrameBuffer::Atlas::Atlas(OpenGLSWFrameBuffer *fb, int w, int h, int format) - : Packer(w, h, true) -{ - Format = format; - UsedList = nullptr; - OneUse = false; - Width = 0; - Height = 0; - Next = nullptr; - - // Attach to the end of the atlas list - Atlas **prev = &fb->Atlases; - while (*prev != nullptr) - { - prev = &((*prev)->Next); - } - *prev = this; - - Tex = fb->CreateTexture("Atlas", w, h, 1, format); - Width = w; - Height = h; -} - -//========================================================================== -// -// Atlas Destructor -// -//========================================================================== - -OpenGLSWFrameBuffer::Atlas::~Atlas() -{ - PackedTexture *box, *next; - - Tex.reset(); - for (box = UsedList; box != nullptr; box = next) - { - next = box->Next; - delete box; - } -} - -//========================================================================== -// -// Atlas :: AllocateImage -// -// Moves the box from the empty list to the used list, sizing it to the -// requested dimensions and adding additional boxes to the empty list if -// needed. -// -// The passed box *MUST* be in this texture atlas's empty list. -// -//========================================================================== - -OpenGLSWFrameBuffer::PackedTexture *OpenGLSWFrameBuffer::Atlas::AllocateImage(const Rect &rect, bool padded) -{ - PackedTexture *box = new PackedTexture; - - box->Owner = this; - box->Area.left = rect.x; - box->Area.top = rect.y; - box->Area.right = rect.x + rect.width; - box->Area.bottom = rect.y + rect.height; - - box->Left = float(box->Area.left + padded) / Width; - box->Right = float(box->Area.right - padded) / Width; - box->Top = float(box->Area.top + padded) / Height; - box->Bottom = float(box->Area.bottom - padded) / Height; - - box->Padded = padded; - - // Add it to the used list. - box->Next = UsedList; - if (box->Next != nullptr) - { - box->Next->Prev = &box->Next; - } - UsedList = box; - box->Prev = &UsedList; - - return box; -} - -//========================================================================== -// -// Atlas :: FreeBox -// -// Removes a box from the used list and deletes it. Space is returned to the -// waste list. Once all boxes for this atlas are freed, the entire bin -// packer is reinitialized for maximum efficiency. -// -//========================================================================== - -void OpenGLSWFrameBuffer::Atlas::FreeBox(OpenGLSWFrameBuffer::PackedTexture *box) -{ - *(box->Prev) = box->Next; - if (box->Next != nullptr) - { - box->Next->Prev = box->Prev; - } - Rect waste; - waste.x = box->Area.left; - waste.y = box->Area.top; - waste.width = box->Area.right - box->Area.left; - waste.height = box->Area.bottom - box->Area.top; - box->Owner->Packer.AddWaste(waste); - delete box; - if (UsedList == nullptr) - { - Packer.Init(Width, Height, true); - } -} - -//========================================================================== -// -// OpenGLTex Constructor -// -//========================================================================== - -OpenGLSWFrameBuffer::OpenGLTex::OpenGLTex(FTexture *tex, FTextureFormat fmt, OpenGLSWFrameBuffer *fb, bool wrapping) - : FNativeTexture(tex, fmt) -{ - // Attach to the texture list for the OpenGLSWFrameBuffer - Next = fb->Textures; - if (Next != nullptr) - { - Next->Prev = &Next; - } - Prev = &fb->Textures; - fb->Textures = this; - - GameTex = tex; - Box = nullptr; - IsGray = false; - - Create(fb, wrapping); -} - -//========================================================================== -// -// OpenGLTex Destructor -// -//========================================================================== - -OpenGLSWFrameBuffer::OpenGLTex::~OpenGLTex() -{ - if (Box != nullptr) - { - Box->Owner->FreeBox(Box); - Box = nullptr; - } - // Detach from the texture list - *Prev = Next; - if (Next != nullptr) - { - Next->Prev = Prev; - } - // Remove link from the game texture - if (GameTex != nullptr) - { - mGameTex->Native[mFormat] = nullptr; - } -} - -//========================================================================== -// -// OpenGLTex :: CheckWrapping -// -// Returns true if the texture is compatible with the specified wrapping -// mode. -// -//========================================================================== - -bool OpenGLSWFrameBuffer::OpenGLTex::CheckWrapping(bool wrapping) -{ - // If it doesn't need to wrap, then it works. - if (!wrapping) - { - return true; - } - // If it needs to wrap, then it can't be packed inside another texture. - return Box->Owner->OneUse; -} - -//========================================================================== -// -// OpenGLTex :: Create -// -// Creates an HWTexture for the texture and copies the image data -// to it. Note that unlike FTexture, this image is row-major. -// -//========================================================================== - -bool OpenGLSWFrameBuffer::OpenGLTex::Create(OpenGLSWFrameBuffer *fb, bool wrapping) -{ - assert(Box == nullptr); - if (Box != nullptr) - { - Box->Owner->FreeBox(Box); - } - - Box = fb->AllocPackedTexture(GameTex->GetWidth(), GameTex->GetHeight(), wrapping, GetTexFormat()); - - if (Box == nullptr) - { - return false; - } - if (!Update()) - { - Box->Owner->FreeBox(Box); - Box = nullptr; - return false; - } - return true; -} - -//========================================================================== -// -// OpenGLTex :: Update -// -// Copies image data from the underlying FTexture to the OpenGL texture. -// -//========================================================================== - -bool OpenGLSWFrameBuffer::OpenGLTex::Update() -{ - LTRBRect rect; - uint8_t *dest; - - assert(Box != nullptr); - assert(Box->Owner != nullptr); - assert(Box->Owner->Tex != nullptr); - assert(GameTex != nullptr); - - int format = Box->Owner->Tex->Format; - - rect = Box->Area; - - if (Box->Owner->Tex->Buffers[0] == 0) - glGenBuffers(2, (GLuint*)Box->Owner->Tex->Buffers); - - int bytesPerPixel = 4; - switch (format) - { - case GL_R8: bytesPerPixel = 1; break; - case GL_RGBA8: bytesPerPixel = 4; break; - default: return false; - } - - int buffersize = (rect.right - rect.left) * (rect.bottom - rect.top) * bytesPerPixel; - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, Box->Owner->Tex->Buffers[Box->Owner->Tex->CurrentBuffer]); - glBufferData(GL_PIXEL_UNPACK_BUFFER, buffersize, nullptr, GL_STREAM_DRAW); - Box->Owner->Tex->CurrentBuffer = (Box->Owner->Tex->CurrentBuffer + 1) & 1; - - static std::vector tempbuffer; - if (gl.es) - tempbuffer.resize(buffersize); - - int pitch = (rect.right - rect.left) * bytesPerPixel; - uint8_t *bits = gl.es ? tempbuffer.data() : (uint8_t *)MapBuffer(GL_PIXEL_UNPACK_BUFFER, buffersize); - dest = bits; - if (!dest) - { - return false; - } - if (Box->Padded) - { - dest += pitch + (format == GL_R8 ? 1 : 4); - } - GameTex->FillBuffer(dest, pitch, GameTex->GetHeight(), mFormat); - if (Box->Padded) - { - // Clear top padding row. - dest = bits; - int numbytes = GameTex->GetWidth() + 2; - if (format != GL_R8) - { - numbytes <<= 2; - } - memset(dest, 0, numbytes); - dest += pitch; - // Clear left and right padding columns. - if (format == GL_R8) - { - for (int y = Box->Area.bottom - Box->Area.top - 2; y > 0; --y) - { - dest[0] = 0; - dest[numbytes - 1] = 0; - dest += pitch; - } - } - else - { - for (int y = Box->Area.bottom - Box->Area.top - 2; y > 0; --y) - { - *(uint32_t *)dest = 0; - *(uint32_t *)(dest + numbytes - 4) = 0; - dest += pitch; - } - } - // Clear bottom padding row. - memset(dest, 0, numbytes); - } - - if (gl.es && format == GL_RGBA8) - { - BgraToRgba((uint32_t*)bits, (const uint32_t *)bits, rect.right - rect.left, rect.bottom - rect.top, rect.right - rect.left); - } - - if (gl.es) - glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, buffersize, bits); - else - glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); - GLint oldBinding = 0; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldBinding); - glBindTexture(GL_TEXTURE_2D, Box->Owner->Tex->Texture); - if (format == GL_RGBA8) - glTexSubImage2D(GL_TEXTURE_2D, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, gl.es ? GL_RGBA : GL_BGRA, GL_UNSIGNED_BYTE, 0); - else - glTexSubImage2D(GL_TEXTURE_2D, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, GL_RED, GL_UNSIGNED_BYTE, 0); - glBindTexture(GL_TEXTURE_2D, oldBinding); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - return true; -} - -//========================================================================== -// -// OpenGLTex :: GetTexFormat -// -// Returns the texture format that would best fit this texture. -// -//========================================================================== - -int OpenGLSWFrameBuffer::OpenGLTex::GetTexFormat() -{ - IsGray = false; - - switch (mFormat) - { - case TEX_Pal: return GL_R8; - case TEX_Gray: IsGray = true; return GL_R8; - case TEX_RGB: return GL_RGBA8; -#if 0 - case TEX_DXT1: return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; - case TEX_DXT2: return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; - case TEX_DXT3: return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; - case TEX_DXT4: return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; // Doesn't exist in OpenGL. Closest match is DXT5. - case TEX_DXT5: return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; -#endif - default: I_FatalError("GameTex->GetFormat() returned invalid format."); - } - return GL_R8; -} - -//========================================================================== -// -// OpenGLPal Constructor -// -//========================================================================== - -OpenGLSWFrameBuffer::OpenGLPal::OpenGLPal(FRemapTable *remap, OpenGLSWFrameBuffer *fb) - : Remap(remap) -{ - int count; - - // Attach to the palette list for the OpenGLSWFrameBuffer - Next = fb->Palettes; - if (Next != nullptr) - { - Next->Prev = &Next; - } - Prev = &fb->Palettes; - fb->Palettes = this; - - int pow2count; - - // Round up to the nearest power of 2. - for (pow2count = 1; pow2count < remap->NumEntries; pow2count <<= 1) - { - } - count = pow2count; - DoColorSkip = false; - - BorderColor = 0; - RoundedPaletteSize = count; - Tex = fb->CreateTexture("Pal", count, 1, 1, GL_RGBA8); - if (Tex) - { - if (!Update()) - { - Tex.reset(); - } - } -} - -//========================================================================== -// -// OpenGLPal Destructor -// -//========================================================================== - -OpenGLSWFrameBuffer::OpenGLPal::~OpenGLPal() -{ - Tex.reset(); - // Detach from the palette list - *Prev = Next; - if (Next != nullptr) - { - Next->Prev = Prev; - } - // Remove link from the remap table - if (Remap != nullptr) - { - Remap->Native = nullptr; - } -} - -//========================================================================== -// -// OpenGLPal :: Update -// -// Copies the palette to the texture. -// -//========================================================================== - -bool OpenGLSWFrameBuffer::OpenGLPal::Update() -{ - uint32_t *buff; - const PalEntry *pal; - int skipat, i; - - assert(Tex != nullptr); - - if (Tex->Buffers[0] == 0) - { - glGenBuffers(2, (GLuint*)Tex->Buffers); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, Tex->Buffers[0]); - glBufferData(GL_PIXEL_UNPACK_BUFFER, RoundedPaletteSize * 4, nullptr, GL_STREAM_DRAW); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, Tex->Buffers[1]); - glBufferData(GL_PIXEL_UNPACK_BUFFER, RoundedPaletteSize * 4, nullptr, GL_STREAM_DRAW); - } - else - { - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, Tex->Buffers[Tex->CurrentBuffer]); - Tex->CurrentBuffer = (Tex->CurrentBuffer + 1) & 1; - } - - int numEntries = MIN(Remap->NumEntries, RoundedPaletteSize); - - std::vector &tempbuffer = Tex->MapBuffer; - if (gl.es) - tempbuffer.resize(numEntries * 4); - - buff = gl.es ? (uint32_t*)tempbuffer.data() : (uint32_t *)MapBuffer(GL_PIXEL_UNPACK_BUFFER, numEntries * 4); - if (buff == nullptr) - { - return false; - } - pal = Remap->Palette; - - // See explanation in UploadPalette() for skipat rationale. - skipat = MIN(numEntries, DoColorSkip ? 256 - 8 : 256); - -#ifndef NO_SSE - // Manual SSE vectorized version here to workaround a bug in GCC's auto-vectorizer - - int sse_count = skipat / 4 * 4; - for (i = 0; i < sse_count; i += 4) - { - _mm_storeu_si128((__m128i*)(&buff[i]), _mm_loadu_si128((__m128i*)(&pal[i]))); - } - switch (skipat - i) - { - // fall through is intentional - case 3: buff[i] = pal[i].d; i++; - case 2: buff[i] = pal[i].d; i++; - case 1: buff[i] = pal[i].d; i++; - default: i++; - } - sse_count = numEntries / 4 * 4; - __m128i alphamask = _mm_set1_epi32(0xff000000); - while (i < sse_count) - { - __m128i lastcolor = _mm_loadu_si128((__m128i*)(&pal[i - 1])); - __m128i color = _mm_loadu_si128((__m128i*)(&pal[i])); - _mm_storeu_si128((__m128i*)(&buff[i]), _mm_or_si128(_mm_and_si128(alphamask, color), _mm_andnot_si128(alphamask, lastcolor))); - i += 4; - } - switch (numEntries - i) - { - // fall through is intentional - case 3: buff[i] = ColorARGB(pal[i].a, pal[i - 1].r, pal[i - 1].g, pal[i - 1].b); i++; - case 2: buff[i] = ColorARGB(pal[i].a, pal[i - 1].r, pal[i - 1].g, pal[i - 1].b); i++; - case 1: buff[i] = ColorARGB(pal[i].a, pal[i - 1].r, pal[i - 1].g, pal[i - 1].b); i++; - default: break; - } - -#else - for (i = 0; i < skipat; ++i) - { - buff[i] = ColorARGB(pal[i].a, pal[i].r, pal[i].g, pal[i].b); - } - for (++i; i < numEntries; ++i) - { - buff[i] = ColorARGB(pal[i].a, pal[i - 1].r, pal[i - 1].g, pal[i - 1].b); - } -#endif - if (numEntries > 1) - { - i = numEntries - 1; - BorderColor = ColorARGB(pal[i].a, pal[i - 1].r, pal[i - 1].g, pal[i - 1].b); - } - - if (gl.es) - { - BgraToRgba((uint32_t*)buff, (const uint32_t *)buff, numEntries, 1, numEntries); - glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, numEntries * 4, buff); - } - else - { - glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); - } - - GLint oldBinding = 0; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldBinding); - glBindTexture(GL_TEXTURE_2D, Tex->Texture); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, numEntries, 1, gl.es ? GL_RGBA : GL_BGRA, GL_UNSIGNED_BYTE, 0); - glBindTexture(GL_TEXTURE_2D, oldBinding); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - - return true; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: Begin2D -// -// Begins 2D mode drawing operations. In particular, DrawTexture is -// rerouted to use Direct3D instead of the software renderer. -// -//========================================================================== - -bool OpenGLSWFrameBuffer::Begin2D(bool copy3d) -{ - Super::Begin2D(copy3d); - if (!Accel2D) - { - return false; - } - if (In2D) - { - return true; - } - In2D = 2 - copy3d; - Update(); - In2D = 3; - - return true; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: DrawBlendingRect -// -// Call after Begin2D to blend the 3D view. -// -//========================================================================== - -void OpenGLSWFrameBuffer::DrawBlendingRect() -{ - if (!In2D || !Accel2D) - { - return; - } - Dim(FlashColor, FlashAmount / 256.f, viewwindowx, viewwindowy, viewwidth, viewheight); -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: CreateTexture -// -// Returns a native texture that wraps a FTexture. -// -//========================================================================== - -FNativeTexture *OpenGLSWFrameBuffer::CreateTexture(FTexture *gametex, FTextureFormat fmt, bool wrapping) -{ - OpenGLTex *tex = new OpenGLTex(gametex, fmt, this, wrapping); - if (tex->Box == nullptr) - { - delete tex; - return nullptr; - } - return tex; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: CreatePalette -// -// Returns a native texture that contains a palette. -// -//========================================================================== - -FNativePalette *OpenGLSWFrameBuffer::CreatePalette(FRemapTable *remap) -{ - OpenGLPal *tex = new OpenGLPal(remap, this); - if (tex->Tex == nullptr) - { - delete tex; - return nullptr; - } - return tex; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: Clear -// -// Fills the specified region with a color. -// -//========================================================================== - -void OpenGLSWFrameBuffer::DoClear(int left, int top, int right, int bottom, int palcolor, uint32_t color) -{ - if (In2D < 2) - { - Super::DoClear(left, top, right, bottom, palcolor, color); - return; - } - if (!InScene) - { - return; - } - if (palcolor >= 0 && color == 0) - { - color = GPalette.BaseColors[palcolor]; - } - else if (APART(color) < 255) - { - Dim(color, APART(color) / 255.f, left, top, right - left, bottom - top); - return; - } - AddColorOnlyQuad(left, top, right - left, bottom - top, color | 0xFF000000); -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: Dim -// -//========================================================================== - -void OpenGLSWFrameBuffer::DoDim(PalEntry color, float amount, int x1, int y1, int w, int h) -{ - if (amount <= 0) - { - return; - } - if (In2D < 2) - { - Super::DoDim(color, amount, x1, y1, w, h); - return; - } - if (!InScene) - { - return; - } - if (amount > 1) - { - amount = 1; - } - AddColorOnlyQuad(x1, y1, w, h, color | (int(amount * 255) << 24)); -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: BeginLineBatch -// -//========================================================================== - -void OpenGLSWFrameBuffer::BeginLineBatch() -{ - if (In2D < 2 || !InScene || BatchType == BATCH_Lines) - { - return; - } - EndQuadBatch(); // Make sure all quads have been drawn first. - VertexData = VertexBuffer->Lock(); - VertexPos = 0; - BatchType = BATCH_Lines; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: EndLineBatch -// -//========================================================================== - -void OpenGLSWFrameBuffer::EndLineBatch() -{ - if (In2D < 2 || !InScene || BatchType != BATCH_Lines) - { - return; - } - VertexBuffer->Unlock(); - if (VertexPos > 0) - { - SetPixelShader(Shaders[SHADER_VertexColor].get()); - SetAlphaBlend(GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - SetStreamSource(VertexBuffer.get()); - DrawLineList(VertexPos / 2); - } - VertexPos = -1; - BatchType = BATCH_None; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: DrawLine -// -//========================================================================== - -void OpenGLSWFrameBuffer::DrawLine(int x0, int y0, int x1, int y1, int palcolor, uint32_t color) -{ - if (In2D < 2) - { - Super::DrawLine(x0, y0, x1, y1, palcolor, color); - return; - } - if (!InScene) - { - return; - } - if (BatchType != BATCH_Lines) - { - BeginLineBatch(); - } - if (VertexPos == NUM_VERTS) - { // Flush the buffer and refill it. - EndLineBatch(); - BeginLineBatch(); - } - // Add the endpoints to the vertex buffer. - VertexData[VertexPos].x = float(x0); - VertexData[VertexPos].y = float(y0); - VertexData[VertexPos].z = 0; - VertexData[VertexPos].rhw = 1; - VertexData[VertexPos].color0 = color; - VertexData[VertexPos].color1 = 0; - VertexData[VertexPos].tu = 0; - VertexData[VertexPos].tv = 0; - - VertexData[VertexPos + 1].x = float(x1); - VertexData[VertexPos + 1].y = float(y1); - VertexData[VertexPos + 1].z = 0; - VertexData[VertexPos + 1].rhw = 1; - VertexData[VertexPos + 1].color0 = color; - VertexData[VertexPos + 1].color1 = 0; - VertexData[VertexPos + 1].tu = 0; - VertexData[VertexPos + 1].tv = 0; - - VertexPos += 2; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: DrawPixel -// -//========================================================================== - -void OpenGLSWFrameBuffer::DrawPixel(int x, int y, int palcolor, uint32_t color) -{ - if (In2D < 2) - { - Super::DrawPixel(x, y, palcolor, color); - return; - } - if (!InScene) - { - return; - } - FBVERTEX pt = - { - float(x), float(y), 0, 1, color - }; - EndBatch(); // Draw out any batched operations. - SetPixelShader(Shaders[SHADER_VertexColor].get()); - SetAlphaBlend(GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - DrawPoints(1, &pt); -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: DrawTextureV -// -// If not in 2D mode, just call the normal software version. -// If in 2D mode, then use Direct3D calls to perform the drawing. -// -//========================================================================== - -void OpenGLSWFrameBuffer::DrawTextureParms(FTexture *img, DrawParms &parms) -{ - if (In2D < 2) - { - Super::DrawTextureParms(img, parms); - return; - } - if (!InScene) - { - return; - } - - FTextureFormat fmt; - if (parms.style.Flags & STYLEF_RedIsAlpha) fmt = TEX_Gray; - else if (parms.remap != nullptr) fmt = TEX_Pal; - else fmt = img->GetFormat(); - - OpenGLTex *tex = static_cast(img->GetNative(fmt, false)); - - if (tex == nullptr) - { - assert(tex != nullptr); - return; - } - - CheckQuadBatch(); - - double xscale = parms.destwidth / parms.texwidth; - double yscale = parms.destheight / parms.texheight; - double x0 = parms.x - parms.left * xscale; - double y0 = parms.y - parms.top * yscale; - double x1 = x0 + parms.destwidth; - double y1 = y0 + parms.destheight; - float u0 = tex->Box->Left; - float v0 = tex->Box->Top; - float u1 = tex->Box->Right; - float v1 = tex->Box->Bottom; - double uscale = 1.f / tex->Box->Owner->Width; - bool scissoring = false; - FBVERTEX *vert; - - if (parms.flipX) - { - swapvalues(u0, u1); - } - if (parms.windowleft > 0 || parms.windowright < parms.texwidth) - { - double wi = MIN(parms.windowright, parms.texwidth); - x0 += parms.windowleft * xscale; - u0 = float(u0 + parms.windowleft * uscale); - x1 -= (parms.texwidth - wi) * xscale; - u1 = float(u1 - (parms.texwidth - wi) * uscale); - } - -#if 0 - float vscale = 1.f / tex->Box->Owner->Height / yscale; - if (y0 < parms.uclip) - { - v0 += (float(parms.uclip) - y0) * vscale; - y0 = float(parms.uclip); - } - if (y1 > parms.dclip) - { - v1 -= (y1 - float(parms.dclip)) * vscale; - y1 = float(parms.dclip); - } - if (x0 < parms.lclip) - { - u0 += float(parms.lclip - x0) * uscale / xscale * 2; - x0 = float(parms.lclip); - } - if (x1 > parms.rclip) - { - u1 -= (x1 - parms.rclip) * uscale / xscale * 2; - x1 = float(parms.rclip); - } -#else - // Use a scissor test because the math above introduces some jitter - // that is noticeable at low resolutions. Unfortunately, this means this - // quad has to be in a batch by itself. - if (y0 < parms.uclip || y1 > parms.dclip || x0 < parms.lclip || x1 > parms.rclip) - { - scissoring = true; - if (QuadBatchPos > 0) - { - EndQuadBatch(); - BeginQuadBatch(); - } - glEnable(GL_SCISSOR_TEST); - glScissor(parms.lclip, parms.uclip, parms.rclip - parms.lclip, parms.dclip - parms.uclip); - } -#endif - parms.bilinear = false; - - uint32_t color0, color1; - BufferedTris *quad = &QuadExtra[QuadBatchPos]; - - if (!SetStyle(tex, parms, color0, color1, *quad)) - { - goto done; - } - - quad->Texture = tex->Box->Owner->Tex.get(); - if (parms.bilinear) - { - quad->Flags |= BQF_Bilinear; - } - quad->NumTris = 2; - quad->NumVerts = 4; - - vert = &VertexData[VertexPos]; - - { - PalEntry color = color1; - color = PalEntry((color.a * parms.color.a) / 255, (color.r * parms.color.r) / 255, (color.g * parms.color.g) / 255, (color.b * parms.color.b) / 255); - color1 = color; - } - - // Fill the vertex buffer. - vert[0].x = float(x0); - vert[0].y = float(y0); - vert[0].z = 0; - vert[0].rhw = 1; - vert[0].color0 = color0; - vert[0].color1 = color1; - vert[0].tu = u0; - vert[0].tv = v0; - - vert[1].x = float(x1); - vert[1].y = float(y0); - vert[1].z = 0; - vert[1].rhw = 1; - vert[1].color0 = color0; - vert[1].color1 = color1; - vert[1].tu = u1; - vert[1].tv = v0; - - vert[2].x = float(x1); - vert[2].y = float(y1); - vert[2].z = 0; - vert[2].rhw = 1; - vert[2].color0 = color0; - vert[2].color1 = color1; - vert[2].tu = u1; - vert[2].tv = v1; - - vert[3].x = float(x0); - vert[3].y = float(y1); - vert[3].z = 0; - vert[3].rhw = 1; - vert[3].color0 = color0; - vert[3].color1 = color1; - vert[3].tu = u0; - vert[3].tv = v1; - - // Fill the vertex index buffer. - IndexData[IndexPos] = VertexPos; - IndexData[IndexPos + 1] = VertexPos + 1; - IndexData[IndexPos + 2] = VertexPos + 2; - IndexData[IndexPos + 3] = VertexPos; - IndexData[IndexPos + 4] = VertexPos + 2; - IndexData[IndexPos + 5] = VertexPos + 3; - - // Batch the quad. - QuadBatchPos++; - VertexPos += 4; - IndexPos += 6; -done: - if (scissoring) - { - EndQuadBatch(); - glDisable(GL_SCISSOR_TEST); - } -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: FlatFill -// -// Fills an area with a repeating copy of the texture. -// -//========================================================================== - -void OpenGLSWFrameBuffer::FlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin) -{ - if (In2D < 2) - { - Super::FlatFill(left, top, right, bottom, src, local_origin); - return; - } - if (!InScene) - { - return; - } - OpenGLTex *tex = static_cast(src->GetNative(src->GetFormat(), true)); - if (tex == nullptr) - { - return; - } - float x0 = float(left); - float y0 = float(top); - float x1 = float(right); - float y1 = float(bottom); - float itw = 1.f / float(src->GetWidth()); - float ith = 1.f / float(src->GetHeight()); - float xo = local_origin ? x0 : 0; - float yo = local_origin ? y0 : 0; - float u0 = (x0 - xo) * itw; - float v0 = (y0 - yo) * ith; - float u1 = (x1 - xo) * itw; - float v1 = (y1 - yo) * ith; - - CheckQuadBatch(); - - BufferedTris *quad = &QuadExtra[QuadBatchPos]; - FBVERTEX *vert = &VertexData[VertexPos]; - - quad->ClearSetup(); - if (tex->GetTexFormat() == GL_R8 && !tex->IsGray) - { - quad->Flags = BQF_WrapUV | BQF_GamePalette; // | BQF_DisableAlphaTest; - quad->ShaderNum = BQS_PalTex; - } - else - { - quad->Flags = BQF_WrapUV; // | BQF_DisableAlphaTest; - quad->ShaderNum = BQS_Plain; - } - quad->Palette = nullptr; - quad->Texture = tex->Box->Owner->Tex.get(); - quad->NumVerts = 4; - quad->NumTris = 2; - - vert[0].x = x0; - vert[0].y = y0; - vert[0].z = 0; - vert[0].rhw = 1; - vert[0].color0 = 0; - vert[0].color1 = 0xFFFFFFFF; - vert[0].tu = u0; - vert[0].tv = v0; - - vert[1].x = x1; - vert[1].y = y0; - vert[1].z = 0; - vert[1].rhw = 1; - vert[1].color0 = 0; - vert[1].color1 = 0xFFFFFFFF; - vert[1].tu = u1; - vert[1].tv = v0; - - vert[2].x = x1; - vert[2].y = y1; - vert[2].z = 0; - vert[2].rhw = 1; - vert[2].color0 = 0; - vert[2].color1 = 0xFFFFFFFF; - vert[2].tu = u1; - vert[2].tv = v1; - - vert[3].x = x0; - vert[3].y = y1; - vert[3].z = 0; - vert[3].rhw = 1; - vert[3].color0 = 0; - vert[3].color1 = 0xFFFFFFFF; - vert[3].tu = u0; - vert[3].tv = v1; - - IndexData[IndexPos] = VertexPos; - IndexData[IndexPos + 1] = VertexPos + 1; - IndexData[IndexPos + 2] = VertexPos + 2; - IndexData[IndexPos + 3] = VertexPos; - IndexData[IndexPos + 4] = VertexPos + 2; - IndexData[IndexPos + 5] = VertexPos + 3; - - QuadBatchPos++; - VertexPos += 4; - IndexPos += 6; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: FillSimplePoly -// -// Here, "simple" means that a simple triangle fan can draw it. -// -//========================================================================== - -void OpenGLSWFrameBuffer::FillSimplePoly(FTexture *texture, FVector2 *points, int npoints, - double originx, double originy, double scalex, double scaley, - DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel, int bottomclip) -{ - // Use an equation similar to player sprites to determine shade - double fadelevel = clamp((swrenderer::LightVisibility::LightLevelToShade(lightlevel, true) / 65536. - 12) / NUMCOLORMAPS, 0.0, 1.0); - - BufferedTris *quad; - FBVERTEX *verts; - OpenGLTex *tex; - float uscale, vscale; - int i, ipos; - uint32_t color0, color1; - float ox, oy; - float cosrot, sinrot; - bool dorotate = rotation != 0; - - if (npoints < 3) - { // This is no polygon. - return; - } - if (In2D < 2) - { - Super::FillSimplePoly(texture, points, npoints, originx, originy, scalex, scaley, rotation, colormap, lightlevel, flatcolor, bottomclip); - return; - } - if (!InScene) - { - return; - } - tex = static_cast(texture->GetNative(texture->GetFormat(), true)); - if (tex == nullptr) - { - return; - } - - cosrot = (float)cos(rotation.Radians()); - sinrot = (float)sin(rotation.Radians()); - - CheckQuadBatch(npoints - 2, npoints); - quad = &QuadExtra[QuadBatchPos]; - verts = &VertexData[VertexPos]; - - color0 = 0; - color1 = 0xFFFFFFFF; - - quad->ClearSetup(); - if (tex->GetTexFormat() == GL_R8 && !tex->IsGray) - { - quad->Flags = BQF_WrapUV | BQF_GamePalette | BQF_DisableAlphaTest; - quad->ShaderNum = BQS_PalTex; - if (colormap.Desaturation != 0) - { - quad->Flags |= BQF_Desaturated; - } - quad->ShaderNum = BQS_InGameColormap; - quad->Desat = colormap.Desaturation; - color0 = ColorARGB(255, colormap.LightColor.r, colormap.LightColor.g, colormap.LightColor.b); - color1 = ColorARGB(uint32_t((1 - fadelevel) * 255), - uint32_t(colormap.FadeColor.r * fadelevel), - uint32_t(colormap.FadeColor.g * fadelevel), - uint32_t(colormap.FadeColor.b * fadelevel)); - } - else - { - quad->Flags = BQF_WrapUV | BQF_DisableAlphaTest; - quad->ShaderNum = BQS_Plain; - } - quad->Palette = nullptr; - quad->Texture = tex->Box->Owner->Tex.get(); - quad->NumVerts = npoints; - quad->NumTris = npoints - 2; - - uscale = float(1.f / (texture->GetScaledWidth() * scalex)); - vscale = float(1.f / (texture->GetScaledHeight() * scaley)); - ox = float(originx); - oy = float(originy); - - for (i = 0; i < npoints; ++i) - { - verts[i].x = points[i].X; - verts[i].y = points[i].Y; - verts[i].z = 0; - verts[i].rhw = 1; - verts[i].color0 = color0; - verts[i].color1 = color1; - float u = points[i].X - ox; - float v = points[i].Y - oy; - if (dorotate) - { - float t = u; - u = t * cosrot - v * sinrot; - v = v * cosrot + t * sinrot; - } - verts[i].tu = u * uscale; - verts[i].tv = v * vscale; - } - for (ipos = IndexPos, i = 2; i < npoints; ++i, ipos += 3) - { - IndexData[ipos] = VertexPos; - IndexData[ipos + 1] = VertexPos + i - 1; - IndexData[ipos + 2] = VertexPos + i; - } - - QuadBatchPos++; - VertexPos += npoints; - IndexPos = ipos; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: AddColorOnlyQuad -// -// Adds a single-color, untextured quad to the batch. -// -//========================================================================== - -void OpenGLSWFrameBuffer::AddColorOnlyQuad(int left, int top, int width, int height, uint32_t color) -{ - BufferedTris *quad; - FBVERTEX *verts; - - CheckQuadBatch(); - quad = &QuadExtra[QuadBatchPos]; - verts = &VertexData[VertexPos]; - - float x = float(left); - float y = float(top); - - quad->ClearSetup(); - quad->ShaderNum = BQS_ColorOnly; - if ((color & 0xFF000000) != 0xFF000000) - { - quad->BlendOp = GL_FUNC_ADD; - quad->SrcBlend = GL_SRC_ALPHA; - quad->DestBlend = GL_ONE_MINUS_SRC_ALPHA; - } - quad->Palette = nullptr; - quad->Texture = nullptr; - quad->NumVerts = 4; - quad->NumTris = 2; - - verts[0].x = x; - verts[0].y = y; - verts[0].z = 0; - verts[0].rhw = 1; - verts[0].color0 = color; - verts[0].color1 = 0; - verts[0].tu = 0; - verts[0].tv = 0; - - verts[1].x = x + width; - verts[1].y = y; - verts[1].z = 0; - verts[1].rhw = 1; - verts[1].color0 = color; - verts[1].color1 = 0; - verts[1].tu = 0; - verts[1].tv = 0; - - verts[2].x = x + width; - verts[2].y = y + height; - verts[2].z = 0; - verts[2].rhw = 1; - verts[2].color0 = color; - verts[2].color1 = 0; - verts[2].tu = 0; - verts[2].tv = 0; - - verts[3].x = x; - verts[3].y = y + height; - verts[3].z = 0; - verts[3].rhw = 1; - verts[3].color0 = color; - verts[3].color1 = 0; - verts[3].tu = 0; - verts[3].tv = 0; - - IndexData[IndexPos] = VertexPos; - IndexData[IndexPos + 1] = VertexPos + 1; - IndexData[IndexPos + 2] = VertexPos + 2; - IndexData[IndexPos + 3] = VertexPos; - IndexData[IndexPos + 4] = VertexPos + 2; - IndexData[IndexPos + 5] = VertexPos + 3; - - QuadBatchPos++; - VertexPos += 4; - IndexPos += 6; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: AddColorOnlyRect -// -// Like AddColorOnlyQuad, except it's hollow. -// -//========================================================================== - -void OpenGLSWFrameBuffer::AddColorOnlyRect(int left, int top, int width, int height, uint32_t color) -{ - AddColorOnlyQuad(left, top, width - 1, 1, color); // top - AddColorOnlyQuad(left + width - 1, top, 1, height - 1, color); // right - AddColorOnlyQuad(left + 1, top + height - 1, width - 1, 1, color); // bottom - AddColorOnlyQuad(left, top + 1, 1, height - 1, color); // left -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: CheckQuadBatch -// -// Make sure there's enough room in the batch for one more set of triangles. -// -//========================================================================== - -void OpenGLSWFrameBuffer::CheckQuadBatch(int numtris, int numverts) -{ - if (BatchType == BATCH_Lines) - { - EndLineBatch(); - } - else if (QuadBatchPos == MAX_QUAD_BATCH || - VertexPos + numverts > NUM_VERTS || - IndexPos + numtris * 3 > NUM_INDEXES) - { - EndQuadBatch(); - } - if (QuadBatchPos < 0) - { - BeginQuadBatch(); - } -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: BeginQuadBatch -// -// Locks the vertex buffer for quads and sets the cursor to 0. -// -//========================================================================== - -void OpenGLSWFrameBuffer::BeginQuadBatch() -{ - if (In2D < 2 || !InScene || QuadBatchPos >= 0) - { - return; - } - EndLineBatch(); // Make sure all lines have been drawn first. - VertexData = VertexBuffer->Lock(); - IndexData = IndexBuffer->Lock(); - VertexPos = 0; - IndexPos = 0; - QuadBatchPos = 0; - BatchType = BATCH_Quads; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: EndQuadBatch -// -// Draws all the quads that have been batched up. -// -//========================================================================== - -void OpenGLSWFrameBuffer::EndQuadBatch() -{ - if (In2D < 2 || !InScene || BatchType != BATCH_Quads) - { - return; - } - BatchType = BATCH_None; - VertexBuffer->Unlock(); - IndexBuffer->Unlock(); - if (QuadBatchPos == 0) - { - QuadBatchPos = -1; - VertexPos = -1; - IndexPos = -1; - return; - } - SetStreamSource(VertexBuffer.get()); - SetIndices(IndexBuffer.get()); - bool uv_wrapped = false; - bool uv_should_wrap; - int indexpos, vertpos; - - indexpos = vertpos = 0; - for (int i = 0; i < QuadBatchPos; ) - { - const BufferedTris *quad = &QuadExtra[i]; - int j; - - int startindex = indexpos; - int startvertex = vertpos; - - indexpos += quad->NumTris * 3; - vertpos += quad->NumVerts; - - // Quads with matching parameters should be done with a single - // DrawPrimitive call. - for (j = i + 1; j < QuadBatchPos; ++j) - { - const BufferedTris *q2 = &QuadExtra[j]; - if (quad->Texture != q2->Texture || - !quad->IsSameSetup(*q2) || - quad->Palette != q2->Palette) - { - break; - } - if (quad->ShaderNum == BQS_InGameColormap && (quad->Flags & BQF_Desaturated) && quad->Desat != q2->Desat) - { - break; - } - indexpos += q2->NumTris * 3; - vertpos += q2->NumVerts; - } - - // Set the palette (if one) - if ((quad->Flags & BQF_Paletted) == BQF_GamePalette) - { - SetPaletteTexture(PaletteTexture.get(), 256, BorderColor); - } - else if ((quad->Flags & BQF_Paletted) == BQF_CustomPalette) - { - assert(quad->Palette != nullptr); - SetPaletteTexture(quad->Palette->Tex.get(), quad->Palette->RoundedPaletteSize, quad->Palette->BorderColor); - } - - // Set the alpha blending - SetAlphaBlend(quad->BlendOp, quad->SrcBlend, quad->DestBlend); - - // Set the alpha test - EnableAlphaTest(!(quad->Flags & BQF_DisableAlphaTest)); - - // Set the pixel shader - if (quad->ShaderNum == BQS_PalTex) - { - SetPixelShader(Shaders[(quad->Flags & BQF_InvertSource) ? SHADER_NormalColorPalInv : SHADER_NormalColorPal].get()); - } - else if (quad->ShaderNum == BQS_Plain) - { - SetPixelShader(Shaders[(quad->Flags & BQF_InvertSource) ? SHADER_NormalColorInv : SHADER_NormalColor].get()); - } - else if (quad->ShaderNum == BQS_RedToAlpha) - { - SetPixelShader(Shaders[(quad->Flags & BQF_InvertSource) ? SHADER_RedToAlphaInv : SHADER_RedToAlpha].get()); - } - else if (quad->ShaderNum == BQS_ColorOnly) - { - SetPixelShader(Shaders[SHADER_VertexColor].get()); - } - else if (quad->ShaderNum == BQS_SpecialColormap) - { - int select; - - select = !!(quad->Flags & BQF_Paletted); - SetPixelShader(Shaders[SHADER_SpecialColormap + select].get()); - } - else if (quad->ShaderNum == BQS_InGameColormap) - { - int select; - - select = !!(quad->Flags & BQF_Desaturated); - select |= !!(quad->Flags & BQF_InvertSource) << 1; - select |= !!(quad->Flags & BQF_Paletted) << 2; - if (quad->Flags & BQF_Desaturated) - { - SetConstant(PSCONST_Desaturation, quad->Desat / 255.f, (255 - quad->Desat) / 255.f, 0, 0); - } - SetPixelShader(Shaders[SHADER_InGameColormap + select].get()); - } - - // Set the texture clamp addressing mode - uv_should_wrap = !!(quad->Flags & BQF_WrapUV); - if (uv_wrapped != uv_should_wrap) - { - uint32_t mode = uv_should_wrap ? GL_REPEAT : GL_CLAMP_TO_EDGE; - uv_wrapped = uv_should_wrap; - SetSamplerWrapS(0, mode); - SetSamplerWrapT(0, mode); - } - - // Set the texture - if (quad->Texture != nullptr) - { - SetTexture(0, quad->Texture); - } - - // Draw the quad - DrawTriangleList( - startvertex, // MinIndex - vertpos - startvertex, // NumVertices - startindex, // StartIndex - (indexpos - startindex) / 3 // PrimitiveCount - /*4 * i, 4 * (j - i), 6 * i, 2 * (j - i)*/); - i = j; - } - if (uv_wrapped) - { - SetSamplerWrapS(0, GL_CLAMP_TO_EDGE); - SetSamplerWrapT(0, GL_CLAMP_TO_EDGE); - } - QuadBatchPos = -1; - VertexPos = -1; - IndexPos = -1; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: EndBatch -// -// Draws whichever type of primitive is currently being batched. -// -//========================================================================== - -void OpenGLSWFrameBuffer::EndBatch() -{ - if (BatchType == BATCH_Quads) - { - EndQuadBatch(); - } - else if (BatchType == BATCH_Lines) - { - EndLineBatch(); - } -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: SetStyle -// -// Patterned after R_SetPatchStyle. -// -//========================================================================== - -bool OpenGLSWFrameBuffer::SetStyle(OpenGLTex *tex, DrawParms &parms, uint32_t &color0, uint32_t &color1, BufferedTris &quad) -{ - int fmt = tex->GetTexFormat(); - FRenderStyle style = parms.style; - float alpha; - bool stencilling; - - if (style.Flags & STYLEF_TransSoulsAlpha) - { - alpha = transsouls; - } - else if (style.Flags & STYLEF_Alpha1) - { - alpha = 1; - } - else - { - alpha = clamp(parms.Alpha, 0.f, 1.f); - } - - style.CheckFuzz(); - if (style.BlendOp == STYLEOP_Shadow) - { - style = LegacyRenderStyles[STYLE_TranslucentStencil]; - alpha = 0.3f; - parms.fillcolor = 0; - } - - // FIXME: Fuzz effect is not written - if (style.BlendOp == STYLEOP_FuzzOrAdd || style.BlendOp == STYLEOP_Fuzz) - { - style.BlendOp = STYLEOP_Add; - } - else if (style.BlendOp == STYLEOP_FuzzOrSub) - { - style.BlendOp = STYLEOP_Sub; - } - else if (style.BlendOp == STYLEOP_FuzzOrRevSub) - { - style.BlendOp = STYLEOP_RevSub; - } - - stencilling = false; - quad.Palette = nullptr; - quad.Flags = 0; - quad.Desat = 0; - - switch (style.BlendOp) - { - default: - case STYLEOP_Add: quad.BlendOp = GL_FUNC_ADD; break; - case STYLEOP_Sub: quad.BlendOp = GL_FUNC_SUBTRACT; break; - case STYLEOP_RevSub: quad.BlendOp = GL_FUNC_REVERSE_SUBTRACT; break; - case STYLEOP_None: return false; - } - quad.SrcBlend = GetStyleAlpha(style.SrcAlpha); - quad.DestBlend = GetStyleAlpha(style.DestAlpha); - - if (style.Flags & STYLEF_InvertOverlay) - { - // Only the overlay color is inverted, not the overlay alpha. - parms.colorOverlay = ColorARGB(APART(parms.colorOverlay), - 255 - RPART(parms.colorOverlay), 255 - GPART(parms.colorOverlay), - 255 - BPART(parms.colorOverlay)); - } - - SetColorOverlay(parms.colorOverlay, alpha, color0, color1); - - if (style.Flags & STYLEF_ColorIsFixed) - { - if (style.Flags & STYLEF_InvertSource) - { // Since the source color is a constant, we can invert it now - // without spending time doing it in the shader. - parms.fillcolor = ColorXRGB(255 - RPART(parms.fillcolor), - 255 - GPART(parms.fillcolor), 255 - BPART(parms.fillcolor)); - } - // Set up the color mod to replace the color from the image data. - color0 = (color0 & ColorRGBA(0, 0, 0, 255)) | (parms.fillcolor & ColorRGBA(255, 255, 255, 0)); - color1 &= ColorRGBA(0, 0, 0, 255); - - if (style.Flags & STYLEF_RedIsAlpha) - { - // Note that if the source texture is paletted, the palette is ignored. - quad.Flags = 0; - quad.ShaderNum = BQS_RedToAlpha; - } - else if (fmt == GL_R8) - { - quad.Flags = BQF_GamePalette; - quad.ShaderNum = BQS_PalTex; - } - else - { - quad.Flags = 0; - quad.ShaderNum = BQS_Plain; - } - } - else - { - if (style.Flags & STYLEF_RedIsAlpha) - { - quad.Flags = 0; - quad.ShaderNum = BQS_RedToAlpha; - } - else if (fmt == GL_R8) - { - if (parms.remap != nullptr) - { - quad.Flags = BQF_CustomPalette; - quad.Palette = reinterpret_cast(parms.remap->GetNative()); - quad.ShaderNum = BQS_PalTex; - } - else if (tex->IsGray) - { - quad.Flags = 0; - quad.ShaderNum = BQS_Plain; - } - else - { - quad.Flags = BQF_GamePalette; - quad.ShaderNum = BQS_PalTex; - } - } - else - { - quad.Flags = 0; - quad.ShaderNum = BQS_Plain; - } - if (style.Flags & STYLEF_InvertSource) - { - quad.Flags |= BQF_InvertSource; - } - - if (parms.specialcolormap != nullptr) - { // Emulate an invulnerability or similar colormap. - float *start, *end; - start = parms.specialcolormap->ColorizeStart; - end = parms.specialcolormap->ColorizeEnd; - if (quad.Flags & BQF_InvertSource) - { - quad.Flags &= ~BQF_InvertSource; - swapvalues(start, end); - } - quad.ShaderNum = BQS_SpecialColormap; - color0 = ColorRGBA(uint32_t(start[0] / 2 * 255), uint32_t(start[1] / 2 * 255), uint32_t(start[2] / 2 * 255), color0 >> 24); - color1 = ColorRGBA(uint32_t(end[0] / 2 * 255), uint32_t(end[1] / 2 * 255), uint32_t(end[2] / 2 * 255), color1 >> 24); - } - else if (parms.colormapstyle != nullptr) - { // Emulate the fading from an in-game colormap (colorized, faded, and desaturated) - if (parms.colormapstyle->Desaturate != 0) - { - quad.Flags |= BQF_Desaturated; - } - quad.ShaderNum = BQS_InGameColormap; - quad.Desat = parms.colormapstyle->Desaturate; - color0 = ColorARGB(color1 >> 24, - parms.colormapstyle->Color.r, - parms.colormapstyle->Color.g, - parms.colormapstyle->Color.b); - double fadelevel = parms.colormapstyle->FadeLevel; - color1 = ColorARGB(uint32_t((1 - fadelevel) * 255), - uint32_t(parms.colormapstyle->Fade.r * fadelevel), - uint32_t(parms.colormapstyle->Fade.g * fadelevel), - uint32_t(parms.colormapstyle->Fade.b * fadelevel)); - } - } - - // For unmasked images, force the alpha from the image data to be ignored. - if (!parms.masked && quad.ShaderNum != BQS_InGameColormap) - { - color0 = (color0 & ColorRGBA(255, 255, 255, 0)) | ColorValue(0, 0, 0, alpha); - color1 &= ColorRGBA(255, 255, 255, 0); - - // If our alpha is one and we are doing normal adding, then we can turn the blend off completely. - if (quad.BlendOp == GL_FUNC_ADD && - ((alpha == 1 && quad.SrcBlend == GL_SRC_ALPHA) || quad.SrcBlend == GL_ONE) && - ((alpha == 1 && quad.DestBlend == GL_ONE_MINUS_SRC_ALPHA) || quad.DestBlend == GL_ZERO)) - { - quad.BlendOp = 0; - } - quad.Flags |= BQF_DisableAlphaTest; - } - return true; -} - -int OpenGLSWFrameBuffer::GetStyleAlpha(int type) -{ - switch (type) - { - case STYLEALPHA_Zero: return GL_ZERO; - case STYLEALPHA_One: return GL_ONE; - case STYLEALPHA_Src: return GL_SRC_ALPHA; - case STYLEALPHA_InvSrc: return GL_ONE_MINUS_SRC_ALPHA; - default: return GL_ZERO; - } -} - - -void OpenGLSWFrameBuffer::SetColorOverlay(uint32_t color, float alpha, uint32_t &color0, uint32_t &color1) -{ - if (APART(color) != 0) - { - int a = APART(color) * 256 / 255; - color0 = ColorRGBA( - (RPART(color) * a) >> 8, - (GPART(color) * a) >> 8, - (BPART(color) * a) >> 8, - 0); - a = 256 - a; - color1 = ColorRGBA(a, a, a, int(alpha * 255)); - } - else - { - color0 = 0; - color1 = ColorValue(1, 1, 1, alpha); - } -} - -void OpenGLSWFrameBuffer::EnableAlphaTest(bool enabled) -{ - if (enabled != AlphaTestEnabled) - { - AlphaTestEnabled = enabled; - //glEnable(GL_ALPHA_TEST); // To do: move to shader as this is only in the compatibility profile - } -} - -void OpenGLSWFrameBuffer::SetAlphaBlend(int op, int srcblend, int destblend) -{ - if (op == 0) - { // Disable alpha blend - if (AlphaBlendEnabled) - { - AlphaBlendEnabled = false; - glDisable(GL_BLEND); - } - } - else - { // Enable alpha blend - assert(srcblend != 0); - assert(destblend != 0); - - if (!AlphaBlendEnabled) - { - AlphaBlendEnabled = true; - glEnable(GL_BLEND); - } - if (AlphaBlendOp != op) - { - AlphaBlendOp = op; - glBlendEquation(op); - } - if (AlphaSrcBlend != srcblend || AlphaDestBlend != destblend) - { - AlphaSrcBlend = srcblend; - AlphaDestBlend = destblend; - glBlendFunc(srcblend, destblend); - } - } -} - -void OpenGLSWFrameBuffer::SetConstant(int cnum, float r, float g, float b, float a) -{ - if (Constant[cnum][0] != r || - Constant[cnum][1] != g || - Constant[cnum][2] != b || - Constant[cnum][3] != a) - { - Constant[cnum][0] = r; - Constant[cnum][1] = g; - Constant[cnum][2] = b; - Constant[cnum][3] = a; - SetPixelShaderConstantF(cnum, Constant[cnum], 1); - } -} - -void OpenGLSWFrameBuffer::SetPixelShader(HWPixelShader *shader) -{ - if (CurPixelShader != shader) - { - CurPixelShader = shader; - SetHWPixelShader(shader); - } -} - -void OpenGLSWFrameBuffer::SetTexture(int tnum, HWTexture *texture) -{ - assert(unsigned(tnum) < countof(Texture)); - if (texture) - { - if (Texture[tnum] != texture || SamplerWrapS[tnum] != texture->WrapS || SamplerWrapT[tnum] != texture->WrapT) - { - Texture[tnum] = texture; - glActiveTexture(GL_TEXTURE0 + tnum); - glBindTexture(GL_TEXTURE_2D, texture->Texture); - if (Texture[tnum]->WrapS != SamplerWrapS[tnum]) - { - Texture[tnum]->WrapS = SamplerWrapS[tnum]; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, SamplerWrapS[tnum]); - } - if (Texture[tnum]->WrapT != SamplerWrapT[tnum]) - { - Texture[tnum]->WrapT = SamplerWrapT[tnum]; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, SamplerWrapT[tnum]); - } - } - } - else if (Texture[tnum] != texture) - { - Texture[tnum] = texture; - glActiveTexture(GL_TEXTURE0 + tnum); - glBindTexture(GL_TEXTURE_2D, 0); - } -} - -void OpenGLSWFrameBuffer::SetSamplerWrapS(int tnum, int mode) -{ - assert(unsigned(tnum) < countof(Texture)); - if (Texture[tnum] && SamplerWrapS[tnum] != mode) - { - SamplerWrapS[tnum] = mode; - Texture[tnum]->WrapS = mode; - glActiveTexture(GL_TEXTURE0 + tnum); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, SamplerWrapS[tnum]); - } -} - -void OpenGLSWFrameBuffer::SetSamplerWrapT(int tnum, int mode) -{ - assert(unsigned(tnum) < countof(Texture)); - if (Texture[tnum] && SamplerWrapT[tnum] != mode) - { - SamplerWrapT[tnum] = mode; - Texture[tnum]->WrapT = mode; - glActiveTexture(GL_TEXTURE0 + tnum); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, SamplerWrapT[tnum]); - } -} - -void OpenGLSWFrameBuffer::SetPaletteTexture(HWTexture *texture, int count, uint32_t border_color) -{ - // The pixel shader receives color indexes in the range [0.0,1.0]. - // The palette texture is also addressed in the range [0.0,1.0], - // HOWEVER the coordinate 1.0 is the right edge of the texture and - // not actually the texture itself. We need to scale and shift - // the palette indexes so they lie exactly in the center of each - // texel. For a normal palette with 256 entries, that means the - // range we use should be [0.5,255.5], adjusted so the coordinate - // is still within [0.0,1.0]. - // - // The constant register c2 is used to hold the multiplier in the - // x part and the adder in the y part. - float fcount = 1 / float(count); - SetConstant(PSCONST_PaletteMod, 255 * fcount, 0.5f * fcount, 0, 0); - SetTexture(1, texture); -} - -void OpenGLSWFrameBuffer::ScaleCoordsFromWindow(int16_t &x, int16_t &y) -{ - int letterboxX, letterboxY, letterboxWidth, letterboxHeight; - GetLetterboxFrame(letterboxX, letterboxY, letterboxWidth, letterboxHeight); - - // Subtract the LB video mode letterboxing - if (IsFullscreen()) - y -= (GetTrueHeight() - VideoHeight) / 2; - - x = int16_t((x - letterboxX) * Width / letterboxWidth); - y = int16_t((y - letterboxY) * Height / letterboxHeight); -} diff --git a/src/gl/system/gl_swframebuffer.h b/src/gl/system/gl_swframebuffer.h deleted file mode 100644 index 401c0a0729..0000000000 --- a/src/gl/system/gl_swframebuffer.h +++ /dev/null @@ -1,507 +0,0 @@ -#ifndef __GL_SWFRAMEBUFFER -#define __GL_SWFRAMEBUFFER - -#ifdef _WIN32 -#include "win32iface.h" -#include "win32gliface.h" -#endif - -#include "SkylineBinPack.h" -#include "textures.h" - -#include - -class FGLDebug; - -#ifdef _WIN32 -class OpenGLSWFrameBuffer : public Win32GLFrameBuffer -{ - typedef Win32GLFrameBuffer Super; -#else -#include "sdlglvideo.h" -class OpenGLSWFrameBuffer : public SDLGLFB -{ - typedef SDLGLFB Super; //[C]commented, DECLARE_CLASS defines this in linux -#endif - - -public: - - explicit OpenGLSWFrameBuffer() {} - OpenGLSWFrameBuffer(void *hMonitor, int width, int height, int bits, int refreshHz, bool fullscreen, bool bgra); - ~OpenGLSWFrameBuffer(); - - bool IsValid() override; - bool Lock(bool buffered) override; - void Unlock() override; - void Update() override; - PalEntry *GetPalette() override; - void GetFlashedPalette(PalEntry palette[256]) override; - void UpdatePalette() override; - bool SetGamma(float gamma) override; - bool SetFlash(PalEntry rgb, int amount) override; - void GetFlash(PalEntry &rgb, int &amount) override; - int GetPageCount() override; - void SetVSync(bool vsync) override; - void NewRefreshRate() override; - void GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type, float &gamma) override; - void ReleaseScreenshotBuffer() override; - void SetBlendingRect(int x1, int y1, int x2, int y2) override; - bool Begin2D(bool copy3d) override; - void DrawBlendingRect() override; - FNativeTexture *CreateTexture(FTexture *gametex, FTextureFormat fmt, bool wrapping) override; - FNativePalette *CreatePalette(FRemapTable *remap) override; - void DrawTextureParms(FTexture *img, DrawParms &parms) override; - void DoClear(int left, int top, int right, int bottom, int palcolor, uint32_t color) override; - void DoDim(PalEntry color, float amount, int x1, int y1, int w, int h) override; - void FlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin) override; - void DrawLine(int x0, int y0, int x1, int y1, int palColor, uint32_t realcolor) override; - void DrawPixel(int x, int y, int palcolor, uint32_t rgbcolor) override; - void FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, double originx, double originy, double scalex, double scaley, DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel, int bottomclip) override; - bool WipeStartScreen(int type) override; - void WipeEndScreen() override; - bool WipeDo(int ticks) override; - void WipeCleanup() override; - -#ifdef WIN32 - void PaletteChanged() override { } - int QueryNewPalette() override { return 0; } - void Blank() override { } - bool PaintToWindow() override; - bool Is8BitMode() override { return false; } - int GetTrueHeight() override { return TrueHeight; } -#endif - - void ScaleCoordsFromWindow(int16_t &x, int16_t &y) override; - -private: - struct FBVERTEX - { - float x, y, z, rhw; - uint32_t color0, color1; - float tu, tv; - }; - - struct BURNVERTEX - { - float x, y, z, rhw; - float tu0, tv0; - float tu1, tv1; - }; - - enum - { - PSCONST_Desaturation, - PSCONST_PaletteMod, - PSCONST_Weights, - PSCONST_Gamma, - PSCONST_ScreenSize, - NumPSCONST - }; - - struct GammaRamp - { - uint16_t red[256], green[256], blue[256]; - }; - - struct LTRBRect - { - int left, top, right, bottom; - }; - - class HWTexture - { - public: - HWTexture() { Buffers[0] = 0; Buffers[1] = 0; } - ~HWTexture(); - - int Texture = 0; - int Buffers[2]; - int CurrentBuffer = 0; - int WrapS = 0; - int WrapT = 0; - int Format = 0; - - std::vector MapBuffer; - }; - - class HWFrameBuffer - { - public: - ~HWFrameBuffer(); - - int Framebuffer = 0; - std::unique_ptr Texture; - }; - - - class HWVertexBuffer - { - public: - ~HWVertexBuffer(); - - FBVERTEX *Lock(); - void Unlock(); - - int VertexArray = 0; - int Buffer = 0; - int Size = 0; - }; - - class HWIndexBuffer - { - public: - ~HWIndexBuffer(); - - uint16_t *Lock(); - void Unlock(); - - int Buffer = 0; - int Size = 0; - - private: - int LockedOldBinding = 0; - }; - - class HWPixelShader - { - public: - ~HWPixelShader(); - - int Program = 0; - int VertexShader = 0; - int FragmentShader = 0; - - int ConstantLocations[NumPSCONST]; - int ImageLocation = -1; - int PaletteLocation = -1; - int NewScreenLocation = -1; - int BurnLocation = -1; - }; - - std::unique_ptr CreateFrameBuffer(const FString &name, int width, int height); - std::unique_ptr CreatePixelShader(FString vertexsrc, FString fragmentsrc, const FString &defines); - std::unique_ptr CreateVertexBuffer(int size); - std::unique_ptr CreateIndexBuffer(int size); - std::unique_ptr CreateTexture(const FString &name, int width, int height, int levels, int format); - - void SetGammaRamp(const GammaRamp *ramp); - void SetPixelShaderConstantF(int uniformIndex, const float *data, int vec4fcount); - void SetHWPixelShader(HWPixelShader *shader); - void SetStreamSource(HWVertexBuffer *vertexBuffer); - void SetIndices(HWIndexBuffer *indexBuffer); - void DrawTriangleFans(int count, const FBVERTEX *vertices); - void DrawTriangleFans(int count, const BURNVERTEX *vertices); - void DrawPoints(int count, const FBVERTEX *vertices); - void DrawLineList(int count); - void DrawTriangleList(int minIndex, int numVertices, int startIndex, int primitiveCount); - void Present(); - - void GetLetterboxFrame(int &x, int &y, int &width, int &height); - - static void BgraToRgba(uint32_t *dest, const uint32_t *src, int width, int height, int srcpitch); - - void BindFBBuffer(); - void *MappedMemBuffer = nullptr; - bool UseMappedMemBuffer = true; - - static uint32_t ColorARGB(uint32_t a, uint32_t r, uint32_t g, uint32_t b) { return ((a & 0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | ((b) & 0xff); } - static uint32_t ColorRGBA(uint32_t r, uint32_t g, uint32_t b, uint32_t a) { return ColorARGB(a, r, g, b); } - static uint32_t ColorXRGB(uint32_t r, uint32_t g, uint32_t b) { return ColorARGB(0xff, r, g, b); } - static uint32_t ColorValue(float r, float g, float b, float a) { return ColorRGBA((uint32_t)(r * 255.0f), (uint32_t)(g * 255.0f), (uint32_t)(b * 255.0f), (uint32_t)(a * 255.0f)); } - - static void *MapBuffer(int target, int size); - - // The number of points for the vertex buffer. - enum { NUM_VERTS = 10240 }; - - // The number of indices for the index buffer. - enum { NUM_INDEXES = ((NUM_VERTS * 6) / 4) }; - - // The number of quads we can batch together. - enum { MAX_QUAD_BATCH = (NUM_INDEXES / 6) }; - - // The default size for a texture atlas. - enum { DEF_ATLAS_WIDTH = 512 }; - enum { DEF_ATLAS_HEIGHT = 512 }; - - // TYPES ------------------------------------------------------------------- - - struct Atlas; - - struct PackedTexture - { - Atlas *Owner; - - PackedTexture **Prev, *Next; - - // Pixels this image covers - LTRBRect Area; - - // Texture coordinates for this image - float Left, Top, Right, Bottom; - - // Texture has extra space on the border? - bool Padded; - }; - - struct Atlas - { - Atlas(OpenGLSWFrameBuffer *fb, int width, int height, int format); - ~Atlas(); - - PackedTexture *AllocateImage(const Rect &rect, bool padded); - void FreeBox(PackedTexture *box); - - SkylineBinPack Packer; - Atlas *Next; - std::unique_ptr Tex; - int Format; - PackedTexture *UsedList; // Boxes that contain images - int Width, Height; - bool OneUse; - }; - - class OpenGLTex : public FNativeTexture - { - public: - OpenGLTex(FTexture *tex, FTextureFormat fmt, OpenGLSWFrameBuffer *fb, bool wrapping); - ~OpenGLTex(); - - FTexture *GameTex; - PackedTexture *Box; - - OpenGLTex **Prev; - OpenGLTex *Next; - - bool IsGray; - - bool Create(OpenGLSWFrameBuffer *fb, bool wrapping); - bool Update(); - bool CheckWrapping(bool wrapping); - int GetTexFormat(); - }; - - class OpenGLPal : public FNativePalette - { - public: - OpenGLPal(FRemapTable *remap, OpenGLSWFrameBuffer *fb); - ~OpenGLPal(); - - OpenGLPal **Prev; - OpenGLPal *Next; - - std::unique_ptr Tex; - uint32_t BorderColor; - bool DoColorSkip; - - bool Update(); - - FRemapTable *Remap; - int RoundedPaletteSize; - }; - - // Flags for a buffered quad - enum - { - BQF_GamePalette = 1, - BQF_CustomPalette = 7, - BQF_Paletted = 7, - BQF_Bilinear = 8, - BQF_WrapUV = 16, - BQF_InvertSource = 32, - BQF_DisableAlphaTest = 64, - BQF_Desaturated = 128, - }; - - // Shaders for a buffered quad - enum - { - BQS_PalTex, - BQS_Plain, - BQS_RedToAlpha, - BQS_ColorOnly, - BQS_SpecialColormap, - BQS_InGameColormap, - }; - - struct BufferedTris - { - uint8_t Flags; - uint8_t ShaderNum; - int BlendOp; - int SrcBlend; - int DestBlend; - - uint8_t Desat; - OpenGLPal *Palette; - HWTexture *Texture; - uint16_t NumVerts; // Number of _unique_ vertices used by this set. - uint16_t NumTris; // Number of triangles used by this set. - - void ClearSetup() - { - Flags = 0; - ShaderNum = 0; - BlendOp = 0; - SrcBlend = 0; - DestBlend = 0; - } - - bool IsSameSetup(const BufferedTris &other) const - { - return Flags == other.Flags && ShaderNum == other.ShaderNum && BlendOp == other.BlendOp && SrcBlend == other.SrcBlend && DestBlend == other.DestBlend; - } - }; - - enum - { - SHADER_NormalColor, - SHADER_NormalColorPal, - SHADER_NormalColorInv, - SHADER_NormalColorPalInv, - - SHADER_RedToAlpha, - SHADER_RedToAlphaInv, - - SHADER_VertexColor, - - SHADER_SpecialColormap, - SHADER_SpecialColormapPal, - - SHADER_InGameColormap, - SHADER_InGameColormapDesat, - SHADER_InGameColormapInv, - SHADER_InGameColormapInvDesat, - SHADER_InGameColormapPal, - SHADER_InGameColormapPalDesat, - SHADER_InGameColormapPalInv, - SHADER_InGameColormapPalInvDesat, - - SHADER_BurnWipe, - SHADER_GammaCorrection, - - NUM_SHADERS - }; - static const char *const ShaderDefines[NUM_SHADERS]; - - void Flip(); - void SetInitialState(); - bool CreateResources(); - void ReleaseResources(); - bool LoadShaders(); - bool CreateFBTexture(); - bool CreatePaletteTexture(); - bool CreateVertexes(); - void UploadPalette(); - void CalcFullscreenCoords(FBVERTEX verts[4], bool viewarea_only, uint32_t color0, uint32_t color1) const; - bool Reset(); - std::unique_ptr CopyCurrentScreen(); - void ReleaseDefaultPoolItems(); - void KillNativePals(); - void KillNativeTexs(); - PackedTexture *AllocPackedTexture(int width, int height, bool wrapping, int format); - void DrawPackedTextures(int packnum); - void DrawLetterbox(int x, int y, int width, int height); - void Draw3DPart(bool copy3d); - bool SetStyle(OpenGLTex *tex, DrawParms &parms, uint32_t &color0, uint32_t &color1, BufferedTris &quad); - static int GetStyleAlpha(int type); - static void SetColorOverlay(uint32_t color, float alpha, uint32_t &color0, uint32_t &color1); - void AddColorOnlyQuad(int left, int top, int width, int height, uint32_t color); - void AddColorOnlyRect(int left, int top, int width, int height, uint32_t color); - void CheckQuadBatch(int numtris = 2, int numverts = 4); - void BeginQuadBatch(); - void EndQuadBatch(); - void BeginLineBatch(); - void EndLineBatch(); - void EndBatch(); - - // State - void EnableAlphaTest(bool enabled); - void SetAlphaBlend(int op, int srcblend = 0, int destblend = 0); - void SetConstant(int cnum, float r, float g, float b, float a); - void SetPixelShader(HWPixelShader *shader); - void SetTexture(int tnum, HWTexture *texture); - void SetSamplerWrapS(int tnum, int mode); - void SetSamplerWrapT(int tnum, int mode); - void SetPaletteTexture(HWTexture *texture, int count, uint32_t border_color); - - bool Valid = false; - std::shared_ptr Debug; - - std::unique_ptr StreamVertexBuffer, StreamVertexBufferBurn; - float ShaderConstants[NumPSCONST * 4]; - HWPixelShader *CurrentShader = nullptr; - - std::unique_ptr OutputFB; - - bool AlphaTestEnabled = false; - bool AlphaBlendEnabled = false; - int AlphaBlendOp = 0; - int AlphaSrcBlend = 0; - int AlphaDestBlend = 0; - float Constant[3][4]; - uint32_t CurBorderColor; - HWPixelShader *CurPixelShader; - HWTexture *Texture[5]; - int SamplerWrapS[5], SamplerWrapT[5]; - - PalEntry SourcePalette[256]; - uint32_t BorderColor; - uint32_t FlashColor0, FlashColor1; - PalEntry FlashColor; - int FlashAmount; - int TrueHeight; - int PixelDoubling; - float Gamma; -#ifdef _WIN32 - bool UpdatePending; -#endif // _WIN32 - bool NeedPalUpdate; - bool NeedGammaUpdate; - LTRBRect BlendingRect; - int In2D; - bool InScene; - bool GatheringWipeScreen; - bool AALines; - uint8_t BlockNum; - OpenGLPal *Palettes = nullptr; - OpenGLTex *Textures = nullptr; - Atlas *Atlases = nullptr; - - std::unique_ptr FBTexture; - std::unique_ptr PaletteTexture; - std::unique_ptr ScreenshotTexture; - - std::unique_ptr VertexBuffer; - FBVERTEX *VertexData = nullptr; - std::unique_ptr IndexBuffer; - uint16_t *IndexData = nullptr; - BufferedTris *QuadExtra = nullptr; - int VertexPos; - int IndexPos; - int QuadBatchPos; - enum { BATCH_None, BATCH_Quads, BATCH_Lines } BatchType; - - std::unique_ptr Shaders[NUM_SHADERS]; - - std::unique_ptr InitialWipeScreen, FinalWipeScreen; - - class Wiper - { - public: - virtual ~Wiper(); - virtual bool Run(int ticks, OpenGLSWFrameBuffer *fb) = 0; - - void DrawScreen(OpenGLSWFrameBuffer *fb, HWTexture *tex, int blendop = 0, uint32_t color0 = 0, uint32_t color1 = 0xFFFFFFF); - }; - - class Wiper_Melt; friend class Wiper_Melt; - class Wiper_Burn; friend class Wiper_Burn; - class Wiper_Crossfade; friend class Wiper_Crossfade; - - Wiper *ScreenWipe; -}; - - -#endif //__GL_SWFRAMEBUFFER diff --git a/src/gl/system/gl_swwipe.cpp b/src/gl/system/gl_swwipe.cpp deleted file mode 100644 index e33b259802..0000000000 --- a/src/gl/system/gl_swwipe.cpp +++ /dev/null @@ -1,587 +0,0 @@ -/* -** gl_swwipe.cpp -** Implements the different screen wipes using OpenGL calls. -** -**--------------------------------------------------------------------------- -** Copyright 1998-2008 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -// HEADER FILES ------------------------------------------------------------ - -#include "gl/system/gl_system.h" -#include "m_swap.h" -#include "v_video.h" -#include "doomstat.h" -#include "m_png.h" -#include "m_crc32.h" -#include "vectors.h" -#include "v_palette.h" -#include "templates.h" - -#include "c_dispatch.h" -#include "templates.h" -#include "i_system.h" -#include "i_video.h" -#include "v_pfx.h" -#include "stats.h" -#include "doomerrors.h" -#include "r_data/r_translate.h" -#include "f_wipe.h" -#include "sbar.h" -#include "w_wad.h" -#include "r_data/colormaps.h" - -#include "gl/system/gl_interface.h" -#include "gl/system/gl_swframebuffer.h" -#include "gl/data/gl_data.h" -#include "gl/utility/gl_clock.h" -#include "gl/utility/gl_templates.h" -#include "gl/gl_functions.h" -#include "gl_debug.h" -#include "m_random.h" - -class OpenGLSWFrameBuffer::Wiper_Crossfade : public OpenGLSWFrameBuffer::Wiper -{ -public: - Wiper_Crossfade(); - bool Run(int ticks, OpenGLSWFrameBuffer *fb); - -private: - int Clock; -}; - -class OpenGLSWFrameBuffer::Wiper_Melt : public OpenGLSWFrameBuffer::Wiper -{ -public: - Wiper_Melt(); - bool Run(int ticks, OpenGLSWFrameBuffer *fb); - -private: - // Match the strip sizes that oldschool Doom used. - static const int WIDTH = 160, HEIGHT = 200; - int y[WIDTH]; -}; - -class OpenGLSWFrameBuffer::Wiper_Burn : public OpenGLSWFrameBuffer::Wiper -{ -public: - Wiper_Burn(OpenGLSWFrameBuffer *fb); - ~Wiper_Burn(); - bool Run(int ticks, OpenGLSWFrameBuffer *fb); - -private: - static const int WIDTH = 64, HEIGHT = 64; - uint8_t BurnArray[WIDTH * (HEIGHT + 5)]; - std::unique_ptr BurnTexture; - int Density; - int BurnTime; -}; - -//========================================================================== -// -// OpenGLSWFrameBuffer :: WipeStartScreen -// -// Called before the current screen has started rendering. This needs to -// save what was drawn the previous frame so that it can be animated into -// what gets drawn this frame. -// -// In fullscreen mode, we use GetFrontBufferData() to grab the data that -// is visible on screen right now. -// -// In windowed mode, we can't do that because we'll get the whole desktop. -// Instead, we can conveniently use the TempRenderTexture, which is normally -// used for gamma-correcting copying the image to the back buffer. -// -//========================================================================== - -bool OpenGLSWFrameBuffer::WipeStartScreen(int type) -{ - if (!Accel2D) - { - return Super::WipeStartScreen(type); - } - - switch (type) - { - case wipe_Melt: - ScreenWipe = new Wiper_Melt; - break; - - case wipe_Burn: - ScreenWipe = new Wiper_Burn(this); - break; - - case wipe_Fade: - ScreenWipe = new Wiper_Crossfade; - break; - - default: - return false; - } - - InitialWipeScreen = CopyCurrentScreen(); - - // Make even fullscreen model render to the TempRenderTexture, so - // we can have a copy of the new screen readily available. - GatheringWipeScreen = true; - return true; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: WipeEndScreen -// -// The screen we want to animate to has just been drawn. This function is -// called in place of Update(), so it has not been Presented yet. -// -//========================================================================== - -void OpenGLSWFrameBuffer::WipeEndScreen() -{ - if (!Accel2D) - { - Super::WipeEndScreen(); - return; - } - - // Don't do anything if there is no starting point. - if (InitialWipeScreen == NULL) - { - return; - } - - // If the whole screen was drawn without 2D accel, get it in to - // video memory now. - if (!In2D) - { - Begin2D(true); - } - - EndBatch(); // Make sure all batched primitives have been drawn. - - FinalWipeScreen = CopyCurrentScreen(); - - // At this point, InitialWipeScreen holds the screen we are wiping from. - // FinalWipeScreen holds the screen we are wiping to, which may be the - // same texture as TempRenderTexture. -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: WipeDo -// -// Perform the actual wipe animation. The number of tics since the last -// time this function was called is passed in. Returns true when the wipe -// is over. The first time this function has been called, the screen is -// still locked from before and EndScene() still has not been called. -// Successive times need to call BeginScene(). -// -//========================================================================== - -bool OpenGLSWFrameBuffer::WipeDo(int ticks) -{ - if (!Accel2D) - { - return Super::WipeDo(ticks); - } - - // Sanity checks. - if (InitialWipeScreen == NULL || FinalWipeScreen == NULL) - { - return true; - } - if (GatheringWipeScreen) - { // This is the first time we've been called for this wipe. - GatheringWipeScreen = false; - } - else - { // This is the second or later time we've been called for this wipe. - InScene = true; - } - - In2D = 3; - - EnableAlphaTest(false); - bool done = ScreenWipe->Run(ticks, this); - return done; -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: WipeCleanup -// -// Release any resources that were specifically created for the wipe. -// -//========================================================================== - -void OpenGLSWFrameBuffer::WipeCleanup() -{ - if (ScreenWipe != NULL) - { - delete ScreenWipe; - ScreenWipe = NULL; - } - InitialWipeScreen.reset(); - FinalWipeScreen.reset(); - GatheringWipeScreen = false; - if (!Accel2D) - { - Super::WipeCleanup(); - return; - } -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: Wiper Constructor -// -//========================================================================== - -OpenGLSWFrameBuffer::Wiper::~Wiper() -{ -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: Wiper :: DrawScreen -// -// Draw either the initial or target screen completely to the screen. -// -//========================================================================== - -void OpenGLSWFrameBuffer::Wiper::DrawScreen(OpenGLSWFrameBuffer *fb, HWTexture *tex, - int blendop, uint32_t color0, uint32_t color1) -{ - FBVERTEX verts[4]; - - fb->CalcFullscreenCoords(verts, false, color0, color1); - fb->SetTexture(0, tex); - fb->SetAlphaBlend(blendop, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - fb->SetPixelShader(fb->Shaders[SHADER_NormalColor].get()); - fb->DrawTriangleFans(2, verts); -} - -// WIPE: CROSSFADE --------------------------------------------------------- - -//========================================================================== -// -// OpenGLSWFrameBuffer :: Wiper_Crossfade Constructor -// -//========================================================================== - -OpenGLSWFrameBuffer::Wiper_Crossfade::Wiper_Crossfade() -: Clock(0) -{ -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: Wiper_Crossfade :: Run -// -// Fades the old screen into the new one over 32 ticks. -// -//========================================================================== - -bool OpenGLSWFrameBuffer::Wiper_Crossfade::Run(int ticks, OpenGLSWFrameBuffer *fb) -{ - Clock += ticks; - - // Put the initial screen back to the buffer. - DrawScreen(fb, fb->InitialWipeScreen.get()); - - // Draw the new screen on top of it. - DrawScreen(fb, fb->FinalWipeScreen.get(), GL_FUNC_ADD, ColorValue(0,0,0,Clock / 32.f), ColorRGBA(255,255,255,0)); - - return Clock >= 32; -} - -// WIPE: MELT -------------------------------------------------------------- - -//========================================================================== -// -// OpenGLSWFrameBuffer :: Wiper_Melt Constructor -// -//========================================================================== - -OpenGLSWFrameBuffer::Wiper_Melt::Wiper_Melt() -{ - int i, r; - - // setup initial column positions - // (y<0 => not ready to scroll yet) - y[0] = -(M_Random() & 15); - for (i = 1; i < WIDTH; ++i) - { - r = (M_Random()%3) - 1; - y[i] = clamp(y[i-1] + r, -15, 0); - } -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: Wiper_Melt :: Run -// -// Fades the old screen into the new one over 32 ticks. -// -//========================================================================== - -bool OpenGLSWFrameBuffer::Wiper_Melt::Run(int ticks, OpenGLSWFrameBuffer *fb) -{ - // Draw the new screen on the bottom. - DrawScreen(fb, fb->FinalWipeScreen.get()); - - int i, dy; - int fbwidth = fb->Width; - int fbheight = fb->Height; - bool done = true; - - // Copy the old screen in vertical strips on top of the new one. - while (ticks--) - { - done = true; - for (i = 0; i < WIDTH; i++) - { - if (y[i] < 0) - { - y[i]++; - done = false; - } - else if (y[i] < HEIGHT) - { - dy = (y[i] < 16) ? y[i]+1 : 8; - y[i] = MIN(y[i] + dy, HEIGHT); - done = false; - } - if (ticks == 0) - { // Only draw for the final tick. - LTRBRect rect; - struct Point { int x, y; } dpt; - - dpt.x = i * fbwidth / WIDTH; - dpt.y = MAX(0, y[i] * fbheight / HEIGHT); - rect.left = dpt.x; - rect.top = 0; - rect.right = (i + 1) * fbwidth / WIDTH; - rect.bottom = fbheight - dpt.y; - if (rect.bottom > rect.top) - { - fb->CheckQuadBatch(); - - BufferedTris *quad = &fb->QuadExtra[fb->QuadBatchPos]; - FBVERTEX *vert = &fb->VertexData[fb->VertexPos]; - uint16_t *index = &fb->IndexData[fb->IndexPos]; - - quad->ClearSetup(); - quad->Flags = BQF_DisableAlphaTest; - quad->ShaderNum = BQS_Plain; - quad->Palette = NULL; - quad->Texture = fb->InitialWipeScreen.get(); - quad->NumVerts = 4; - quad->NumTris = 2; - - // Fill the vertex buffer. - float u0 = rect.left / float(fb->Width); - float v0 = 0; - float u1 = rect.right / float(fb->Width); - float v1 = (rect.bottom - rect.top) / float(fb->Height); - - float x0 = float(rect.left); - float x1 = float(rect.right); - float y0 = float(dpt.y); - float y1 = float(fbheight); - - vert[0].x = x0; - vert[0].y = y0; - vert[0].z = 0; - vert[0].rhw = 1; - vert[0].color0 = 0; - vert[0].color1 = 0xFFFFFFF; - vert[0].tu = u0; - vert[0].tv = v0; - - vert[1].x = x1; - vert[1].y = y0; - vert[1].z = 0; - vert[1].rhw = 1; - vert[1].color0 = 0; - vert[1].color1 = 0xFFFFFFF; - vert[1].tu = u1; - vert[1].tv = v0; - - vert[2].x = x1; - vert[2].y = y1; - vert[2].z = 0; - vert[2].rhw = 1; - vert[2].color0 = 0; - vert[2].color1 = 0xFFFFFFF; - vert[2].tu = u1; - vert[2].tv = v1; - - vert[3].x = x0; - vert[3].y = y1; - vert[3].z = 0; - vert[3].rhw = 1; - vert[3].color0 = 0; - vert[3].color1 = 0xFFFFFFF; - vert[3].tu = u0; - vert[3].tv = v1; - - // Fill the vertex index buffer. - index[0] = fb->VertexPos; - index[1] = fb->VertexPos + 1; - index[2] = fb->VertexPos + 2; - index[3] = fb->VertexPos; - index[4] = fb->VertexPos + 2; - index[5] = fb->VertexPos + 3; - - // Batch the quad. - fb->QuadBatchPos++; - fb->VertexPos += 4; - fb->IndexPos += 6; - } - } - } - } - fb->EndQuadBatch(); - return done; -} - -// WIPE: BURN -------------------------------------------------------------- - -//========================================================================== -// -// OpenGLSWFrameBuffer :: Wiper_Burn Constructor -// -//========================================================================== - -OpenGLSWFrameBuffer::Wiper_Burn::Wiper_Burn(OpenGLSWFrameBuffer *fb) -{ - Density = 4; - BurnTime = 0; - memset(BurnArray, 0, sizeof(BurnArray)); - if (fb->Shaders[SHADER_BurnWipe] == nullptr) - { - BurnTexture = nullptr; - } - - BurnTexture = fb->CreateTexture("BurnWipe", WIDTH, HEIGHT, 1, GL_R8); -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: Wiper_Burn Destructor -// -//========================================================================== - -OpenGLSWFrameBuffer::Wiper_Burn::~Wiper_Burn() -{ - BurnTexture.reset(); -} - -//========================================================================== -// -// OpenGLSWFrameBuffer :: Wiper_Burn :: Run -// -//========================================================================== - -bool OpenGLSWFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLSWFrameBuffer *fb) -{ - bool done; - - BurnTime += ticks; - ticks *= 2; - - // Make the fire burn - done = false; - while (!done && ticks--) - { - Density = wipe_CalcBurn(BurnArray, WIDTH, HEIGHT, Density); - done = (Density < 0); - } - - // Update the burn texture with the new burn data - - if (BurnTexture->Buffers[0] == 0) - { - glGenBuffers(2, (GLuint*)BurnTexture->Buffers); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, BurnTexture->Buffers[0]); - glBufferData(GL_PIXEL_UNPACK_BUFFER, WIDTH * HEIGHT, nullptr, GL_STREAM_DRAW); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, BurnTexture->Buffers[1]); - glBufferData(GL_PIXEL_UNPACK_BUFFER, WIDTH * HEIGHT, nullptr, GL_STREAM_DRAW); - } - else - { - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, BurnTexture->Buffers[BurnTexture->CurrentBuffer]); - BurnTexture->CurrentBuffer = (BurnTexture->CurrentBuffer + 1) & 1; - } - - uint8_t *dest = (uint8_t*)glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, WIDTH * HEIGHT, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT); - if (dest) - { - memcpy(dest, BurnArray, WIDTH * HEIGHT); - glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); - - GLint oldBinding = 0; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldBinding); - glBindTexture(GL_TEXTURE_2D, BurnTexture->Texture); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, WIDTH, HEIGHT, GL_RED, GL_UNSIGNED_BYTE, 0); - glBindTexture(GL_TEXTURE_2D, oldBinding); - - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - } - - // Put the initial screen back to the buffer. - DrawScreen(fb, fb->InitialWipeScreen.get()); - - // Burn the new screen on top of it. - float right = float(fb->Width); - float bot = float(fb->Height); - - BURNVERTEX verts[4] = - { - { 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0, 0 }, - { right, 0.f, 0.f, 1.f, 1.f, 0.f, 1, 0 }, - { right, bot, 0.f, 1.f, 1.f, 1.f, 1, 1 }, - { 0.f, bot, 0.f, 1.f, 0.f, 1.f, 0, 1 } - }; - - fb->SetTexture(0, fb->FinalWipeScreen.get()); - fb->SetTexture(1, BurnTexture.get()); - fb->SetAlphaBlend(GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - fb->SetPixelShader(fb->Shaders[SHADER_BurnWipe].get()); - glActiveTexture(GL_TEXTURE1); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - fb->DrawTriangleFans(2, verts); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glActiveTexture(GL_TEXTURE0); - - // The fire may not always stabilize, so the wipe is forced to end - // after an arbitrary maximum time. - return done || (BurnTime > 40); -} diff --git a/src/gl/system/gl_system.h b/src/gl/system/gl_system.h index a8dcd129e4..0ad2f33034 100644 --- a/src/gl/system/gl_system.h +++ b/src/gl/system/gl_system.h @@ -6,7 +6,6 @@ #include #include #include -//#include #include #include #include @@ -20,20 +19,12 @@ #endif #include -#ifdef _MSC_VER -#define F_OK 0 /* Check for file existence */ -#define W_OK 2 /* Check for write permission */ -#define R_OK 4 /* Check for read permission */ -#include -#else -#include -#endif #include #include #include //GL headers -#include "gl_load.h" +#include "gl_load/gl_load.h" #if defined(__APPLE__) #include diff --git a/src/gl/system/gl_threads.cpp b/src/gl/system/gl_threads.cpp deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/gl/system/gl_wipe.cpp b/src/gl/system/gl_wipe.cpp index db03f99c1b..289a3edb75 100644 --- a/src/gl/system/gl_wipe.cpp +++ b/src/gl/system/gl_wipe.cpp @@ -39,12 +39,9 @@ #include "gl/system/gl_framebuffer.h" #include "gl/system/gl_cvars.h" #include "gl/shaders/gl_shader.h" -#include "gl/textures/gl_translate.h" #include "gl/textures/gl_material.h" #include "gl/textures/gl_samplers.h" -#include "gl/utility/gl_templates.h" #include "gl/data/gl_vertexbuffer.h" -#include "gl/renderer/gl_2ddrawer.h" //=========================================================================== @@ -123,7 +120,7 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type) } const auto &viewport = GLRenderer->mScreenViewport; - wipestartscreen = new FHardwareTexture(viewport.width, viewport.height, true); + wipestartscreen = new FHardwareTexture(true); wipestartscreen->CreateTexture(NULL, viewport.width, viewport.height, 0, false, 0, "WipeStartScreen"); GLRenderer->mSamplerManager->Bind(0, CLAMP_NOFILTER, -1); GLRenderer->mSamplerManager->Bind(1, CLAMP_NONE, -1); @@ -169,11 +166,9 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type) void OpenGLFrameBuffer::WipeEndScreen() { - GLRenderer->m2DDrawer->Draw(); - GLRenderer->m2DDrawer->Clear(); - + GLRenderer->Flush(); const auto &viewport = GLRenderer->mScreenViewport; - wipeendscreen = new FHardwareTexture(viewport.width, viewport.height, true); + wipeendscreen = new FHardwareTexture(true); wipeendscreen->CreateTexture(NULL, viewport.width, viewport.height, 0, false, 0, "WipeEndScreen"); GLRenderer->mSamplerManager->Bind(0, CLAMP_NOFILTER, -1); glFinish(); @@ -187,7 +182,6 @@ void OpenGLFrameBuffer::WipeEndScreen() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - Unlock(); } //========================================================================== @@ -208,8 +202,6 @@ bool OpenGLFrameBuffer::WipeDo(int ticks) // Sanity checks. if (wipestartscreen != nullptr && wipeendscreen != nullptr) { - Lock(true); - gl_RenderState.EnableTexture(true); gl_RenderState.EnableFog(false); glDisable(GL_DEPTH_TEST); @@ -520,7 +512,7 @@ bool OpenGLFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLFrameBuffer *fb) } if (BurnTexture != NULL) delete BurnTexture; - BurnTexture = new FHardwareTexture(WIDTH, HEIGHT, true); + BurnTexture = new FHardwareTexture(true); // Update the burn texture with the new burn data uint8_t rgb_buffer[WIDTH*HEIGHT*4]; diff --git a/src/gl/textures/gl_hwtexture.cpp b/src/gl/textures/gl_hwtexture.cpp index f6edec6870..0ab9457fa4 100644 --- a/src/gl/textures/gl_hwtexture.cpp +++ b/src/gl/textures/gl_hwtexture.cpp @@ -85,7 +85,7 @@ static void ResampleBoxPrecalc(TArray& boxes, int oldDim) } } -void FHardwareTexture::Resize(int width, int height, unsigned char *src_data, unsigned char *dst_data) +void FHardwareTexture::Resize(int swidth, int sheight, int width, int height, unsigned char *src_data, unsigned char *dst_data) { // This function implements a simple pre-blur/box averaging method for @@ -96,8 +96,8 @@ void FHardwareTexture::Resize(int width, int height, unsigned char *src_data, un TArray vPrecalcs(height, true); TArray hPrecalcs(width, true); - ResampleBoxPrecalc(vPrecalcs, texheight); - ResampleBoxPrecalc(hPrecalcs, texwidth); + ResampleBoxPrecalc(vPrecalcs, sheight); + ResampleBoxPrecalc(hPrecalcs, swidth); int averaged_pixels, averaged_alpha, src_pixel_index; double sum_r, sum_g, sum_b, sum_a; @@ -122,7 +122,7 @@ void FHardwareTexture::Resize(int width, int height, unsigned char *src_data, un for (int i = hPrecalc.boxStart; i <= hPrecalc.boxEnd; ++i) { // Calculate the actual index in our source pixels - src_pixel_index = j * texwidth + i; + src_pixel_index = j * swidth + i; int a = src_data[src_pixel_index * 4 + 3]; if (a > 0) // do not use color from fully transparent pixels @@ -177,13 +177,15 @@ unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int FGLDebug::LabelObject(GL_TEXTURE, glTex->glTexID, name); lastbound[texunit] = glTex->glTexID; - if (!buffer) + rw = GetTexDimension(w); + rh = GetTexDimension(h); + if (glBufferID > 0) + { + glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); + buffer = nullptr; + } + else if (!buffer) { - w=texwidth; - h=abs(texheight); - rw = GetTexDimension (w); - rh = GetTexDimension (h); - // The texture must at least be initialized if no data is present. glTex->mipmapped = false; buffer=(unsigned char *)calloc(4,rw * (rh+1)); @@ -192,24 +194,57 @@ unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int } else { - rw = GetTexDimension (w); - rh = GetTexDimension (h); - if (rw < w || rh < h) { // The texture is larger than what the hardware can handle so scale it down. unsigned char * scaledbuffer=(unsigned char *)calloc(4,rw * (rh+1)); if (scaledbuffer) { - Resize(rw, rh, buffer, scaledbuffer); + Resize(w, h, rw, rh, buffer, scaledbuffer); deletebuffer=true; buffer=scaledbuffer; } } } - glTexImage2D(GL_TEXTURE_2D, 0, texformat, rw, rh, 0, GL_BGRA, GL_UNSIGNED_BYTE, buffer); + // store the physical size. + texwidth = rw; + texheight = rh; - if (deletebuffer) free(buffer); + int sourcetype; + if (glTextureBytes > 0) + { + if (glTextureBytes < 4) glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + if (gl.legacyMode) + { + // Do not use 2 and 3 here. They won't do anything useful!!! + static const int ITypes[] = { GL_LUMINANCE8, GL_LUMINANCE8_ALPHA8, GL_RGB8, GL_RGBA8 }; + static const int STypes[] = { GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_BGR, GL_BGRA }; + + texformat = ITypes[glTextureBytes - 1]; + sourcetype = STypes[glTextureBytes - 1]; + } + else + { + static const int ITypes[] = { GL_R8, GL_RG8, GL_RGB8, GL_RGBA8 }; + static const int STypes[] = { GL_RED, GL_RG, GL_BGR, GL_BGRA }; + + texformat = ITypes[glTextureBytes - 1]; + sourcetype = STypes[glTextureBytes - 1]; + } + } + else + { + sourcetype = GL_BGRA; + } + + glTexImage2D(GL_TEXTURE_2D, 0, texformat, rw, rh, 0, sourcetype, GL_UNSIGNED_BYTE, buffer); + + if (deletebuffer && buffer) free(buffer); + else if (glBufferID) + { + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + } if (mipmap && TexFilter[gl_texture_filter].mipmapping) { @@ -222,16 +257,41 @@ unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int } +//=========================================================================== +// +// +// +//=========================================================================== +void FHardwareTexture::AllocateBuffer(int w, int h, int texelsize) +{ + int rw = GetTexDimension(w); + int rh = GetTexDimension(h); + if (texelsize < 1 || texelsize > 4) texelsize = 4; + glTextureBytes = texelsize; + if (rw == w || rh == h) + { + glGenBuffers(1, &glBufferID); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, glBufferID); + glBufferData(GL_PIXEL_UNPACK_BUFFER, w*h*texelsize, nullptr, GL_DYNAMIC_DRAW); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); + } +} + + +uint8_t *FHardwareTexture::MapBuffer() +{ + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, glBufferID); + return (uint8_t*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE); +} + //=========================================================================== // // Creates a texture // //=========================================================================== -FHardwareTexture::FHardwareTexture(int _width, int _height, bool nocompression) +FHardwareTexture::FHardwareTexture(bool nocompression) { forcenocompression = nocompression; - texwidth=_width; - texheight=_height; glDefTex.glTexID = 0; glDefTex.translation = 0; @@ -314,6 +374,7 @@ void FHardwareTexture::CleanUnused(SpriteHits &usedtranslations) FHardwareTexture::~FHardwareTexture() { Clean(true); + glDeleteBuffers(1, &glBufferID); } diff --git a/src/gl/textures/gl_hwtexture.h b/src/gl/textures/gl_hwtexture.h index 59fc981698..9dac63cbba 100644 --- a/src/gl/textures/gl_hwtexture.h +++ b/src/gl/textures/gl_hwtexture.h @@ -60,20 +60,22 @@ public: private: - short texwidth, texheight; + short texwidth = 0, texheight = 0; bool forcenocompression; TranslatedTexture glDefTex; TArray glTex_Translated; unsigned int glDepthID; // only used by camera textures + unsigned int glBufferID = 0; + int glTextureBytes = 4; TranslatedTexture * GetTexID(int translation); int GetDepthBuffer(); - void Resize(int width, int height, unsigned char *src_data, unsigned char *dst_data); + void Resize(int swidth, int sheight, int width, int height, unsigned char *src_data, unsigned char *dst_data); public: - FHardwareTexture(int w, int h, bool nocompress); + FHardwareTexture(bool nocompress); ~FHardwareTexture(); static void Unbind(int texunit); @@ -82,6 +84,9 @@ public: void BindToFrameBuffer(); unsigned int Bind(int texunit, int translation, bool needmipmap); + void AllocateBuffer(int w, int h, int texelsize); + uint8_t *MapBuffer(); + unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, const FString &name); unsigned int GetTextureHandle(int translation); diff --git a/src/gl/textures/gl_material.cpp b/src/gl/textures/gl_material.cpp index 6ec03a3d5f..be71fffd24 100644 --- a/src/gl/textures/gl_material.cpp +++ b/src/gl/textures/gl_material.cpp @@ -42,9 +42,6 @@ #include "gl/system/gl_framebuffer.h" #include "gl/renderer/gl_lightdata.h" #include "gl/renderer/gl_renderer.h" -#include "gl/data/gl_data.h" -#include "gl/textures/gl_texture.h" -#include "gl/textures/gl_translate.h" #include "gl/textures/gl_material.h" #include "gl/textures/gl_samplers.h" #include "gl/shaders/gl_shader.h" @@ -71,16 +68,27 @@ FGLTexture::FGLTexture(FTexture * tx, bool expandpatches) tex = tx; mHwTexture = NULL; - HiresLump = -1; - hirestexture = NULL; - bHasColorkey = false; - bIsTransparent = -1; - bExpandFlag = expandpatches; lastSampler = 254; lastTranslation = -1; tex->gl_info.SystemTexture[expandpatches] = this; } +//=========================================================================== +// +// Constructor 2 for the SW framebuffer which provides its own hardware texture. +// +//=========================================================================== +FGLTexture::FGLTexture(FTexture * tx, FHardwareTexture *hwtex) +{ + assert(tx->gl_info.SystemTexture[0] == NULL); + tex = tx; + + mHwTexture = hwtex; + lastSampler = 254; + lastTranslation = -1; + tex->gl_info.SystemTexture[0] = this; +} + //=========================================================================== // // Destructor @@ -90,58 +98,7 @@ FGLTexture::FGLTexture(FTexture * tx, bool expandpatches) FGLTexture::~FGLTexture() { Clean(true); - if (hirestexture) delete hirestexture; -} - -//========================================================================== -// -// Checks for the presence of a hires texture replacement and loads it -// -//========================================================================== -unsigned char *FGLTexture::LoadHiresTexture(FTexture *tex, int *width, int *height) -{ - if (bExpandFlag) return NULL; // doesn't work for expanded textures - - if (HiresLump==-1) - { - bHasColorkey = false; - HiresLump = CheckDDPK3(tex); - if (HiresLump < 0) HiresLump = CheckExternalFile(tex, bHasColorkey); - - if (HiresLump >=0) - { - hirestexture = FTexture::CreateTexture(HiresLump, ETextureType::Any); - } - } - if (hirestexture != NULL) - { - int w=hirestexture->GetWidth(); - int h=hirestexture->GetHeight(); - - unsigned char * buffer=new unsigned char[w*(h+1)*4]; - memset(buffer, 0, w * (h+1) * 4); - - FBitmap bmp(buffer, w*4, w, h); - - int trans = hirestexture->CopyTrueColorPixels(&bmp, 0, 0); - hirestexture->CheckTrans(buffer, w*h, trans); - bIsTransparent = hirestexture->gl_info.mIsTransparent; - - if (bHasColorkey) - { - // This is a crappy Doomsday color keyed image - // We have to remove the key manually. :( - uint32_t * dwdata=(uint32_t*)buffer; - for (int i=(w*h);i>0;i--) - { - if (dwdata[i]==0xffffff00 || dwdata[i]==0xffff00ff) dwdata[i]=0; - } - } - *width = w; - *height = h; - return buffer; - } - return NULL; + for (auto & i : tex->gl_info.SystemTexture) if (i == this) i = nullptr; } //=========================================================================== @@ -178,81 +135,6 @@ void FGLTexture::CleanUnused(SpriteHits &usedtranslations) } -//=========================================================================== -// -// Initializes the buffer for the texture data -// -//=========================================================================== - -unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, FTexture *hirescheck, bool createexpanded, bool alphatrans) -{ - unsigned char * buffer; - int W, H; - int isTransparent = -1; - - - // Textures that are already scaled in the texture lump will not get replaced - // by hires textures - if (gl_texture_usehires && hirescheck != NULL && !alphatrans) - { - buffer = LoadHiresTexture (hirescheck, &w, &h); - if (buffer) - { - return buffer; - } - } - - int exx = bExpandFlag && createexpanded; - - W = w = tex->GetWidth() + 2 * exx; - H = h = tex->GetHeight() + 2 * exx; - - - buffer=new unsigned char[W*(H+1)*4]; - memset(buffer, 0, W * (H+1) * 4); - - FBitmap bmp(buffer, W*4, W, H); - - if (translation <= 0 || alphatrans) - { - int trans = tex->CopyTrueColorPixels(&bmp, exx, exx); - tex->CheckTrans(buffer, W*H, trans); - isTransparent = tex->gl_info.mIsTransparent; - if (bIsTransparent == -1) bIsTransparent = isTransparent; - // alpha texture for legacy mode - if (alphatrans) - { - for (int i = 0; i < W*H; i++) - { - int b = buffer[4 * i]; - int g = buffer[4 * i + 1]; - int r = buffer[4 * i + 2]; - int gray = Luminance(r, g, b); - buffer[4 * i] = 255; - buffer[4 * i + 1] = 255; - buffer[4 * i + 2] = 255; - buffer[4 * i + 3] = (buffer[4 * i + 3] * gray) >> 8; - } - } - } - else - { - // When using translations everything must be mapped to the base palette. - // so use CopyTrueColorTranslated - tex->CopyTrueColorTranslated(&bmp, exx, exx, 0, GLTranslationPalette::GetPalette(translation)); - isTransparent = 0; - // This is not conclusive for setting the texture's transparency info. - } - - // if we just want the texture for some checks there's no need for upsampling. - if (!createexpanded) return buffer; - - // [BB] The hqnx upsampling (not the scaleN one) destroys partial transparency, don't upsamle textures using it. - // [BB] Potentially upsample the buffer. - return gl_CreateUpsampledTextureBuffer ( tex, buffer, W, H, w, h, !!isTransparent); -} - - //=========================================================================== // // Create hardware texture for world use @@ -264,7 +146,7 @@ FHardwareTexture *FGLTexture::CreateHwTexture() if (tex->UseType==ETextureType::Null) return NULL; // Cannot register a NULL texture if (mHwTexture == NULL) { - mHwTexture = new FHardwareTexture(tex->GetWidth() + bExpandFlag*2, tex->GetHeight() + bExpandFlag*2, tex->gl_info.bNoCompress); + mHwTexture = new FHardwareTexture(tex->bNoCompress); } return mHwTexture; } @@ -275,21 +157,18 @@ FHardwareTexture *FGLTexture::CreateHwTexture() // //=========================================================================== -const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int translation, FTexture *hirescheck) +const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int translation, int flags) { int usebright = false; - bool alphatrans = translation == INT_MAX; // This is only needed for legacy mode because no texture combine setting allows using the color as alpha. - if (!alphatrans) + if (translation <= 0) { - if (translation <= 0) - { - translation = -translation; - } - else - { - translation = GLTranslationPalette::GetInternalTranslation(translation); - } + translation = -translation; + } + else + { + auto remap = TranslationToTable(translation); + translation = remap == nullptr ? 0 : remap->GetUniqueIndex(); } bool needmipmap = (clampmode <= CLAMP_XY); @@ -312,11 +191,11 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int transla int w=0, h=0; // Create this texture - unsigned char * buffer = NULL; + unsigned char * buffer = nullptr; if (!tex->bHasCanvas) { - buffer = CreateTexBuffer(translation, w, h, hirescheck, true, alphatrans); + buffer = tex->CreateTexBuffer(translation, w, h, flags | CTF_ProcessData); if (tex->bWarped && gl.legacyMode && w*h <= 256*256) // do not software-warp larger textures, especially on the old systems that still need this fallback. { // need to do software warping @@ -327,7 +206,6 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int transla buffer = warpbuffer; wt->GenTime[0] = screen->FrameTime; } - tex->ProcessData(buffer, w, h, false); } if (!hwtex->CreateTexture(buffer, w, h, texunit, needmipmap, translation, "FGLTexture.Bind")) { @@ -449,39 +327,43 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) } else */ - if (tx->bWarped) + if (tx->UseType == ETextureType::SWCanvas && tx->WidthBits == 0) + { + mShaderIndex = SHADER_Paletted; + } + else if (tx->bWarped) { mShaderIndex = tx->bWarped; // This picks SHADER_Warp1 or SHADER_Warp2 - tx->gl_info.shaderspeed = static_cast(tx)->GetSpeed(); + tx->shaderspeed = static_cast(tx)->GetSpeed(); } else if (tx->bHasCanvas) { - if (tx->gl_info.shaderindex >= FIRST_USER_SHADER) + if (tx->shaderindex >= FIRST_USER_SHADER) { - mShaderIndex = tx->gl_info.shaderindex; + mShaderIndex = tx->shaderindex; } // no brightmap for cameratexture } else { - if (tx->gl_info.shaderindex >= FIRST_USER_SHADER) + if (tx->shaderindex >= FIRST_USER_SHADER) { - mShaderIndex = tx->gl_info.shaderindex; + mShaderIndex = tx->shaderindex; } else { - if (tx->gl_info.Normal && tx->gl_info.Specular) + if (tx->Normal && tx->Specular) { - for (auto &texture : { tx->gl_info.Normal, tx->gl_info.Specular }) + for (auto &texture : { tx->Normal, tx->Specular }) { ValidateSysTexture(texture, expanded); mTextureLayers.Push({ texture, false }); } mShaderIndex = SHADER_Specular; } - else if (tx->gl_info.Normal && tx->gl_info.Metallic && tx->gl_info.Roughness && tx->gl_info.AmbientOcclusion) + else if (tx->Normal && tx->Metallic && tx->Roughness && tx->AmbientOcclusion) { - for (auto &texture : { tx->gl_info.Normal, tx->gl_info.Metallic, tx->gl_info.Roughness, tx->gl_info.AmbientOcclusion }) + for (auto &texture : { tx->Normal, tx->Metallic, tx->Roughness, tx->AmbientOcclusion }) { ValidateSysTexture(texture, expanded); mTextureLayers.Push({ texture, false }); @@ -490,10 +372,10 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) } tx->CreateDefaultBrightmap(); - if (tx->gl_info.Brightmap != NULL) + if (tx->Brightmap != NULL) { - ValidateSysTexture(tx->gl_info.Brightmap, expanded); - FTextureLayer layer = {tx->gl_info.Brightmap, false}; + ValidateSysTexture(tx->Brightmap, expanded); + FTextureLayer layer = {tx->Brightmap, false}; mTextureLayers.Push(layer); if (mShaderIndex == SHADER_Specular) mShaderIndex = SHADER_SpecularBrightmap; @@ -509,8 +391,8 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) mWidth = tx->GetWidth(); mHeight = tx->GetHeight(); - mLeftOffset = tx->LeftOffset; - mTopOffset = tx->TopOffset; + mLeftOffset = tx->GetLeftOffset(0); // These only get used by decals and decals should not use renderer-specific offsets. + mTopOffset = tx->GetTopOffset(0); mRenderWidth = tx->GetScaledWidth(); mRenderHeight = tx->GetScaledHeight(); mSpriteU[0] = mSpriteV[0] = 0.f; @@ -523,59 +405,26 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) mBaseLayer = ValidateSysTexture(basetex, expanded); } - float fxScale = tx->Scale.X; - float fyScale = tx->Scale.Y; - - // mSpriteRect is for positioning the sprite in the scene. - mSpriteRect.left = -mLeftOffset / fxScale; - mSpriteRect.top = -mTopOffset / fyScale; - mSpriteRect.width = mWidth / fxScale; - mSpriteRect.height = mHeight / fyScale; - + mExpanded = expanded; if (expanded) { - // a little adjustment to make sprites look better with texture filtering: - // create a 1 pixel wide empty frame around them. - int trim[4]; - bool trimmed = TrimBorders(trim); // get the trim size before adding the empty frame - int oldwidth = mWidth; int oldheight = mHeight; - mWidth+=2; - mHeight+=2; - mLeftOffset+=1; - mTopOffset+=1; + mTrimResult = TrimBorders(trim); // get the trim size before adding the empty frame + mWidth += 2; + mHeight += 2; mRenderWidth = mRenderWidth * mWidth / oldwidth; mRenderHeight = mRenderHeight * mHeight / oldheight; - // Reposition the sprite with the frame considered - mSpriteRect.left = -mLeftOffset / fxScale; - mSpriteRect.top = -mTopOffset / fyScale; - mSpriteRect.width = mWidth / fxScale; - mSpriteRect.height = mHeight / fyScale; - - if (trimmed) - { - mSpriteRect.left += trim[0] / fxScale; - mSpriteRect.top += trim[1] / fyScale; - - mSpriteRect.width -= (oldwidth - trim[2]) / fxScale; - mSpriteRect.height -= (oldheight - trim[3]) / fyScale; - - mSpriteU[0] = trim[0] / (float)mWidth; - mSpriteV[0] = trim[1] / (float)mHeight; - mSpriteU[1] -= (oldwidth - trim[0] - trim[2]) / (float)mWidth; - mSpriteV[1] -= (oldheight - trim[1] - trim[3]) / (float)mHeight; - } } + SetSpriteRect(); mTextureLayers.ShrinkToFit(); mMaxBound = -1; mMaterials.Push(this); tx->gl_info.Material[expanded] = this; - if (tx->bHasCanvas) tx->gl_info.mIsTransparent = 0; - mExpanded = expanded; + if (tx->bHasCanvas) tx->bTranslucent = 0; } //=========================================================================== @@ -597,21 +446,74 @@ FMaterial::~FMaterial() } - //=========================================================================== -// -// Finds gaps in the texture which can be skipped by the renderer -// This was mainly added to speed up one area in E4M6 of 007LTSD +// +// Set the sprite rectangle // //=========================================================================== -bool FMaterial::TrimBorders(int *rect) +void FMaterial::SetSpriteRect() +{ + auto leftOffset = tex->GetLeftOffsetHW(); + auto topOffset = tex->GetTopOffsetHW(); + + float fxScale = tex->Scale.X; + float fyScale = tex->Scale.Y; + + // mSpriteRect is for positioning the sprite in the scene. + mSpriteRect.left = -leftOffset / fxScale; + mSpriteRect.top = -topOffset / fyScale; + mSpriteRect.width = mWidth / fxScale; + mSpriteRect.height = mHeight / fyScale; + + if (mExpanded) + { + // a little adjustment to make sprites look better with texture filtering: + // create a 1 pixel wide empty frame around them. + + int oldwidth = mWidth - 2; + int oldheight = mHeight - 2; + + leftOffset += 1; + topOffset += 1; + + // Reposition the sprite with the frame considered + mSpriteRect.left = -leftOffset / fxScale; + mSpriteRect.top = -topOffset / fyScale; + mSpriteRect.width = mWidth / fxScale; + mSpriteRect.height = mHeight / fyScale; + + if (mTrimResult) + { + mSpriteRect.left += trim[0] / fxScale; + mSpriteRect.top += trim[1] / fyScale; + + mSpriteRect.width -= (oldwidth - trim[2]) / fxScale; + mSpriteRect.height -= (oldheight - trim[3]) / fyScale; + + mSpriteU[0] = trim[0] / (float)mWidth; + mSpriteV[0] = trim[1] / (float)mHeight; + mSpriteU[1] -= (oldwidth - trim[0] - trim[2]) / (float)mWidth; + mSpriteV[1] -= (oldheight - trim[1] - trim[3]) / (float)mHeight; + } + } +} + + +//=========================================================================== +// +// Finds empty space around the texture. +// Used for sprites that got placed into a huge empty frame. +// +//=========================================================================== + +bool FMaterial::TrimBorders(uint16_t *rect) { PalEntry col; int w; int h; - unsigned char *buffer = CreateTexBuffer(0, w, h, false, false); + unsigned char *buffer = tex->CreateTexBuffer(0, w, h); if (buffer == NULL) { @@ -721,12 +623,15 @@ void FMaterial::Bind(int clampmode, int translation) int usebright = false; int maxbound = 0; - bool allowhires = tex->Scale.X == 1 && tex->Scale.Y == 1 && clampmode <= CLAMP_XY && !mExpanded; + if (tex->UseType == ETextureType::SWCanvas) clampmode = CLAMP_NOFILTER; if (tex->bHasCanvas) clampmode = CLAMP_CAMTEX; else if (tex->bWarped && clampmode <= CLAMP_XY) clampmode = CLAMP_NONE; - const FHardwareTexture *gltexture = mBaseLayer->Bind(0, clampmode, translation, allowhires? tex:NULL); + // Textures that are already scaled in the texture lump will not get replaced by hires textures. + int flags = mExpanded? CTF_Expand : (gl_texture_usehires && tex->Scale.X == 1 && tex->Scale.Y == 1 && clampmode <= CLAMP_XY)? CTF_CheckHires : 0; + + const FHardwareTexture *gltexture = mBaseLayer->Bind(0, clampmode, translation, flags); if (gltexture != NULL) { for(unsigned i=0;igl_info.SystemTexture[mExpanded]->Bind(i+1, clampmode, 0, NULL); + layer->gl_info.SystemTexture[mExpanded]->Bind(i+1, clampmode, 0, 0); maxbound = i+1; } } @@ -833,8 +738,8 @@ int FMaterial::GetAreas(FloatRect **pAreas) const if (mShaderIndex == SHADER_Default) // texture splitting can only be done if there's no attached effects { FTexture *tex = mBaseLayer->tex; - *pAreas = tex->gl_info.areas; - return tex->gl_info.areacount; + *pAreas = tex->areas; + return tex->areacount; } else { @@ -853,7 +758,7 @@ void FMaterial::BindToFrameBuffer() if (mBaseLayer->mHwTexture == NULL) { // must create the hardware texture first - mBaseLayer->Bind(0, 0, 0, NULL); + mBaseLayer->Bind(0, 0, 0, 0); FHardwareTexture::Unbind(0); ClearLastTexture(); } @@ -879,14 +784,14 @@ again: { if (expand) { - if (tex->bWarped || tex->bHasCanvas || tex->gl_info.shaderindex >= FIRST_USER_SHADER) + if (tex->bWarped || tex->bHasCanvas || tex->shaderindex >= FIRST_USER_SHADER || (tex->shaderindex >= SHADER_Specular && tex->shaderindex <= SHADER_PBRBrightmap)) { tex->gl_info.bNoExpand = true; goto again; } - if (tex->gl_info.Brightmap != NULL && - (tex->GetWidth() != tex->gl_info.Brightmap->GetWidth() || - tex->GetHeight() != tex->gl_info.Brightmap->GetHeight()) + if (tex->Brightmap != NULL && + (tex->GetWidth() != tex->Brightmap->GetWidth() || + tex->GetHeight() != tex->Brightmap->GetHeight()) ) { // do not expand if the brightmap's size differs. diff --git a/src/gl/textures/gl_material.h b/src/gl/textures/gl_material.h index fc10f3a492..60ec531e58 100644 --- a/src/gl/textures/gl_material.h +++ b/src/gl/textures/gl_material.h @@ -45,45 +45,35 @@ struct FTexCoordInfo //=========================================================================== // -// this is the texture maintenance class for OpenGL. +// device independent wrapper around the hardware texture and its sampler state // //=========================================================================== class FMaterial; - class FGLTexture { friend class FMaterial; public: FTexture * tex; - FTexture * hirestexture; - int8_t bIsTransparent; - int HiresLump; private: FHardwareTexture *mHwTexture; - bool bHasColorkey; // only for hires - bool bExpandFlag; uint8_t lastSampler; int lastTranslation; - unsigned char * LoadHiresTexture(FTexture *hirescheck, int *width, int *height); - FHardwareTexture *CreateHwTexture(); - const FHardwareTexture *Bind(int texunit, int clamp, int translation, FTexture *hirescheck); + const FHardwareTexture *Bind(int texunit, int clamp, int translation, int flags); public: FGLTexture(FTexture * tx, bool expandpatches); + FGLTexture(FTexture * tx, FHardwareTexture *hwtex); // for the SW framebuffer ~FGLTexture(); - unsigned char * CreateTexBuffer(int translation, int & w, int & h, FTexture *hirescheck, bool createexpanded = true, bool alphatrans = false); - void Clean(bool all); void CleanUnused(SpriteHits &usedtranslations); - int Dump(int i); - + bool isInitialized() const { return mHwTexture != nullptr; } }; //=========================================================================== @@ -102,6 +92,9 @@ class FMaterial bool animated; }; + // This array is needed because not all textures are managed by the texture manager + // but some code needs to discard all hardware dependent data attached to any created texture. + // Font characters are not, for example. static TArray mMaterials; static int mMaxBound; @@ -116,20 +109,29 @@ class FMaterial short mRenderWidth; short mRenderHeight; bool mExpanded; + bool mTrimResult; + uint16_t trim[4]; float mSpriteU[2], mSpriteV[2]; FloatRect mSpriteRect; FGLTexture * ValidateSysTexture(FTexture * tex, bool expand); - bool TrimBorders(int *rect); + bool TrimBorders(uint16_t *rect); public: FTexture *tex; FMaterial(FTexture *tex, bool forceexpand); ~FMaterial(); + void SetSpriteRect(); void Precache(); void PrecacheList(SpriteHits &translations); + void AddTextureLayer(FTexture *tex) + { + FTextureLayer layer = { tex, false }; + ValidateTexture(tex, false); + mTextureLayers.Push(layer); + } bool isMasked() const { return !!mBaseLayer->tex->bMasked; @@ -142,11 +144,6 @@ public: void Bind(int clamp, int translation); - unsigned char * CreateTexBuffer(int translation, int & w, int & h, bool allowhires=true, bool createexpanded = true) const - { - return mBaseLayer->CreateTexBuffer(translation, w, h, allowhires? tex : NULL, createexpanded); - } - void Clean(bool f) { mBaseLayer->Clean(f); @@ -193,37 +190,6 @@ public: return mTopOffset; } - int GetScaledLeftOffset() const - { - return int(mLeftOffset / tex->Scale.X); - } - - int GetScaledTopOffset() const - { - return int(mTopOffset / tex->Scale.Y); - } - - float GetScaledLeftOffsetFloat() const - { - return float(mLeftOffset / tex->Scale.X); - } - - float GetScaledTopOffsetFloat() const - { - return float(mTopOffset/ tex->Scale.Y); - } - - // This is scaled size in floating point as needed by sprites - float GetScaledWidthFloat() const - { - return float(mWidth / tex->Scale.X); - } - - float GetScaledHeightFloat() const - { - return float(mHeight / tex->Scale.Y); - } - // Get right/bottom UV coordinates for patch drawing float GetUL() const { return 0; } float GetVT() const { return 0; } @@ -238,25 +204,6 @@ public: float GetSpriteVB() const { return mSpriteV[1]; } - - bool GetTransparent() const - { - if (mBaseLayer->bIsTransparent == -1) - { - if (!mBaseLayer->tex->bHasCanvas) - { - int w, h; - unsigned char *buffer = CreateTexBuffer(0, w, h); - delete [] buffer; - } - else - { - mBaseLayer->bIsTransparent = 0; - } - } - return !!mBaseLayer->bIsTransparent; - } - static void DeleteAll(); static void FlushAll(); static FMaterial *ValidateTexture(FTexture * tex, bool expand); diff --git a/src/gl/textures/gl_samplers.cpp b/src/gl/textures/gl_samplers.cpp index df1d105397..5ca9a8d0b9 100644 --- a/src/gl/textures/gl_samplers.cpp +++ b/src/gl/textures/gl_samplers.cpp @@ -94,6 +94,7 @@ uint8_t FSamplerManager::Bind(int texunit, int num, int lastval) } else { + int filter = V_IsHardwareRenderer() ? gl_texture_filter : 0; glActiveTexture(GL_TEXTURE0 + texunit); switch (num) { @@ -102,8 +103,8 @@ uint8_t FSamplerManager::Bind(int texunit, int num, int lastval) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); if (lastval >= CLAMP_XY_NOMIP) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].minfilter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[gl_texture_filter].magfilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[filter].minfilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[filter].magfilter); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_texture_filter_anisotropic); } break; @@ -113,8 +114,8 @@ uint8_t FSamplerManager::Bind(int texunit, int num, int lastval) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); if (lastval >= CLAMP_XY_NOMIP) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].minfilter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[gl_texture_filter].magfilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[filter].minfilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[filter].magfilter); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_texture_filter_anisotropic); } break; @@ -124,8 +125,8 @@ uint8_t FSamplerManager::Bind(int texunit, int num, int lastval) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); if (lastval >= CLAMP_XY_NOMIP) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].minfilter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[gl_texture_filter].magfilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[filter].minfilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[filter].magfilter); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_texture_filter_anisotropic); } break; @@ -135,8 +136,8 @@ uint8_t FSamplerManager::Bind(int texunit, int num, int lastval) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); if (lastval >= CLAMP_XY_NOMIP) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].minfilter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[gl_texture_filter].magfilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[filter].minfilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[filter].magfilter); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_texture_filter_anisotropic); } break; @@ -144,8 +145,8 @@ uint8_t FSamplerManager::Bind(int texunit, int num, int lastval) case CLAMP_XY_NOMIP: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].magfilter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[gl_texture_filter].magfilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[filter].magfilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[filter].magfilter); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1); break; @@ -160,8 +161,8 @@ uint8_t FSamplerManager::Bind(int texunit, int num, int lastval) case CLAMP_CAMTEX: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].magfilter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[gl_texture_filter].magfilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[filter].magfilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[filter].magfilter); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1); break; } @@ -176,17 +177,18 @@ void FSamplerManager::SetTextureFilterMode() if (gl.flags & RFL_SAMPLER_OBJECTS) { UnbindAll(); + int filter = V_IsHardwareRenderer() ? gl_texture_filter : 0; for (int i = 0; i < 4; i++) { - glSamplerParameteri(mSamplers[i], GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].minfilter); - glSamplerParameteri(mSamplers[i], GL_TEXTURE_MAG_FILTER, TexFilter[gl_texture_filter].magfilter); + glSamplerParameteri(mSamplers[i], GL_TEXTURE_MIN_FILTER, TexFilter[filter].minfilter); + glSamplerParameteri(mSamplers[i], GL_TEXTURE_MAG_FILTER, TexFilter[filter].magfilter); glSamplerParameterf(mSamplers[i], GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_texture_filter_anisotropic); } - glSamplerParameteri(mSamplers[4], GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].magfilter); - glSamplerParameteri(mSamplers[4], GL_TEXTURE_MAG_FILTER, TexFilter[gl_texture_filter].magfilter); - glSamplerParameteri(mSamplers[6], GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].magfilter); - glSamplerParameteri(mSamplers[6], GL_TEXTURE_MAG_FILTER, TexFilter[gl_texture_filter].magfilter); + glSamplerParameteri(mSamplers[4], GL_TEXTURE_MIN_FILTER, TexFilter[filter].magfilter); + glSamplerParameteri(mSamplers[4], GL_TEXTURE_MAG_FILTER, TexFilter[filter].magfilter); + glSamplerParameteri(mSamplers[6], GL_TEXTURE_MIN_FILTER, TexFilter[filter].magfilter); + glSamplerParameteri(mSamplers[6], GL_TEXTURE_MAG_FILTER, TexFilter[filter].magfilter); } else { diff --git a/src/gl/textures/gl_texture.cpp b/src/gl/textures/gl_texture.cpp index c313611172..e6dafc4c51 100644 --- a/src/gl/textures/gl_texture.cpp +++ b/src/gl/textures/gl_texture.cpp @@ -34,19 +34,14 @@ #include "r_state.h" #include "actor.h" #include "cmdlib.h" -#ifdef _WIN32 -#include "win32gliface.h" -#endif #include "v_palette.h" #include "sc_man.h" #include "textures/skyboxtexture.h" #include "gl/system/gl_interface.h" #include "gl/renderer/gl_renderer.h" -#include "gl/textures/gl_texture.h" #include "gl/textures/gl_material.h" #include "gl/textures/gl_samplers.h" -#include "gl/textures/gl_translate.h" #include "gl/models/gl_models.h" //========================================================================== @@ -117,94 +112,7 @@ int TexFormat[]={ -bool HasGlobalBrightmap; -FRemapTable GlobalBrightmap; - -//=========================================================================== -// -// Examines the colormap to see if some of the colors have to be -// considered fullbright all the time. -// -//=========================================================================== - -void gl_GenerateGlobalBrightmapFromColormap() -{ - HasGlobalBrightmap = false; - int lump = Wads.CheckNumForName("COLORMAP"); - if (lump == -1) lump = Wads.CheckNumForName("COLORMAP", ns_colormaps); - if (lump == -1) return; - FMemLump cmap = Wads.ReadLump(lump); - uint8_t palbuffer[768]; - ReadPalette(Wads.CheckNumForName("PLAYPAL"), palbuffer); - - const unsigned char *cmapdata = (const unsigned char *)cmap.GetMem(); - const uint8_t *paldata = palbuffer; - - const int black = 0; - const int white = ColorMatcher.Pick(255,255,255); - - - GlobalBrightmap.MakeIdentity(); - memset(GlobalBrightmap.Remap, white, 256); - for(int i=0;i<256;i++) GlobalBrightmap.Palette[i]=PalEntry(255,255,255,255); - for(int j=0;j<32;j++) - { - for(int i=0;i<256;i++) - { - // the palette comparison should be for ==0 but that gives false positives with Heretic - // and Hexen. - if (cmapdata[i+j*256]!=i || (paldata[3*i]<10 && paldata[3*i+1]<10 && paldata[3*i+2]<10)) - { - GlobalBrightmap.Remap[i]=black; - GlobalBrightmap.Palette[i] = PalEntry(255, 0, 0, 0); - } - } - } - for(int i=0;i<256;i++) - { - HasGlobalBrightmap |= GlobalBrightmap.Remap[i] == white; - if (GlobalBrightmap.Remap[i] == white) DPrintf(DMSG_NOTIFY, "Marked color %d as fullbright\n",i); - } -} - - -//========================================================================== -// -// GL status data for a texture -// -//========================================================================== - -FTexture::MiscGLInfo::MiscGLInfo() throw() -{ - bGlowing = false; - GlowColor = 0; - GlowHeight = 128; - bSkybox = false; - bFullbright = false; - bBrightmapChecked = false; - bDisableFullbright = false; - bNoFilter = false; - bNoCompress = false; - bNoExpand = false; - areas = NULL; - areacount = 0; - mIsTransparent = -1; - shaderspeed = 1.f; - shaderindex = 0; - Glossiness = 10.0f; - SpecularLevel = 0.1f; - - Material[1] = Material[0] = NULL; - SystemTexture[1] = SystemTexture[0] = NULL; - Brightmap = NULL; - Normal = NULL; - Specular = NULL; - Metallic = NULL; - Roughness = NULL; - AmbientOcclusion = NULL; -} - -FTexture::MiscGLInfo::~MiscGLInfo() +FTexture::GLTexInfo::~GLTexInfo() { for (int i = 0; i < 2; i++) { @@ -214,648 +122,23 @@ FTexture::MiscGLInfo::~MiscGLInfo() if (SystemTexture[i] != NULL) delete SystemTexture[i]; SystemTexture[i] = NULL; } - - // this is just a reference to another texture in the texture manager. - Brightmap = NULL; - - if (areas != NULL) delete [] areas; - areas = NULL; } //=========================================================================== // -// Checks if the texture has a default brightmap and creates it if so -// -//=========================================================================== -void FTexture::CreateDefaultBrightmap() -{ - if (!gl_info.bBrightmapChecked) - { - // Check for brightmaps - if (UseBasePalette() && HasGlobalBrightmap && - UseType != ETextureType::Decal && UseType != ETextureType::MiscPatch && UseType != ETextureType::FontChar && - gl_info.Brightmap == NULL && bWarped == 0 - ) - { - // May have one - let's check when we use this texture - const uint8_t *texbuf = GetPixels(DefaultRenderStyle()); - const int white = ColorMatcher.Pick(255,255,255); - - int size = GetWidth() * GetHeight(); - for(int i=0;iGetTextureBuffer(this, w, h); - - if (buffer) - { - gl_info.GlowColor = averageColor((uint32_t *) buffer, w*h, 153); - delete[] buffer; - } - - // Black glow equals nothing so switch glowing off - if (gl_info.GlowColor == 0) gl_info.bGlowing = false; - } - data[0]=gl_info.GlowColor.r/255.0f; - data[1]=gl_info.GlowColor.g/255.0f; - data[2]=gl_info.GlowColor.b/255.0f; -} - -//=========================================================================== -// -// Finds gaps in the texture which can be skipped by the renderer -// This was mainly added to speed up one area in E4M6 of 007LTSD +// Sprite adjust has changed. +// This needs to alter the material's sprite rect. // //=========================================================================== -bool FTexture::FindHoles(const unsigned char * buffer, int w, int h) +void FTexture::SetSpriteAdjust() { - const unsigned char * li; - int y,x; - int startdraw,lendraw; - int gaps[5][2]; - int gapc=0; - - - // already done! - if (gl_info.areacount) return false; - if (UseType == ETextureType::Flat) return false; // flats don't have transparent parts - gl_info.areacount=-1; //whatever happens next, it shouldn't be done twice! - - // large textures are excluded for performance reasons - if (h>512) return false; - - startdraw=-1; - lendraw=0; - for(y=0;y 0) - { - FloatRect * rcs = new FloatRect[gapc]; - - for (x = 0; x < gapc; x++) - { - // gaps are stored as texture (u/v) coordinates - rcs[x].width = rcs[x].left = -1.0f; - rcs[x].top = (float)gaps[x][0] / (float)h; - rcs[x].height = (float)gaps[x][1] / (float)h; - } - gl_info.areas = rcs; - } - else gl_info.areas = nullptr; - gl_info.areacount=gapc; - - return true; -} - -//---------------------------------------------------------------------------- -// -// -// -//---------------------------------------------------------------------------- - -void FTexture::CheckTrans(unsigned char * buffer, int size, int trans) -{ - if (gl_info.mIsTransparent == -1) - { - gl_info.mIsTransparent = trans; - if (trans == -1) - { - uint32_t * dwbuf = (uint32_t*)buffer; - for(int i=0;i>24; - - if (alpha != 0xff && alpha != 0) - { - gl_info.mIsTransparent = 1; - return; - } - } - gl_info.mIsTransparent = 0; - } + if (mat != nullptr) mat->SetSpriteRect(); } } - -//=========================================================================== -// -// smooth the edges of transparent fields in the texture -// -//=========================================================================== - -#ifdef WORDS_BIGENDIAN -#define MSB 0 -#define SOME_MASK 0xffffff00 -#else -#define MSB 3 -#define SOME_MASK 0x00ffffff -#endif - -#define CHKPIX(ofs) (l1[(ofs)*4+MSB]==255 ? (( ((uint32_t*)l1)[0] = ((uint32_t*)l1)[ofs]&SOME_MASK), trans=true ) : false) - -bool FTexture::SmoothEdges(unsigned char * buffer,int w, int h) -{ - int x,y; - bool trans=buffer[MSB]==0; // If I set this to false here the code won't detect textures - // that only contain transparent pixels. - bool semitrans = false; - unsigned char * l1; - - if (h<=1 || w<=1) return false; // makes (a) no sense and (b) doesn't work with this code! - - l1=buffer; - - - if (l1[MSB]==0 && !CHKPIX(1)) CHKPIX(w); - else if (l1[MSB]<255) semitrans=true; - l1+=4; - for(x=1;xbNoDecals; - Rotations = source->Rotations; - UseType = source->UseType; - bMasked = false; - id.SetInvalid(); - SourceLump = -1; -} - -uint8_t *FBrightmapTexture::MakeTexture(FRenderStyle style) -{ - // This function is only necessary to satisfy the parent class's interface. - // This will never be called. - return nullptr; -} - -int FBrightmapTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) -{ - SourcePic->CopyTrueColorTranslated(bmp, x, y, rotate, GlobalBrightmap.Palette); - return 0; -} - -//========================================================================== -// -// Parses a material definition -// -//========================================================================== - -void gl_ParseMaterial(FScanner &sc, int deflump) -{ - ETextureType type = ETextureType::Any; - bool disable_fullbright = false; - bool disable_fullbright_specified = false; - bool thiswad = false; - bool iwad = false; - - FTexture *textures[6]; - const char *keywords[7] = { "brightmap", "normal", "specular", "metallic", "roughness", "ao", nullptr }; - const char *notFound[6] = { "Brightmap", "Normalmap", "Specular texture", "Metallic texture", "Roughness texture", "Ambient occlusion texture" }; - memset(textures, 0, sizeof(textures)); - - sc.MustGetString(); - if (sc.Compare("texture")) type = ETextureType::Wall; - else if (sc.Compare("flat")) type = ETextureType::Flat; - else if (sc.Compare("sprite")) type = ETextureType::Sprite; - else sc.UnGet(); - - sc.MustGetString(); - FTextureID no = TexMan.CheckForTexture(sc.String, type, FTextureManager::TEXMAN_TryAny | FTextureManager::TEXMAN_Overridable); - FTexture *tex = TexMan[no]; - - sc.MustGetToken('{'); - while (!sc.CheckToken('}')) - { - sc.MustGetString(); - if (sc.Compare("disablefullbright")) - { - // This can also be used without a brightness map to disable - // fullbright in rotations that only use brightness maps on - // other angles. - disable_fullbright = true; - disable_fullbright_specified = true; - } - else if (sc.Compare("thiswad")) - { - // only affects textures defined in the WAD containing the definition file. - thiswad = true; - } - else if (sc.Compare ("iwad")) - { - // only affects textures defined in the IWAD. - iwad = true; - } - else if (sc.Compare("glossiness")) - { - sc.MustGetFloat(); - if (tex) - tex->gl_info.Glossiness = sc.Float; - } - else if (sc.Compare("specularlevel")) - { - sc.MustGetFloat(); - if (tex) - tex->gl_info.SpecularLevel = sc.Float; - } - else - { - for (int i = 0; keywords[i] != nullptr; i++) - { - if (sc.Compare (keywords[i])) - { - sc.MustGetString(); - if (textures[i]) - Printf("Multiple %s definitions in texture %s\n", keywords[i], tex? tex->Name.GetChars() : "(null)"); - textures[i] = TexMan.FindTexture(sc.String, ETextureType::Any, FTextureManager::TEXMAN_TryAny); - if (!textures[i]) - Printf("%s '%s' not found in texture '%s'\n", notFound[i], sc.String, tex? tex->Name.GetChars() : "(null)"); - break; - } - } - } - } - if (!tex) - { - return; - } - if (thiswad || iwad) - { - bool useme = false; - int lumpnum = tex->GetSourceLump(); - - if (lumpnum != -1) - { - if (iwad && Wads.GetLumpFile(lumpnum) <= Wads.GetIwadNum()) useme = true; - if (thiswad && Wads.GetLumpFile(lumpnum) == deflump) useme = true; - } - if (!useme) return; - } - - FTexture **bindings[6] = - { - &tex->gl_info.Brightmap, - &tex->gl_info.Normal, - &tex->gl_info.Specular, - &tex->gl_info.Metallic, - &tex->gl_info.Roughness, - &tex->gl_info.AmbientOcclusion - }; - for (int i = 0; keywords[i] != nullptr; i++) - { - if (textures[i]) - { - textures[i]->bMasked = false; - *bindings[i] = textures[i]; - } - } - - if (disable_fullbright_specified) - tex->gl_info.bDisableFullbright = disable_fullbright; -} - -//========================================================================== -// -// Parses a brightmap definition -// -//========================================================================== - -void gl_ParseBrightmap(FScanner &sc, int deflump) -{ - ETextureType type = ETextureType::Any; - bool disable_fullbright=false; - bool thiswad = false; - bool iwad = false; - FTexture *bmtex = NULL; - - sc.MustGetString(); - if (sc.Compare("texture")) type = ETextureType::Wall; - else if (sc.Compare("flat")) type = ETextureType::Flat; - else if (sc.Compare("sprite")) type = ETextureType::Sprite; - else sc.UnGet(); - - sc.MustGetString(); - FTextureID no = TexMan.CheckForTexture(sc.String, type, FTextureManager::TEXMAN_TryAny | FTextureManager::TEXMAN_Overridable); - FTexture *tex = TexMan[no]; - - sc.MustGetToken('{'); - while (!sc.CheckToken('}')) - { - sc.MustGetString(); - if (sc.Compare("disablefullbright")) - { - // This can also be used without a brightness map to disable - // fullbright in rotations that only use brightness maps on - // other angles. - disable_fullbright = true; - } - else if (sc.Compare("thiswad")) - { - // only affects textures defined in the WAD containing the definition file. - thiswad = true; - } - else if (sc.Compare ("iwad")) - { - // only affects textures defined in the IWAD. - iwad = true; - } - else if (sc.Compare ("map")) - { - sc.MustGetString(); - - if (bmtex != NULL) - { - Printf("Multiple brightmap definitions in texture %s\n", tex? tex->Name.GetChars() : "(null)"); - } - - bmtex = TexMan.FindTexture(sc.String, ETextureType::Any, FTextureManager::TEXMAN_TryAny); - - if (bmtex == NULL) - Printf("Brightmap '%s' not found in texture '%s'\n", sc.String, tex? tex->Name.GetChars() : "(null)"); - } - } - if (!tex) - { - return; - } - if (thiswad || iwad) - { - bool useme = false; - int lumpnum = tex->GetSourceLump(); - - if (lumpnum != -1) - { - if (iwad && Wads.GetLumpFile(lumpnum) <= Wads.GetIwadNum()) useme = true; - if (thiswad && Wads.GetLumpFile(lumpnum) == deflump) useme = true; - } - if (!useme) return; - } - - if (bmtex != NULL) - { - /* I do not think this is needed any longer - if (tex->bWarped != 0) - { - Printf("Cannot combine warping with brightmap on texture '%s'\n", tex->Name.GetChars()); - return; - } - */ - - bmtex->bMasked = false; - tex->gl_info.Brightmap = bmtex; - } - tex->gl_info.bDisableFullbright = disable_fullbright; -} - -//========================================================================== -// -// Search auto paths for extra material textures -// -//========================================================================== - -struct AutoTextureSearchPath -{ - const char *path; - ptrdiff_t offset; - - void SetTexture(FTexture *material, FTexture *texture) const - { - *reinterpret_cast(reinterpret_cast(&material->gl_info) + offset) = texture; - } -}; - -static AutoTextureSearchPath autosearchpaths[] = -{ - { "brightmaps/auto/", offsetof(FTexture::MiscGLInfo, Brightmap) }, // For backwards compatibility - { "materials/brightmaps/auto/", offsetof(FTexture::MiscGLInfo, Brightmap) }, - { "materials/normalmaps/auto/", offsetof(FTexture::MiscGLInfo, Normal) }, - { "materials/specular/auto/", offsetof(FTexture::MiscGLInfo, Specular) }, - { "materials/metallic/auto/", offsetof(FTexture::MiscGLInfo, Metallic) }, - { "materials/roughness/auto/", offsetof(FTexture::MiscGLInfo, Roughness) }, - { "materials/ao/auto/", offsetof(FTexture::MiscGLInfo, AmbientOcclusion) } -}; - -void AddAutoMaterials() -{ - int num = Wads.GetNumLumps(); - for (int i = 0; i < num; i++) - { - const char *name = Wads.GetLumpFullName(i); - for (const AutoTextureSearchPath &searchpath : autosearchpaths) - { - if (strstr(name, searchpath.path) == name) - { - TArray list; - FString texname = ExtractFileBase(name, false); - TexMan.ListTextures(texname, list); - auto bmtex = TexMan.FindTexture(name, ETextureType::Any, FTextureManager::TEXMAN_TryAny); - for (auto texid : list) - { - bmtex->bMasked = false; - searchpath.SetTexture(TexMan[texid], bmtex); - } - } - } - } -} - -//========================================================================== -// -// Parses a GLBoom+ detail texture definition -// -// Syntax is this: -// detail -// { -// (walls | flats) [default_detail_name [width [height [offset_x [offset_y]]]]] -// { -// texture_name [detail_name [width [height [offset_x [offset_y]]]]] -// } -// } -// This merely parses the block and returns no error if valid. The feature -// is not actually implemented, so nothing else happens. -//========================================================================== - -void gl_ParseDetailTexture(FScanner &sc) -{ - while (!sc.CheckToken('}')) - { - sc.MustGetString(); - if (sc.Compare("walls") || sc.Compare("flats")) - { - if (!sc.CheckToken('{')) - { - sc.MustGetString(); // Default detail texture - if (sc.CheckFloat()) // Width - if (sc.CheckFloat()) // Height - if (sc.CheckFloat()) // OffsX - if (sc.CheckFloat()) // OffsY - { - // Nothing - } - } - else sc.UnGet(); - sc.MustGetToken('{'); - while (!sc.CheckToken('}')) - { - sc.MustGetString(); // Texture - if (sc.GetString()) // Detail texture - { - if (sc.CheckFloat()) // Width - if (sc.CheckFloat()) // Height - if (sc.CheckFloat()) // OffsX - if (sc.CheckFloat()) // OffsY - { - // Nothing - } - } - else sc.UnGet(); - } - } - } -} - - //========================================================================== // // DFrameBuffer :: PrecacheTexture @@ -912,7 +195,7 @@ void gl_PrecacheTexture(uint8_t *texhitlist, TMap &actorhitl if (texhitlist[i] & (FTextureManager::HIT_Sky | FTextureManager::HIT_Wall)) { FTexture *tex = TexMan.ByIndex(i); - if (tex->gl_info.bSkybox) + if (tex->bSkybox) { FSkyBox *sb = static_cast(tex); for (int i = 0; i<6; i++) @@ -933,7 +216,8 @@ void gl_PrecacheTexture(uint8_t *texhitlist, TMap &actorhitl while (it.NextPair(pair)) { PClassActor *cls = pair->Key; - int gltrans = GLTranslationPalette::GetInternalTranslation(GetDefaultByType(cls)->Translation); + auto remap = TranslationToTable(GetDefaultByType(cls)->Translation); + int gltrans = remap == nullptr ? 0 : remap->GetUniqueIndex(); for (unsigned i = 0; i < cls->GetStateCount(); i++) { @@ -1027,7 +311,7 @@ void gl_PrecacheTexture(uint8_t *texhitlist, TMap &actorhitl } // cache all used models - FGLModelRenderer renderer; + FGLModelRenderer renderer(-1); for (unsigned i = 0; i < Models.Size(); i++) { if (modellist[i]) diff --git a/src/gl/textures/gl_texture.h b/src/gl/textures/gl_texture.h deleted file mode 100644 index 44016f181a..0000000000 --- a/src/gl/textures/gl_texture.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef __GL_TEXTURE_H__ -#define __GL_TEXTURE_H__ - -#include "r_defs.h" -#include "textures/textures.h" - -class FBrightmapTexture : public FWorldTexture -{ -public: - FBrightmapTexture (FTexture *source); - - uint8_t *MakeTexture(FRenderStyle style) override; - int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) override; - bool UseBasePalette() override { return false; } - -protected: - FTexture *SourcePic; -}; - - -void gl_GenerateGlobalBrightmapFromColormap(); - - - -unsigned char *gl_CreateUpsampledTextureBuffer ( const FTexture *inputTexture, unsigned char *inputBuffer, const int inWidth, const int inHeight, int &outWidth, int &outHeight, bool hasAlpha ); -int CheckDDPK3(FTexture *tex); -int CheckExternalFile(FTexture *tex, bool & hascolorkey); - -#endif // __GL_HQRESIZE_H__ - diff --git a/src/gl/textures/gl_translate.cpp b/src/gl/textures/gl_translate.cpp deleted file mode 100644 index 20a58e22cf..0000000000 --- a/src/gl/textures/gl_translate.cpp +++ /dev/null @@ -1,75 +0,0 @@ -// -//--------------------------------------------------------------------------- -// -// Copyright(C) 2007-2016 Christoph Oelckers -// All rights reserved. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with this program. If not, see http://www.gnu.org/licenses/ -// -//-------------------------------------------------------------------------- -// -/* -** gl_translate.cpp -** GL-related translation stuff -** -*/ - -#include "doomtype.h" -#include "r_data/r_translate.h" -#include "gl/textures/gl_translate.h" -#include "m_crc32.h" - -TArray GLTranslationPalette::AllPalettes; - - -GLTranslationPalette *GLTranslationPalette::CreatePalette(FRemapTable *remap) -{ - GLTranslationPalette *p = new GLTranslationPalette(remap); - p->Update(); - return p; -} - -bool GLTranslationPalette::Update() -{ - PalData pd; - - memset(pd.pe, 0, sizeof(pd.pe)); - memcpy(pd.pe, remap->Palette, remap->NumEntries * sizeof(*remap->Palette)); - pd.crc32 = CalcCRC32((uint8_t*)pd.pe, sizeof(pd.pe)); - for(unsigned int i=0;i< AllPalettes.Size(); i++) - { - if (pd.crc32 == AllPalettes[i].crc32) - { - if (!memcmp(pd.pe, AllPalettes[i].pe, sizeof(pd.pe))) - { - Index = 1+i; - return true; - } - } - } - Index = 1+AllPalettes.Push(pd); - return true; -} - -int GLTranslationPalette::GetInternalTranslation(int trans) -{ - if (trans <= 0) return 0; - - FRemapTable *remap = TranslationToTable(trans); - if (remap == NULL || remap->Inactive) return 0; - - GLTranslationPalette *tpal = static_cast(remap->GetNative()); - if (tpal == NULL) return 0; - return tpal->GetIndex(); -} diff --git a/src/gl/textures/gl_translate.h b/src/gl/textures/gl_translate.h deleted file mode 100644 index 07ede1a226..0000000000 --- a/src/gl/textures/gl_translate.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef __GL_TRANSLATE__ -#define __GL_TRANSLATE__ - -#include "doomtype.h" -#include "v_video.h" - -enum -{ - TRANSLATION_ICE = -1, - TRANSLATION_INTENSITY = -2, - TRANSLATION_SHADE = -3, -}; - - -class GLTranslationPalette : public FNativePalette -{ - struct PalData - { - int crc32; - PalEntry pe[256]; - }; - static TArray AllPalettes; - - int Index; - FRemapTable *remap; - - GLTranslationPalette(FRemapTable *r) { remap=r; Index=-1; } - -public: - - static GLTranslationPalette *CreatePalette(FRemapTable *remap); - static int GetInternalTranslation(int trans); - static PalEntry *GetPalette(unsigned int index) - { - return index > 0 && index <= AllPalettes.Size()? AllPalettes[index-1].pe : NULL; - } - bool Update(); - int GetIndex() const { return Index; } -}; - - -#endif diff --git a/src/gl/shaders/gl_texshader.cpp b/src/gl/unused/gl_texshader.cpp similarity index 100% rename from src/gl/shaders/gl_texshader.cpp rename to src/gl/unused/gl_texshader.cpp diff --git a/src/gl/shaders/gl_texshader.h b/src/gl/unused/gl_texshader.h similarity index 100% rename from src/gl/shaders/gl_texshader.h rename to src/gl/unused/gl_texshader.h diff --git a/src/gl/utility/gl_clock.cpp b/src/gl/utility/gl_clock.cpp index 1003fae865..532accba49 100644 --- a/src/gl/utility/gl_clock.cpp +++ b/src/gl/utility/gl_clock.cpp @@ -1,7 +1,6 @@ /* ** -** This is a copy of the regular cycle_t from a time when that was based -** on QueryPerformanceCounter which is too costly for real-time profiling. +** Hardware render profiling info ** **--------------------------------------------------------------------------- ** Copyright 1998-2016 Randy Heit @@ -34,17 +33,6 @@ ** */ -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#include - -#elif defined __APPLE__ -#include -#endif - -#include - #include "i_system.h" #include "g_level.h" #include "c_console.h" @@ -53,7 +41,6 @@ #include "v_video.h" #include "g_levellocals.h" #include "gl/utility/gl_clock.h" -#include "gl/utility/gl_convert.h" #include "i_time.h" glcycle_t RenderWall,SetupWall,ClipWall; @@ -69,67 +56,6 @@ int vertexcount, flatvertices, flatprimitives; int rendered_lines,rendered_flats,rendered_sprites,render_vertexsplit,render_texsplit,rendered_decals, rendered_portals; int iter_dlightf, iter_dlight, draw_dlight, draw_dlightf; -double gl_SecondsPerCycle = 1e-8; -double gl_MillisecPerCycle = 1e-5; // 100 MHz - -// For GL timing the performance counter is far too costly so we still need RDTSC -// even though it may not be perfect. - -void gl_CalculateCPUSpeed () -{ - #ifdef _WIN32 - LARGE_INTEGER freq; - - QueryPerformanceFrequency (&freq); - - if (freq.QuadPart != 0) - { - LARGE_INTEGER count1, count2; - unsigned minDiff; - int64_t ClockCalibration = 0; - - // Count cycles for at least 55 milliseconds. - // The performance counter is very low resolution compared to CPU - // speeds today, so the longer we count, the more accurate our estimate. - // On the other hand, we don't want to count too long, because we don't - // want the user to notice us spend time here, since most users will - // probably never use the performance statistics. - minDiff = freq.LowPart * 11 / 200; - - // Minimize the chance of task switching during the testing by going very - // high priority. This is another reason to avoid timing for too long. - SetPriorityClass (GetCurrentProcess (), REALTIME_PRIORITY_CLASS); - SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_TIME_CRITICAL); - ClockCalibration = __rdtsc(); - QueryPerformanceCounter (&count1); - do - { - QueryPerformanceCounter (&count2); - } while ((uint32_t)((uint64_t)count2.QuadPart - (uint64_t)count1.QuadPart) < minDiff); - ClockCalibration = __rdtsc() - ClockCalibration; - QueryPerformanceCounter (&count2); - SetPriorityClass (GetCurrentProcess (), NORMAL_PRIORITY_CLASS); - SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_NORMAL); - - double CyclesPerSecond = (double)ClockCalibration * - (double)freq.QuadPart / - (double)((__int64)count2.QuadPart - (__int64)count1.QuadPart); - gl_SecondsPerCycle = 1.0 / CyclesPerSecond; - gl_MillisecPerCycle = 1000.0 / CyclesPerSecond; - } - #elif defined __APPLE__ - long long frequency; - size_t size = sizeof frequency; - - if (0 == sysctlbyname("machdep.tsc.frequency", &frequency, &size, nullptr, 0) && 0 != frequency) - { - gl_SecondsPerCycle = 1.0 / frequency; - gl_MillisecPerCycle = 1000.0 / frequency; - } - #endif -} - - void ResetProfilingData() { All.Reset(); @@ -239,7 +165,7 @@ void CheckBench() AppendRenderTimes(compose); AppendLightStats(compose); AppendMissingTextureStats(compose); - compose.AppendFormat("%" PRIu64 " fps\n\n", screen->GetLastFPS()); + compose.AppendFormat("%llu fps\n\n", screen->GetLastFPS()); FILE *f = fopen("benchmarks.txt", "at"); if (f != NULL) @@ -270,11 +196,11 @@ CCMD(bench) C_HideConsole (); } -bool gl_benching = false; +bool glcycle_t::active = false; void checkBenchActive() { FStat *stat = FStat::FindStat("rendertimes"); - gl_benching = ((stat != NULL && stat->isActive()) || printstats); + glcycle_t::active = ((stat != NULL && stat->isActive()) || printstats); } diff --git a/src/gl/utility/gl_clock.h b/src/gl/utility/gl_clock.h index fb96a69a27..2c0448eed9 100644 --- a/src/gl/utility/gl_clock.h +++ b/src/gl/utility/gl_clock.h @@ -5,92 +5,6 @@ #include "x86.h" #include "m_fixed.h" -extern bool gl_benching; - -extern double gl_SecondsPerCycle; -extern double gl_MillisecPerCycle; - -#ifdef _MSC_VER - -__forceinline int64_t GetClockCycle () -{ - return __rdtsc(); -} - -#elif defined __APPLE__ && (defined __i386__ || defined __x86_64__) - -inline int64_t GetClockCycle() -{ - return __builtin_ia32_rdtsc(); -} - -#elif defined(__GNUG__) && defined(__i386__) - -inline int64_t GetClockCycle() -{ - if (CPU.bRDTSC) - { - int64_t res; - asm volatile ("rdtsc" : "=A" (res)); - return res; - } - else - { - return 0; - } -} - -#else - -inline int64_t GetClockCycle () -{ - return 0; -} -#endif - -class glcycle_t -{ -public: - glcycle_t &operator= (const glcycle_t &o) - { - Counter = o.Counter; - return *this; - } - - void Reset() - { - Counter = 0; - } - - __forceinline void Clock() - { - // Not using QueryPerformanceCounter directly, so we don't need - // to pull in the Windows headers for every single file that - // wants to do some profiling. - int64_t time = (gl_benching? GetClockCycle() : 0); - Counter -= time; - } - - __forceinline void Unclock() - { - int64_t time = (gl_benching? GetClockCycle() : 0); - Counter += time; - } - - double Time() - { - return double(Counter) * gl_SecondsPerCycle; - } - - double TimeMS() - { - return double(Counter) * gl_MillisecPerCycle; - } - -private: - int64_t Counter; -}; - extern glcycle_t RenderWall,SetupWall,ClipWall; extern glcycle_t RenderFlat,SetupFlat; extern glcycle_t RenderSprite,SetupSprite; diff --git a/src/gl/utility/gl_convert.h b/src/gl/utility/gl_convert.h deleted file mode 100644 index 61eede6b41..0000000000 --- a/src/gl/utility/gl_convert.h +++ /dev/null @@ -1,7 +0,0 @@ - -#ifndef __GLC_CONVERT -#define __GLC_CONVERT - -#include "m_fixed.h" - -#endif \ No newline at end of file diff --git a/src/gl/utility/gl_geometric.h b/src/gl/utility/gl_geometric.h deleted file mode 100644 index 5f5fad8e51..0000000000 --- a/src/gl/utility/gl_geometric.h +++ /dev/null @@ -1,86 +0,0 @@ -/* -** gl_geometric.h -** -**--------------------------------------------------------------------------- -** Copyright 2003 Timothy Stump -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -#ifndef __GL_GEOM -#define __GL_GEOM - -#include "math.h" -#include "r_defs.h" -#include "gl/scene/gl_wall.h" - -struct GLSeg; - -class Plane -{ -public: - void Set(GLSeg *seg) - { - m_normal = seg->Normal(); - m_d = m_normal | FVector3(-seg->x1, 0, -seg->y1); - } - - void Set(secplane_t &plane) - { - m_normal = { (float)plane.Normal().X, (float)plane.Normal().Z, (float)plane.Normal().Y }; - m_d = (float)plane.fD(); - } - - - float DistToPoint(float x, float y, float z) - { - FVector3 p(x, y, z); - - return (m_normal | p) + m_d; - } - - - bool PointOnSide(float x, float y, float z) - { - return DistToPoint(x, y, z) < 0.f; - } - - bool PointOnSide(FVector3 &v) { return PointOnSide(v.X, v.Y, v.Z); } - bool ValidNormal() { return m_normal.LengthSquared() == 1.f; } - - float A() { return m_normal.X; } - float B() { return m_normal.Y; } - float C() { return m_normal.Z; } - float D() { return m_d; } - - const FVector3 &Normal() const { return m_normal; } -protected: - FVector3 m_normal; - float m_d; -}; - -#endif diff --git a/src/gl/utility/gl_templates.h b/src/gl/utility/gl_templates.h deleted file mode 100644 index 1ebef1f48c..0000000000 --- a/src/gl/utility/gl_templates.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef __GL_BASIC -#define __GL_BASIC - -#include -#include "stats.h" - - -// Disabled because it doesn't work and only accumulates large portions of blocked heap -// without providing any relevant performance boost. -template struct FreeList -{ - //T * freelist; - - T * GetNew() - { - /* - if (freelist) - { - T * n=freelist; - freelist=*((T**)n); - return new ((void*)n) T; - } - */ - return new T; - } - - void Release(T * node) - { - /* - node->~T(); - *((T**)node) = freelist; - freelist=node; - */ - delete node; - } - - ~FreeList() - { - /* - while (freelist!=NULL) - { - T * n = freelist; - freelist=*((T**)n); - delete n; - } - */ - } -}; - -template class UniqueList -{ - TArray Array; - FreeList TheFreeList; - -public: - - T * Get(T * t) - { - for(unsigned i=0;i lua LoadGen.lua -style=pointer_c -spec=gl -version=3.3 -profile=compatibility -extfile=gl_extlist.txt load +-- > lua LoadGen.lua -style=pointer_c -spec=gl -version=4.5 -profile=compatibility -extfile=gl_extlist.txt load ARB_buffer_storage ARB_shader_storage_buffer_object diff --git a/src/gl/system/gl_load.c b/src/gl_load/gl_load.c similarity index 67% rename from src/gl/system/gl_load.c rename to src/gl_load/gl_load.c index 12734d7153..4bfbb78786 100644 --- a/src/gl/system/gl_load.c +++ b/src/gl_load/gl_load.c @@ -984,7 +984,303 @@ void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribP3uiv)(GLuint index, GLenum type, GLb void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribP4ui)(GLuint index, GLenum type, GLboolean normalized, GLuint value) = NULL; void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribP4uiv)(GLuint index, GLenum type, GLboolean normalized, const GLuint * value) = NULL; -static int Load_Version_3_3(void) +void (CODEGEN_FUNCPTR *_ptrc_glBeginQueryIndexed)(GLenum target, GLuint index, GLuint id) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glBindTransformFeedback)(GLenum target, GLuint id) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glBlendEquationSeparatei)(GLuint buf, GLenum modeRGB, GLenum modeAlpha) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glBlendEquationi)(GLuint buf, GLenum mode) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glBlendFuncSeparatei)(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glBlendFunci)(GLuint buf, GLenum src, GLenum dst) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDeleteTransformFeedbacks)(GLsizei n, const GLuint * ids) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDrawArraysIndirect)(GLenum mode, const void * indirect) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDrawElementsIndirect)(GLenum mode, GLenum type, const void * indirect) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDrawTransformFeedback)(GLenum mode, GLuint id) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDrawTransformFeedbackStream)(GLenum mode, GLuint id, GLuint stream) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glEndQueryIndexed)(GLenum target, GLuint index) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGenTransformFeedbacks)(GLsizei n, GLuint * ids) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetActiveSubroutineName)(GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei * length, GLchar * name) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetActiveSubroutineUniformName)(GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei * length, GLchar * name) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetActiveSubroutineUniformiv)(GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint * values) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetProgramStageiv)(GLuint program, GLenum shadertype, GLenum pname, GLint * values) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetQueryIndexediv)(GLenum target, GLuint index, GLenum pname, GLint * params) = NULL; +GLuint (CODEGEN_FUNCPTR *_ptrc_glGetSubroutineIndex)(GLuint program, GLenum shadertype, const GLchar * name) = NULL; +GLint (CODEGEN_FUNCPTR *_ptrc_glGetSubroutineUniformLocation)(GLuint program, GLenum shadertype, const GLchar * name) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetUniformSubroutineuiv)(GLenum shadertype, GLint location, GLuint * params) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetUniformdv)(GLuint program, GLint location, GLdouble * params) = NULL; +GLboolean (CODEGEN_FUNCPTR *_ptrc_glIsTransformFeedback)(GLuint id) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glMinSampleShading)(GLfloat value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glPatchParameterfv)(GLenum pname, const GLfloat * values) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glPatchParameteri)(GLenum pname, GLint value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glPauseTransformFeedback)(void) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glResumeTransformFeedback)(void) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniform1d)(GLint location, GLdouble x) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniform1dv)(GLint location, GLsizei count, const GLdouble * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniform2d)(GLint location, GLdouble x, GLdouble y) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniform2dv)(GLint location, GLsizei count, const GLdouble * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniform3d)(GLint location, GLdouble x, GLdouble y, GLdouble z) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniform3dv)(GLint location, GLsizei count, const GLdouble * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniform4d)(GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniform4dv)(GLint location, GLsizei count, const GLdouble * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix2dv)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix2x3dv)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix2x4dv)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix3dv)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix3x2dv)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix3x4dv)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix4dv)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix4x2dv)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix4x3dv)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUniformSubroutinesuiv)(GLenum shadertype, GLsizei count, const GLuint * indices) = NULL; + +void (CODEGEN_FUNCPTR *_ptrc_glActiveShaderProgram)(GLuint pipeline, GLuint program) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glBindProgramPipeline)(GLuint pipeline) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glClearDepthf)(GLfloat d) = NULL; +GLuint (CODEGEN_FUNCPTR *_ptrc_glCreateShaderProgramv)(GLenum type, GLsizei count, const GLchar *const* strings) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDeleteProgramPipelines)(GLsizei n, const GLuint * pipelines) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDepthRangeArrayv)(GLuint first, GLsizei count, const GLdouble * v) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDepthRangeIndexed)(GLuint index, GLdouble n, GLdouble f) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDepthRangef)(GLfloat n, GLfloat f) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGenProgramPipelines)(GLsizei n, GLuint * pipelines) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetDoublei_v)(GLenum target, GLuint index, GLdouble * data) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetFloati_v)(GLenum target, GLuint index, GLfloat * data) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetProgramBinary)(GLuint program, GLsizei bufSize, GLsizei * length, GLenum * binaryFormat, void * binary) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetProgramPipelineInfoLog)(GLuint pipeline, GLsizei bufSize, GLsizei * length, GLchar * infoLog) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetProgramPipelineiv)(GLuint pipeline, GLenum pname, GLint * params) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetShaderPrecisionFormat)(GLenum shadertype, GLenum precisiontype, GLint * range, GLint * precision) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetVertexAttribLdv)(GLuint index, GLenum pname, GLdouble * params) = NULL; +GLboolean (CODEGEN_FUNCPTR *_ptrc_glIsProgramPipeline)(GLuint pipeline) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramBinary)(GLuint program, GLenum binaryFormat, const void * binary, GLsizei length) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramParameteri)(GLuint program, GLenum pname, GLint value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform1d)(GLuint program, GLint location, GLdouble v0) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform1dv)(GLuint program, GLint location, GLsizei count, const GLdouble * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform1f)(GLuint program, GLint location, GLfloat v0) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform1fv)(GLuint program, GLint location, GLsizei count, const GLfloat * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform1i)(GLuint program, GLint location, GLint v0) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform1iv)(GLuint program, GLint location, GLsizei count, const GLint * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform1ui)(GLuint program, GLint location, GLuint v0) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform1uiv)(GLuint program, GLint location, GLsizei count, const GLuint * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform2d)(GLuint program, GLint location, GLdouble v0, GLdouble v1) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform2dv)(GLuint program, GLint location, GLsizei count, const GLdouble * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform2f)(GLuint program, GLint location, GLfloat v0, GLfloat v1) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform2fv)(GLuint program, GLint location, GLsizei count, const GLfloat * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform2i)(GLuint program, GLint location, GLint v0, GLint v1) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform2iv)(GLuint program, GLint location, GLsizei count, const GLint * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform2ui)(GLuint program, GLint location, GLuint v0, GLuint v1) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform2uiv)(GLuint program, GLint location, GLsizei count, const GLuint * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform3d)(GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform3dv)(GLuint program, GLint location, GLsizei count, const GLdouble * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform3f)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform3fv)(GLuint program, GLint location, GLsizei count, const GLfloat * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform3i)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform3iv)(GLuint program, GLint location, GLsizei count, const GLint * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform3ui)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform3uiv)(GLuint program, GLint location, GLsizei count, const GLuint * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform4d)(GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform4dv)(GLuint program, GLint location, GLsizei count, const GLdouble * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform4f)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform4fv)(GLuint program, GLint location, GLsizei count, const GLfloat * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform4i)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform4iv)(GLuint program, GLint location, GLsizei count, const GLint * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform4ui)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform4uiv)(GLuint program, GLint location, GLsizei count, const GLuint * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix2dv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix2fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix2x3dv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix2x3fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix2x4dv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix2x4fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix3dv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix3fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix3x2dv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix3x2fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix3x4dv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix3x4fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix4dv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix4fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix4x2dv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix4x2fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix4x3dv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix4x3fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glReleaseShaderCompiler)(void) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glScissorArrayv)(GLuint first, GLsizei count, const GLint * v) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glScissorIndexed)(GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glScissorIndexedv)(GLuint index, const GLint * v) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glShaderBinary)(GLsizei count, const GLuint * shaders, GLenum binaryformat, const void * binary, GLsizei length) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glUseProgramStages)(GLuint pipeline, GLbitfield stages, GLuint program) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glValidateProgramPipeline)(GLuint pipeline) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribL1d)(GLuint index, GLdouble x) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribL1dv)(GLuint index, const GLdouble * v) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribL2d)(GLuint index, GLdouble x, GLdouble y) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribL2dv)(GLuint index, const GLdouble * v) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribL3d)(GLuint index, GLdouble x, GLdouble y, GLdouble z) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribL3dv)(GLuint index, const GLdouble * v) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribL4d)(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribL4dv)(GLuint index, const GLdouble * v) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribLPointer)(GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glViewportArrayv)(GLuint first, GLsizei count, const GLfloat * v) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glViewportIndexedf)(GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glViewportIndexedfv)(GLuint index, const GLfloat * v) = NULL; + +void (CODEGEN_FUNCPTR *_ptrc_glBindImageTexture)(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDrawArraysInstancedBaseInstance)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDrawElementsInstancedBaseInstance)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLuint baseinstance) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDrawElementsInstancedBaseVertexBaseInstance)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDrawTransformFeedbackInstanced)(GLenum mode, GLuint id, GLsizei instancecount) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDrawTransformFeedbackStreamInstanced)(GLenum mode, GLuint id, GLuint stream, GLsizei instancecount) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetActiveAtomicCounterBufferiv)(GLuint program, GLuint bufferIndex, GLenum pname, GLint * params) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetInternalformativ)(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint * params) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glMemoryBarrier)(GLbitfield barriers) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTexStorage1D)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTexStorage2D)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTexStorage3D)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) = NULL; + +void (CODEGEN_FUNCPTR *_ptrc_glBindVertexBuffer)(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glClearBufferData)(GLenum target, GLenum internalformat, GLenum format, GLenum type, const void * data) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glClearBufferSubData)(GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void * data) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCopyImageSubData)(GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDispatchCompute)(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDispatchComputeIndirect)(GLintptr indirect) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glFramebufferParameteri)(GLenum target, GLenum pname, GLint param) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetFramebufferParameteriv)(GLenum target, GLenum pname, GLint * params) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetInternalformati64v)(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 * params) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetProgramInterfaceiv)(GLuint program, GLenum programInterface, GLenum pname, GLint * params) = NULL; +GLuint (CODEGEN_FUNCPTR *_ptrc_glGetProgramResourceIndex)(GLuint program, GLenum programInterface, const GLchar * name) = NULL; +GLint (CODEGEN_FUNCPTR *_ptrc_glGetProgramResourceLocation)(GLuint program, GLenum programInterface, const GLchar * name) = NULL; +GLint (CODEGEN_FUNCPTR *_ptrc_glGetProgramResourceLocationIndex)(GLuint program, GLenum programInterface, const GLchar * name) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetProgramResourceName)(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei * length, GLchar * name) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetProgramResourceiv)(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum * props, GLsizei bufSize, GLsizei * length, GLint * params) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glMultiDrawArraysIndirect)(GLenum mode, const void * indirect, GLsizei drawcount, GLsizei stride) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glMultiDrawElementsIndirect)(GLenum mode, GLenum type, const void * indirect, GLsizei drawcount, GLsizei stride) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTexBufferRange)(GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTexStorage2DMultisample)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTexStorage3DMultisample)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTextureView)(GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribBinding)(GLuint attribindex, GLuint bindingindex) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribFormat)(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribIFormat)(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribLFormat)(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexBindingDivisor)(GLuint bindingindex, GLuint divisor) = NULL; + +void (CODEGEN_FUNCPTR *_ptrc_glBindBuffersBase)(GLenum target, GLuint first, GLsizei count, const GLuint * buffers) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glBindBuffersRange)(GLenum target, GLuint first, GLsizei count, const GLuint * buffers, const GLintptr * offsets, const GLsizeiptr * sizes) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glBindImageTextures)(GLuint first, GLsizei count, const GLuint * textures) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glBindSamplers)(GLuint first, GLsizei count, const GLuint * samplers) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glBindTextures)(GLuint first, GLsizei count, const GLuint * textures) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glBindVertexBuffers)(GLuint first, GLsizei count, const GLuint * buffers, const GLintptr * offsets, const GLsizei * strides) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glClearTexImage)(GLuint texture, GLint level, GLenum format, GLenum type, const void * data) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glClearTexSubImage)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * data) = NULL; + +void (CODEGEN_FUNCPTR *_ptrc_glBindTextureUnit)(GLuint unit, GLuint texture) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glBlitNamedFramebuffer)(GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) = NULL; +GLenum (CODEGEN_FUNCPTR *_ptrc_glCheckNamedFramebufferStatus)(GLuint framebuffer, GLenum target) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glClearNamedBufferData)(GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void * data) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glClearNamedBufferSubData)(GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void * data) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glClearNamedFramebufferfi)(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat depth, GLint stencil) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glClearNamedFramebufferfv)(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glClearNamedFramebufferiv)(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glClearNamedFramebufferuiv)(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint * value) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glClipControl)(GLenum origin, GLenum depth) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCompressedTextureSubImage1D)(GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void * data) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCompressedTextureSubImage2D)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void * data) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCompressedTextureSubImage3D)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void * data) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCopyNamedBufferSubData)(GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCopyTextureSubImage1D)(GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCopyTextureSubImage2D)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCopyTextureSubImage3D)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCreateBuffers)(GLsizei n, GLuint * buffers) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCreateFramebuffers)(GLsizei n, GLuint * framebuffers) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCreateProgramPipelines)(GLsizei n, GLuint * pipelines) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCreateQueries)(GLenum target, GLsizei n, GLuint * ids) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCreateRenderbuffers)(GLsizei n, GLuint * renderbuffers) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCreateSamplers)(GLsizei n, GLuint * samplers) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCreateTextures)(GLenum target, GLsizei n, GLuint * textures) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCreateTransformFeedbacks)(GLsizei n, GLuint * ids) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glCreateVertexArrays)(GLsizei n, GLuint * arrays) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glDisableVertexArrayAttrib)(GLuint vaobj, GLuint index) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glEnableVertexArrayAttrib)(GLuint vaobj, GLuint index) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glFlushMappedNamedBufferRange)(GLuint buffer, GLintptr offset, GLsizeiptr length) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGenerateTextureMipmap)(GLuint texture) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetCompressedTextureImage)(GLuint texture, GLint level, GLsizei bufSize, void * pixels) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetCompressedTextureSubImage)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei bufSize, void * pixels) = NULL; +GLenum (CODEGEN_FUNCPTR *_ptrc_glGetGraphicsResetStatus)(void) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetNamedBufferParameteri64v)(GLuint buffer, GLenum pname, GLint64 * params) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetNamedBufferParameteriv)(GLuint buffer, GLenum pname, GLint * params) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetNamedBufferPointerv)(GLuint buffer, GLenum pname, void ** params) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetNamedBufferSubData)(GLuint buffer, GLintptr offset, GLsizeiptr size, void * data) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetNamedFramebufferAttachmentParameteriv)(GLuint framebuffer, GLenum attachment, GLenum pname, GLint * params) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetNamedFramebufferParameteriv)(GLuint framebuffer, GLenum pname, GLint * param) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetNamedRenderbufferParameteriv)(GLuint renderbuffer, GLenum pname, GLint * params) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetQueryBufferObjecti64v)(GLuint id, GLuint buffer, GLenum pname, GLintptr offset) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetQueryBufferObjectiv)(GLuint id, GLuint buffer, GLenum pname, GLintptr offset) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetQueryBufferObjectui64v)(GLuint id, GLuint buffer, GLenum pname, GLintptr offset) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetQueryBufferObjectuiv)(GLuint id, GLuint buffer, GLenum pname, GLintptr offset) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetTextureImage)(GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void * pixels) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetTextureLevelParameterfv)(GLuint texture, GLint level, GLenum pname, GLfloat * params) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetTextureLevelParameteriv)(GLuint texture, GLint level, GLenum pname, GLint * params) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetTextureParameterIiv)(GLuint texture, GLenum pname, GLint * params) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetTextureParameterIuiv)(GLuint texture, GLenum pname, GLuint * params) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetTextureParameterfv)(GLuint texture, GLenum pname, GLfloat * params) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetTextureParameteriv)(GLuint texture, GLenum pname, GLint * params) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetTextureSubImage)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, void * pixels) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetTransformFeedbacki64_v)(GLuint xfb, GLenum pname, GLuint index, GLint64 * param) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetTransformFeedbacki_v)(GLuint xfb, GLenum pname, GLuint index, GLint * param) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetTransformFeedbackiv)(GLuint xfb, GLenum pname, GLint * param) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetVertexArrayIndexed64iv)(GLuint vaobj, GLuint index, GLenum pname, GLint64 * param) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetVertexArrayIndexediv)(GLuint vaobj, GLuint index, GLenum pname, GLint * param) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetVertexArrayiv)(GLuint vaobj, GLenum pname, GLint * param) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetnCompressedTexImage)(GLenum target, GLint lod, GLsizei bufSize, void * pixels) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetnTexImage)(GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void * pixels) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetnUniformdv)(GLuint program, GLint location, GLsizei bufSize, GLdouble * params) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetnUniformfv)(GLuint program, GLint location, GLsizei bufSize, GLfloat * params) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetnUniformiv)(GLuint program, GLint location, GLsizei bufSize, GLint * params) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glGetnUniformuiv)(GLuint program, GLint location, GLsizei bufSize, GLuint * params) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glInvalidateNamedFramebufferData)(GLuint framebuffer, GLsizei numAttachments, const GLenum * attachments) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glInvalidateNamedFramebufferSubData)(GLuint framebuffer, GLsizei numAttachments, const GLenum * attachments, GLint x, GLint y, GLsizei width, GLsizei height) = NULL; +void * (CODEGEN_FUNCPTR *_ptrc_glMapNamedBuffer)(GLuint buffer, GLenum access) = NULL; +void * (CODEGEN_FUNCPTR *_ptrc_glMapNamedBufferRange)(GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glMemoryBarrierByRegion)(GLbitfield barriers) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glNamedBufferData)(GLuint buffer, GLsizeiptr size, const void * data, GLenum usage) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glNamedBufferStorage)(GLuint buffer, GLsizeiptr size, const void * data, GLbitfield flags) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glNamedBufferSubData)(GLuint buffer, GLintptr offset, GLsizeiptr size, const void * data) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glNamedFramebufferDrawBuffer)(GLuint framebuffer, GLenum buf) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glNamedFramebufferDrawBuffers)(GLuint framebuffer, GLsizei n, const GLenum * bufs) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glNamedFramebufferParameteri)(GLuint framebuffer, GLenum pname, GLint param) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glNamedFramebufferReadBuffer)(GLuint framebuffer, GLenum src) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glNamedFramebufferRenderbuffer)(GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glNamedFramebufferTexture)(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glNamedFramebufferTextureLayer)(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glNamedRenderbufferStorage)(GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glNamedRenderbufferStorageMultisample)(GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glReadnPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void * data) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTextureBarrier)(void) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTextureBuffer)(GLuint texture, GLenum internalformat, GLuint buffer) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTextureBufferRange)(GLuint texture, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTextureParameterIiv)(GLuint texture, GLenum pname, const GLint * params) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTextureParameterIuiv)(GLuint texture, GLenum pname, const GLuint * params) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTextureParameterf)(GLuint texture, GLenum pname, GLfloat param) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTextureParameterfv)(GLuint texture, GLenum pname, const GLfloat * param) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTextureParameteri)(GLuint texture, GLenum pname, GLint param) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTextureParameteriv)(GLuint texture, GLenum pname, const GLint * param) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTextureStorage1D)(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTextureStorage2D)(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTextureStorage2DMultisample)(GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTextureStorage3D)(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTextureStorage3DMultisample)(GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTextureSubImage1D)(GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void * pixels) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTextureSubImage2D)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * pixels) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTextureSubImage3D)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * pixels) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTransformFeedbackBufferBase)(GLuint xfb, GLuint index, GLuint buffer) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glTransformFeedbackBufferRange)(GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) = NULL; +GLboolean (CODEGEN_FUNCPTR *_ptrc_glUnmapNamedBuffer)(GLuint buffer) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexArrayAttribBinding)(GLuint vaobj, GLuint attribindex, GLuint bindingindex) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexArrayAttribFormat)(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexArrayAttribIFormat)(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexArrayAttribLFormat)(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexArrayBindingDivisor)(GLuint vaobj, GLuint bindingindex, GLuint divisor) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexArrayElementBuffer)(GLuint vaobj, GLuint buffer) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexArrayVertexBuffer)(GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride) = NULL; +void (CODEGEN_FUNCPTR *_ptrc_glVertexArrayVertexBuffers)(GLuint vaobj, GLuint first, GLsizei count, const GLuint * buffers, const GLintptr * offsets, const GLsizei * strides) = NULL; + +static int Load_Version_4_5(void) { int numFailed = 0; _ptrc_glAccum = (void (CODEGEN_FUNCPTR *)(GLenum, GLfloat))IntGetProcAddress("glAccum"); @@ -2375,6 +2671,622 @@ static int Load_Version_3_3(void) if(!_ptrc_glVertexAttribP4ui) numFailed++; _ptrc_glVertexAttribP4uiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLboolean, const GLuint *))IntGetProcAddress("glVertexAttribP4uiv"); if(!_ptrc_glVertexAttribP4uiv) numFailed++; + _ptrc_glBeginQueryIndexed = (void (CODEGEN_FUNCPTR *)(GLenum, GLuint, GLuint))IntGetProcAddress("glBeginQueryIndexed"); + if(!_ptrc_glBeginQueryIndexed) numFailed++; + _ptrc_glBindTransformFeedback = (void (CODEGEN_FUNCPTR *)(GLenum, GLuint))IntGetProcAddress("glBindTransformFeedback"); + if(!_ptrc_glBindTransformFeedback) numFailed++; + _ptrc_glBlendEquationSeparatei = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLenum))IntGetProcAddress("glBlendEquationSeparatei"); + if(!_ptrc_glBlendEquationSeparatei) numFailed++; + _ptrc_glBlendEquationi = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum))IntGetProcAddress("glBlendEquationi"); + if(!_ptrc_glBlendEquationi) numFailed++; + _ptrc_glBlendFuncSeparatei = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLenum, GLenum, GLenum))IntGetProcAddress("glBlendFuncSeparatei"); + if(!_ptrc_glBlendFuncSeparatei) numFailed++; + _ptrc_glBlendFunci = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLenum))IntGetProcAddress("glBlendFunci"); + if(!_ptrc_glBlendFunci) numFailed++; + _ptrc_glDeleteTransformFeedbacks = (void (CODEGEN_FUNCPTR *)(GLsizei, const GLuint *))IntGetProcAddress("glDeleteTransformFeedbacks"); + if(!_ptrc_glDeleteTransformFeedbacks) numFailed++; + _ptrc_glDrawArraysIndirect = (void (CODEGEN_FUNCPTR *)(GLenum, const void *))IntGetProcAddress("glDrawArraysIndirect"); + if(!_ptrc_glDrawArraysIndirect) numFailed++; + _ptrc_glDrawElementsIndirect = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, const void *))IntGetProcAddress("glDrawElementsIndirect"); + if(!_ptrc_glDrawElementsIndirect) numFailed++; + _ptrc_glDrawTransformFeedback = (void (CODEGEN_FUNCPTR *)(GLenum, GLuint))IntGetProcAddress("glDrawTransformFeedback"); + if(!_ptrc_glDrawTransformFeedback) numFailed++; + _ptrc_glDrawTransformFeedbackStream = (void (CODEGEN_FUNCPTR *)(GLenum, GLuint, GLuint))IntGetProcAddress("glDrawTransformFeedbackStream"); + if(!_ptrc_glDrawTransformFeedbackStream) numFailed++; + _ptrc_glEndQueryIndexed = (void (CODEGEN_FUNCPTR *)(GLenum, GLuint))IntGetProcAddress("glEndQueryIndexed"); + if(!_ptrc_glEndQueryIndexed) numFailed++; + _ptrc_glGenTransformFeedbacks = (void (CODEGEN_FUNCPTR *)(GLsizei, GLuint *))IntGetProcAddress("glGenTransformFeedbacks"); + if(!_ptrc_glGenTransformFeedbacks) numFailed++; + _ptrc_glGetActiveSubroutineName = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLuint, GLsizei, GLsizei *, GLchar *))IntGetProcAddress("glGetActiveSubroutineName"); + if(!_ptrc_glGetActiveSubroutineName) numFailed++; + _ptrc_glGetActiveSubroutineUniformName = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLuint, GLsizei, GLsizei *, GLchar *))IntGetProcAddress("glGetActiveSubroutineUniformName"); + if(!_ptrc_glGetActiveSubroutineUniformName) numFailed++; + _ptrc_glGetActiveSubroutineUniformiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLuint, GLenum, GLint *))IntGetProcAddress("glGetActiveSubroutineUniformiv"); + if(!_ptrc_glGetActiveSubroutineUniformiv) numFailed++; + _ptrc_glGetProgramStageiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLenum, GLint *))IntGetProcAddress("glGetProgramStageiv"); + if(!_ptrc_glGetProgramStageiv) numFailed++; + _ptrc_glGetQueryIndexediv = (void (CODEGEN_FUNCPTR *)(GLenum, GLuint, GLenum, GLint *))IntGetProcAddress("glGetQueryIndexediv"); + if(!_ptrc_glGetQueryIndexediv) numFailed++; + _ptrc_glGetSubroutineIndex = (GLuint (CODEGEN_FUNCPTR *)(GLuint, GLenum, const GLchar *))IntGetProcAddress("glGetSubroutineIndex"); + if(!_ptrc_glGetSubroutineIndex) numFailed++; + _ptrc_glGetSubroutineUniformLocation = (GLint (CODEGEN_FUNCPTR *)(GLuint, GLenum, const GLchar *))IntGetProcAddress("glGetSubroutineUniformLocation"); + if(!_ptrc_glGetSubroutineUniformLocation) numFailed++; + _ptrc_glGetUniformSubroutineuiv = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLuint *))IntGetProcAddress("glGetUniformSubroutineuiv"); + if(!_ptrc_glGetUniformSubroutineuiv) numFailed++; + _ptrc_glGetUniformdv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLdouble *))IntGetProcAddress("glGetUniformdv"); + if(!_ptrc_glGetUniformdv) numFailed++; + _ptrc_glIsTransformFeedback = (GLboolean (CODEGEN_FUNCPTR *)(GLuint))IntGetProcAddress("glIsTransformFeedback"); + if(!_ptrc_glIsTransformFeedback) numFailed++; + _ptrc_glMinSampleShading = (void (CODEGEN_FUNCPTR *)(GLfloat))IntGetProcAddress("glMinSampleShading"); + if(!_ptrc_glMinSampleShading) numFailed++; + _ptrc_glPatchParameterfv = (void (CODEGEN_FUNCPTR *)(GLenum, const GLfloat *))IntGetProcAddress("glPatchParameterfv"); + if(!_ptrc_glPatchParameterfv) numFailed++; + _ptrc_glPatchParameteri = (void (CODEGEN_FUNCPTR *)(GLenum, GLint))IntGetProcAddress("glPatchParameteri"); + if(!_ptrc_glPatchParameteri) numFailed++; + _ptrc_glPauseTransformFeedback = (void (CODEGEN_FUNCPTR *)(void))IntGetProcAddress("glPauseTransformFeedback"); + if(!_ptrc_glPauseTransformFeedback) numFailed++; + _ptrc_glResumeTransformFeedback = (void (CODEGEN_FUNCPTR *)(void))IntGetProcAddress("glResumeTransformFeedback"); + if(!_ptrc_glResumeTransformFeedback) numFailed++; + _ptrc_glUniform1d = (void (CODEGEN_FUNCPTR *)(GLint, GLdouble))IntGetProcAddress("glUniform1d"); + if(!_ptrc_glUniform1d) numFailed++; + _ptrc_glUniform1dv = (void (CODEGEN_FUNCPTR *)(GLint, GLsizei, const GLdouble *))IntGetProcAddress("glUniform1dv"); + if(!_ptrc_glUniform1dv) numFailed++; + _ptrc_glUniform2d = (void (CODEGEN_FUNCPTR *)(GLint, GLdouble, GLdouble))IntGetProcAddress("glUniform2d"); + if(!_ptrc_glUniform2d) numFailed++; + _ptrc_glUniform2dv = (void (CODEGEN_FUNCPTR *)(GLint, GLsizei, const GLdouble *))IntGetProcAddress("glUniform2dv"); + if(!_ptrc_glUniform2dv) numFailed++; + _ptrc_glUniform3d = (void (CODEGEN_FUNCPTR *)(GLint, GLdouble, GLdouble, GLdouble))IntGetProcAddress("glUniform3d"); + if(!_ptrc_glUniform3d) numFailed++; + _ptrc_glUniform3dv = (void (CODEGEN_FUNCPTR *)(GLint, GLsizei, const GLdouble *))IntGetProcAddress("glUniform3dv"); + if(!_ptrc_glUniform3dv) numFailed++; + _ptrc_glUniform4d = (void (CODEGEN_FUNCPTR *)(GLint, GLdouble, GLdouble, GLdouble, GLdouble))IntGetProcAddress("glUniform4d"); + if(!_ptrc_glUniform4d) numFailed++; + _ptrc_glUniform4dv = (void (CODEGEN_FUNCPTR *)(GLint, GLsizei, const GLdouble *))IntGetProcAddress("glUniform4dv"); + if(!_ptrc_glUniform4dv) numFailed++; + _ptrc_glUniformMatrix2dv = (void (CODEGEN_FUNCPTR *)(GLint, GLsizei, GLboolean, const GLdouble *))IntGetProcAddress("glUniformMatrix2dv"); + if(!_ptrc_glUniformMatrix2dv) numFailed++; + _ptrc_glUniformMatrix2x3dv = (void (CODEGEN_FUNCPTR *)(GLint, GLsizei, GLboolean, const GLdouble *))IntGetProcAddress("glUniformMatrix2x3dv"); + if(!_ptrc_glUniformMatrix2x3dv) numFailed++; + _ptrc_glUniformMatrix2x4dv = (void (CODEGEN_FUNCPTR *)(GLint, GLsizei, GLboolean, const GLdouble *))IntGetProcAddress("glUniformMatrix2x4dv"); + if(!_ptrc_glUniformMatrix2x4dv) numFailed++; + _ptrc_glUniformMatrix3dv = (void (CODEGEN_FUNCPTR *)(GLint, GLsizei, GLboolean, const GLdouble *))IntGetProcAddress("glUniformMatrix3dv"); + if(!_ptrc_glUniformMatrix3dv) numFailed++; + _ptrc_glUniformMatrix3x2dv = (void (CODEGEN_FUNCPTR *)(GLint, GLsizei, GLboolean, const GLdouble *))IntGetProcAddress("glUniformMatrix3x2dv"); + if(!_ptrc_glUniformMatrix3x2dv) numFailed++; + _ptrc_glUniformMatrix3x4dv = (void (CODEGEN_FUNCPTR *)(GLint, GLsizei, GLboolean, const GLdouble *))IntGetProcAddress("glUniformMatrix3x4dv"); + if(!_ptrc_glUniformMatrix3x4dv) numFailed++; + _ptrc_glUniformMatrix4dv = (void (CODEGEN_FUNCPTR *)(GLint, GLsizei, GLboolean, const GLdouble *))IntGetProcAddress("glUniformMatrix4dv"); + if(!_ptrc_glUniformMatrix4dv) numFailed++; + _ptrc_glUniformMatrix4x2dv = (void (CODEGEN_FUNCPTR *)(GLint, GLsizei, GLboolean, const GLdouble *))IntGetProcAddress("glUniformMatrix4x2dv"); + if(!_ptrc_glUniformMatrix4x2dv) numFailed++; + _ptrc_glUniformMatrix4x3dv = (void (CODEGEN_FUNCPTR *)(GLint, GLsizei, GLboolean, const GLdouble *))IntGetProcAddress("glUniformMatrix4x3dv"); + if(!_ptrc_glUniformMatrix4x3dv) numFailed++; + _ptrc_glUniformSubroutinesuiv = (void (CODEGEN_FUNCPTR *)(GLenum, GLsizei, const GLuint *))IntGetProcAddress("glUniformSubroutinesuiv"); + if(!_ptrc_glUniformSubroutinesuiv) numFailed++; + _ptrc_glActiveShaderProgram = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint))IntGetProcAddress("glActiveShaderProgram"); + if(!_ptrc_glActiveShaderProgram) numFailed++; + _ptrc_glBindProgramPipeline = (void (CODEGEN_FUNCPTR *)(GLuint))IntGetProcAddress("glBindProgramPipeline"); + if(!_ptrc_glBindProgramPipeline) numFailed++; + _ptrc_glClearDepthf = (void (CODEGEN_FUNCPTR *)(GLfloat))IntGetProcAddress("glClearDepthf"); + if(!_ptrc_glClearDepthf) numFailed++; + _ptrc_glCreateShaderProgramv = (GLuint (CODEGEN_FUNCPTR *)(GLenum, GLsizei, const GLchar *const*))IntGetProcAddress("glCreateShaderProgramv"); + if(!_ptrc_glCreateShaderProgramv) numFailed++; + _ptrc_glDeleteProgramPipelines = (void (CODEGEN_FUNCPTR *)(GLsizei, const GLuint *))IntGetProcAddress("glDeleteProgramPipelines"); + if(!_ptrc_glDeleteProgramPipelines) numFailed++; + _ptrc_glDepthRangeArrayv = (void (CODEGEN_FUNCPTR *)(GLuint, GLsizei, const GLdouble *))IntGetProcAddress("glDepthRangeArrayv"); + if(!_ptrc_glDepthRangeArrayv) numFailed++; + _ptrc_glDepthRangeIndexed = (void (CODEGEN_FUNCPTR *)(GLuint, GLdouble, GLdouble))IntGetProcAddress("glDepthRangeIndexed"); + if(!_ptrc_glDepthRangeIndexed) numFailed++; + _ptrc_glDepthRangef = (void (CODEGEN_FUNCPTR *)(GLfloat, GLfloat))IntGetProcAddress("glDepthRangef"); + if(!_ptrc_glDepthRangef) numFailed++; + _ptrc_glGenProgramPipelines = (void (CODEGEN_FUNCPTR *)(GLsizei, GLuint *))IntGetProcAddress("glGenProgramPipelines"); + if(!_ptrc_glGenProgramPipelines) numFailed++; + _ptrc_glGetDoublei_v = (void (CODEGEN_FUNCPTR *)(GLenum, GLuint, GLdouble *))IntGetProcAddress("glGetDoublei_v"); + if(!_ptrc_glGetDoublei_v) numFailed++; + _ptrc_glGetFloati_v = (void (CODEGEN_FUNCPTR *)(GLenum, GLuint, GLfloat *))IntGetProcAddress("glGetFloati_v"); + if(!_ptrc_glGetFloati_v) numFailed++; + _ptrc_glGetProgramBinary = (void (CODEGEN_FUNCPTR *)(GLuint, GLsizei, GLsizei *, GLenum *, void *))IntGetProcAddress("glGetProgramBinary"); + if(!_ptrc_glGetProgramBinary) numFailed++; + _ptrc_glGetProgramPipelineInfoLog = (void (CODEGEN_FUNCPTR *)(GLuint, GLsizei, GLsizei *, GLchar *))IntGetProcAddress("glGetProgramPipelineInfoLog"); + if(!_ptrc_glGetProgramPipelineInfoLog) numFailed++; + _ptrc_glGetProgramPipelineiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLint *))IntGetProcAddress("glGetProgramPipelineiv"); + if(!_ptrc_glGetProgramPipelineiv) numFailed++; + _ptrc_glGetShaderPrecisionFormat = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLint *, GLint *))IntGetProcAddress("glGetShaderPrecisionFormat"); + if(!_ptrc_glGetShaderPrecisionFormat) numFailed++; + _ptrc_glGetVertexAttribLdv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLdouble *))IntGetProcAddress("glGetVertexAttribLdv"); + if(!_ptrc_glGetVertexAttribLdv) numFailed++; + _ptrc_glIsProgramPipeline = (GLboolean (CODEGEN_FUNCPTR *)(GLuint))IntGetProcAddress("glIsProgramPipeline"); + if(!_ptrc_glIsProgramPipeline) numFailed++; + _ptrc_glProgramBinary = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, const void *, GLsizei))IntGetProcAddress("glProgramBinary"); + if(!_ptrc_glProgramBinary) numFailed++; + _ptrc_glProgramParameteri = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLint))IntGetProcAddress("glProgramParameteri"); + if(!_ptrc_glProgramParameteri) numFailed++; + _ptrc_glProgramUniform1d = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLdouble))IntGetProcAddress("glProgramUniform1d"); + if(!_ptrc_glProgramUniform1d) numFailed++; + _ptrc_glProgramUniform1dv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, const GLdouble *))IntGetProcAddress("glProgramUniform1dv"); + if(!_ptrc_glProgramUniform1dv) numFailed++; + _ptrc_glProgramUniform1f = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLfloat))IntGetProcAddress("glProgramUniform1f"); + if(!_ptrc_glProgramUniform1f) numFailed++; + _ptrc_glProgramUniform1fv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, const GLfloat *))IntGetProcAddress("glProgramUniform1fv"); + if(!_ptrc_glProgramUniform1fv) numFailed++; + _ptrc_glProgramUniform1i = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLint))IntGetProcAddress("glProgramUniform1i"); + if(!_ptrc_glProgramUniform1i) numFailed++; + _ptrc_glProgramUniform1iv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, const GLint *))IntGetProcAddress("glProgramUniform1iv"); + if(!_ptrc_glProgramUniform1iv) numFailed++; + _ptrc_glProgramUniform1ui = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLuint))IntGetProcAddress("glProgramUniform1ui"); + if(!_ptrc_glProgramUniform1ui) numFailed++; + _ptrc_glProgramUniform1uiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, const GLuint *))IntGetProcAddress("glProgramUniform1uiv"); + if(!_ptrc_glProgramUniform1uiv) numFailed++; + _ptrc_glProgramUniform2d = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLdouble, GLdouble))IntGetProcAddress("glProgramUniform2d"); + if(!_ptrc_glProgramUniform2d) numFailed++; + _ptrc_glProgramUniform2dv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, const GLdouble *))IntGetProcAddress("glProgramUniform2dv"); + if(!_ptrc_glProgramUniform2dv) numFailed++; + _ptrc_glProgramUniform2f = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLfloat, GLfloat))IntGetProcAddress("glProgramUniform2f"); + if(!_ptrc_glProgramUniform2f) numFailed++; + _ptrc_glProgramUniform2fv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, const GLfloat *))IntGetProcAddress("glProgramUniform2fv"); + if(!_ptrc_glProgramUniform2fv) numFailed++; + _ptrc_glProgramUniform2i = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLint, GLint))IntGetProcAddress("glProgramUniform2i"); + if(!_ptrc_glProgramUniform2i) numFailed++; + _ptrc_glProgramUniform2iv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, const GLint *))IntGetProcAddress("glProgramUniform2iv"); + if(!_ptrc_glProgramUniform2iv) numFailed++; + _ptrc_glProgramUniform2ui = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLuint, GLuint))IntGetProcAddress("glProgramUniform2ui"); + if(!_ptrc_glProgramUniform2ui) numFailed++; + _ptrc_glProgramUniform2uiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, const GLuint *))IntGetProcAddress("glProgramUniform2uiv"); + if(!_ptrc_glProgramUniform2uiv) numFailed++; + _ptrc_glProgramUniform3d = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLdouble, GLdouble, GLdouble))IntGetProcAddress("glProgramUniform3d"); + if(!_ptrc_glProgramUniform3d) numFailed++; + _ptrc_glProgramUniform3dv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, const GLdouble *))IntGetProcAddress("glProgramUniform3dv"); + if(!_ptrc_glProgramUniform3dv) numFailed++; + _ptrc_glProgramUniform3f = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLfloat, GLfloat, GLfloat))IntGetProcAddress("glProgramUniform3f"); + if(!_ptrc_glProgramUniform3f) numFailed++; + _ptrc_glProgramUniform3fv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, const GLfloat *))IntGetProcAddress("glProgramUniform3fv"); + if(!_ptrc_glProgramUniform3fv) numFailed++; + _ptrc_glProgramUniform3i = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLint, GLint, GLint))IntGetProcAddress("glProgramUniform3i"); + if(!_ptrc_glProgramUniform3i) numFailed++; + _ptrc_glProgramUniform3iv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, const GLint *))IntGetProcAddress("glProgramUniform3iv"); + if(!_ptrc_glProgramUniform3iv) numFailed++; + _ptrc_glProgramUniform3ui = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLuint, GLuint, GLuint))IntGetProcAddress("glProgramUniform3ui"); + if(!_ptrc_glProgramUniform3ui) numFailed++; + _ptrc_glProgramUniform3uiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, const GLuint *))IntGetProcAddress("glProgramUniform3uiv"); + if(!_ptrc_glProgramUniform3uiv) numFailed++; + _ptrc_glProgramUniform4d = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLdouble, GLdouble, GLdouble, GLdouble))IntGetProcAddress("glProgramUniform4d"); + if(!_ptrc_glProgramUniform4d) numFailed++; + _ptrc_glProgramUniform4dv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, const GLdouble *))IntGetProcAddress("glProgramUniform4dv"); + if(!_ptrc_glProgramUniform4dv) numFailed++; + _ptrc_glProgramUniform4f = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLfloat, GLfloat, GLfloat, GLfloat))IntGetProcAddress("glProgramUniform4f"); + if(!_ptrc_glProgramUniform4f) numFailed++; + _ptrc_glProgramUniform4fv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, const GLfloat *))IntGetProcAddress("glProgramUniform4fv"); + if(!_ptrc_glProgramUniform4fv) numFailed++; + _ptrc_glProgramUniform4i = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLint, GLint, GLint, GLint))IntGetProcAddress("glProgramUniform4i"); + if(!_ptrc_glProgramUniform4i) numFailed++; + _ptrc_glProgramUniform4iv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, const GLint *))IntGetProcAddress("glProgramUniform4iv"); + if(!_ptrc_glProgramUniform4iv) numFailed++; + _ptrc_glProgramUniform4ui = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLuint, GLuint, GLuint, GLuint))IntGetProcAddress("glProgramUniform4ui"); + if(!_ptrc_glProgramUniform4ui) numFailed++; + _ptrc_glProgramUniform4uiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, const GLuint *))IntGetProcAddress("glProgramUniform4uiv"); + if(!_ptrc_glProgramUniform4uiv) numFailed++; + _ptrc_glProgramUniformMatrix2dv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, GLboolean, const GLdouble *))IntGetProcAddress("glProgramUniformMatrix2dv"); + if(!_ptrc_glProgramUniformMatrix2dv) numFailed++; + _ptrc_glProgramUniformMatrix2fv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, GLboolean, const GLfloat *))IntGetProcAddress("glProgramUniformMatrix2fv"); + if(!_ptrc_glProgramUniformMatrix2fv) numFailed++; + _ptrc_glProgramUniformMatrix2x3dv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, GLboolean, const GLdouble *))IntGetProcAddress("glProgramUniformMatrix2x3dv"); + if(!_ptrc_glProgramUniformMatrix2x3dv) numFailed++; + _ptrc_glProgramUniformMatrix2x3fv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, GLboolean, const GLfloat *))IntGetProcAddress("glProgramUniformMatrix2x3fv"); + if(!_ptrc_glProgramUniformMatrix2x3fv) numFailed++; + _ptrc_glProgramUniformMatrix2x4dv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, GLboolean, const GLdouble *))IntGetProcAddress("glProgramUniformMatrix2x4dv"); + if(!_ptrc_glProgramUniformMatrix2x4dv) numFailed++; + _ptrc_glProgramUniformMatrix2x4fv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, GLboolean, const GLfloat *))IntGetProcAddress("glProgramUniformMatrix2x4fv"); + if(!_ptrc_glProgramUniformMatrix2x4fv) numFailed++; + _ptrc_glProgramUniformMatrix3dv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, GLboolean, const GLdouble *))IntGetProcAddress("glProgramUniformMatrix3dv"); + if(!_ptrc_glProgramUniformMatrix3dv) numFailed++; + _ptrc_glProgramUniformMatrix3fv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, GLboolean, const GLfloat *))IntGetProcAddress("glProgramUniformMatrix3fv"); + if(!_ptrc_glProgramUniformMatrix3fv) numFailed++; + _ptrc_glProgramUniformMatrix3x2dv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, GLboolean, const GLdouble *))IntGetProcAddress("glProgramUniformMatrix3x2dv"); + if(!_ptrc_glProgramUniformMatrix3x2dv) numFailed++; + _ptrc_glProgramUniformMatrix3x2fv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, GLboolean, const GLfloat *))IntGetProcAddress("glProgramUniformMatrix3x2fv"); + if(!_ptrc_glProgramUniformMatrix3x2fv) numFailed++; + _ptrc_glProgramUniformMatrix3x4dv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, GLboolean, const GLdouble *))IntGetProcAddress("glProgramUniformMatrix3x4dv"); + if(!_ptrc_glProgramUniformMatrix3x4dv) numFailed++; + _ptrc_glProgramUniformMatrix3x4fv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, GLboolean, const GLfloat *))IntGetProcAddress("glProgramUniformMatrix3x4fv"); + if(!_ptrc_glProgramUniformMatrix3x4fv) numFailed++; + _ptrc_glProgramUniformMatrix4dv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, GLboolean, const GLdouble *))IntGetProcAddress("glProgramUniformMatrix4dv"); + if(!_ptrc_glProgramUniformMatrix4dv) numFailed++; + _ptrc_glProgramUniformMatrix4fv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, GLboolean, const GLfloat *))IntGetProcAddress("glProgramUniformMatrix4fv"); + if(!_ptrc_glProgramUniformMatrix4fv) numFailed++; + _ptrc_glProgramUniformMatrix4x2dv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, GLboolean, const GLdouble *))IntGetProcAddress("glProgramUniformMatrix4x2dv"); + if(!_ptrc_glProgramUniformMatrix4x2dv) numFailed++; + _ptrc_glProgramUniformMatrix4x2fv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, GLboolean, const GLfloat *))IntGetProcAddress("glProgramUniformMatrix4x2fv"); + if(!_ptrc_glProgramUniformMatrix4x2fv) numFailed++; + _ptrc_glProgramUniformMatrix4x3dv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, GLboolean, const GLdouble *))IntGetProcAddress("glProgramUniformMatrix4x3dv"); + if(!_ptrc_glProgramUniformMatrix4x3dv) numFailed++; + _ptrc_glProgramUniformMatrix4x3fv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, GLboolean, const GLfloat *))IntGetProcAddress("glProgramUniformMatrix4x3fv"); + if(!_ptrc_glProgramUniformMatrix4x3fv) numFailed++; + _ptrc_glReleaseShaderCompiler = (void (CODEGEN_FUNCPTR *)(void))IntGetProcAddress("glReleaseShaderCompiler"); + if(!_ptrc_glReleaseShaderCompiler) numFailed++; + _ptrc_glScissorArrayv = (void (CODEGEN_FUNCPTR *)(GLuint, GLsizei, const GLint *))IntGetProcAddress("glScissorArrayv"); + if(!_ptrc_glScissorArrayv) numFailed++; + _ptrc_glScissorIndexed = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLint, GLsizei, GLsizei))IntGetProcAddress("glScissorIndexed"); + if(!_ptrc_glScissorIndexed) numFailed++; + _ptrc_glScissorIndexedv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLint *))IntGetProcAddress("glScissorIndexedv"); + if(!_ptrc_glScissorIndexedv) numFailed++; + _ptrc_glShaderBinary = (void (CODEGEN_FUNCPTR *)(GLsizei, const GLuint *, GLenum, const void *, GLsizei))IntGetProcAddress("glShaderBinary"); + if(!_ptrc_glShaderBinary) numFailed++; + _ptrc_glUseProgramStages = (void (CODEGEN_FUNCPTR *)(GLuint, GLbitfield, GLuint))IntGetProcAddress("glUseProgramStages"); + if(!_ptrc_glUseProgramStages) numFailed++; + _ptrc_glValidateProgramPipeline = (void (CODEGEN_FUNCPTR *)(GLuint))IntGetProcAddress("glValidateProgramPipeline"); + if(!_ptrc_glValidateProgramPipeline) numFailed++; + _ptrc_glVertexAttribL1d = (void (CODEGEN_FUNCPTR *)(GLuint, GLdouble))IntGetProcAddress("glVertexAttribL1d"); + if(!_ptrc_glVertexAttribL1d) numFailed++; + _ptrc_glVertexAttribL1dv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLdouble *))IntGetProcAddress("glVertexAttribL1dv"); + if(!_ptrc_glVertexAttribL1dv) numFailed++; + _ptrc_glVertexAttribL2d = (void (CODEGEN_FUNCPTR *)(GLuint, GLdouble, GLdouble))IntGetProcAddress("glVertexAttribL2d"); + if(!_ptrc_glVertexAttribL2d) numFailed++; + _ptrc_glVertexAttribL2dv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLdouble *))IntGetProcAddress("glVertexAttribL2dv"); + if(!_ptrc_glVertexAttribL2dv) numFailed++; + _ptrc_glVertexAttribL3d = (void (CODEGEN_FUNCPTR *)(GLuint, GLdouble, GLdouble, GLdouble))IntGetProcAddress("glVertexAttribL3d"); + if(!_ptrc_glVertexAttribL3d) numFailed++; + _ptrc_glVertexAttribL3dv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLdouble *))IntGetProcAddress("glVertexAttribL3dv"); + if(!_ptrc_glVertexAttribL3dv) numFailed++; + _ptrc_glVertexAttribL4d = (void (CODEGEN_FUNCPTR *)(GLuint, GLdouble, GLdouble, GLdouble, GLdouble))IntGetProcAddress("glVertexAttribL4d"); + if(!_ptrc_glVertexAttribL4d) numFailed++; + _ptrc_glVertexAttribL4dv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLdouble *))IntGetProcAddress("glVertexAttribL4dv"); + if(!_ptrc_glVertexAttribL4dv) numFailed++; + _ptrc_glVertexAttribLPointer = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLenum, GLsizei, const void *))IntGetProcAddress("glVertexAttribLPointer"); + if(!_ptrc_glVertexAttribLPointer) numFailed++; + _ptrc_glViewportArrayv = (void (CODEGEN_FUNCPTR *)(GLuint, GLsizei, const GLfloat *))IntGetProcAddress("glViewportArrayv"); + if(!_ptrc_glViewportArrayv) numFailed++; + _ptrc_glViewportIndexedf = (void (CODEGEN_FUNCPTR *)(GLuint, GLfloat, GLfloat, GLfloat, GLfloat))IntGetProcAddress("glViewportIndexedf"); + if(!_ptrc_glViewportIndexedf) numFailed++; + _ptrc_glViewportIndexedfv = (void (CODEGEN_FUNCPTR *)(GLuint, const GLfloat *))IntGetProcAddress("glViewportIndexedfv"); + if(!_ptrc_glViewportIndexedfv) numFailed++; + _ptrc_glBindImageTexture = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLint, GLboolean, GLint, GLenum, GLenum))IntGetProcAddress("glBindImageTexture"); + if(!_ptrc_glBindImageTexture) numFailed++; + _ptrc_glDrawArraysInstancedBaseInstance = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLsizei, GLsizei, GLuint))IntGetProcAddress("glDrawArraysInstancedBaseInstance"); + if(!_ptrc_glDrawArraysInstancedBaseInstance) numFailed++; + _ptrc_glDrawElementsInstancedBaseInstance = (void (CODEGEN_FUNCPTR *)(GLenum, GLsizei, GLenum, const void *, GLsizei, GLuint))IntGetProcAddress("glDrawElementsInstancedBaseInstance"); + if(!_ptrc_glDrawElementsInstancedBaseInstance) numFailed++; + _ptrc_glDrawElementsInstancedBaseVertexBaseInstance = (void (CODEGEN_FUNCPTR *)(GLenum, GLsizei, GLenum, const void *, GLsizei, GLint, GLuint))IntGetProcAddress("glDrawElementsInstancedBaseVertexBaseInstance"); + if(!_ptrc_glDrawElementsInstancedBaseVertexBaseInstance) numFailed++; + _ptrc_glDrawTransformFeedbackInstanced = (void (CODEGEN_FUNCPTR *)(GLenum, GLuint, GLsizei))IntGetProcAddress("glDrawTransformFeedbackInstanced"); + if(!_ptrc_glDrawTransformFeedbackInstanced) numFailed++; + _ptrc_glDrawTransformFeedbackStreamInstanced = (void (CODEGEN_FUNCPTR *)(GLenum, GLuint, GLuint, GLsizei))IntGetProcAddress("glDrawTransformFeedbackStreamInstanced"); + if(!_ptrc_glDrawTransformFeedbackStreamInstanced) numFailed++; + _ptrc_glGetActiveAtomicCounterBufferiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLenum, GLint *))IntGetProcAddress("glGetActiveAtomicCounterBufferiv"); + if(!_ptrc_glGetActiveAtomicCounterBufferiv) numFailed++; + _ptrc_glGetInternalformativ = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLenum, GLsizei, GLint *))IntGetProcAddress("glGetInternalformativ"); + if(!_ptrc_glGetInternalformativ) numFailed++; + _ptrc_glMemoryBarrier = (void (CODEGEN_FUNCPTR *)(GLbitfield))IntGetProcAddress("glMemoryBarrier"); + if(!_ptrc_glMemoryBarrier) numFailed++; + _ptrc_glTexStorage1D = (void (CODEGEN_FUNCPTR *)(GLenum, GLsizei, GLenum, GLsizei))IntGetProcAddress("glTexStorage1D"); + if(!_ptrc_glTexStorage1D) numFailed++; + _ptrc_glTexStorage2D = (void (CODEGEN_FUNCPTR *)(GLenum, GLsizei, GLenum, GLsizei, GLsizei))IntGetProcAddress("glTexStorage2D"); + if(!_ptrc_glTexStorage2D) numFailed++; + _ptrc_glTexStorage3D = (void (CODEGEN_FUNCPTR *)(GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLsizei))IntGetProcAddress("glTexStorage3D"); + if(!_ptrc_glTexStorage3D) numFailed++; + _ptrc_glBindVertexBuffer = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLintptr, GLsizei))IntGetProcAddress("glBindVertexBuffer"); + if(!_ptrc_glBindVertexBuffer) numFailed++; + _ptrc_glClearBufferData = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLenum, GLenum, const void *))IntGetProcAddress("glClearBufferData"); + if(!_ptrc_glClearBufferData) numFailed++; + _ptrc_glClearBufferSubData = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLintptr, GLsizeiptr, GLenum, GLenum, const void *))IntGetProcAddress("glClearBufferSubData"); + if(!_ptrc_glClearBufferSubData) numFailed++; + _ptrc_glCopyImageSubData = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLint, GLint, GLint, GLint, GLuint, GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei))IntGetProcAddress("glCopyImageSubData"); + if(!_ptrc_glCopyImageSubData) numFailed++; + _ptrc_glDebugMessageCallback = (void (CODEGEN_FUNCPTR *)(GLDEBUGPROC, const void *))IntGetProcAddress("glDebugMessageCallback"); + if(!_ptrc_glDebugMessageCallback) numFailed++; + _ptrc_glDebugMessageControl = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLenum, GLsizei, const GLuint *, GLboolean))IntGetProcAddress("glDebugMessageControl"); + if(!_ptrc_glDebugMessageControl) numFailed++; + _ptrc_glDebugMessageInsert = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar *))IntGetProcAddress("glDebugMessageInsert"); + if(!_ptrc_glDebugMessageInsert) numFailed++; + _ptrc_glDispatchCompute = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLuint))IntGetProcAddress("glDispatchCompute"); + if(!_ptrc_glDispatchCompute) numFailed++; + _ptrc_glDispatchComputeIndirect = (void (CODEGEN_FUNCPTR *)(GLintptr))IntGetProcAddress("glDispatchComputeIndirect"); + if(!_ptrc_glDispatchComputeIndirect) numFailed++; + _ptrc_glFramebufferParameteri = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLint))IntGetProcAddress("glFramebufferParameteri"); + if(!_ptrc_glFramebufferParameteri) numFailed++; + _ptrc_glGetDebugMessageLog = (GLuint (CODEGEN_FUNCPTR *)(GLuint, GLsizei, GLenum *, GLenum *, GLuint *, GLenum *, GLsizei *, GLchar *))IntGetProcAddress("glGetDebugMessageLog"); + if(!_ptrc_glGetDebugMessageLog) numFailed++; + _ptrc_glGetFramebufferParameteriv = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLint *))IntGetProcAddress("glGetFramebufferParameteriv"); + if(!_ptrc_glGetFramebufferParameteriv) numFailed++; + _ptrc_glGetInternalformati64v = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLenum, GLsizei, GLint64 *))IntGetProcAddress("glGetInternalformati64v"); + if(!_ptrc_glGetInternalformati64v) numFailed++; + _ptrc_glGetObjectLabel = (void (CODEGEN_FUNCPTR *)(GLenum, GLuint, GLsizei, GLsizei *, GLchar *))IntGetProcAddress("glGetObjectLabel"); + if(!_ptrc_glGetObjectLabel) numFailed++; + _ptrc_glGetObjectPtrLabel = (void (CODEGEN_FUNCPTR *)(const void *, GLsizei, GLsizei *, GLchar *))IntGetProcAddress("glGetObjectPtrLabel"); + if(!_ptrc_glGetObjectPtrLabel) numFailed++; + _ptrc_glGetProgramInterfaceiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLenum, GLint *))IntGetProcAddress("glGetProgramInterfaceiv"); + if(!_ptrc_glGetProgramInterfaceiv) numFailed++; + _ptrc_glGetProgramResourceIndex = (GLuint (CODEGEN_FUNCPTR *)(GLuint, GLenum, const GLchar *))IntGetProcAddress("glGetProgramResourceIndex"); + if(!_ptrc_glGetProgramResourceIndex) numFailed++; + _ptrc_glGetProgramResourceLocation = (GLint (CODEGEN_FUNCPTR *)(GLuint, GLenum, const GLchar *))IntGetProcAddress("glGetProgramResourceLocation"); + if(!_ptrc_glGetProgramResourceLocation) numFailed++; + _ptrc_glGetProgramResourceLocationIndex = (GLint (CODEGEN_FUNCPTR *)(GLuint, GLenum, const GLchar *))IntGetProcAddress("glGetProgramResourceLocationIndex"); + if(!_ptrc_glGetProgramResourceLocationIndex) numFailed++; + _ptrc_glGetProgramResourceName = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLuint, GLsizei, GLsizei *, GLchar *))IntGetProcAddress("glGetProgramResourceName"); + if(!_ptrc_glGetProgramResourceName) numFailed++; + _ptrc_glGetProgramResourceiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLuint, GLsizei, const GLenum *, GLsizei, GLsizei *, GLint *))IntGetProcAddress("glGetProgramResourceiv"); + if(!_ptrc_glGetProgramResourceiv) numFailed++; + _ptrc_glInvalidateBufferData = (void (CODEGEN_FUNCPTR *)(GLuint))IntGetProcAddress("glInvalidateBufferData"); + if(!_ptrc_glInvalidateBufferData) numFailed++; + _ptrc_glInvalidateBufferSubData = (void (CODEGEN_FUNCPTR *)(GLuint, GLintptr, GLsizeiptr))IntGetProcAddress("glInvalidateBufferSubData"); + if(!_ptrc_glInvalidateBufferSubData) numFailed++; + _ptrc_glInvalidateFramebuffer = (void (CODEGEN_FUNCPTR *)(GLenum, GLsizei, const GLenum *))IntGetProcAddress("glInvalidateFramebuffer"); + if(!_ptrc_glInvalidateFramebuffer) numFailed++; + _ptrc_glInvalidateSubFramebuffer = (void (CODEGEN_FUNCPTR *)(GLenum, GLsizei, const GLenum *, GLint, GLint, GLsizei, GLsizei))IntGetProcAddress("glInvalidateSubFramebuffer"); + if(!_ptrc_glInvalidateSubFramebuffer) numFailed++; + _ptrc_glInvalidateTexImage = (void (CODEGEN_FUNCPTR *)(GLuint, GLint))IntGetProcAddress("glInvalidateTexImage"); + if(!_ptrc_glInvalidateTexImage) numFailed++; + _ptrc_glInvalidateTexSubImage = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei))IntGetProcAddress("glInvalidateTexSubImage"); + if(!_ptrc_glInvalidateTexSubImage) numFailed++; + _ptrc_glMultiDrawArraysIndirect = (void (CODEGEN_FUNCPTR *)(GLenum, const void *, GLsizei, GLsizei))IntGetProcAddress("glMultiDrawArraysIndirect"); + if(!_ptrc_glMultiDrawArraysIndirect) numFailed++; + _ptrc_glMultiDrawElementsIndirect = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, const void *, GLsizei, GLsizei))IntGetProcAddress("glMultiDrawElementsIndirect"); + if(!_ptrc_glMultiDrawElementsIndirect) numFailed++; + _ptrc_glObjectLabel = (void (CODEGEN_FUNCPTR *)(GLenum, GLuint, GLsizei, const GLchar *))IntGetProcAddress("glObjectLabel"); + if(!_ptrc_glObjectLabel) numFailed++; + _ptrc_glObjectPtrLabel = (void (CODEGEN_FUNCPTR *)(const void *, GLsizei, const GLchar *))IntGetProcAddress("glObjectPtrLabel"); + if(!_ptrc_glObjectPtrLabel) numFailed++; + _ptrc_glPopDebugGroup = (void (CODEGEN_FUNCPTR *)(void))IntGetProcAddress("glPopDebugGroup"); + if(!_ptrc_glPopDebugGroup) numFailed++; + _ptrc_glPushDebugGroup = (void (CODEGEN_FUNCPTR *)(GLenum, GLuint, GLsizei, const GLchar *))IntGetProcAddress("glPushDebugGroup"); + if(!_ptrc_glPushDebugGroup) numFailed++; + _ptrc_glShaderStorageBlockBinding = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLuint))IntGetProcAddress("glShaderStorageBlockBinding"); + if(!_ptrc_glShaderStorageBlockBinding) numFailed++; + _ptrc_glTexBufferRange = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum, GLuint, GLintptr, GLsizeiptr))IntGetProcAddress("glTexBufferRange"); + if(!_ptrc_glTexBufferRange) numFailed++; + _ptrc_glTexStorage2DMultisample = (void (CODEGEN_FUNCPTR *)(GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLboolean))IntGetProcAddress("glTexStorage2DMultisample"); + if(!_ptrc_glTexStorage2DMultisample) numFailed++; + _ptrc_glTexStorage3DMultisample = (void (CODEGEN_FUNCPTR *)(GLenum, GLsizei, GLenum, GLsizei, GLsizei, GLsizei, GLboolean))IntGetProcAddress("glTexStorage3DMultisample"); + if(!_ptrc_glTexStorage3DMultisample) numFailed++; + _ptrc_glTextureView = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLuint, GLenum, GLuint, GLuint, GLuint, GLuint))IntGetProcAddress("glTextureView"); + if(!_ptrc_glTextureView) numFailed++; + _ptrc_glVertexAttribBinding = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint))IntGetProcAddress("glVertexAttribBinding"); + if(!_ptrc_glVertexAttribBinding) numFailed++; + _ptrc_glVertexAttribFormat = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLenum, GLboolean, GLuint))IntGetProcAddress("glVertexAttribFormat"); + if(!_ptrc_glVertexAttribFormat) numFailed++; + _ptrc_glVertexAttribIFormat = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLenum, GLuint))IntGetProcAddress("glVertexAttribIFormat"); + if(!_ptrc_glVertexAttribIFormat) numFailed++; + _ptrc_glVertexAttribLFormat = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLenum, GLuint))IntGetProcAddress("glVertexAttribLFormat"); + if(!_ptrc_glVertexAttribLFormat) numFailed++; + _ptrc_glVertexBindingDivisor = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint))IntGetProcAddress("glVertexBindingDivisor"); + if(!_ptrc_glVertexBindingDivisor) numFailed++; + _ptrc_glBindBuffersBase = (void (CODEGEN_FUNCPTR *)(GLenum, GLuint, GLsizei, const GLuint *))IntGetProcAddress("glBindBuffersBase"); + if(!_ptrc_glBindBuffersBase) numFailed++; + _ptrc_glBindBuffersRange = (void (CODEGEN_FUNCPTR *)(GLenum, GLuint, GLsizei, const GLuint *, const GLintptr *, const GLsizeiptr *))IntGetProcAddress("glBindBuffersRange"); + if(!_ptrc_glBindBuffersRange) numFailed++; + _ptrc_glBindImageTextures = (void (CODEGEN_FUNCPTR *)(GLuint, GLsizei, const GLuint *))IntGetProcAddress("glBindImageTextures"); + if(!_ptrc_glBindImageTextures) numFailed++; + _ptrc_glBindSamplers = (void (CODEGEN_FUNCPTR *)(GLuint, GLsizei, const GLuint *))IntGetProcAddress("glBindSamplers"); + if(!_ptrc_glBindSamplers) numFailed++; + _ptrc_glBindTextures = (void (CODEGEN_FUNCPTR *)(GLuint, GLsizei, const GLuint *))IntGetProcAddress("glBindTextures"); + if(!_ptrc_glBindTextures) numFailed++; + _ptrc_glBindVertexBuffers = (void (CODEGEN_FUNCPTR *)(GLuint, GLsizei, const GLuint *, const GLintptr *, const GLsizei *))IntGetProcAddress("glBindVertexBuffers"); + if(!_ptrc_glBindVertexBuffers) numFailed++; + _ptrc_glBufferStorage = (void (CODEGEN_FUNCPTR *)(GLenum, GLsizeiptr, const void *, GLbitfield))IntGetProcAddress("glBufferStorage"); + if(!_ptrc_glBufferStorage) numFailed++; + _ptrc_glClearTexImage = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLenum, GLenum, const void *))IntGetProcAddress("glClearTexImage"); + if(!_ptrc_glClearTexImage) numFailed++; + _ptrc_glClearTexSubImage = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const void *))IntGetProcAddress("glClearTexSubImage"); + if(!_ptrc_glClearTexSubImage) numFailed++; + _ptrc_glBindTextureUnit = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint))IntGetProcAddress("glBindTextureUnit"); + if(!_ptrc_glBindTextureUnit) numFailed++; + _ptrc_glBlitNamedFramebuffer = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum))IntGetProcAddress("glBlitNamedFramebuffer"); + if(!_ptrc_glBlitNamedFramebuffer) numFailed++; + _ptrc_glCheckNamedFramebufferStatus = (GLenum (CODEGEN_FUNCPTR *)(GLuint, GLenum))IntGetProcAddress("glCheckNamedFramebufferStatus"); + if(!_ptrc_glCheckNamedFramebufferStatus) numFailed++; + _ptrc_glClearNamedBufferData = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLenum, GLenum, const void *))IntGetProcAddress("glClearNamedBufferData"); + if(!_ptrc_glClearNamedBufferData) numFailed++; + _ptrc_glClearNamedBufferSubData = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLintptr, GLsizeiptr, GLenum, GLenum, const void *))IntGetProcAddress("glClearNamedBufferSubData"); + if(!_ptrc_glClearNamedBufferSubData) numFailed++; + _ptrc_glClearNamedFramebufferfi = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLint, const GLfloat, GLint))IntGetProcAddress("glClearNamedFramebufferfi"); + if(!_ptrc_glClearNamedFramebufferfi) numFailed++; + _ptrc_glClearNamedFramebufferfv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLint, const GLfloat *))IntGetProcAddress("glClearNamedFramebufferfv"); + if(!_ptrc_glClearNamedFramebufferfv) numFailed++; + _ptrc_glClearNamedFramebufferiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLint, const GLint *))IntGetProcAddress("glClearNamedFramebufferiv"); + if(!_ptrc_glClearNamedFramebufferiv) numFailed++; + _ptrc_glClearNamedFramebufferuiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLint, const GLuint *))IntGetProcAddress("glClearNamedFramebufferuiv"); + if(!_ptrc_glClearNamedFramebufferuiv) numFailed++; + _ptrc_glClipControl = (void (CODEGEN_FUNCPTR *)(GLenum, GLenum))IntGetProcAddress("glClipControl"); + if(!_ptrc_glClipControl) numFailed++; + _ptrc_glCompressedTextureSubImage1D = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLint, GLsizei, GLenum, GLsizei, const void *))IntGetProcAddress("glCompressedTextureSubImage1D"); + if(!_ptrc_glCompressedTextureSubImage1D) numFailed++; + _ptrc_glCompressedTextureSubImage2D = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const void *))IntGetProcAddress("glCompressedTextureSubImage2D"); + if(!_ptrc_glCompressedTextureSubImage2D) numFailed++; + _ptrc_glCompressedTextureSubImage3D = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const void *))IntGetProcAddress("glCompressedTextureSubImage3D"); + if(!_ptrc_glCompressedTextureSubImage3D) numFailed++; + _ptrc_glCopyNamedBufferSubData = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLintptr, GLintptr, GLsizeiptr))IntGetProcAddress("glCopyNamedBufferSubData"); + if(!_ptrc_glCopyNamedBufferSubData) numFailed++; + _ptrc_glCopyTextureSubImage1D = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLint, GLint, GLint, GLsizei))IntGetProcAddress("glCopyTextureSubImage1D"); + if(!_ptrc_glCopyTextureSubImage1D) numFailed++; + _ptrc_glCopyTextureSubImage2D = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei))IntGetProcAddress("glCopyTextureSubImage2D"); + if(!_ptrc_glCopyTextureSubImage2D) numFailed++; + _ptrc_glCopyTextureSubImage3D = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei))IntGetProcAddress("glCopyTextureSubImage3D"); + if(!_ptrc_glCopyTextureSubImage3D) numFailed++; + _ptrc_glCreateBuffers = (void (CODEGEN_FUNCPTR *)(GLsizei, GLuint *))IntGetProcAddress("glCreateBuffers"); + if(!_ptrc_glCreateBuffers) numFailed++; + _ptrc_glCreateFramebuffers = (void (CODEGEN_FUNCPTR *)(GLsizei, GLuint *))IntGetProcAddress("glCreateFramebuffers"); + if(!_ptrc_glCreateFramebuffers) numFailed++; + _ptrc_glCreateProgramPipelines = (void (CODEGEN_FUNCPTR *)(GLsizei, GLuint *))IntGetProcAddress("glCreateProgramPipelines"); + if(!_ptrc_glCreateProgramPipelines) numFailed++; + _ptrc_glCreateQueries = (void (CODEGEN_FUNCPTR *)(GLenum, GLsizei, GLuint *))IntGetProcAddress("glCreateQueries"); + if(!_ptrc_glCreateQueries) numFailed++; + _ptrc_glCreateRenderbuffers = (void (CODEGEN_FUNCPTR *)(GLsizei, GLuint *))IntGetProcAddress("glCreateRenderbuffers"); + if(!_ptrc_glCreateRenderbuffers) numFailed++; + _ptrc_glCreateSamplers = (void (CODEGEN_FUNCPTR *)(GLsizei, GLuint *))IntGetProcAddress("glCreateSamplers"); + if(!_ptrc_glCreateSamplers) numFailed++; + _ptrc_glCreateTextures = (void (CODEGEN_FUNCPTR *)(GLenum, GLsizei, GLuint *))IntGetProcAddress("glCreateTextures"); + if(!_ptrc_glCreateTextures) numFailed++; + _ptrc_glCreateTransformFeedbacks = (void (CODEGEN_FUNCPTR *)(GLsizei, GLuint *))IntGetProcAddress("glCreateTransformFeedbacks"); + if(!_ptrc_glCreateTransformFeedbacks) numFailed++; + _ptrc_glCreateVertexArrays = (void (CODEGEN_FUNCPTR *)(GLsizei, GLuint *))IntGetProcAddress("glCreateVertexArrays"); + if(!_ptrc_glCreateVertexArrays) numFailed++; + _ptrc_glDisableVertexArrayAttrib = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint))IntGetProcAddress("glDisableVertexArrayAttrib"); + if(!_ptrc_glDisableVertexArrayAttrib) numFailed++; + _ptrc_glEnableVertexArrayAttrib = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint))IntGetProcAddress("glEnableVertexArrayAttrib"); + if(!_ptrc_glEnableVertexArrayAttrib) numFailed++; + _ptrc_glFlushMappedNamedBufferRange = (void (CODEGEN_FUNCPTR *)(GLuint, GLintptr, GLsizeiptr))IntGetProcAddress("glFlushMappedNamedBufferRange"); + if(!_ptrc_glFlushMappedNamedBufferRange) numFailed++; + _ptrc_glGenerateTextureMipmap = (void (CODEGEN_FUNCPTR *)(GLuint))IntGetProcAddress("glGenerateTextureMipmap"); + if(!_ptrc_glGenerateTextureMipmap) numFailed++; + _ptrc_glGetCompressedTextureImage = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, void *))IntGetProcAddress("glGetCompressedTextureImage"); + if(!_ptrc_glGetCompressedTextureImage) numFailed++; + _ptrc_glGetCompressedTextureSubImage = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLsizei, void *))IntGetProcAddress("glGetCompressedTextureSubImage"); + if(!_ptrc_glGetCompressedTextureSubImage) numFailed++; + _ptrc_glGetGraphicsResetStatus = (GLenum (CODEGEN_FUNCPTR *)(void))IntGetProcAddress("glGetGraphicsResetStatus"); + if(!_ptrc_glGetGraphicsResetStatus) numFailed++; + _ptrc_glGetNamedBufferParameteri64v = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLint64 *))IntGetProcAddress("glGetNamedBufferParameteri64v"); + if(!_ptrc_glGetNamedBufferParameteri64v) numFailed++; + _ptrc_glGetNamedBufferParameteriv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLint *))IntGetProcAddress("glGetNamedBufferParameteriv"); + if(!_ptrc_glGetNamedBufferParameteriv) numFailed++; + _ptrc_glGetNamedBufferPointerv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, void **))IntGetProcAddress("glGetNamedBufferPointerv"); + if(!_ptrc_glGetNamedBufferPointerv) numFailed++; + _ptrc_glGetNamedBufferSubData = (void (CODEGEN_FUNCPTR *)(GLuint, GLintptr, GLsizeiptr, void *))IntGetProcAddress("glGetNamedBufferSubData"); + if(!_ptrc_glGetNamedBufferSubData) numFailed++; + _ptrc_glGetNamedFramebufferAttachmentParameteriv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLenum, GLint *))IntGetProcAddress("glGetNamedFramebufferAttachmentParameteriv"); + if(!_ptrc_glGetNamedFramebufferAttachmentParameteriv) numFailed++; + _ptrc_glGetNamedFramebufferParameteriv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLint *))IntGetProcAddress("glGetNamedFramebufferParameteriv"); + if(!_ptrc_glGetNamedFramebufferParameteriv) numFailed++; + _ptrc_glGetNamedRenderbufferParameteriv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLint *))IntGetProcAddress("glGetNamedRenderbufferParameteriv"); + if(!_ptrc_glGetNamedRenderbufferParameteriv) numFailed++; + _ptrc_glGetQueryBufferObjecti64v = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLenum, GLintptr))IntGetProcAddress("glGetQueryBufferObjecti64v"); + if(!_ptrc_glGetQueryBufferObjecti64v) numFailed++; + _ptrc_glGetQueryBufferObjectiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLenum, GLintptr))IntGetProcAddress("glGetQueryBufferObjectiv"); + if(!_ptrc_glGetQueryBufferObjectiv) numFailed++; + _ptrc_glGetQueryBufferObjectui64v = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLenum, GLintptr))IntGetProcAddress("glGetQueryBufferObjectui64v"); + if(!_ptrc_glGetQueryBufferObjectui64v) numFailed++; + _ptrc_glGetQueryBufferObjectuiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLenum, GLintptr))IntGetProcAddress("glGetQueryBufferObjectuiv"); + if(!_ptrc_glGetQueryBufferObjectuiv) numFailed++; + _ptrc_glGetTextureImage = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLenum, GLenum, GLsizei, void *))IntGetProcAddress("glGetTextureImage"); + if(!_ptrc_glGetTextureImage) numFailed++; + _ptrc_glGetTextureLevelParameterfv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLenum, GLfloat *))IntGetProcAddress("glGetTextureLevelParameterfv"); + if(!_ptrc_glGetTextureLevelParameterfv) numFailed++; + _ptrc_glGetTextureLevelParameteriv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLenum, GLint *))IntGetProcAddress("glGetTextureLevelParameteriv"); + if(!_ptrc_glGetTextureLevelParameteriv) numFailed++; + _ptrc_glGetTextureParameterIiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLint *))IntGetProcAddress("glGetTextureParameterIiv"); + if(!_ptrc_glGetTextureParameterIiv) numFailed++; + _ptrc_glGetTextureParameterIuiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLuint *))IntGetProcAddress("glGetTextureParameterIuiv"); + if(!_ptrc_glGetTextureParameterIuiv) numFailed++; + _ptrc_glGetTextureParameterfv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLfloat *))IntGetProcAddress("glGetTextureParameterfv"); + if(!_ptrc_glGetTextureParameterfv) numFailed++; + _ptrc_glGetTextureParameteriv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLint *))IntGetProcAddress("glGetTextureParameteriv"); + if(!_ptrc_glGetTextureParameteriv) numFailed++; + _ptrc_glGetTextureSubImage = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, GLsizei, void *))IntGetProcAddress("glGetTextureSubImage"); + if(!_ptrc_glGetTextureSubImage) numFailed++; + _ptrc_glGetTransformFeedbacki64_v = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLuint, GLint64 *))IntGetProcAddress("glGetTransformFeedbacki64_v"); + if(!_ptrc_glGetTransformFeedbacki64_v) numFailed++; + _ptrc_glGetTransformFeedbacki_v = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLuint, GLint *))IntGetProcAddress("glGetTransformFeedbacki_v"); + if(!_ptrc_glGetTransformFeedbacki_v) numFailed++; + _ptrc_glGetTransformFeedbackiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLint *))IntGetProcAddress("glGetTransformFeedbackiv"); + if(!_ptrc_glGetTransformFeedbackiv) numFailed++; + _ptrc_glGetVertexArrayIndexed64iv = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLenum, GLint64 *))IntGetProcAddress("glGetVertexArrayIndexed64iv"); + if(!_ptrc_glGetVertexArrayIndexed64iv) numFailed++; + _ptrc_glGetVertexArrayIndexediv = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLenum, GLint *))IntGetProcAddress("glGetVertexArrayIndexediv"); + if(!_ptrc_glGetVertexArrayIndexediv) numFailed++; + _ptrc_glGetVertexArrayiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLint *))IntGetProcAddress("glGetVertexArrayiv"); + if(!_ptrc_glGetVertexArrayiv) numFailed++; + _ptrc_glGetnCompressedTexImage = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLsizei, void *))IntGetProcAddress("glGetnCompressedTexImage"); + if(!_ptrc_glGetnCompressedTexImage) numFailed++; + _ptrc_glGetnTexImage = (void (CODEGEN_FUNCPTR *)(GLenum, GLint, GLenum, GLenum, GLsizei, void *))IntGetProcAddress("glGetnTexImage"); + if(!_ptrc_glGetnTexImage) numFailed++; + _ptrc_glGetnUniformdv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, GLdouble *))IntGetProcAddress("glGetnUniformdv"); + if(!_ptrc_glGetnUniformdv) numFailed++; + _ptrc_glGetnUniformfv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, GLfloat *))IntGetProcAddress("glGetnUniformfv"); + if(!_ptrc_glGetnUniformfv) numFailed++; + _ptrc_glGetnUniformiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, GLint *))IntGetProcAddress("glGetnUniformiv"); + if(!_ptrc_glGetnUniformiv) numFailed++; + _ptrc_glGetnUniformuiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLsizei, GLuint *))IntGetProcAddress("glGetnUniformuiv"); + if(!_ptrc_glGetnUniformuiv) numFailed++; + _ptrc_glInvalidateNamedFramebufferData = (void (CODEGEN_FUNCPTR *)(GLuint, GLsizei, const GLenum *))IntGetProcAddress("glInvalidateNamedFramebufferData"); + if(!_ptrc_glInvalidateNamedFramebufferData) numFailed++; + _ptrc_glInvalidateNamedFramebufferSubData = (void (CODEGEN_FUNCPTR *)(GLuint, GLsizei, const GLenum *, GLint, GLint, GLsizei, GLsizei))IntGetProcAddress("glInvalidateNamedFramebufferSubData"); + if(!_ptrc_glInvalidateNamedFramebufferSubData) numFailed++; + _ptrc_glMapNamedBuffer = (void * (CODEGEN_FUNCPTR *)(GLuint, GLenum))IntGetProcAddress("glMapNamedBuffer"); + if(!_ptrc_glMapNamedBuffer) numFailed++; + _ptrc_glMapNamedBufferRange = (void * (CODEGEN_FUNCPTR *)(GLuint, GLintptr, GLsizeiptr, GLbitfield))IntGetProcAddress("glMapNamedBufferRange"); + if(!_ptrc_glMapNamedBufferRange) numFailed++; + _ptrc_glMemoryBarrierByRegion = (void (CODEGEN_FUNCPTR *)(GLbitfield))IntGetProcAddress("glMemoryBarrierByRegion"); + if(!_ptrc_glMemoryBarrierByRegion) numFailed++; + _ptrc_glNamedBufferData = (void (CODEGEN_FUNCPTR *)(GLuint, GLsizeiptr, const void *, GLenum))IntGetProcAddress("glNamedBufferData"); + if(!_ptrc_glNamedBufferData) numFailed++; + _ptrc_glNamedBufferStorage = (void (CODEGEN_FUNCPTR *)(GLuint, GLsizeiptr, const void *, GLbitfield))IntGetProcAddress("glNamedBufferStorage"); + if(!_ptrc_glNamedBufferStorage) numFailed++; + _ptrc_glNamedBufferSubData = (void (CODEGEN_FUNCPTR *)(GLuint, GLintptr, GLsizeiptr, const void *))IntGetProcAddress("glNamedBufferSubData"); + if(!_ptrc_glNamedBufferSubData) numFailed++; + _ptrc_glNamedFramebufferDrawBuffer = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum))IntGetProcAddress("glNamedFramebufferDrawBuffer"); + if(!_ptrc_glNamedFramebufferDrawBuffer) numFailed++; + _ptrc_glNamedFramebufferDrawBuffers = (void (CODEGEN_FUNCPTR *)(GLuint, GLsizei, const GLenum *))IntGetProcAddress("glNamedFramebufferDrawBuffers"); + if(!_ptrc_glNamedFramebufferDrawBuffers) numFailed++; + _ptrc_glNamedFramebufferParameteri = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLint))IntGetProcAddress("glNamedFramebufferParameteri"); + if(!_ptrc_glNamedFramebufferParameteri) numFailed++; + _ptrc_glNamedFramebufferReadBuffer = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum))IntGetProcAddress("glNamedFramebufferReadBuffer"); + if(!_ptrc_glNamedFramebufferReadBuffer) numFailed++; + _ptrc_glNamedFramebufferRenderbuffer = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLenum, GLuint))IntGetProcAddress("glNamedFramebufferRenderbuffer"); + if(!_ptrc_glNamedFramebufferRenderbuffer) numFailed++; + _ptrc_glNamedFramebufferTexture = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLuint, GLint))IntGetProcAddress("glNamedFramebufferTexture"); + if(!_ptrc_glNamedFramebufferTexture) numFailed++; + _ptrc_glNamedFramebufferTextureLayer = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLuint, GLint, GLint))IntGetProcAddress("glNamedFramebufferTextureLayer"); + if(!_ptrc_glNamedFramebufferTextureLayer) numFailed++; + _ptrc_glNamedRenderbufferStorage = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLsizei, GLsizei))IntGetProcAddress("glNamedRenderbufferStorage"); + if(!_ptrc_glNamedRenderbufferStorage) numFailed++; + _ptrc_glNamedRenderbufferStorageMultisample = (void (CODEGEN_FUNCPTR *)(GLuint, GLsizei, GLenum, GLsizei, GLsizei))IntGetProcAddress("glNamedRenderbufferStorageMultisample"); + if(!_ptrc_glNamedRenderbufferStorageMultisample) numFailed++; + _ptrc_glReadnPixels = (void (CODEGEN_FUNCPTR *)(GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLsizei, void *))IntGetProcAddress("glReadnPixels"); + if(!_ptrc_glReadnPixels) numFailed++; + _ptrc_glTextureBarrier = (void (CODEGEN_FUNCPTR *)(void))IntGetProcAddress("glTextureBarrier"); + if(!_ptrc_glTextureBarrier) numFailed++; + _ptrc_glTextureBuffer = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLuint))IntGetProcAddress("glTextureBuffer"); + if(!_ptrc_glTextureBuffer) numFailed++; + _ptrc_glTextureBufferRange = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLuint, GLintptr, GLsizeiptr))IntGetProcAddress("glTextureBufferRange"); + if(!_ptrc_glTextureBufferRange) numFailed++; + _ptrc_glTextureParameterIiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, const GLint *))IntGetProcAddress("glTextureParameterIiv"); + if(!_ptrc_glTextureParameterIiv) numFailed++; + _ptrc_glTextureParameterIuiv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, const GLuint *))IntGetProcAddress("glTextureParameterIuiv"); + if(!_ptrc_glTextureParameterIuiv) numFailed++; + _ptrc_glTextureParameterf = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLfloat))IntGetProcAddress("glTextureParameterf"); + if(!_ptrc_glTextureParameterf) numFailed++; + _ptrc_glTextureParameterfv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, const GLfloat *))IntGetProcAddress("glTextureParameterfv"); + if(!_ptrc_glTextureParameterfv) numFailed++; + _ptrc_glTextureParameteri = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, GLint))IntGetProcAddress("glTextureParameteri"); + if(!_ptrc_glTextureParameteri) numFailed++; + _ptrc_glTextureParameteriv = (void (CODEGEN_FUNCPTR *)(GLuint, GLenum, const GLint *))IntGetProcAddress("glTextureParameteriv"); + if(!_ptrc_glTextureParameteriv) numFailed++; + _ptrc_glTextureStorage1D = (void (CODEGEN_FUNCPTR *)(GLuint, GLsizei, GLenum, GLsizei))IntGetProcAddress("glTextureStorage1D"); + if(!_ptrc_glTextureStorage1D) numFailed++; + _ptrc_glTextureStorage2D = (void (CODEGEN_FUNCPTR *)(GLuint, GLsizei, GLenum, GLsizei, GLsizei))IntGetProcAddress("glTextureStorage2D"); + if(!_ptrc_glTextureStorage2D) numFailed++; + _ptrc_glTextureStorage2DMultisample = (void (CODEGEN_FUNCPTR *)(GLuint, GLsizei, GLenum, GLsizei, GLsizei, GLboolean))IntGetProcAddress("glTextureStorage2DMultisample"); + if(!_ptrc_glTextureStorage2DMultisample) numFailed++; + _ptrc_glTextureStorage3D = (void (CODEGEN_FUNCPTR *)(GLuint, GLsizei, GLenum, GLsizei, GLsizei, GLsizei))IntGetProcAddress("glTextureStorage3D"); + if(!_ptrc_glTextureStorage3D) numFailed++; + _ptrc_glTextureStorage3DMultisample = (void (CODEGEN_FUNCPTR *)(GLuint, GLsizei, GLenum, GLsizei, GLsizei, GLsizei, GLboolean))IntGetProcAddress("glTextureStorage3DMultisample"); + if(!_ptrc_glTextureStorage3DMultisample) numFailed++; + _ptrc_glTextureSubImage1D = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLint, GLsizei, GLenum, GLenum, const void *))IntGetProcAddress("glTextureSubImage1D"); + if(!_ptrc_glTextureSubImage1D) numFailed++; + _ptrc_glTextureSubImage2D = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const void *))IntGetProcAddress("glTextureSubImage2D"); + if(!_ptrc_glTextureSubImage2D) numFailed++; + _ptrc_glTextureSubImage3D = (void (CODEGEN_FUNCPTR *)(GLuint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const void *))IntGetProcAddress("glTextureSubImage3D"); + if(!_ptrc_glTextureSubImage3D) numFailed++; + _ptrc_glTransformFeedbackBufferBase = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLuint))IntGetProcAddress("glTransformFeedbackBufferBase"); + if(!_ptrc_glTransformFeedbackBufferBase) numFailed++; + _ptrc_glTransformFeedbackBufferRange = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLuint, GLintptr, GLsizeiptr))IntGetProcAddress("glTransformFeedbackBufferRange"); + if(!_ptrc_glTransformFeedbackBufferRange) numFailed++; + _ptrc_glUnmapNamedBuffer = (GLboolean (CODEGEN_FUNCPTR *)(GLuint))IntGetProcAddress("glUnmapNamedBuffer"); + if(!_ptrc_glUnmapNamedBuffer) numFailed++; + _ptrc_glVertexArrayAttribBinding = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLuint))IntGetProcAddress("glVertexArrayAttribBinding"); + if(!_ptrc_glVertexArrayAttribBinding) numFailed++; + _ptrc_glVertexArrayAttribFormat = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLint, GLenum, GLboolean, GLuint))IntGetProcAddress("glVertexArrayAttribFormat"); + if(!_ptrc_glVertexArrayAttribFormat) numFailed++; + _ptrc_glVertexArrayAttribIFormat = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLint, GLenum, GLuint))IntGetProcAddress("glVertexArrayAttribIFormat"); + if(!_ptrc_glVertexArrayAttribIFormat) numFailed++; + _ptrc_glVertexArrayAttribLFormat = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLint, GLenum, GLuint))IntGetProcAddress("glVertexArrayAttribLFormat"); + if(!_ptrc_glVertexArrayAttribLFormat) numFailed++; + _ptrc_glVertexArrayBindingDivisor = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLuint))IntGetProcAddress("glVertexArrayBindingDivisor"); + if(!_ptrc_glVertexArrayBindingDivisor) numFailed++; + _ptrc_glVertexArrayElementBuffer = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint))IntGetProcAddress("glVertexArrayElementBuffer"); + if(!_ptrc_glVertexArrayElementBuffer) numFailed++; + _ptrc_glVertexArrayVertexBuffer = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLuint, GLintptr, GLsizei))IntGetProcAddress("glVertexArrayVertexBuffer"); + if(!_ptrc_glVertexArrayVertexBuffer) numFailed++; + _ptrc_glVertexArrayVertexBuffers = (void (CODEGEN_FUNCPTR *)(GLuint, GLuint, GLsizei, const GLuint *, const GLintptr *, const GLsizei *))IntGetProcAddress("glVertexArrayVertexBuffers"); + if(!_ptrc_glVertexArrayVertexBuffers) numFailed++; return numFailed; } @@ -2525,7 +3437,7 @@ int ogl_LoadFunctions() ProcExtsFromExtString((const char *)_ptrc_glGetString(GL_EXTENSIONS)); } - numFailed = Load_Version_3_3(); + numFailed = Load_Version_4_5(); if(numFailed == 0) return ogl_LOAD_SUCCEEDED; diff --git a/src/gl/system/gl_load.h b/src/gl_load/gl_load.h similarity index 66% rename from src/gl/system/gl_load.h rename to src/gl_load/gl_load.h index ee849aaf96..4748d68169 100644 --- a/src/gl/system/gl_load.h +++ b/src/gl_load/gl_load.h @@ -1539,6 +1539,534 @@ extern int ogl_ext_ARB_invalidate_subdata; #define GL_TIME_ELAPSED 0x88BF #define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE +#define GL_ACTIVE_SUBROUTINES 0x8DE5 +#define GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48 +#define GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6 +#define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47 +#define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49 +#define GL_COMPATIBLE_SUBROUTINES 0x8E4B +#define GL_DOUBLE_MAT2 0x8F46 +#define GL_DOUBLE_MAT2x3 0x8F49 +#define GL_DOUBLE_MAT2x4 0x8F4A +#define GL_DOUBLE_MAT3 0x8F47 +#define GL_DOUBLE_MAT3x2 0x8F4B +#define GL_DOUBLE_MAT3x4 0x8F4C +#define GL_DOUBLE_MAT4 0x8F48 +#define GL_DOUBLE_MAT4x2 0x8F4D +#define GL_DOUBLE_MAT4x3 0x8F4E +#define GL_DOUBLE_VEC2 0x8FFC +#define GL_DOUBLE_VEC3 0x8FFD +#define GL_DOUBLE_VEC4 0x8FFE +#define GL_DRAW_INDIRECT_BUFFER 0x8F3F +#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43 +#define GL_FRACTIONAL_EVEN 0x8E7C +#define GL_FRACTIONAL_ODD 0x8E7B +#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D +#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F +#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E +#define GL_ISOLINES 0x8E7A +#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E +#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F +#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C +#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A +#define GL_MAX_PATCH_VERTICES 0x8E7D +#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F +#define GL_MAX_SUBROUTINES 0x8DE7 +#define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8 +#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C +#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83 +#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81 +#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85 +#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89 +#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F +#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D +#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86 +#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82 +#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A +#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80 +#define GL_MAX_TESS_GEN_LEVEL 0x8E7E +#define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84 +#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70 +#define GL_MAX_VERTEX_STREAMS 0x8E71 +#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B +#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E +#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37 +#define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A +#define GL_PATCHES 0x000E +#define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73 +#define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74 +#define GL_PATCH_VERTICES 0x8E72 +#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B +#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C +#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D +#define GL_SAMPLE_SHADING 0x8C36 +#define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75 +#define GL_TESS_CONTROL_SHADER 0x8E88 +#define GL_TESS_EVALUATION_SHADER 0x8E87 +#define GL_TESS_GEN_MODE 0x8E76 +#define GL_TESS_GEN_POINT_MODE 0x8E79 +#define GL_TESS_GEN_SPACING 0x8E77 +#define GL_TESS_GEN_VERTEX_ORDER 0x8E78 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A +#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009 +#define GL_TRANSFORM_FEEDBACK 0x8E22 +#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 +#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1 +#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F + +#define GL_ACTIVE_PROGRAM 0x8259 +#define GL_ALL_SHADER_BITS 0xFFFFFFFF +#define GL_FIXED 0x140C +#define GL_FRAGMENT_SHADER_BIT 0x00000002 +#define GL_GEOMETRY_SHADER_BIT 0x00000004 +#define GL_HIGH_FLOAT 0x8DF2 +#define GL_HIGH_INT 0x8DF5 +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B +#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A +#define GL_LAYER_PROVOKING_VERTEX 0x825E +#define GL_LOW_FLOAT 0x8DF0 +#define GL_LOW_INT 0x8DF3 +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#define GL_MAX_VIEWPORTS 0x825B +#define GL_MEDIUM_FLOAT 0x8DF1 +#define GL_MEDIUM_INT 0x8DF4 +#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 +#define GL_PROGRAM_BINARY_FORMATS 0x87FF +#define GL_PROGRAM_BINARY_LENGTH 0x8741 +#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257 +#define GL_PROGRAM_PIPELINE_BINDING 0x825A +#define GL_PROGRAM_SEPARABLE 0x8258 +#define GL_RGB565 0x8D62 +#define GL_SHADER_BINARY_FORMATS 0x8DF8 +#define GL_SHADER_COMPILER 0x8DFA +#define GL_TESS_CONTROL_SHADER_BIT 0x00000008 +#define GL_TESS_EVALUATION_SHADER_BIT 0x00000010 +#define GL_UNDEFINED_VERTEX 0x8260 +#define GL_VERTEX_SHADER_BIT 0x00000001 +#define GL_VIEWPORT_BOUNDS_RANGE 0x825D +#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX 0x825F +#define GL_VIEWPORT_SUBPIXEL_BITS 0x825C + +#define GL_ACTIVE_ATOMIC_COUNTER_BUFFERS 0x92D9 +#define GL_ALL_BARRIER_BITS 0xFFFFFFFF +#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000 +#define GL_ATOMIC_COUNTER_BUFFER 0x92C0 +#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS 0x92C5 +#define GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES 0x92C6 +#define GL_ATOMIC_COUNTER_BUFFER_BINDING 0x92C1 +#define GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE 0x92C4 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER 0x92CB +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER 0x92CA +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER 0x92C8 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER 0x92C9 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER 0x92C7 +#define GL_ATOMIC_COUNTER_BUFFER_SIZE 0x92C3 +#define GL_ATOMIC_COUNTER_BUFFER_START 0x92C2 +#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200 +#define GL_COMMAND_BARRIER_BIT 0x00000040 +#define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C +#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E +#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F +#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D +#define GL_COPY_READ_BUFFER_BINDING 0x8F36 +#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37 +#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002 +#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400 +#define GL_IMAGE_1D 0x904C +#define GL_IMAGE_1D_ARRAY 0x9052 +#define GL_IMAGE_2D 0x904D +#define GL_IMAGE_2D_ARRAY 0x9053 +#define GL_IMAGE_2D_MULTISAMPLE 0x9055 +#define GL_IMAGE_2D_MULTISAMPLE_ARRAY 0x9056 +#define GL_IMAGE_2D_RECT 0x904F +#define GL_IMAGE_3D 0x904E +#define GL_IMAGE_BINDING_ACCESS 0x8F3E +#define GL_IMAGE_BINDING_FORMAT 0x906E +#define GL_IMAGE_BINDING_LAYER 0x8F3D +#define GL_IMAGE_BINDING_LAYERED 0x8F3C +#define GL_IMAGE_BINDING_LEVEL 0x8F3B +#define GL_IMAGE_BINDING_NAME 0x8F3A +#define GL_IMAGE_BUFFER 0x9051 +#define GL_IMAGE_CUBE 0x9050 +#define GL_IMAGE_CUBE_MAP_ARRAY 0x9054 +#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9 +#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8 +#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7 +#define GL_INT_IMAGE_1D 0x9057 +#define GL_INT_IMAGE_1D_ARRAY 0x905D +#define GL_INT_IMAGE_2D 0x9058 +#define GL_INT_IMAGE_2D_ARRAY 0x905E +#define GL_INT_IMAGE_2D_MULTISAMPLE 0x9060 +#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061 +#define GL_INT_IMAGE_2D_RECT 0x905A +#define GL_INT_IMAGE_3D 0x9059 +#define GL_INT_IMAGE_BUFFER 0x905C +#define GL_INT_IMAGE_CUBE 0x905B +#define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F +#define GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS 0x92DC +#define GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE 0x92D8 +#define GL_MAX_COMBINED_ATOMIC_COUNTERS 0x92D7 +#define GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS 0x92D1 +#define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF +/*Copied GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS From: ARB_shader_storage_buffer_object*/ +#define GL_MAX_FRAGMENT_ATOMIC_COUNTERS 0x92D6 +#define GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS 0x92D0 +#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE +#define GL_MAX_GEOMETRY_ATOMIC_COUNTERS 0x92D5 +#define GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS 0x92CF +#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS 0x90CD +#define GL_MAX_IMAGE_SAMPLES 0x906D +#define GL_MAX_IMAGE_UNITS 0x8F38 +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS 0x92D3 +#define GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS 0x92CD +#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS 0x90CB +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS 0x92D4 +#define GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS 0x92CE +#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS 0x90CC +#define GL_MAX_VERTEX_ATOMIC_COUNTERS 0x92D2 +#define GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS 0x92CC +#define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA +#define GL_MIN_MAP_BUFFER_ALIGNMENT 0x90BC +#define GL_NUM_SAMPLE_COUNTS 0x9380 +#define GL_PACK_COMPRESSED_BLOCK_DEPTH 0x912D +#define GL_PACK_COMPRESSED_BLOCK_HEIGHT 0x912C +#define GL_PACK_COMPRESSED_BLOCK_SIZE 0x912E +#define GL_PACK_COMPRESSED_BLOCK_WIDTH 0x912B +#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080 +#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020 +#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008 +#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F +#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100 +#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24 +#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800 +#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23 +#define GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX 0x92DA +#define GL_UNIFORM_BARRIER_BIT 0x00000004 +#define GL_UNPACK_COMPRESSED_BLOCK_DEPTH 0x9129 +#define GL_UNPACK_COMPRESSED_BLOCK_HEIGHT 0x9128 +#define GL_UNPACK_COMPRESSED_BLOCK_SIZE 0x912A +#define GL_UNPACK_COMPRESSED_BLOCK_WIDTH 0x9127 +#define GL_UNSIGNED_INT_ATOMIC_COUNTER 0x92DB +#define GL_UNSIGNED_INT_IMAGE_1D 0x9062 +#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY 0x9068 +#define GL_UNSIGNED_INT_IMAGE_2D 0x9063 +#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069 +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B +#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C +#define GL_UNSIGNED_INT_IMAGE_2D_RECT 0x9065 +#define GL_UNSIGNED_INT_IMAGE_3D 0x9064 +#define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067 +#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066 +#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A +#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001 + +#define GL_ACTIVE_RESOURCES 0x92F5 +#define GL_ACTIVE_VARIABLES 0x9305 +#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A +#define GL_ARRAY_SIZE 0x92FB +#define GL_ARRAY_STRIDE 0x92FE +#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301 +#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED +#define GL_AUTO_GENERATE_MIPMAP 0x8295 +#define GL_BLOCK_INDEX 0x92FD +/*Copied GL_BUFFER From: KHR_debug*/ +#define GL_BUFFER_BINDING 0x9302 +#define GL_BUFFER_DATA_SIZE 0x9303 +#define GL_BUFFER_VARIABLE 0x92E5 +#define GL_CAVEAT_SUPPORT 0x82B8 +#define GL_CLEAR_BUFFER 0x82B4 +#define GL_COLOR_COMPONENTS 0x8283 +#define GL_COLOR_ENCODING 0x8296 +#define GL_COLOR_RENDERABLE 0x8286 +#define GL_COMPRESSED_R11_EAC 0x9270 +#define GL_COMPRESSED_RG11_EAC 0x9272 +#define GL_COMPRESSED_RGB8_ETC2 0x9274 +#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276 +#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278 +#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271 +#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 +#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279 +#define GL_COMPRESSED_SRGB8_ETC2 0x9275 +#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277 +#define GL_COMPUTE_SHADER 0x91B9 +#define GL_COMPUTE_SHADER_BIT 0x00000020 +#define GL_COMPUTE_SUBROUTINE 0x92ED +#define GL_COMPUTE_SUBROUTINE_UNIFORM 0x92F3 +#define GL_COMPUTE_TEXTURE 0x82A0 +#define GL_COMPUTE_WORK_GROUP_SIZE 0x8267 +/*Copied GL_CONTEXT_FLAG_DEBUG_BIT From: KHR_debug*/ +/*Copied GL_DEBUG_CALLBACK_FUNCTION From: KHR_debug*/ +/*Copied GL_DEBUG_CALLBACK_USER_PARAM From: KHR_debug*/ +/*Copied GL_DEBUG_GROUP_STACK_DEPTH From: KHR_debug*/ +/*Copied GL_DEBUG_LOGGED_MESSAGES From: KHR_debug*/ +/*Copied GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH From: KHR_debug*/ +/*Copied GL_DEBUG_OUTPUT From: KHR_debug*/ +/*Copied GL_DEBUG_OUTPUT_SYNCHRONOUS From: KHR_debug*/ +/*Copied GL_DEBUG_SEVERITY_HIGH From: KHR_debug*/ +/*Copied GL_DEBUG_SEVERITY_LOW From: KHR_debug*/ +/*Copied GL_DEBUG_SEVERITY_MEDIUM From: KHR_debug*/ +/*Copied GL_DEBUG_SEVERITY_NOTIFICATION From: KHR_debug*/ +/*Copied GL_DEBUG_SOURCE_API From: KHR_debug*/ +/*Copied GL_DEBUG_SOURCE_APPLICATION From: KHR_debug*/ +/*Copied GL_DEBUG_SOURCE_OTHER From: KHR_debug*/ +/*Copied GL_DEBUG_SOURCE_SHADER_COMPILER From: KHR_debug*/ +/*Copied GL_DEBUG_SOURCE_THIRD_PARTY From: KHR_debug*/ +/*Copied GL_DEBUG_SOURCE_WINDOW_SYSTEM From: KHR_debug*/ +/*Copied GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR From: KHR_debug*/ +/*Copied GL_DEBUG_TYPE_ERROR From: KHR_debug*/ +/*Copied GL_DEBUG_TYPE_MARKER From: KHR_debug*/ +/*Copied GL_DEBUG_TYPE_OTHER From: KHR_debug*/ +/*Copied GL_DEBUG_TYPE_PERFORMANCE From: KHR_debug*/ +/*Copied GL_DEBUG_TYPE_POP_GROUP From: KHR_debug*/ +/*Copied GL_DEBUG_TYPE_PORTABILITY From: KHR_debug*/ +/*Copied GL_DEBUG_TYPE_PUSH_GROUP From: KHR_debug*/ +/*Copied GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR From: KHR_debug*/ +#define GL_DEPTH_COMPONENTS 0x8284 +#define GL_DEPTH_RENDERABLE 0x8287 +#define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA +#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE +#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF +#define GL_FILTER 0x829A +#define GL_FRAGMENT_SUBROUTINE 0x92EC +#define GL_FRAGMENT_SUBROUTINE_UNIFORM 0x92F2 +#define GL_FRAGMENT_TEXTURE 0x829F +#define GL_FRAMEBUFFER_BLEND 0x828B +#define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314 +#define GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311 +#define GL_FRAMEBUFFER_DEFAULT_LAYERS 0x9312 +#define GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313 +#define GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310 +#define GL_FRAMEBUFFER_RENDERABLE 0x8289 +#define GL_FRAMEBUFFER_RENDERABLE_LAYERED 0x828A +#define GL_FULL_SUPPORT 0x82B7 +#define GL_GEOMETRY_SUBROUTINE 0x92EB +#define GL_GEOMETRY_SUBROUTINE_UNIFORM 0x92F1 +#define GL_GEOMETRY_TEXTURE 0x829E +#define GL_GET_TEXTURE_IMAGE_FORMAT 0x8291 +#define GL_GET_TEXTURE_IMAGE_TYPE 0x8292 +#define GL_IMAGE_CLASS_10_10_10_2 0x82C3 +#define GL_IMAGE_CLASS_11_11_10 0x82C2 +#define GL_IMAGE_CLASS_1_X_16 0x82BE +#define GL_IMAGE_CLASS_1_X_32 0x82BB +#define GL_IMAGE_CLASS_1_X_8 0x82C1 +#define GL_IMAGE_CLASS_2_X_16 0x82BD +#define GL_IMAGE_CLASS_2_X_32 0x82BA +#define GL_IMAGE_CLASS_2_X_8 0x82C0 +#define GL_IMAGE_CLASS_4_X_16 0x82BC +#define GL_IMAGE_CLASS_4_X_32 0x82B9 +#define GL_IMAGE_CLASS_4_X_8 0x82BF +#define GL_IMAGE_COMPATIBILITY_CLASS 0x82A8 +#define GL_IMAGE_PIXEL_FORMAT 0x82A9 +#define GL_IMAGE_PIXEL_TYPE 0x82AA +#define GL_IMAGE_TEXEL_SIZE 0x82A7 +#define GL_INTERNALFORMAT_ALPHA_SIZE 0x8274 +#define GL_INTERNALFORMAT_ALPHA_TYPE 0x827B +#define GL_INTERNALFORMAT_BLUE_SIZE 0x8273 +#define GL_INTERNALFORMAT_BLUE_TYPE 0x827A +#define GL_INTERNALFORMAT_DEPTH_SIZE 0x8275 +#define GL_INTERNALFORMAT_DEPTH_TYPE 0x827C +#define GL_INTERNALFORMAT_GREEN_SIZE 0x8272 +#define GL_INTERNALFORMAT_GREEN_TYPE 0x8279 +#define GL_INTERNALFORMAT_PREFERRED 0x8270 +#define GL_INTERNALFORMAT_RED_SIZE 0x8271 +#define GL_INTERNALFORMAT_RED_TYPE 0x8278 +#define GL_INTERNALFORMAT_SHARED_SIZE 0x8277 +#define GL_INTERNALFORMAT_STENCIL_SIZE 0x8276 +#define GL_INTERNALFORMAT_STENCIL_TYPE 0x827D +#define GL_INTERNALFORMAT_SUPPORTED 0x826F +#define GL_IS_PER_PATCH 0x92E7 +#define GL_IS_ROW_MAJOR 0x9300 +#define GL_LOCATION 0x930E +#define GL_LOCATION_INDEX 0x930F +#define GL_MANUAL_GENERATE_MIPMAP 0x8294 +#define GL_MATRIX_STRIDE 0x92FF +#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266 +#define GL_MAX_COMBINED_DIMENSIONS 0x8282 +/*Copied GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES From: ARB_shader_storage_buffer_object*/ +/*Copied GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS From: ARB_shader_storage_buffer_object*/ +#define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265 +#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264 +#define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD +/*Copied GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS From: ARB_shader_storage_buffer_object*/ +#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262 +#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC +#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB +#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263 +#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE +#define GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS 0x90EB +#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF +/*Copied GL_MAX_DEBUG_GROUP_STACK_DEPTH From: KHR_debug*/ +/*Copied GL_MAX_DEBUG_LOGGED_MESSAGES From: KHR_debug*/ +/*Copied GL_MAX_DEBUG_MESSAGE_LENGTH From: KHR_debug*/ +#define GL_MAX_DEPTH 0x8280 +#define GL_MAX_ELEMENT_INDEX 0x8D6B +/*Copied GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS From: ARB_shader_storage_buffer_object*/ +#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316 +#define GL_MAX_FRAMEBUFFER_LAYERS 0x9317 +#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318 +#define GL_MAX_FRAMEBUFFER_WIDTH 0x9315 +/*Copied GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS From: ARB_shader_storage_buffer_object*/ +#define GL_MAX_HEIGHT 0x827F +/*Copied GL_MAX_LABEL_LENGTH From: KHR_debug*/ +#define GL_MAX_LAYERS 0x8281 +#define GL_MAX_NAME_LENGTH 0x92F6 +#define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7 +#define GL_MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8 +/*Copied GL_MAX_SHADER_STORAGE_BLOCK_SIZE From: ARB_shader_storage_buffer_object*/ +/*Copied GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS From: ARB_shader_storage_buffer_object*/ +/*Copied GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS From: ARB_shader_storage_buffer_object*/ +/*Copied GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS From: ARB_shader_storage_buffer_object*/ +#define GL_MAX_UNIFORM_LOCATIONS 0x826E +#define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA +#define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9 +/*Copied GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS From: ARB_shader_storage_buffer_object*/ +#define GL_MAX_WIDTH 0x827E +#define GL_MIPMAP 0x8293 +#define GL_NAME_LENGTH 0x92F9 +#define GL_NUM_ACTIVE_VARIABLES 0x9304 +#define GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9 +#define GL_OFFSET 0x92FC +#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69 +/*Copied GL_PROGRAM From: KHR_debug*/ +#define GL_PROGRAM_INPUT 0x92E3 +#define GL_PROGRAM_OUTPUT 0x92E4 +/*Copied GL_PROGRAM_PIPELINE From: KHR_debug*/ +/*Copied GL_QUERY From: KHR_debug*/ +#define GL_READ_PIXELS 0x828C +#define GL_READ_PIXELS_FORMAT 0x828D +#define GL_READ_PIXELS_TYPE 0x828E +#define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B +#define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A +#define GL_REFERENCED_BY_GEOMETRY_SHADER 0x9309 +#define GL_REFERENCED_BY_TESS_CONTROL_SHADER 0x9307 +#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308 +#define GL_REFERENCED_BY_VERTEX_SHADER 0x9306 +/*Copied GL_SAMPLER From: KHR_debug*/ +/*Copied GL_SHADER From: KHR_debug*/ +#define GL_SHADER_IMAGE_ATOMIC 0x82A6 +#define GL_SHADER_IMAGE_LOAD 0x82A4 +#define GL_SHADER_IMAGE_STORE 0x82A5 +/*Copied GL_SHADER_STORAGE_BARRIER_BIT From: ARB_shader_storage_buffer_object*/ +#define GL_SHADER_STORAGE_BLOCK 0x92E6 +/*Copied GL_SHADER_STORAGE_BUFFER From: ARB_shader_storage_buffer_object*/ +/*Copied GL_SHADER_STORAGE_BUFFER_BINDING From: ARB_shader_storage_buffer_object*/ +/*Copied GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT From: ARB_shader_storage_buffer_object*/ +/*Copied GL_SHADER_STORAGE_BUFFER_SIZE From: ARB_shader_storage_buffer_object*/ +/*Copied GL_SHADER_STORAGE_BUFFER_START From: ARB_shader_storage_buffer_object*/ +#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST 0x82AC +#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE 0x82AE +#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST 0x82AD +#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE 0x82AF +#define GL_SRGB_READ 0x8297 +#define GL_SRGB_WRITE 0x8298 +#define GL_STENCIL_COMPONENTS 0x8285 +#define GL_STENCIL_RENDERABLE 0x8288 +#define GL_TESS_CONTROL_SUBROUTINE 0x92E9 +#define GL_TESS_CONTROL_SUBROUTINE_UNIFORM 0x92EF +#define GL_TESS_CONTROL_TEXTURE 0x829C +#define GL_TESS_EVALUATION_SUBROUTINE 0x92EA +#define GL_TESS_EVALUATION_SUBROUTINE_UNIFORM 0x92F0 +#define GL_TESS_EVALUATION_TEXTURE 0x829D +#define GL_TEXTURE_BUFFER_OFFSET 0x919D +#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT 0x919F +#define GL_TEXTURE_BUFFER_SIZE 0x919E +#define GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT 0x82B2 +#define GL_TEXTURE_COMPRESSED_BLOCK_SIZE 0x82B3 +#define GL_TEXTURE_COMPRESSED_BLOCK_WIDTH 0x82B1 +#define GL_TEXTURE_GATHER 0x82A2 +#define GL_TEXTURE_GATHER_SHADOW 0x82A3 +#define GL_TEXTURE_IMAGE_FORMAT 0x828F +#define GL_TEXTURE_IMAGE_TYPE 0x8290 +#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF +#define GL_TEXTURE_SHADOW 0x82A1 +#define GL_TEXTURE_VIEW 0x82B5 +#define GL_TEXTURE_VIEW_MIN_LAYER 0x82DD +#define GL_TEXTURE_VIEW_MIN_LEVEL 0x82DB +#define GL_TEXTURE_VIEW_NUM_LAYERS 0x82DE +#define GL_TEXTURE_VIEW_NUM_LEVELS 0x82DC +#define GL_TOP_LEVEL_ARRAY_SIZE 0x930C +#define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D +#define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4 +#define GL_TYPE 0x92FA +#define GL_UNIFORM 0x92E1 +#define GL_UNIFORM_BLOCK 0x92E2 +#define GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER 0x90EC +#define GL_VERTEX_ATTRIB_ARRAY_LONG 0x874E +#define GL_VERTEX_ATTRIB_BINDING 0x82D4 +#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5 +#define GL_VERTEX_BINDING_BUFFER 0x8F4F +#define GL_VERTEX_BINDING_DIVISOR 0x82D6 +#define GL_VERTEX_BINDING_OFFSET 0x82D7 +#define GL_VERTEX_BINDING_STRIDE 0x82D8 +#define GL_VERTEX_SUBROUTINE 0x92E8 +#define GL_VERTEX_SUBROUTINE_UNIFORM 0x92EE +#define GL_VERTEX_TEXTURE 0x829B +#define GL_VIEW_CLASS_128_BITS 0x82C4 +#define GL_VIEW_CLASS_16_BITS 0x82CA +#define GL_VIEW_CLASS_24_BITS 0x82C9 +#define GL_VIEW_CLASS_32_BITS 0x82C8 +#define GL_VIEW_CLASS_48_BITS 0x82C7 +#define GL_VIEW_CLASS_64_BITS 0x82C6 +#define GL_VIEW_CLASS_8_BITS 0x82CB +#define GL_VIEW_CLASS_96_BITS 0x82C5 +#define GL_VIEW_CLASS_BPTC_FLOAT 0x82D3 +#define GL_VIEW_CLASS_BPTC_UNORM 0x82D2 +#define GL_VIEW_CLASS_RGTC1_RED 0x82D0 +#define GL_VIEW_CLASS_RGTC2_RG 0x82D1 +#define GL_VIEW_CLASS_S3TC_DXT1_RGB 0x82CC +#define GL_VIEW_CLASS_S3TC_DXT1_RGBA 0x82CD +#define GL_VIEW_CLASS_S3TC_DXT3_RGBA 0x82CE +#define GL_VIEW_CLASS_S3TC_DXT5_RGBA 0x82CF +#define GL_VIEW_COMPATIBILITY_CLASS 0x82B6 + +/*Copied GL_BUFFER_IMMUTABLE_STORAGE From: ARB_buffer_storage*/ +/*Copied GL_BUFFER_STORAGE_FLAGS From: ARB_buffer_storage*/ +#define GL_CLEAR_TEXTURE 0x9365 +/*Copied GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT From: ARB_buffer_storage*/ +/*Copied GL_CLIENT_STORAGE_BIT From: ARB_buffer_storage*/ +/*Copied GL_DYNAMIC_STORAGE_BIT From: ARB_buffer_storage*/ +#define GL_LOCATION_COMPONENT 0x934A +/*Copied GL_MAP_COHERENT_BIT From: ARB_buffer_storage*/ +/*Copied GL_MAP_PERSISTENT_BIT From: ARB_buffer_storage*/ +#define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5 +#define GL_MIRROR_CLAMP_TO_EDGE 0x8743 +#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221 +#define GL_QUERY_BUFFER 0x9192 +#define GL_QUERY_BUFFER_BARRIER_BIT 0x00008000 +#define GL_QUERY_BUFFER_BINDING 0x9193 +#define GL_QUERY_RESULT_NO_WAIT 0x9194 +#define GL_TEXTURE_BUFFER_BINDING 0x8C2A +#define GL_TRANSFORM_FEEDBACK_BUFFER_INDEX 0x934B +#define GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE 0x934C + +#define GL_CLIP_DEPTH_MODE 0x935D +#define GL_CLIP_ORIGIN 0x935C +#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT 0x00000004 +#define GL_CONTEXT_LOST 0x0507 +#define GL_CONTEXT_RELEASE_BEHAVIOR 0x82FB +#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82FC +#define GL_GUILTY_CONTEXT_RESET 0x8253 +#define GL_INNOCENT_CONTEXT_RESET 0x8254 +#define GL_LOSE_CONTEXT_ON_RESET 0x8252 +#define GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES 0x82FA +#define GL_MAX_CULL_DISTANCES 0x82F9 +#define GL_NEGATIVE_ONE_TO_ONE 0x935E +#define GL_NO_RESET_NOTIFICATION 0x8261 +#define GL_QUERY_BY_REGION_NO_WAIT_INVERTED 0x8E1A +#define GL_QUERY_BY_REGION_WAIT_INVERTED 0x8E19 +#define GL_QUERY_NO_WAIT_INVERTED 0x8E18 +#define GL_QUERY_TARGET 0x82EA +#define GL_QUERY_WAIT_INVERTED 0x8E17 +#define GL_RESET_NOTIFICATION_STRATEGY 0x8256 +#define GL_TEXTURE_TARGET 0x1006 +#define GL_UNKNOWN_CONTEXT_RESET 0x8255 +#define GL_ZERO_TO_ONE 0x935F #ifndef GL_ARB_buffer_storage #define GL_ARB_buffer_storage 1 @@ -1654,7 +2182,6 @@ extern void (CODEGEN_FUNCPTR *_ptrc_glInvalidateTexSubImage)(GLuint texture, GLi #define glInvalidateTexSubImage _ptrc_glInvalidateTexSubImage #endif /*GL_ARB_invalidate_subdata*/ - extern void (CODEGEN_FUNCPTR *_ptrc_glAccum)(GLenum op, GLfloat value); #define glAccum _ptrc_glAccum extern void (CODEGEN_FUNCPTR *_ptrc_glAlphaFunc)(GLenum func, GLfloat ref); @@ -3055,6 +3582,628 @@ extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribP4ui)(GLuint index, GLenum typ extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribP4uiv)(GLuint index, GLenum type, GLboolean normalized, const GLuint * value); #define glVertexAttribP4uiv _ptrc_glVertexAttribP4uiv +extern void (CODEGEN_FUNCPTR *_ptrc_glBeginQueryIndexed)(GLenum target, GLuint index, GLuint id); +#define glBeginQueryIndexed _ptrc_glBeginQueryIndexed +extern void (CODEGEN_FUNCPTR *_ptrc_glBindTransformFeedback)(GLenum target, GLuint id); +#define glBindTransformFeedback _ptrc_glBindTransformFeedback +extern void (CODEGEN_FUNCPTR *_ptrc_glBlendEquationSeparatei)(GLuint buf, GLenum modeRGB, GLenum modeAlpha); +#define glBlendEquationSeparatei _ptrc_glBlendEquationSeparatei +extern void (CODEGEN_FUNCPTR *_ptrc_glBlendEquationi)(GLuint buf, GLenum mode); +#define glBlendEquationi _ptrc_glBlendEquationi +extern void (CODEGEN_FUNCPTR *_ptrc_glBlendFuncSeparatei)(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +#define glBlendFuncSeparatei _ptrc_glBlendFuncSeparatei +extern void (CODEGEN_FUNCPTR *_ptrc_glBlendFunci)(GLuint buf, GLenum src, GLenum dst); +#define glBlendFunci _ptrc_glBlendFunci +extern void (CODEGEN_FUNCPTR *_ptrc_glDeleteTransformFeedbacks)(GLsizei n, const GLuint * ids); +#define glDeleteTransformFeedbacks _ptrc_glDeleteTransformFeedbacks +extern void (CODEGEN_FUNCPTR *_ptrc_glDrawArraysIndirect)(GLenum mode, const void * indirect); +#define glDrawArraysIndirect _ptrc_glDrawArraysIndirect +extern void (CODEGEN_FUNCPTR *_ptrc_glDrawElementsIndirect)(GLenum mode, GLenum type, const void * indirect); +#define glDrawElementsIndirect _ptrc_glDrawElementsIndirect +extern void (CODEGEN_FUNCPTR *_ptrc_glDrawTransformFeedback)(GLenum mode, GLuint id); +#define glDrawTransformFeedback _ptrc_glDrawTransformFeedback +extern void (CODEGEN_FUNCPTR *_ptrc_glDrawTransformFeedbackStream)(GLenum mode, GLuint id, GLuint stream); +#define glDrawTransformFeedbackStream _ptrc_glDrawTransformFeedbackStream +extern void (CODEGEN_FUNCPTR *_ptrc_glEndQueryIndexed)(GLenum target, GLuint index); +#define glEndQueryIndexed _ptrc_glEndQueryIndexed +extern void (CODEGEN_FUNCPTR *_ptrc_glGenTransformFeedbacks)(GLsizei n, GLuint * ids); +#define glGenTransformFeedbacks _ptrc_glGenTransformFeedbacks +extern void (CODEGEN_FUNCPTR *_ptrc_glGetActiveSubroutineName)(GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei * length, GLchar * name); +#define glGetActiveSubroutineName _ptrc_glGetActiveSubroutineName +extern void (CODEGEN_FUNCPTR *_ptrc_glGetActiveSubroutineUniformName)(GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei * length, GLchar * name); +#define glGetActiveSubroutineUniformName _ptrc_glGetActiveSubroutineUniformName +extern void (CODEGEN_FUNCPTR *_ptrc_glGetActiveSubroutineUniformiv)(GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint * values); +#define glGetActiveSubroutineUniformiv _ptrc_glGetActiveSubroutineUniformiv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetProgramStageiv)(GLuint program, GLenum shadertype, GLenum pname, GLint * values); +#define glGetProgramStageiv _ptrc_glGetProgramStageiv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetQueryIndexediv)(GLenum target, GLuint index, GLenum pname, GLint * params); +#define glGetQueryIndexediv _ptrc_glGetQueryIndexediv +extern GLuint (CODEGEN_FUNCPTR *_ptrc_glGetSubroutineIndex)(GLuint program, GLenum shadertype, const GLchar * name); +#define glGetSubroutineIndex _ptrc_glGetSubroutineIndex +extern GLint (CODEGEN_FUNCPTR *_ptrc_glGetSubroutineUniformLocation)(GLuint program, GLenum shadertype, const GLchar * name); +#define glGetSubroutineUniformLocation _ptrc_glGetSubroutineUniformLocation +extern void (CODEGEN_FUNCPTR *_ptrc_glGetUniformSubroutineuiv)(GLenum shadertype, GLint location, GLuint * params); +#define glGetUniformSubroutineuiv _ptrc_glGetUniformSubroutineuiv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetUniformdv)(GLuint program, GLint location, GLdouble * params); +#define glGetUniformdv _ptrc_glGetUniformdv +extern GLboolean (CODEGEN_FUNCPTR *_ptrc_glIsTransformFeedback)(GLuint id); +#define glIsTransformFeedback _ptrc_glIsTransformFeedback +extern void (CODEGEN_FUNCPTR *_ptrc_glMinSampleShading)(GLfloat value); +#define glMinSampleShading _ptrc_glMinSampleShading +extern void (CODEGEN_FUNCPTR *_ptrc_glPatchParameterfv)(GLenum pname, const GLfloat * values); +#define glPatchParameterfv _ptrc_glPatchParameterfv +extern void (CODEGEN_FUNCPTR *_ptrc_glPatchParameteri)(GLenum pname, GLint value); +#define glPatchParameteri _ptrc_glPatchParameteri +extern void (CODEGEN_FUNCPTR *_ptrc_glPauseTransformFeedback)(void); +#define glPauseTransformFeedback _ptrc_glPauseTransformFeedback +extern void (CODEGEN_FUNCPTR *_ptrc_glResumeTransformFeedback)(void); +#define glResumeTransformFeedback _ptrc_glResumeTransformFeedback +extern void (CODEGEN_FUNCPTR *_ptrc_glUniform1d)(GLint location, GLdouble x); +#define glUniform1d _ptrc_glUniform1d +extern void (CODEGEN_FUNCPTR *_ptrc_glUniform1dv)(GLint location, GLsizei count, const GLdouble * value); +#define glUniform1dv _ptrc_glUniform1dv +extern void (CODEGEN_FUNCPTR *_ptrc_glUniform2d)(GLint location, GLdouble x, GLdouble y); +#define glUniform2d _ptrc_glUniform2d +extern void (CODEGEN_FUNCPTR *_ptrc_glUniform2dv)(GLint location, GLsizei count, const GLdouble * value); +#define glUniform2dv _ptrc_glUniform2dv +extern void (CODEGEN_FUNCPTR *_ptrc_glUniform3d)(GLint location, GLdouble x, GLdouble y, GLdouble z); +#define glUniform3d _ptrc_glUniform3d +extern void (CODEGEN_FUNCPTR *_ptrc_glUniform3dv)(GLint location, GLsizei count, const GLdouble * value); +#define glUniform3dv _ptrc_glUniform3dv +extern void (CODEGEN_FUNCPTR *_ptrc_glUniform4d)(GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +#define glUniform4d _ptrc_glUniform4d +extern void (CODEGEN_FUNCPTR *_ptrc_glUniform4dv)(GLint location, GLsizei count, const GLdouble * value); +#define glUniform4dv _ptrc_glUniform4dv +extern void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix2dv)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +#define glUniformMatrix2dv _ptrc_glUniformMatrix2dv +extern void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix2x3dv)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +#define glUniformMatrix2x3dv _ptrc_glUniformMatrix2x3dv +extern void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix2x4dv)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +#define glUniformMatrix2x4dv _ptrc_glUniformMatrix2x4dv +extern void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix3dv)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +#define glUniformMatrix3dv _ptrc_glUniformMatrix3dv +extern void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix3x2dv)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +#define glUniformMatrix3x2dv _ptrc_glUniformMatrix3x2dv +extern void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix3x4dv)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +#define glUniformMatrix3x4dv _ptrc_glUniformMatrix3x4dv +extern void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix4dv)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +#define glUniformMatrix4dv _ptrc_glUniformMatrix4dv +extern void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix4x2dv)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +#define glUniformMatrix4x2dv _ptrc_glUniformMatrix4x2dv +extern void (CODEGEN_FUNCPTR *_ptrc_glUniformMatrix4x3dv)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +#define glUniformMatrix4x3dv _ptrc_glUniformMatrix4x3dv +extern void (CODEGEN_FUNCPTR *_ptrc_glUniformSubroutinesuiv)(GLenum shadertype, GLsizei count, const GLuint * indices); +#define glUniformSubroutinesuiv _ptrc_glUniformSubroutinesuiv + +extern void (CODEGEN_FUNCPTR *_ptrc_glActiveShaderProgram)(GLuint pipeline, GLuint program); +#define glActiveShaderProgram _ptrc_glActiveShaderProgram +extern void (CODEGEN_FUNCPTR *_ptrc_glBindProgramPipeline)(GLuint pipeline); +#define glBindProgramPipeline _ptrc_glBindProgramPipeline +extern void (CODEGEN_FUNCPTR *_ptrc_glClearDepthf)(GLfloat d); +#define glClearDepthf _ptrc_glClearDepthf +extern GLuint (CODEGEN_FUNCPTR *_ptrc_glCreateShaderProgramv)(GLenum type, GLsizei count, const GLchar *const* strings); +#define glCreateShaderProgramv _ptrc_glCreateShaderProgramv +extern void (CODEGEN_FUNCPTR *_ptrc_glDeleteProgramPipelines)(GLsizei n, const GLuint * pipelines); +#define glDeleteProgramPipelines _ptrc_glDeleteProgramPipelines +extern void (CODEGEN_FUNCPTR *_ptrc_glDepthRangeArrayv)(GLuint first, GLsizei count, const GLdouble * v); +#define glDepthRangeArrayv _ptrc_glDepthRangeArrayv +extern void (CODEGEN_FUNCPTR *_ptrc_glDepthRangeIndexed)(GLuint index, GLdouble n, GLdouble f); +#define glDepthRangeIndexed _ptrc_glDepthRangeIndexed +extern void (CODEGEN_FUNCPTR *_ptrc_glDepthRangef)(GLfloat n, GLfloat f); +#define glDepthRangef _ptrc_glDepthRangef +extern void (CODEGEN_FUNCPTR *_ptrc_glGenProgramPipelines)(GLsizei n, GLuint * pipelines); +#define glGenProgramPipelines _ptrc_glGenProgramPipelines +extern void (CODEGEN_FUNCPTR *_ptrc_glGetDoublei_v)(GLenum target, GLuint index, GLdouble * data); +#define glGetDoublei_v _ptrc_glGetDoublei_v +extern void (CODEGEN_FUNCPTR *_ptrc_glGetFloati_v)(GLenum target, GLuint index, GLfloat * data); +#define glGetFloati_v _ptrc_glGetFloati_v +extern void (CODEGEN_FUNCPTR *_ptrc_glGetProgramBinary)(GLuint program, GLsizei bufSize, GLsizei * length, GLenum * binaryFormat, void * binary); +#define glGetProgramBinary _ptrc_glGetProgramBinary +extern void (CODEGEN_FUNCPTR *_ptrc_glGetProgramPipelineInfoLog)(GLuint pipeline, GLsizei bufSize, GLsizei * length, GLchar * infoLog); +#define glGetProgramPipelineInfoLog _ptrc_glGetProgramPipelineInfoLog +extern void (CODEGEN_FUNCPTR *_ptrc_glGetProgramPipelineiv)(GLuint pipeline, GLenum pname, GLint * params); +#define glGetProgramPipelineiv _ptrc_glGetProgramPipelineiv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetShaderPrecisionFormat)(GLenum shadertype, GLenum precisiontype, GLint * range, GLint * precision); +#define glGetShaderPrecisionFormat _ptrc_glGetShaderPrecisionFormat +extern void (CODEGEN_FUNCPTR *_ptrc_glGetVertexAttribLdv)(GLuint index, GLenum pname, GLdouble * params); +#define glGetVertexAttribLdv _ptrc_glGetVertexAttribLdv +extern GLboolean (CODEGEN_FUNCPTR *_ptrc_glIsProgramPipeline)(GLuint pipeline); +#define glIsProgramPipeline _ptrc_glIsProgramPipeline +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramBinary)(GLuint program, GLenum binaryFormat, const void * binary, GLsizei length); +#define glProgramBinary _ptrc_glProgramBinary +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramParameteri)(GLuint program, GLenum pname, GLint value); +#define glProgramParameteri _ptrc_glProgramParameteri +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform1d)(GLuint program, GLint location, GLdouble v0); +#define glProgramUniform1d _ptrc_glProgramUniform1d +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform1dv)(GLuint program, GLint location, GLsizei count, const GLdouble * value); +#define glProgramUniform1dv _ptrc_glProgramUniform1dv +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform1f)(GLuint program, GLint location, GLfloat v0); +#define glProgramUniform1f _ptrc_glProgramUniform1f +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform1fv)(GLuint program, GLint location, GLsizei count, const GLfloat * value); +#define glProgramUniform1fv _ptrc_glProgramUniform1fv +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform1i)(GLuint program, GLint location, GLint v0); +#define glProgramUniform1i _ptrc_glProgramUniform1i +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform1iv)(GLuint program, GLint location, GLsizei count, const GLint * value); +#define glProgramUniform1iv _ptrc_glProgramUniform1iv +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform1ui)(GLuint program, GLint location, GLuint v0); +#define glProgramUniform1ui _ptrc_glProgramUniform1ui +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform1uiv)(GLuint program, GLint location, GLsizei count, const GLuint * value); +#define glProgramUniform1uiv _ptrc_glProgramUniform1uiv +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform2d)(GLuint program, GLint location, GLdouble v0, GLdouble v1); +#define glProgramUniform2d _ptrc_glProgramUniform2d +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform2dv)(GLuint program, GLint location, GLsizei count, const GLdouble * value); +#define glProgramUniform2dv _ptrc_glProgramUniform2dv +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform2f)(GLuint program, GLint location, GLfloat v0, GLfloat v1); +#define glProgramUniform2f _ptrc_glProgramUniform2f +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform2fv)(GLuint program, GLint location, GLsizei count, const GLfloat * value); +#define glProgramUniform2fv _ptrc_glProgramUniform2fv +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform2i)(GLuint program, GLint location, GLint v0, GLint v1); +#define glProgramUniform2i _ptrc_glProgramUniform2i +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform2iv)(GLuint program, GLint location, GLsizei count, const GLint * value); +#define glProgramUniform2iv _ptrc_glProgramUniform2iv +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform2ui)(GLuint program, GLint location, GLuint v0, GLuint v1); +#define glProgramUniform2ui _ptrc_glProgramUniform2ui +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform2uiv)(GLuint program, GLint location, GLsizei count, const GLuint * value); +#define glProgramUniform2uiv _ptrc_glProgramUniform2uiv +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform3d)(GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2); +#define glProgramUniform3d _ptrc_glProgramUniform3d +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform3dv)(GLuint program, GLint location, GLsizei count, const GLdouble * value); +#define glProgramUniform3dv _ptrc_glProgramUniform3dv +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform3f)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); +#define glProgramUniform3f _ptrc_glProgramUniform3f +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform3fv)(GLuint program, GLint location, GLsizei count, const GLfloat * value); +#define glProgramUniform3fv _ptrc_glProgramUniform3fv +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform3i)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2); +#define glProgramUniform3i _ptrc_glProgramUniform3i +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform3iv)(GLuint program, GLint location, GLsizei count, const GLint * value); +#define glProgramUniform3iv _ptrc_glProgramUniform3iv +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform3ui)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); +#define glProgramUniform3ui _ptrc_glProgramUniform3ui +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform3uiv)(GLuint program, GLint location, GLsizei count, const GLuint * value); +#define glProgramUniform3uiv _ptrc_glProgramUniform3uiv +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform4d)(GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3); +#define glProgramUniform4d _ptrc_glProgramUniform4d +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform4dv)(GLuint program, GLint location, GLsizei count, const GLdouble * value); +#define glProgramUniform4dv _ptrc_glProgramUniform4dv +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform4f)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +#define glProgramUniform4f _ptrc_glProgramUniform4f +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform4fv)(GLuint program, GLint location, GLsizei count, const GLfloat * value); +#define glProgramUniform4fv _ptrc_glProgramUniform4fv +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform4i)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); +#define glProgramUniform4i _ptrc_glProgramUniform4i +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform4iv)(GLuint program, GLint location, GLsizei count, const GLint * value); +#define glProgramUniform4iv _ptrc_glProgramUniform4iv +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform4ui)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); +#define glProgramUniform4ui _ptrc_glProgramUniform4ui +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniform4uiv)(GLuint program, GLint location, GLsizei count, const GLuint * value); +#define glProgramUniform4uiv _ptrc_glProgramUniform4uiv +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix2dv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +#define glProgramUniformMatrix2dv _ptrc_glProgramUniformMatrix2dv +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix2fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +#define glProgramUniformMatrix2fv _ptrc_glProgramUniformMatrix2fv +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix2x3dv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +#define glProgramUniformMatrix2x3dv _ptrc_glProgramUniformMatrix2x3dv +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix2x3fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +#define glProgramUniformMatrix2x3fv _ptrc_glProgramUniformMatrix2x3fv +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix2x4dv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +#define glProgramUniformMatrix2x4dv _ptrc_glProgramUniformMatrix2x4dv +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix2x4fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +#define glProgramUniformMatrix2x4fv _ptrc_glProgramUniformMatrix2x4fv +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix3dv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +#define glProgramUniformMatrix3dv _ptrc_glProgramUniformMatrix3dv +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix3fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +#define glProgramUniformMatrix3fv _ptrc_glProgramUniformMatrix3fv +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix3x2dv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +#define glProgramUniformMatrix3x2dv _ptrc_glProgramUniformMatrix3x2dv +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix3x2fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +#define glProgramUniformMatrix3x2fv _ptrc_glProgramUniformMatrix3x2fv +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix3x4dv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +#define glProgramUniformMatrix3x4dv _ptrc_glProgramUniformMatrix3x4dv +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix3x4fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +#define glProgramUniformMatrix3x4fv _ptrc_glProgramUniformMatrix3x4fv +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix4dv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +#define glProgramUniformMatrix4dv _ptrc_glProgramUniformMatrix4dv +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix4fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +#define glProgramUniformMatrix4fv _ptrc_glProgramUniformMatrix4fv +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix4x2dv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +#define glProgramUniformMatrix4x2dv _ptrc_glProgramUniformMatrix4x2dv +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix4x2fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +#define glProgramUniformMatrix4x2fv _ptrc_glProgramUniformMatrix4x2fv +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix4x3dv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); +#define glProgramUniformMatrix4x3dv _ptrc_glProgramUniformMatrix4x3dv +extern void (CODEGEN_FUNCPTR *_ptrc_glProgramUniformMatrix4x3fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); +#define glProgramUniformMatrix4x3fv _ptrc_glProgramUniformMatrix4x3fv +extern void (CODEGEN_FUNCPTR *_ptrc_glReleaseShaderCompiler)(void); +#define glReleaseShaderCompiler _ptrc_glReleaseShaderCompiler +extern void (CODEGEN_FUNCPTR *_ptrc_glScissorArrayv)(GLuint first, GLsizei count, const GLint * v); +#define glScissorArrayv _ptrc_glScissorArrayv +extern void (CODEGEN_FUNCPTR *_ptrc_glScissorIndexed)(GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); +#define glScissorIndexed _ptrc_glScissorIndexed +extern void (CODEGEN_FUNCPTR *_ptrc_glScissorIndexedv)(GLuint index, const GLint * v); +#define glScissorIndexedv _ptrc_glScissorIndexedv +extern void (CODEGEN_FUNCPTR *_ptrc_glShaderBinary)(GLsizei count, const GLuint * shaders, GLenum binaryformat, const void * binary, GLsizei length); +#define glShaderBinary _ptrc_glShaderBinary +extern void (CODEGEN_FUNCPTR *_ptrc_glUseProgramStages)(GLuint pipeline, GLbitfield stages, GLuint program); +#define glUseProgramStages _ptrc_glUseProgramStages +extern void (CODEGEN_FUNCPTR *_ptrc_glValidateProgramPipeline)(GLuint pipeline); +#define glValidateProgramPipeline _ptrc_glValidateProgramPipeline +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribL1d)(GLuint index, GLdouble x); +#define glVertexAttribL1d _ptrc_glVertexAttribL1d +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribL1dv)(GLuint index, const GLdouble * v); +#define glVertexAttribL1dv _ptrc_glVertexAttribL1dv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribL2d)(GLuint index, GLdouble x, GLdouble y); +#define glVertexAttribL2d _ptrc_glVertexAttribL2d +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribL2dv)(GLuint index, const GLdouble * v); +#define glVertexAttribL2dv _ptrc_glVertexAttribL2dv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribL3d)(GLuint index, GLdouble x, GLdouble y, GLdouble z); +#define glVertexAttribL3d _ptrc_glVertexAttribL3d +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribL3dv)(GLuint index, const GLdouble * v); +#define glVertexAttribL3dv _ptrc_glVertexAttribL3dv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribL4d)(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); +#define glVertexAttribL4d _ptrc_glVertexAttribL4d +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribL4dv)(GLuint index, const GLdouble * v); +#define glVertexAttribL4dv _ptrc_glVertexAttribL4dv +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribLPointer)(GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer); +#define glVertexAttribLPointer _ptrc_glVertexAttribLPointer +extern void (CODEGEN_FUNCPTR *_ptrc_glViewportArrayv)(GLuint first, GLsizei count, const GLfloat * v); +#define glViewportArrayv _ptrc_glViewportArrayv +extern void (CODEGEN_FUNCPTR *_ptrc_glViewportIndexedf)(GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); +#define glViewportIndexedf _ptrc_glViewportIndexedf +extern void (CODEGEN_FUNCPTR *_ptrc_glViewportIndexedfv)(GLuint index, const GLfloat * v); +#define glViewportIndexedfv _ptrc_glViewportIndexedfv + +extern void (CODEGEN_FUNCPTR *_ptrc_glBindImageTexture)(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); +#define glBindImageTexture _ptrc_glBindImageTexture +extern void (CODEGEN_FUNCPTR *_ptrc_glDrawArraysInstancedBaseInstance)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); +#define glDrawArraysInstancedBaseInstance _ptrc_glDrawArraysInstancedBaseInstance +extern void (CODEGEN_FUNCPTR *_ptrc_glDrawElementsInstancedBaseInstance)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLuint baseinstance); +#define glDrawElementsInstancedBaseInstance _ptrc_glDrawElementsInstancedBaseInstance +extern void (CODEGEN_FUNCPTR *_ptrc_glDrawElementsInstancedBaseVertexBaseInstance)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); +#define glDrawElementsInstancedBaseVertexBaseInstance _ptrc_glDrawElementsInstancedBaseVertexBaseInstance +extern void (CODEGEN_FUNCPTR *_ptrc_glDrawTransformFeedbackInstanced)(GLenum mode, GLuint id, GLsizei instancecount); +#define glDrawTransformFeedbackInstanced _ptrc_glDrawTransformFeedbackInstanced +extern void (CODEGEN_FUNCPTR *_ptrc_glDrawTransformFeedbackStreamInstanced)(GLenum mode, GLuint id, GLuint stream, GLsizei instancecount); +#define glDrawTransformFeedbackStreamInstanced _ptrc_glDrawTransformFeedbackStreamInstanced +extern void (CODEGEN_FUNCPTR *_ptrc_glGetActiveAtomicCounterBufferiv)(GLuint program, GLuint bufferIndex, GLenum pname, GLint * params); +#define glGetActiveAtomicCounterBufferiv _ptrc_glGetActiveAtomicCounterBufferiv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetInternalformativ)(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint * params); +#define glGetInternalformativ _ptrc_glGetInternalformativ +extern void (CODEGEN_FUNCPTR *_ptrc_glMemoryBarrier)(GLbitfield barriers); +#define glMemoryBarrier _ptrc_glMemoryBarrier +extern void (CODEGEN_FUNCPTR *_ptrc_glTexStorage1D)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +#define glTexStorage1D _ptrc_glTexStorage1D +extern void (CODEGEN_FUNCPTR *_ptrc_glTexStorage2D)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +#define glTexStorage2D _ptrc_glTexStorage2D +extern void (CODEGEN_FUNCPTR *_ptrc_glTexStorage3D)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +#define glTexStorage3D _ptrc_glTexStorage3D + +extern void (CODEGEN_FUNCPTR *_ptrc_glBindVertexBuffer)(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +#define glBindVertexBuffer _ptrc_glBindVertexBuffer +extern void (CODEGEN_FUNCPTR *_ptrc_glClearBufferData)(GLenum target, GLenum internalformat, GLenum format, GLenum type, const void * data); +#define glClearBufferData _ptrc_glClearBufferData +extern void (CODEGEN_FUNCPTR *_ptrc_glClearBufferSubData)(GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void * data); +#define glClearBufferSubData _ptrc_glClearBufferSubData +extern void (CODEGEN_FUNCPTR *_ptrc_glCopyImageSubData)(GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); +#define glCopyImageSubData _ptrc_glCopyImageSubData +extern void (CODEGEN_FUNCPTR *_ptrc_glDebugMessageCallback)(GLDEBUGPROC callback, const void * userParam); +#define glDebugMessageCallback _ptrc_glDebugMessageCallback +extern void (CODEGEN_FUNCPTR *_ptrc_glDebugMessageControl)(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint * ids, GLboolean enabled); +#define glDebugMessageControl _ptrc_glDebugMessageControl +extern void (CODEGEN_FUNCPTR *_ptrc_glDebugMessageInsert)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar * buf); +#define glDebugMessageInsert _ptrc_glDebugMessageInsert +extern void (CODEGEN_FUNCPTR *_ptrc_glDispatchCompute)(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); +#define glDispatchCompute _ptrc_glDispatchCompute +extern void (CODEGEN_FUNCPTR *_ptrc_glDispatchComputeIndirect)(GLintptr indirect); +#define glDispatchComputeIndirect _ptrc_glDispatchComputeIndirect +extern void (CODEGEN_FUNCPTR *_ptrc_glFramebufferParameteri)(GLenum target, GLenum pname, GLint param); +#define glFramebufferParameteri _ptrc_glFramebufferParameteri +extern GLuint (CODEGEN_FUNCPTR *_ptrc_glGetDebugMessageLog)(GLuint count, GLsizei bufSize, GLenum * sources, GLenum * types, GLuint * ids, GLenum * severities, GLsizei * lengths, GLchar * messageLog); +#define glGetDebugMessageLog _ptrc_glGetDebugMessageLog +extern void (CODEGEN_FUNCPTR *_ptrc_glGetFramebufferParameteriv)(GLenum target, GLenum pname, GLint * params); +#define glGetFramebufferParameteriv _ptrc_glGetFramebufferParameteriv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetInternalformati64v)(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 * params); +#define glGetInternalformati64v _ptrc_glGetInternalformati64v +extern void (CODEGEN_FUNCPTR *_ptrc_glGetObjectLabel)(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei * length, GLchar * label); +#define glGetObjectLabel _ptrc_glGetObjectLabel +extern void (CODEGEN_FUNCPTR *_ptrc_glGetObjectPtrLabel)(const void * ptr, GLsizei bufSize, GLsizei * length, GLchar * label); +#define glGetObjectPtrLabel _ptrc_glGetObjectPtrLabel +extern void (CODEGEN_FUNCPTR *_ptrc_glGetProgramInterfaceiv)(GLuint program, GLenum programInterface, GLenum pname, GLint * params); +#define glGetProgramInterfaceiv _ptrc_glGetProgramInterfaceiv +extern GLuint (CODEGEN_FUNCPTR *_ptrc_glGetProgramResourceIndex)(GLuint program, GLenum programInterface, const GLchar * name); +#define glGetProgramResourceIndex _ptrc_glGetProgramResourceIndex +extern GLint (CODEGEN_FUNCPTR *_ptrc_glGetProgramResourceLocation)(GLuint program, GLenum programInterface, const GLchar * name); +#define glGetProgramResourceLocation _ptrc_glGetProgramResourceLocation +extern GLint (CODEGEN_FUNCPTR *_ptrc_glGetProgramResourceLocationIndex)(GLuint program, GLenum programInterface, const GLchar * name); +#define glGetProgramResourceLocationIndex _ptrc_glGetProgramResourceLocationIndex +extern void (CODEGEN_FUNCPTR *_ptrc_glGetProgramResourceName)(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei * length, GLchar * name); +#define glGetProgramResourceName _ptrc_glGetProgramResourceName +extern void (CODEGEN_FUNCPTR *_ptrc_glGetProgramResourceiv)(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum * props, GLsizei bufSize, GLsizei * length, GLint * params); +#define glGetProgramResourceiv _ptrc_glGetProgramResourceiv +extern void (CODEGEN_FUNCPTR *_ptrc_glInvalidateBufferData)(GLuint buffer); +#define glInvalidateBufferData _ptrc_glInvalidateBufferData +extern void (CODEGEN_FUNCPTR *_ptrc_glInvalidateBufferSubData)(GLuint buffer, GLintptr offset, GLsizeiptr length); +#define glInvalidateBufferSubData _ptrc_glInvalidateBufferSubData +extern void (CODEGEN_FUNCPTR *_ptrc_glInvalidateFramebuffer)(GLenum target, GLsizei numAttachments, const GLenum * attachments); +#define glInvalidateFramebuffer _ptrc_glInvalidateFramebuffer +extern void (CODEGEN_FUNCPTR *_ptrc_glInvalidateSubFramebuffer)(GLenum target, GLsizei numAttachments, const GLenum * attachments, GLint x, GLint y, GLsizei width, GLsizei height); +#define glInvalidateSubFramebuffer _ptrc_glInvalidateSubFramebuffer +extern void (CODEGEN_FUNCPTR *_ptrc_glInvalidateTexImage)(GLuint texture, GLint level); +#define glInvalidateTexImage _ptrc_glInvalidateTexImage +extern void (CODEGEN_FUNCPTR *_ptrc_glInvalidateTexSubImage)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); +#define glInvalidateTexSubImage _ptrc_glInvalidateTexSubImage +extern void (CODEGEN_FUNCPTR *_ptrc_glMultiDrawArraysIndirect)(GLenum mode, const void * indirect, GLsizei drawcount, GLsizei stride); +#define glMultiDrawArraysIndirect _ptrc_glMultiDrawArraysIndirect +extern void (CODEGEN_FUNCPTR *_ptrc_glMultiDrawElementsIndirect)(GLenum mode, GLenum type, const void * indirect, GLsizei drawcount, GLsizei stride); +#define glMultiDrawElementsIndirect _ptrc_glMultiDrawElementsIndirect +extern void (CODEGEN_FUNCPTR *_ptrc_glObjectLabel)(GLenum identifier, GLuint name, GLsizei length, const GLchar * label); +#define glObjectLabel _ptrc_glObjectLabel +extern void (CODEGEN_FUNCPTR *_ptrc_glObjectPtrLabel)(const void * ptr, GLsizei length, const GLchar * label); +#define glObjectPtrLabel _ptrc_glObjectPtrLabel +extern void (CODEGEN_FUNCPTR *_ptrc_glPopDebugGroup)(void); +#define glPopDebugGroup _ptrc_glPopDebugGroup +extern void (CODEGEN_FUNCPTR *_ptrc_glPushDebugGroup)(GLenum source, GLuint id, GLsizei length, const GLchar * message); +#define glPushDebugGroup _ptrc_glPushDebugGroup +extern void (CODEGEN_FUNCPTR *_ptrc_glShaderStorageBlockBinding)(GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding); +#define glShaderStorageBlockBinding _ptrc_glShaderStorageBlockBinding +extern void (CODEGEN_FUNCPTR *_ptrc_glTexBufferRange)(GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +#define glTexBufferRange _ptrc_glTexBufferRange +extern void (CODEGEN_FUNCPTR *_ptrc_glTexStorage2DMultisample)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +#define glTexStorage2DMultisample _ptrc_glTexStorage2DMultisample +extern void (CODEGEN_FUNCPTR *_ptrc_glTexStorage3DMultisample)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +#define glTexStorage3DMultisample _ptrc_glTexStorage3DMultisample +extern void (CODEGEN_FUNCPTR *_ptrc_glTextureView)(GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); +#define glTextureView _ptrc_glTextureView +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribBinding)(GLuint attribindex, GLuint bindingindex); +#define glVertexAttribBinding _ptrc_glVertexAttribBinding +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribFormat)(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +#define glVertexAttribFormat _ptrc_glVertexAttribFormat +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribIFormat)(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +#define glVertexAttribIFormat _ptrc_glVertexAttribIFormat +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexAttribLFormat)(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +#define glVertexAttribLFormat _ptrc_glVertexAttribLFormat +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexBindingDivisor)(GLuint bindingindex, GLuint divisor); +#define glVertexBindingDivisor _ptrc_glVertexBindingDivisor + +extern void (CODEGEN_FUNCPTR *_ptrc_glBindBuffersBase)(GLenum target, GLuint first, GLsizei count, const GLuint * buffers); +#define glBindBuffersBase _ptrc_glBindBuffersBase +extern void (CODEGEN_FUNCPTR *_ptrc_glBindBuffersRange)(GLenum target, GLuint first, GLsizei count, const GLuint * buffers, const GLintptr * offsets, const GLsizeiptr * sizes); +#define glBindBuffersRange _ptrc_glBindBuffersRange +extern void (CODEGEN_FUNCPTR *_ptrc_glBindImageTextures)(GLuint first, GLsizei count, const GLuint * textures); +#define glBindImageTextures _ptrc_glBindImageTextures +extern void (CODEGEN_FUNCPTR *_ptrc_glBindSamplers)(GLuint first, GLsizei count, const GLuint * samplers); +#define glBindSamplers _ptrc_glBindSamplers +extern void (CODEGEN_FUNCPTR *_ptrc_glBindTextures)(GLuint first, GLsizei count, const GLuint * textures); +#define glBindTextures _ptrc_glBindTextures +extern void (CODEGEN_FUNCPTR *_ptrc_glBindVertexBuffers)(GLuint first, GLsizei count, const GLuint * buffers, const GLintptr * offsets, const GLsizei * strides); +#define glBindVertexBuffers _ptrc_glBindVertexBuffers +extern void (CODEGEN_FUNCPTR *_ptrc_glBufferStorage)(GLenum target, GLsizeiptr size, const void * data, GLbitfield flags); +#define glBufferStorage _ptrc_glBufferStorage +extern void (CODEGEN_FUNCPTR *_ptrc_glClearTexImage)(GLuint texture, GLint level, GLenum format, GLenum type, const void * data); +#define glClearTexImage _ptrc_glClearTexImage +extern void (CODEGEN_FUNCPTR *_ptrc_glClearTexSubImage)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * data); +#define glClearTexSubImage _ptrc_glClearTexSubImage + +extern void (CODEGEN_FUNCPTR *_ptrc_glBindTextureUnit)(GLuint unit, GLuint texture); +#define glBindTextureUnit _ptrc_glBindTextureUnit +extern void (CODEGEN_FUNCPTR *_ptrc_glBlitNamedFramebuffer)(GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#define glBlitNamedFramebuffer _ptrc_glBlitNamedFramebuffer +extern GLenum (CODEGEN_FUNCPTR *_ptrc_glCheckNamedFramebufferStatus)(GLuint framebuffer, GLenum target); +#define glCheckNamedFramebufferStatus _ptrc_glCheckNamedFramebufferStatus +extern void (CODEGEN_FUNCPTR *_ptrc_glClearNamedBufferData)(GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void * data); +#define glClearNamedBufferData _ptrc_glClearNamedBufferData +extern void (CODEGEN_FUNCPTR *_ptrc_glClearNamedBufferSubData)(GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void * data); +#define glClearNamedBufferSubData _ptrc_glClearNamedBufferSubData +extern void (CODEGEN_FUNCPTR *_ptrc_glClearNamedFramebufferfi)(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat depth, GLint stencil); +#define glClearNamedFramebufferfi _ptrc_glClearNamedFramebufferfi +extern void (CODEGEN_FUNCPTR *_ptrc_glClearNamedFramebufferfv)(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat * value); +#define glClearNamedFramebufferfv _ptrc_glClearNamedFramebufferfv +extern void (CODEGEN_FUNCPTR *_ptrc_glClearNamedFramebufferiv)(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint * value); +#define glClearNamedFramebufferiv _ptrc_glClearNamedFramebufferiv +extern void (CODEGEN_FUNCPTR *_ptrc_glClearNamedFramebufferuiv)(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint * value); +#define glClearNamedFramebufferuiv _ptrc_glClearNamedFramebufferuiv +extern void (CODEGEN_FUNCPTR *_ptrc_glClipControl)(GLenum origin, GLenum depth); +#define glClipControl _ptrc_glClipControl +extern void (CODEGEN_FUNCPTR *_ptrc_glCompressedTextureSubImage1D)(GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void * data); +#define glCompressedTextureSubImage1D _ptrc_glCompressedTextureSubImage1D +extern void (CODEGEN_FUNCPTR *_ptrc_glCompressedTextureSubImage2D)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void * data); +#define glCompressedTextureSubImage2D _ptrc_glCompressedTextureSubImage2D +extern void (CODEGEN_FUNCPTR *_ptrc_glCompressedTextureSubImage3D)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void * data); +#define glCompressedTextureSubImage3D _ptrc_glCompressedTextureSubImage3D +extern void (CODEGEN_FUNCPTR *_ptrc_glCopyNamedBufferSubData)(GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); +#define glCopyNamedBufferSubData _ptrc_glCopyNamedBufferSubData +extern void (CODEGEN_FUNCPTR *_ptrc_glCopyTextureSubImage1D)(GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +#define glCopyTextureSubImage1D _ptrc_glCopyTextureSubImage1D +extern void (CODEGEN_FUNCPTR *_ptrc_glCopyTextureSubImage2D)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +#define glCopyTextureSubImage2D _ptrc_glCopyTextureSubImage2D +extern void (CODEGEN_FUNCPTR *_ptrc_glCopyTextureSubImage3D)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); +#define glCopyTextureSubImage3D _ptrc_glCopyTextureSubImage3D +extern void (CODEGEN_FUNCPTR *_ptrc_glCreateBuffers)(GLsizei n, GLuint * buffers); +#define glCreateBuffers _ptrc_glCreateBuffers +extern void (CODEGEN_FUNCPTR *_ptrc_glCreateFramebuffers)(GLsizei n, GLuint * framebuffers); +#define glCreateFramebuffers _ptrc_glCreateFramebuffers +extern void (CODEGEN_FUNCPTR *_ptrc_glCreateProgramPipelines)(GLsizei n, GLuint * pipelines); +#define glCreateProgramPipelines _ptrc_glCreateProgramPipelines +extern void (CODEGEN_FUNCPTR *_ptrc_glCreateQueries)(GLenum target, GLsizei n, GLuint * ids); +#define glCreateQueries _ptrc_glCreateQueries +extern void (CODEGEN_FUNCPTR *_ptrc_glCreateRenderbuffers)(GLsizei n, GLuint * renderbuffers); +#define glCreateRenderbuffers _ptrc_glCreateRenderbuffers +extern void (CODEGEN_FUNCPTR *_ptrc_glCreateSamplers)(GLsizei n, GLuint * samplers); +#define glCreateSamplers _ptrc_glCreateSamplers +extern void (CODEGEN_FUNCPTR *_ptrc_glCreateTextures)(GLenum target, GLsizei n, GLuint * textures); +#define glCreateTextures _ptrc_glCreateTextures +extern void (CODEGEN_FUNCPTR *_ptrc_glCreateTransformFeedbacks)(GLsizei n, GLuint * ids); +#define glCreateTransformFeedbacks _ptrc_glCreateTransformFeedbacks +extern void (CODEGEN_FUNCPTR *_ptrc_glCreateVertexArrays)(GLsizei n, GLuint * arrays); +#define glCreateVertexArrays _ptrc_glCreateVertexArrays +extern void (CODEGEN_FUNCPTR *_ptrc_glDisableVertexArrayAttrib)(GLuint vaobj, GLuint index); +#define glDisableVertexArrayAttrib _ptrc_glDisableVertexArrayAttrib +extern void (CODEGEN_FUNCPTR *_ptrc_glEnableVertexArrayAttrib)(GLuint vaobj, GLuint index); +#define glEnableVertexArrayAttrib _ptrc_glEnableVertexArrayAttrib +extern void (CODEGEN_FUNCPTR *_ptrc_glFlushMappedNamedBufferRange)(GLuint buffer, GLintptr offset, GLsizeiptr length); +#define glFlushMappedNamedBufferRange _ptrc_glFlushMappedNamedBufferRange +extern void (CODEGEN_FUNCPTR *_ptrc_glGenerateTextureMipmap)(GLuint texture); +#define glGenerateTextureMipmap _ptrc_glGenerateTextureMipmap +extern void (CODEGEN_FUNCPTR *_ptrc_glGetCompressedTextureImage)(GLuint texture, GLint level, GLsizei bufSize, void * pixels); +#define glGetCompressedTextureImage _ptrc_glGetCompressedTextureImage +extern void (CODEGEN_FUNCPTR *_ptrc_glGetCompressedTextureSubImage)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei bufSize, void * pixels); +#define glGetCompressedTextureSubImage _ptrc_glGetCompressedTextureSubImage +extern GLenum (CODEGEN_FUNCPTR *_ptrc_glGetGraphicsResetStatus)(void); +#define glGetGraphicsResetStatus _ptrc_glGetGraphicsResetStatus +extern void (CODEGEN_FUNCPTR *_ptrc_glGetNamedBufferParameteri64v)(GLuint buffer, GLenum pname, GLint64 * params); +#define glGetNamedBufferParameteri64v _ptrc_glGetNamedBufferParameteri64v +extern void (CODEGEN_FUNCPTR *_ptrc_glGetNamedBufferParameteriv)(GLuint buffer, GLenum pname, GLint * params); +#define glGetNamedBufferParameteriv _ptrc_glGetNamedBufferParameteriv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetNamedBufferPointerv)(GLuint buffer, GLenum pname, void ** params); +#define glGetNamedBufferPointerv _ptrc_glGetNamedBufferPointerv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetNamedBufferSubData)(GLuint buffer, GLintptr offset, GLsizeiptr size, void * data); +#define glGetNamedBufferSubData _ptrc_glGetNamedBufferSubData +extern void (CODEGEN_FUNCPTR *_ptrc_glGetNamedFramebufferAttachmentParameteriv)(GLuint framebuffer, GLenum attachment, GLenum pname, GLint * params); +#define glGetNamedFramebufferAttachmentParameteriv _ptrc_glGetNamedFramebufferAttachmentParameteriv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetNamedFramebufferParameteriv)(GLuint framebuffer, GLenum pname, GLint * param); +#define glGetNamedFramebufferParameteriv _ptrc_glGetNamedFramebufferParameteriv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetNamedRenderbufferParameteriv)(GLuint renderbuffer, GLenum pname, GLint * params); +#define glGetNamedRenderbufferParameteriv _ptrc_glGetNamedRenderbufferParameteriv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetQueryBufferObjecti64v)(GLuint id, GLuint buffer, GLenum pname, GLintptr offset); +#define glGetQueryBufferObjecti64v _ptrc_glGetQueryBufferObjecti64v +extern void (CODEGEN_FUNCPTR *_ptrc_glGetQueryBufferObjectiv)(GLuint id, GLuint buffer, GLenum pname, GLintptr offset); +#define glGetQueryBufferObjectiv _ptrc_glGetQueryBufferObjectiv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetQueryBufferObjectui64v)(GLuint id, GLuint buffer, GLenum pname, GLintptr offset); +#define glGetQueryBufferObjectui64v _ptrc_glGetQueryBufferObjectui64v +extern void (CODEGEN_FUNCPTR *_ptrc_glGetQueryBufferObjectuiv)(GLuint id, GLuint buffer, GLenum pname, GLintptr offset); +#define glGetQueryBufferObjectuiv _ptrc_glGetQueryBufferObjectuiv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetTextureImage)(GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void * pixels); +#define glGetTextureImage _ptrc_glGetTextureImage +extern void (CODEGEN_FUNCPTR *_ptrc_glGetTextureLevelParameterfv)(GLuint texture, GLint level, GLenum pname, GLfloat * params); +#define glGetTextureLevelParameterfv _ptrc_glGetTextureLevelParameterfv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetTextureLevelParameteriv)(GLuint texture, GLint level, GLenum pname, GLint * params); +#define glGetTextureLevelParameteriv _ptrc_glGetTextureLevelParameteriv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetTextureParameterIiv)(GLuint texture, GLenum pname, GLint * params); +#define glGetTextureParameterIiv _ptrc_glGetTextureParameterIiv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetTextureParameterIuiv)(GLuint texture, GLenum pname, GLuint * params); +#define glGetTextureParameterIuiv _ptrc_glGetTextureParameterIuiv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetTextureParameterfv)(GLuint texture, GLenum pname, GLfloat * params); +#define glGetTextureParameterfv _ptrc_glGetTextureParameterfv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetTextureParameteriv)(GLuint texture, GLenum pname, GLint * params); +#define glGetTextureParameteriv _ptrc_glGetTextureParameteriv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetTextureSubImage)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, void * pixels); +#define glGetTextureSubImage _ptrc_glGetTextureSubImage +extern void (CODEGEN_FUNCPTR *_ptrc_glGetTransformFeedbacki64_v)(GLuint xfb, GLenum pname, GLuint index, GLint64 * param); +#define glGetTransformFeedbacki64_v _ptrc_glGetTransformFeedbacki64_v +extern void (CODEGEN_FUNCPTR *_ptrc_glGetTransformFeedbacki_v)(GLuint xfb, GLenum pname, GLuint index, GLint * param); +#define glGetTransformFeedbacki_v _ptrc_glGetTransformFeedbacki_v +extern void (CODEGEN_FUNCPTR *_ptrc_glGetTransformFeedbackiv)(GLuint xfb, GLenum pname, GLint * param); +#define glGetTransformFeedbackiv _ptrc_glGetTransformFeedbackiv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetVertexArrayIndexed64iv)(GLuint vaobj, GLuint index, GLenum pname, GLint64 * param); +#define glGetVertexArrayIndexed64iv _ptrc_glGetVertexArrayIndexed64iv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetVertexArrayIndexediv)(GLuint vaobj, GLuint index, GLenum pname, GLint * param); +#define glGetVertexArrayIndexediv _ptrc_glGetVertexArrayIndexediv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetVertexArrayiv)(GLuint vaobj, GLenum pname, GLint * param); +#define glGetVertexArrayiv _ptrc_glGetVertexArrayiv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetnCompressedTexImage)(GLenum target, GLint lod, GLsizei bufSize, void * pixels); +#define glGetnCompressedTexImage _ptrc_glGetnCompressedTexImage +extern void (CODEGEN_FUNCPTR *_ptrc_glGetnTexImage)(GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void * pixels); +#define glGetnTexImage _ptrc_glGetnTexImage +extern void (CODEGEN_FUNCPTR *_ptrc_glGetnUniformdv)(GLuint program, GLint location, GLsizei bufSize, GLdouble * params); +#define glGetnUniformdv _ptrc_glGetnUniformdv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetnUniformfv)(GLuint program, GLint location, GLsizei bufSize, GLfloat * params); +#define glGetnUniformfv _ptrc_glGetnUniformfv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetnUniformiv)(GLuint program, GLint location, GLsizei bufSize, GLint * params); +#define glGetnUniformiv _ptrc_glGetnUniformiv +extern void (CODEGEN_FUNCPTR *_ptrc_glGetnUniformuiv)(GLuint program, GLint location, GLsizei bufSize, GLuint * params); +#define glGetnUniformuiv _ptrc_glGetnUniformuiv +extern void (CODEGEN_FUNCPTR *_ptrc_glInvalidateNamedFramebufferData)(GLuint framebuffer, GLsizei numAttachments, const GLenum * attachments); +#define glInvalidateNamedFramebufferData _ptrc_glInvalidateNamedFramebufferData +extern void (CODEGEN_FUNCPTR *_ptrc_glInvalidateNamedFramebufferSubData)(GLuint framebuffer, GLsizei numAttachments, const GLenum * attachments, GLint x, GLint y, GLsizei width, GLsizei height); +#define glInvalidateNamedFramebufferSubData _ptrc_glInvalidateNamedFramebufferSubData +extern void * (CODEGEN_FUNCPTR *_ptrc_glMapNamedBuffer)(GLuint buffer, GLenum access); +#define glMapNamedBuffer _ptrc_glMapNamedBuffer +extern void * (CODEGEN_FUNCPTR *_ptrc_glMapNamedBufferRange)(GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); +#define glMapNamedBufferRange _ptrc_glMapNamedBufferRange +extern void (CODEGEN_FUNCPTR *_ptrc_glMemoryBarrierByRegion)(GLbitfield barriers); +#define glMemoryBarrierByRegion _ptrc_glMemoryBarrierByRegion +extern void (CODEGEN_FUNCPTR *_ptrc_glNamedBufferData)(GLuint buffer, GLsizeiptr size, const void * data, GLenum usage); +#define glNamedBufferData _ptrc_glNamedBufferData +extern void (CODEGEN_FUNCPTR *_ptrc_glNamedBufferStorage)(GLuint buffer, GLsizeiptr size, const void * data, GLbitfield flags); +#define glNamedBufferStorage _ptrc_glNamedBufferStorage +extern void (CODEGEN_FUNCPTR *_ptrc_glNamedBufferSubData)(GLuint buffer, GLintptr offset, GLsizeiptr size, const void * data); +#define glNamedBufferSubData _ptrc_glNamedBufferSubData +extern void (CODEGEN_FUNCPTR *_ptrc_glNamedFramebufferDrawBuffer)(GLuint framebuffer, GLenum buf); +#define glNamedFramebufferDrawBuffer _ptrc_glNamedFramebufferDrawBuffer +extern void (CODEGEN_FUNCPTR *_ptrc_glNamedFramebufferDrawBuffers)(GLuint framebuffer, GLsizei n, const GLenum * bufs); +#define glNamedFramebufferDrawBuffers _ptrc_glNamedFramebufferDrawBuffers +extern void (CODEGEN_FUNCPTR *_ptrc_glNamedFramebufferParameteri)(GLuint framebuffer, GLenum pname, GLint param); +#define glNamedFramebufferParameteri _ptrc_glNamedFramebufferParameteri +extern void (CODEGEN_FUNCPTR *_ptrc_glNamedFramebufferReadBuffer)(GLuint framebuffer, GLenum src); +#define glNamedFramebufferReadBuffer _ptrc_glNamedFramebufferReadBuffer +extern void (CODEGEN_FUNCPTR *_ptrc_glNamedFramebufferRenderbuffer)(GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +#define glNamedFramebufferRenderbuffer _ptrc_glNamedFramebufferRenderbuffer +extern void (CODEGEN_FUNCPTR *_ptrc_glNamedFramebufferTexture)(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); +#define glNamedFramebufferTexture _ptrc_glNamedFramebufferTexture +extern void (CODEGEN_FUNCPTR *_ptrc_glNamedFramebufferTextureLayer)(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); +#define glNamedFramebufferTextureLayer _ptrc_glNamedFramebufferTextureLayer +extern void (CODEGEN_FUNCPTR *_ptrc_glNamedRenderbufferStorage)(GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); +#define glNamedRenderbufferStorage _ptrc_glNamedRenderbufferStorage +extern void (CODEGEN_FUNCPTR *_ptrc_glNamedRenderbufferStorageMultisample)(GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#define glNamedRenderbufferStorageMultisample _ptrc_glNamedRenderbufferStorageMultisample +extern void (CODEGEN_FUNCPTR *_ptrc_glReadnPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void * data); +#define glReadnPixels _ptrc_glReadnPixels +extern void (CODEGEN_FUNCPTR *_ptrc_glTextureBarrier)(void); +#define glTextureBarrier _ptrc_glTextureBarrier +extern void (CODEGEN_FUNCPTR *_ptrc_glTextureBuffer)(GLuint texture, GLenum internalformat, GLuint buffer); +#define glTextureBuffer _ptrc_glTextureBuffer +extern void (CODEGEN_FUNCPTR *_ptrc_glTextureBufferRange)(GLuint texture, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); +#define glTextureBufferRange _ptrc_glTextureBufferRange +extern void (CODEGEN_FUNCPTR *_ptrc_glTextureParameterIiv)(GLuint texture, GLenum pname, const GLint * params); +#define glTextureParameterIiv _ptrc_glTextureParameterIiv +extern void (CODEGEN_FUNCPTR *_ptrc_glTextureParameterIuiv)(GLuint texture, GLenum pname, const GLuint * params); +#define glTextureParameterIuiv _ptrc_glTextureParameterIuiv +extern void (CODEGEN_FUNCPTR *_ptrc_glTextureParameterf)(GLuint texture, GLenum pname, GLfloat param); +#define glTextureParameterf _ptrc_glTextureParameterf +extern void (CODEGEN_FUNCPTR *_ptrc_glTextureParameterfv)(GLuint texture, GLenum pname, const GLfloat * param); +#define glTextureParameterfv _ptrc_glTextureParameterfv +extern void (CODEGEN_FUNCPTR *_ptrc_glTextureParameteri)(GLuint texture, GLenum pname, GLint param); +#define glTextureParameteri _ptrc_glTextureParameteri +extern void (CODEGEN_FUNCPTR *_ptrc_glTextureParameteriv)(GLuint texture, GLenum pname, const GLint * param); +#define glTextureParameteriv _ptrc_glTextureParameteriv +extern void (CODEGEN_FUNCPTR *_ptrc_glTextureStorage1D)(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width); +#define glTextureStorage1D _ptrc_glTextureStorage1D +extern void (CODEGEN_FUNCPTR *_ptrc_glTextureStorage2D)(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +#define glTextureStorage2D _ptrc_glTextureStorage2D +extern void (CODEGEN_FUNCPTR *_ptrc_glTextureStorage2DMultisample)(GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); +#define glTextureStorage2DMultisample _ptrc_glTextureStorage2DMultisample +extern void (CODEGEN_FUNCPTR *_ptrc_glTextureStorage3D)(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +#define glTextureStorage3D _ptrc_glTextureStorage3D +extern void (CODEGEN_FUNCPTR *_ptrc_glTextureStorage3DMultisample)(GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +#define glTextureStorage3DMultisample _ptrc_glTextureStorage3DMultisample +extern void (CODEGEN_FUNCPTR *_ptrc_glTextureSubImage1D)(GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void * pixels); +#define glTextureSubImage1D _ptrc_glTextureSubImage1D +extern void (CODEGEN_FUNCPTR *_ptrc_glTextureSubImage2D)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * pixels); +#define glTextureSubImage2D _ptrc_glTextureSubImage2D +extern void (CODEGEN_FUNCPTR *_ptrc_glTextureSubImage3D)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * pixels); +#define glTextureSubImage3D _ptrc_glTextureSubImage3D +extern void (CODEGEN_FUNCPTR *_ptrc_glTransformFeedbackBufferBase)(GLuint xfb, GLuint index, GLuint buffer); +#define glTransformFeedbackBufferBase _ptrc_glTransformFeedbackBufferBase +extern void (CODEGEN_FUNCPTR *_ptrc_glTransformFeedbackBufferRange)(GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +#define glTransformFeedbackBufferRange _ptrc_glTransformFeedbackBufferRange +extern GLboolean (CODEGEN_FUNCPTR *_ptrc_glUnmapNamedBuffer)(GLuint buffer); +#define glUnmapNamedBuffer _ptrc_glUnmapNamedBuffer +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexArrayAttribBinding)(GLuint vaobj, GLuint attribindex, GLuint bindingindex); +#define glVertexArrayAttribBinding _ptrc_glVertexArrayAttribBinding +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexArrayAttribFormat)(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); +#define glVertexArrayAttribFormat _ptrc_glVertexArrayAttribFormat +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexArrayAttribIFormat)(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +#define glVertexArrayAttribIFormat _ptrc_glVertexArrayAttribIFormat +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexArrayAttribLFormat)(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); +#define glVertexArrayAttribLFormat _ptrc_glVertexArrayAttribLFormat +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexArrayBindingDivisor)(GLuint vaobj, GLuint bindingindex, GLuint divisor); +#define glVertexArrayBindingDivisor _ptrc_glVertexArrayBindingDivisor +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexArrayElementBuffer)(GLuint vaobj, GLuint buffer); +#define glVertexArrayElementBuffer _ptrc_glVertexArrayElementBuffer +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexArrayVertexBuffer)(GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); +#define glVertexArrayVertexBuffer _ptrc_glVertexArrayVertexBuffer +extern void (CODEGEN_FUNCPTR *_ptrc_glVertexArrayVertexBuffers)(GLuint vaobj, GLuint first, GLsizei count, const GLuint * buffers, const GLintptr * offsets, const GLsizei * strides); +#define glVertexArrayVertexBuffers _ptrc_glVertexArrayVertexBuffers + enum ogl_LoadStatus { ogl_LOAD_FAILED = 0, diff --git a/src/hu_scores.cpp b/src/hu_scores.cpp index a399011812..91c3dacfc6 100644 --- a/src/hu_scores.cpp +++ b/src/hu_scores.cpp @@ -184,7 +184,6 @@ void HU_DrawScores (player_t *player) HU_DoDrawScores (player, sortedplayers); - V_SetBorderNeedRefresh(); } //========================================================================== @@ -213,14 +212,14 @@ void HU_GetPlayerWidths(int &maxnamewidth, int &maxscorewidth, int &maxiconheigh if (players[i].mo->ScoreIcon.isValid()) { FTexture *pic = TexMan[players[i].mo->ScoreIcon]; - width = pic->GetScaledWidth() - pic->GetScaledLeftOffset() + 2; + width = pic->GetScaledWidth() - pic->GetScaledLeftOffset(0) + 2; if (width > maxscorewidth) { maxscorewidth = width; } // The icon's top offset does not count toward its height, because // zdoom.pk3's standard Hexen class icons are designed that way. - int height = pic->GetScaledHeight() - pic->GetScaledTopOffset(); + int height = pic->GetScaledHeight() - pic->GetScaledTopOffset(0); if (height > maxiconheight) { maxiconheight = height; diff --git a/src/gl/dynlights/gl_aabbtree.cpp b/src/hwrenderer/dynlights/hw_aabbtree.cpp similarity index 98% rename from src/gl/dynlights/gl_aabbtree.cpp rename to src/hwrenderer/dynlights/hw_aabbtree.cpp index 73bb544743..5df3c4ac78 100644 --- a/src/gl/dynlights/gl_aabbtree.cpp +++ b/src/hwrenderer/dynlights/hw_aabbtree.cpp @@ -20,12 +20,12 @@ //-------------------------------------------------------------------------- // -#include "gl/system/gl_system.h" -#include "gl/shaders/gl_shader.h" -#include "gl/dynlights/gl_aabbtree.h" -#include "gl/system/gl_interface.h" #include "r_state.h" #include "g_levellocals.h" +#include "hw_aabbtree.h" + +namespace hwrenderer +{ LevelAABBTree::LevelAABBTree() { @@ -286,3 +286,6 @@ int LevelAABBTree::GenerateTreeNode(int *lines, int num_lines, const FVector2 *c nodes.Push(AABBTreeNode(aabb_min, aabb_max, left_index, right_index)); return (int)nodes.Size() - 1; } + + +} diff --git a/src/gl/dynlights/gl_aabbtree.h b/src/hwrenderer/dynlights/hw_aabbtree.h similarity index 98% rename from src/gl/dynlights/gl_aabbtree.h rename to src/hwrenderer/dynlights/hw_aabbtree.h index 0de075be58..d21ac0c61e 100644 --- a/src/gl/dynlights/gl_aabbtree.h +++ b/src/hwrenderer/dynlights/hw_aabbtree.h @@ -3,6 +3,9 @@ #include "vectors.h" +namespace hwrenderer +{ + // Node in a binary AABB tree struct AABBTreeNode { @@ -57,3 +60,5 @@ private: // Generate a tree node and its children recursively int GenerateTreeNode(int *lines, int num_lines, const FVector2 *centroids, int *work_buffer); }; + +} // namespace diff --git a/src/intermission/intermission.cpp b/src/intermission/intermission.cpp index 3115e81693..25750a58e8 100644 --- a/src/intermission/intermission.cpp +++ b/src/intermission/intermission.cpp @@ -77,8 +77,6 @@ CVAR(Bool, nointerscrollabort, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); void DIntermissionScreen::Init(FIntermissionAction *desc, bool first) { - int lumpnum; - if (desc->mCdTrack == 0 || !S_ChangeCDMusic (desc->mCdTrack, desc->mCdId)) { if (desc->mMusic.IsEmpty()) @@ -121,26 +119,6 @@ void DIntermissionScreen::Init(FIntermissionAction *desc, bool first) mFlatfill = desc->mFlatfill; } S_Sound (CHAN_VOICE | CHAN_UI, desc->mSound, 1.0f, ATTN_NONE); - if (desc->mPalette.IsNotEmpty() && (lumpnum = Wads.CheckNumForFullName(desc->mPalette, true)) > 0) - { - PalEntry *palette; - uint8_t palbuffer[768]; - const uint8_t *orgpal; - FMemLump lump; - int i; - - ReadPalette(lumpnum, palbuffer); - orgpal = (uint8_t *)palbuffer; - palette = screen->GetPalette (); - for (i = 256; i > 0; i--, orgpal += 3) - { - *palette++ = PalEntry (orgpal[0], orgpal[1], orgpal[2]); - } - screen->UpdatePalette (); - mPaletteChanged = true; - NoWipe = 1; - M_EnableMenu(false); - } mOverlays.Resize(desc->mOverlays.Size()); for (unsigned i=0; i < mOverlays.Size(); i++) { @@ -208,21 +186,6 @@ void DIntermissionScreen::Drawer () void DIntermissionScreen::OnDestroy() { - if (mPaletteChanged) - { - PalEntry *palette; - int i; - - palette = screen->GetPalette (); - for (i = 0; i < 256; ++i) - { - palette[i] = GPalette.BaseColors[i]; - } - screen->UpdatePalette (); - NoWipe = 5; - mPaletteChanged = false; - M_EnableMenu(true); - } S_StopSound(CHAN_VOICE); Super::OnDestroy(); } @@ -793,7 +756,7 @@ bool DIntermissionController::Responder (event_t *ev) { if (mScreen != NULL) { - if (!mScreen->mPaletteChanged && ev->type == EV_KeyDown) + if (ev->type == EV_KeyDown) { const char *cmd = Bindings.GetBind (ev->data1); diff --git a/src/intermission/intermission.h b/src/intermission/intermission.h index 9111ebe994..a73d18a128 100644 --- a/src/intermission/intermission.h +++ b/src/intermission/intermission.h @@ -73,7 +73,6 @@ struct FIntermissionAction int mCdId; int mDuration; FString mBackground; - FString mPalette; FString mSound; bool mFlatfill; bool mMusicLooping; @@ -169,7 +168,6 @@ protected: public: int mTicker; - bool mPaletteChanged; DIntermissionScreen() {} virtual void Init(FIntermissionAction *desc, bool first); diff --git a/src/intermission/intermission_parse.cpp b/src/intermission/intermission_parse.cpp index 2841b70f71..c3fb7b53e5 100644 --- a/src/intermission/intermission_parse.cpp +++ b/src/intermission/intermission_parse.cpp @@ -135,7 +135,7 @@ bool FIntermissionAction::ParseKey(FScanner &sc) if (sc.CheckToken(',')) { sc.MustGetToken(TK_StringConst); - mPalette = sc.String; + sc.ScriptMessage("Palette override will be ignored"); } } return true; diff --git a/src/menu/loadsavemenu.cpp b/src/menu/loadsavemenu.cpp index 7d4b1ebf49..d43a2e42c4 100644 --- a/src/menu/loadsavemenu.cpp +++ b/src/menu/loadsavemenu.cpp @@ -386,7 +386,6 @@ void FSavegameManager::LoadSavegame(int Selected) quickSaveSlot = SaveGames[Selected]; } M_ClearMenus(); - V_SetBorderNeedRefresh(); LastAccessed = Selected; } @@ -428,7 +427,6 @@ void FSavegameManager::DoSave(int Selected, const char *savegamestring) G_SaveGame(filename, savegamestring); } M_ClearMenus(); - V_SetBorderNeedRefresh(); } DEFINE_ACTION_FUNCTION(FSavegameManager, DoSave) @@ -487,7 +485,7 @@ unsigned FSavegameManager::ExtractSaveData(int index) arc("Comment", pcomment); comment = time; - if (time.Len() > 0) comment += "\n\n"; + if (time.Len() > 0) comment += "\n"; comment += pcomment; SaveComment = V_BreakLines(SmallFont, WindowSize, comment.GetChars()); @@ -619,10 +617,12 @@ void FSavegameManager::DrawSaveComment(FFont *font, int cr, int x, int y, int sc CleanXfac = CleanYfac = scalefactor; + int maxlines = screen->GetHeight()>400?10:screen->GetHeight()>240?7:screen->GetHeight()>200?8:5; + if (SmallFont->GetHeight() > 9) maxlines--; // not Doom // I'm not sure why SaveComment would go nullptr in this loop, but I got // a crash report where it was nullptr when i reached 1, so now I check // for that. - for (int i = 0; SaveComment != nullptr && SaveComment[i].Width >= 0 && i < 6; ++i) + for (int i = 0; SaveComment != nullptr && SaveComment[i].Width >= 0 && i < maxlines; ++i) { screen->DrawText(font, cr, x, y + font->GetHeight() * i * scalefactor, SaveComment[i].Text, DTA_CleanNoMove, true, TAG_DONE); } diff --git a/src/menu/menu.cpp b/src/menu/menu.cpp index bf8999ded8..915449e456 100644 --- a/src/menu/menu.cpp +++ b/src/menu/menu.cpp @@ -74,6 +74,20 @@ CVAR (Float, snd_menuvolume, 0.6f, CVAR_ARCHIVE) CVAR(Int, m_use_mouse, 2, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR(Int, m_show_backbutton, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +CUSTOM_CVAR(Float, dimamount, -1.f, CVAR_ARCHIVE) +{ + if (self < 0.f && self != -1.f) + { + self = -1.f; + } + else if (self > 1.f) + { + self = 1.f; + } +} +CVAR(Color, dimcolor, 0xffd700, CVAR_ARCHIVE) + + DEFINE_ACTION_FUNCTION(DMenu, GetCurrentMenu) { @@ -766,6 +780,41 @@ void M_Ticker (void) } } +//========================================================================== +// +// M_Dim +// +// Applies a colored overlay to the entire screen, with the opacity +// determined by the dimamount cvar. +// +//========================================================================== + +static void M_Dim() +{ + PalEntry dimmer; + float amount; + + if (dimamount >= 0) + { + dimmer = PalEntry(dimcolor); + amount = dimamount; + } + else + { + dimmer = gameinfo.dimcolor; + amount = gameinfo.dimamount; + } + + if (gameinfo.gametype == GAME_Hexen && gamestate == GS_DEMOSCREEN) + { // On the Hexen title screen, the default dimming is not + // enough to make the menus readable. + amount = MIN(1.f, amount*2.f); + } + + screen->Dim(dimmer, amount, 0, 0, screen->GetWidth(), screen->GetHeight()); +} + + //============================================================================= // // @@ -778,24 +827,13 @@ void M_Drawer (void) AActor *camera = player->camera; PalEntry fade = 0; - if (!screen->Accel2D && camera != nullptr && (gamestate == GS_LEVEL || gamestate == GS_TITLELEVEL)) - { - if (camera->player != nullptr) - { - player = camera->player; - } - fade = PalEntry (uint8_t(player->BlendA*255), uint8_t(player->BlendR*255), uint8_t(player->BlendG*255), uint8_t(player->BlendB*255)); - } - - if (CurrentMenu != nullptr && menuactive != MENU_Off) { if (GLRenderer) GLRenderer->BlurScene(gameinfo.bluramount); if (!CurrentMenu->DontDim) { - screen->Dim(fade); - V_SetBorderNeedRefresh(); + M_Dim(); } CurrentMenu->CallDrawer(); } @@ -816,7 +854,6 @@ void M_ClearMenus() CurrentMenu->Destroy(); CurrentMenu = parent; } - V_SetBorderNeedRefresh(); menuactive = MENU_Off; } diff --git a/src/p_3dfloors.cpp b/src/p_3dfloors.cpp index 2ad3741666..376a1b060a 100644 --- a/src/p_3dfloors.cpp +++ b/src/p_3dfloors.cpp @@ -50,8 +50,6 @@ #include "g_levellocals.h" #include "actorinlines.h" -extern int currentrenderer; - //========================================================================== // // 3D Floors @@ -197,7 +195,7 @@ static void P_Add3DFloor(sector_t* sec, sector_t* sec2, line_t* master, int flag // kg3D - software renderer only hack // this is really required because of ceilingclip and floorclip - if((currentrenderer == 0) && (flags & FF_BOTHPLANES)) + if(flags & FF_BOTHPLANES) { P_Add3DFloor(sec, sec2, master, FF_EXISTS | FF_THISINSIDE | FF_RENDERPLANES | FF_NOSHADE | FF_SEETHROUGH | FF_SHOOTTHROUGH | (flags & (FF_INVERTSECTOR | FF_TRANSLUCENT | FF_ADDITIVETRANS)), alpha); diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index 6b19942e0f..40af00067a 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -912,7 +912,7 @@ bool FMultiBlockLinesIterator::Next(FMultiBlockLinesIterator::CheckResult *item) bool FMultiBlockLinesIterator::startIteratorForGroup(int group) { - offset = Displacements.getOffset(basegroup, group); + offset = level.Displacements.getOffset(basegroup, group); offset.X += checkpoint.X; offset.Y += checkpoint.Y; cursector = group == startsector->PortalGroup ? startsector : P_PointInSector(offset); @@ -1219,7 +1219,7 @@ bool FMultiBlockThingsIterator::Next(FMultiBlockThingsIterator::CheckResult *ite if (thing != NULL) { item->thing = thing; - item->Position = checkpoint + Displacements.getOffset(basegroup, thing->Sector->PortalGroup); + item->Position = checkpoint + level.Displacements.getOffset(basegroup, thing->Sector->PortalGroup); item->portalflags = portalflags; return true; } @@ -1258,7 +1258,7 @@ bool FMultiBlockThingsIterator::Next(FMultiBlockThingsIterator::CheckResult *ite void FMultiBlockThingsIterator::startIteratorForGroup(int group) { - DVector2 offset = Displacements.getOffset(basegroup, group); + DVector2 offset = level.Displacements.getOffset(basegroup, group); offset.X += checkpoint.X; offset.Y += checkpoint.Y; bbox.setBox(offset.X, offset.Y, checkpoint.Z); diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 21126f645b..35f9931d72 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -741,10 +741,7 @@ bool AActor::SetState (FState *newstate, bool nofunction) newstate = newstate->GetNextState(); } while (tics == 0); - if (Renderer != NULL) - { - SetDynamicLights(); - } + SetDynamicLights(); return true; } diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index af6daf4284..cf79afc6f1 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -943,7 +943,6 @@ void G_SerializeLevel(FSerializer &arc, bool hubload) } arc("saveversion", SaveVersion); - Renderer->StartSerialize(arc); if (arc.isReading()) { DThinker::DestroyAllThinkers(); @@ -993,7 +992,7 @@ void G_SerializeLevel(FSerializer &arc, bool hubload) arc("sidedefs", level.sides, level.loadsides); arc("sectors", level.sectors, level.loadsectors); arc("zones", level.Zones); - arc("lineportals", linePortals); + arc("lineportals", level.linePortals); arc("sectorportals", level.sectorPortals); if (arc.isReading()) P_CollectLinkedPortals(); @@ -1024,6 +1023,5 @@ void G_SerializeLevel(FSerializer &arc, bool hubload) } } AActor::RecreateAllAttachedLights(); - Renderer->EndSerialize(arc); - + InitPortalGroups(); } diff --git a/src/p_secnodes.cpp b/src/p_secnodes.cpp index f95c28b39c..0e62e622bc 100644 --- a/src/p_secnodes.cpp +++ b/src/p_secnodes.cpp @@ -389,16 +389,16 @@ void AActor::UpdateRenderSectorList() { // Only check if the map contains line portals ClearRenderLineList(); - if (PortalBlockmap.containsLines && Pos().XY() != OldRenderPos.XY()) + if (level.PortalBlockmap.containsLines && Pos().XY() != OldRenderPos.XY()) { int bx = level.blockmap.GetBlockX(X()); int by = level.blockmap.GetBlockY(Y()); FBoundingBox bb(X(), Y(), MIN(radius*1.5, 128.)); // Don't go further than 128 map units, even for large actors // Are there any portals near the actor's position? - if (level.blockmap.isValidBlock(bx, by) && PortalBlockmap(bx, by).neighborContainsLines) + if (level.blockmap.isValidBlock(bx, by) && level.PortalBlockmap(bx, by).neighborContainsLines) { // Go through the entire list. In most cases this is faster than setting up a blockmap iterator - for (auto &p : linePortals) + for (auto &p : level.linePortals) { if (p.mType == PORTT_VISUAL) continue; if (bb.inRange(p.mOrigin) && bb.BoxOnLineSide(p.mOrigin)) diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index f26c7e229a..94a1fe8a59 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -3,7 +3,7 @@ // Copyright 1993-1996 id Software // Copyright 1998-1998 Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman // Copyright 1999-2016 Randy Heit -// Copyright 2002-2017 Christoph Oelckers +// Copyright 2002-2018 Christoph Oelckers // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -1527,6 +1527,112 @@ DEFINE_ACTION_FUNCTION(_Sector, NextLowestFloorAt) } + //========================================================================== + // + // Checks whether a sprite should be affected by a glow + // + //========================================================================== + + int sector_t::CheckSpriteGlow(int lightlevel, const DVector3 &pos) + { + float bottomglowcolor[4]; + bottomglowcolor[3] = 0; + auto c = planes[sector_t::floor].GlowColor; + if (c == 0) + { + FTexture *tex = TexMan[GetTexture(sector_t::floor)]; + if (tex != NULL && tex->isGlowing()) + { + if (!tex->bAutoGlowing) tex = TexMan(GetTexture(sector_t::floor)); + if (tex->isGlowing()) // recheck the current animation frame. + { + tex->GetGlowColor(bottomglowcolor); + bottomglowcolor[3] = (float)tex->GlowHeight; + } + } + } + else if (c != ~0u) + { + bottomglowcolor[0] = c.r / 255.f; + bottomglowcolor[1] = c.g / 255.f; + bottomglowcolor[2] = c.b / 255.f; + bottomglowcolor[3] = planes[sector_t::floor].GlowHeight; + } + + if (bottomglowcolor[3]> 0) + { + double floordiff = pos.Z - floorplane.ZatPoint(pos); + if (floordiff < bottomglowcolor[3]) + { + int maxlight = (255 + lightlevel) >> 1; + double lightfrac = floordiff / bottomglowcolor[3]; + if (lightfrac < 0) lightfrac = 0; + lightlevel = int(lightfrac*lightlevel + maxlight * (1 - lightfrac)); + } + } + return lightlevel; + } + + //========================================================================== + // + // Checks whether a wall should glow + // + //========================================================================== + bool sector_t::GetWallGlow(float *topglowcolor, float *bottomglowcolor) + { + bool ret = false; + bottomglowcolor[3] = topglowcolor[3] = 0; + auto c = planes[sector_t::ceiling].GlowColor; + if (c == 0) + { + FTexture *tex = TexMan[GetTexture(sector_t::ceiling)]; + if (tex != NULL && tex->isGlowing()) + { + if (!tex->bAutoGlowing) tex = TexMan(GetTexture(sector_t::ceiling)); + if (tex->isGlowing()) // recheck the current animation frame. + { + ret = true; + tex->GetGlowColor(topglowcolor); + topglowcolor[3] = (float)tex->GlowHeight; + } + } + } + else if (c != ~0u) + { + topglowcolor[0] = c.r / 255.f; + topglowcolor[1] = c.g / 255.f; + topglowcolor[2] = c.b / 255.f; + topglowcolor[3] = planes[sector_t::ceiling].GlowHeight; + ret = topglowcolor[3] > 0; + } + + c = planes[sector_t::floor].GlowColor; + if (c == 0) + { + FTexture *tex = TexMan[GetTexture(sector_t::floor)]; + if (tex != NULL && tex->isGlowing()) + { + if (!tex->bAutoGlowing) tex = TexMan(GetTexture(sector_t::floor)); + if (tex->isGlowing()) // recheck the current animation frame. + { + ret = true; + tex->GetGlowColor(bottomglowcolor); + bottomglowcolor[3] = (float)tex->GlowHeight; + } + } + } + else if (c != ~0u) + { + bottomglowcolor[0] = c.r / 255.f; + bottomglowcolor[1] = c.g / 255.f; + bottomglowcolor[2] = c.b / 255.f; + bottomglowcolor[3] = planes[sector_t::floor].GlowHeight; + ret = bottomglowcolor[3] > 0; + } + return ret; + } + + //=========================================================================== // // @@ -2395,6 +2501,46 @@ int side_t::GetLightLevel (bool foggy, int baselight, bool is3dlight, int *pfake return baselight; } +//========================================================================== +// +// Recalculate all heights affecting this vertex. +// +//========================================================================== + +void vertex_t::RecalcVertexHeights() +{ + int i, j, k; + float height; + + numheights = 0; + for (i = 0; i < numsectors; i++) + { + for (j = 0; j<2; j++) + { + if (j == 0) height = (float)sectors[i]->ceilingplane.ZatPoint(this); + else height = (float)sectors[i]->floorplane.ZatPoint(this); + + for (k = 0; k < numheights; k++) + { + if (height == heightlist[k]) break; + if (height < heightlist[k]) + { + memmove(&heightlist[k + 1], &heightlist[k], sizeof(float) * (numheights - k)); + heightlist[k] = height; + numheights++; + break; + } + } + if (k == numheights) heightlist[numheights++] = height; + } + } + if (numheights <= 2) numheights = 0; // is not in need of any special attention + dirty = false; +} + + + + DEFINE_ACTION_FUNCTION(_Secplane, isSlope) { PARAM_SELF_STRUCT_PROLOGUE(secplane_t); diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 648502542a..d9c5b92005 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -110,6 +110,8 @@ #include "p_spec.h" #include "p_saveg.h" #include "g_levellocals.h" +#include "c_dispatch.h" +#include "a_dynlight.h" #ifndef NO_EDATA #include "edata.h" #endif @@ -127,6 +129,7 @@ void P_SetSlopes (); void P_CopySlopes(); void BloodCrypt (void *data, int key, int len); void P_ClearUDMFKeys(); +void InitRenderInfo(); extern AActor *P_SpawnMapThing (FMapThing *mthing, int position); @@ -1499,6 +1502,8 @@ void P_LoadSectors (MapData *map, FMissingTextureTracker &missingtex) ss->ZoneNumber = 0xFFFF; ss->terrainnum[sector_t::ceiling] = ss->terrainnum[sector_t::floor] = -1; + + // [RH] Sectors default to white light with the default fade. // If they are outside (have a sky ceiling), they use the outside fog. ss->Colormap.LightColor = PalEntry(255, 255, 255); @@ -1506,11 +1511,16 @@ void P_LoadSectors (MapData *map, FMissingTextureTracker &missingtex) { ss->Colormap.FadeColor.SetRGB(level.outsidefog); } + else if (level.flags & LEVEL_HASFADETABLE) + { + ss->Colormap.FadeColor= 0x939393; // The true color software renderer needs this. (The hardware renderer will ignore this value if LEVEL_HASFADETABLE is set.) + } else { ss->Colormap.FadeColor.SetRGB(level.fadeto); } + // killough 8/28/98: initialize all sectors to normal friction ss->friction = ORIG_FRICTION; ss->movefactor = ORIG_FRICTION_FACTOR; @@ -3417,6 +3427,7 @@ void P_GetPolySpots (MapData * map, TArray &spots, TAr // Preloads all relevant graphics for the level. // //=========================================================================== +void gl_PrecacheTexture(uint8_t *texhitlist, TMap &actorhitlist); static void P_PrecacheLevel() { @@ -3491,21 +3502,35 @@ static void P_PrecacheLevel() if (tex.Exists()) hitlist[tex.GetIndex()] |= FTextureManager::HIT_Wall; } - Renderer->Precache(hitlist, actorhitlist); + // This is just a temporary solution, until the hardware renderer's texture manager is in a better state. + if (!V_IsHardwareRenderer()) + SWRenderer->Precache(hitlist, actorhitlist); + else + gl_PrecacheTexture(hitlist, actorhitlist); delete[] hitlist; } extern polyblock_t **PolyBlockMap; -//=========================================================================== + +//========================================================================== // // // -//=========================================================================== +//========================================================================== void P_FreeLevelData () { + TThinkerIterator it(STAT_DLIGHT); + auto mo = it.Next(); + while (mo) + { + auto next = it.Next(); + mo->Destroy(); + mo = next; + } + // [ZZ] delete per-map event handlers E_Shutdown(true); MapThingsConverted.Clear(); @@ -3520,7 +3545,6 @@ void P_FreeLevelData () AActor::ClearTIDHashes(); interpolator.ClearInterpolations(); // [RH] Nothing to interpolate on a fresh level. - Renderer->CleanLevelData(); FPolyObj::ClearAllSubsectorLinks(); // can't be done as part of the polyobj deletion process. SN_StopAllSequences (); DThinker::DestroyAllThinkers (); @@ -3530,14 +3554,26 @@ void P_FreeLevelData () level.killed_monsters = level.found_items = level.found_secrets = wminfo.maxfrags = 0; + // delete allocated data in the level arrays. if (level.sectors.Size() > 0) { delete[] level.sectors[0].e; + if (level.sectors[0].subsectors) + { + delete[] level.sectors[0].subsectors; + level.sectors[0].subsectors = nullptr; + } } for (auto &sub : level.subsectors) { if (sub.BSP != nullptr) delete sub.BSP; } + if (level.sides.Size() > 0 && level.sides[0].segs) + { + delete[] level.sides[0].segs; + level.sides[0].segs = nullptr; + } + FBehavior::StaticUnloadModules (); level.segs.Clear(); @@ -3639,7 +3675,7 @@ void P_SetupLevel (const char *lumpname, int position) // This is motivated as follows: - bool RequireGLNodes = Renderer->RequireGLNodes() || am_textured; + bool RequireGLNodes = true; // Even the software renderer needs GL nodes now. for (i = 0; i < (int)countof(times); ++i) { @@ -3756,7 +3792,7 @@ void P_SetupLevel (const char *lumpname, int position) { level.maptype = MAPTYPE_UDMF; } - CheckCompatibility(map); + FName checksum = CheckCompatibility(map); if (ib_compatflags & BCOMPATF_REBUILDNODES) { ForceNodeBuild = true; @@ -3834,7 +3870,7 @@ void P_SetupLevel (const char *lumpname, int position) times[0].Unclock(); } - SetCompatibilityParams(); + SetCompatibilityParams(checksum); times[6].Clock(); P_LoopSidedefs (true); @@ -4097,7 +4133,10 @@ void P_SetupLevel (const char *lumpname, int position) } // This must be done BEFORE the PolyObj Spawn!!! - Renderer->PreprocessLevel(); + InitRenderInfo(); // create hardware independent renderer resources for the level. + screen->InitForLevel(); // create hardware dependent level resources (e.g. the vertex buffer) + SWRenderer->SetColormap(); //The SW renderer needs to do some special setup for the level's default colormap. + InitPortalGroups(); times[16].Clock(); if (reloop) P_LoopSidedefs (false); @@ -4294,3 +4333,48 @@ CCMD (lineloc) } #endif +//========================================================================== +// +// dumpgeometry +// +//========================================================================== + +CCMD(dumpgeometry) +{ + for (auto §or : level.sectors) + { + Printf(PRINT_LOG, "Sector %d\n", sector.sectornum); + for (int j = 0; jIndex()), sub->sector->sectornum, sub->hacked & 1 ? "hacked" : ""); + for (uint32_t k = 0; knumlines; k++) + { + seg_t * seg = sub->firstline + k; + if (seg->linedef) + { + Printf(PRINT_LOG, " (%4.4f, %4.4f), (%4.4f, %4.4f) - seg %d, linedef %d, side %d", + seg->v1->fX(), seg->v1->fY(), seg->v2->fX(), seg->v2->fY(), + seg->Index(), seg->linedef->Index(), seg->sidedef != seg->linedef->sidedef[0]); + } + else + { + Printf(PRINT_LOG, " (%4.4f, %4.4f), (%4.4f, %4.4f) - seg %d, miniseg", + seg->v1->fX(), seg->v1->fY(), seg->v2->fX(), seg->v2->fY(), seg->Index()); + } + if (seg->PartnerSeg) + { + subsector_t * sub2 = seg->PartnerSeg->Subsector; + Printf(PRINT_LOG, ", back sector = %d, real back sector = %d", sub2->render_sector->sectornum, seg->PartnerSeg->frontsector->sectornum); + } + else if (seg->backsector) + { + Printf(PRINT_LOG, ", back sector = %d (no partnerseg)", seg->backsector->sectornum); + } + + Printf(PRINT_LOG, "\n"); + } + } + } +} \ No newline at end of file diff --git a/src/p_sight.cpp b/src/p_sight.cpp index 62f9735285..2ba942c809 100644 --- a/src/p_sight.cpp +++ b/src/p_sight.cpp @@ -486,10 +486,10 @@ int SightCheck::P_SightBlockLinesIterator (int x, int y) // if any of the previous blocks may contain a portal we may abort the collection of lines here, but we may not abort the sight check. // (We still try to delay activating this for as long as possible.) - portalfound = portalfound || PortalBlockmap(x, y).containsLinkedPortals; + portalfound = portalfound || level.PortalBlockmap(x, y).containsLinkedPortals; polyLink = PolyBlockMap[offset]; - portalfound |= (polyLink && PortalBlockmap.hasLinkedPolyPortals); + portalfound |= (polyLink && level.PortalBlockmap.hasLinkedPolyPortals); while (polyLink) { if (polyLink->polyobj) diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 2d7d3ddc06..3185b6c204 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -242,6 +242,28 @@ bool P_ActivateLine (line_t *line, AActor *mo, int side, int activationType, DVe return true; } +DEFINE_ACTION_FUNCTION(_Line, Activate) +{ + PARAM_SELF_STRUCT_PROLOGUE(line_t); + PARAM_POINTER(mo, AActor); + PARAM_INT(side); + PARAM_INT(activationType); + ACTION_RETURN_BOOL(P_ActivateLine(self, mo, side, activationType, NULL)); +} + +DEFINE_ACTION_FUNCTION(_Line, RemoteActivate) +{ + PARAM_SELF_STRUCT_PROLOGUE(line_t); + PARAM_POINTER(mo, AActor); + PARAM_INT(side); + PARAM_INT(activationType); + PARAM_FLOAT(optx); + PARAM_FLOAT(opty); + PARAM_FLOAT(optz); + DVector3 optpos = DVector3(optx, opty, optz); + ACTION_RETURN_BOOL(P_ActivateLine(self, mo, side, activationType, &optpos)); +} + //============================================================================ // // P_TestActivateLine diff --git a/src/p_things.cpp b/src/p_things.cpp index 0ff35bdcc5..b8a0c5ffbe 100644 --- a/src/p_things.cpp +++ b/src/p_things.cpp @@ -917,15 +917,15 @@ int P_Thing_Warp(AActor *caller, AActor *reference, double xofs, double yofs, do if (flags & WARPF_WARPINTERPOLATION) { // This just translates the movement but doesn't change the vector - DVector3 displacedold = old + Displacements.getOffset(oldpgroup, caller->Sector->PortalGroup); + DVector3 displacedold = old + level.Displacements.getOffset(oldpgroup, caller->Sector->PortalGroup); caller->Prev += caller->Pos() - displacedold; caller->PrevPortalGroup = caller->Sector->PortalGroup; } else if (flags & WARPF_COPYINTERPOLATION) { // Map both positions of the reference actor to the current portal group - DVector3 displacedold = old + Displacements.getOffset(reference->PrevPortalGroup, caller->Sector->PortalGroup); - DVector3 displacedref = old + Displacements.getOffset(reference->Sector->PortalGroup, caller->Sector->PortalGroup); + DVector3 displacedold = old + level.Displacements.getOffset(reference->PrevPortalGroup, caller->Sector->PortalGroup); + DVector3 displacedref = old + level.Displacements.getOffset(reference->Sector->PortalGroup, caller->Sector->PortalGroup); caller->Prev = caller->Pos() + displacedold - displacedref; caller->PrevPortalGroup = caller->Sector->PortalGroup; } diff --git a/src/p_user.cpp b/src/p_user.cpp index d622827bae..6ec5b629fe 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -730,13 +730,36 @@ bool player_t::GetPainFlash(FName type, PalEntry *color) const // //=========================================================================== +EXTERN_CVAR(Float, maxviewpitch) +EXTERN_CVAR(Bool, cl_oldfreelooklimit); + + +static int GetSoftPitch(bool down) +{ + int MAX_DN_ANGLE = MIN(56, (int)maxviewpitch); // Max looking down angle + int MAX_UP_ANGLE = MIN(32, (int)maxviewpitch); // Max looking up angle + return (down ? MAX_DN_ANGLE : ((cl_oldfreelooklimit) ? MAX_UP_ANGLE : MAX_DN_ANGLE)); +} + void player_t::SendPitchLimits() const { if (this - players == consoleplayer) { + int uppitch, downpitch; + + if (V_IsSoftwareRenderer()) + { + uppitch = GetSoftPitch(false); + downpitch = GetSoftPitch(true); + } + else + { + uppitch = downpitch = (int)maxviewpitch; + } + Net_WriteByte(DEM_SETPITCHLIMIT); - Net_WriteByte(Renderer->GetMaxViewPitch(false)); // up - Net_WriteByte(Renderer->GetMaxViewPitch(true)); // down + Net_WriteByte(uppitch); + Net_WriteByte(downpitch); } } @@ -2326,7 +2349,7 @@ void P_PredictionLerpReset() bool P_LerpCalculate(AActor *pmo, PredictPos from, PredictPos to, PredictPos &result, float scale) { - //DVector2 pfrom = Displacements.getOffset(from.portalgroup, to.portalgroup); + //DVector2 pfrom = level.Displacements.getOffset(from.portalgroup, to.portalgroup); DVector3 vecFrom = from.pos; DVector3 vecTo = to.pos; DVector3 vecResult; diff --git a/src/po_man.cpp b/src/po_man.cpp index 1fa323c5e7..359b887b8a 100644 --- a/src/po_man.cpp +++ b/src/po_man.cpp @@ -906,7 +906,7 @@ void FPolyObj::UpdateLinks() { processed[destgroup] = true; DVector2 delta = port->mDisplacement - old; - Displacements.MoveGroup(destgroup, delta); + level.Displacements.MoveGroup(destgroup, delta); } } } diff --git a/src/polyrenderer/drawers/poly_triangle.cpp b/src/polyrenderer/drawers/poly_triangle.cpp index df8b2896a4..ac1c48af1b 100644 --- a/src/polyrenderer/drawers/poly_triangle.cpp +++ b/src/polyrenderer/drawers/poly_triangle.cpp @@ -47,7 +47,7 @@ void PolyTriangleDrawer::ClearBuffers(DCanvas *canvas) void PolyTriangleDrawer::SetViewport(const DrawerCommandQueuePtr &queue, int x, int y, int width, int height, DCanvas *canvas, bool span_drawers) { - uint8_t *dest = (uint8_t*)canvas->GetBuffer(); + uint8_t *dest = (uint8_t*)canvas->GetPixels(); int dest_width = canvas->GetWidth(); int dest_height = canvas->GetHeight(); int dest_pitch = canvas->GetPitch(); @@ -605,7 +605,7 @@ void DrawPolyTrianglesCommand::Execute(DrawerThread *thread) void DrawRectCommand::Execute(DrawerThread *thread) { auto renderTarget = PolyRenderer::Instance()->RenderTarget; - const void *destOrg = renderTarget->GetBuffer(); + const void *destOrg = renderTarget->GetPixels(); int destWidth = renderTarget->GetWidth(); int destHeight = renderTarget->GetHeight(); int destPitch = renderTarget->GetPitch(); diff --git a/src/polyrenderer/poly_renderer.cpp b/src/polyrenderer/poly_renderer.cpp index b01646fce2..f23b264eda 100644 --- a/src/polyrenderer/poly_renderer.cpp +++ b/src/polyrenderer/poly_renderer.cpp @@ -39,12 +39,9 @@ #include "swrenderer/viewport/r_viewport.h" #include "swrenderer/r_swcolormaps.h" -EXTERN_CVAR(Bool, r_shadercolormaps) EXTERN_CVAR(Int, screenblocks) EXTERN_CVAR(Float, r_visibility) -void InitGLRMapinfoData(); - ///////////////////////////////////////////////////////////////////////////// PolyRenderer *PolyRenderer::Instance() @@ -57,12 +54,12 @@ PolyRenderer::PolyRenderer() { } -void PolyRenderer::RenderView(player_t *player) +void PolyRenderer::RenderView(player_t *player, DCanvas *target) { using namespace swrenderer; - RenderTarget = screen; - + RenderTarget = target; + RenderToCanvas = false; int width = SCREENWIDTH; int height = SCREENHEIGHT; float trueratio; @@ -71,13 +68,6 @@ void PolyRenderer::RenderView(player_t *player) RenderActorView(player->mo, false); - // Apply special colormap if the target cannot do it - CameraLight *cameraLight = CameraLight::Instance(); - if (cameraLight->ShaderColormap() && RenderTarget->IsBgra() && !(r_shadercolormaps && screen->Accel2D)) - { - Threads.MainThread()->DrawQueue->Push(cameraLight->ShaderColormap(), screen); - } - Threads.MainThread()->FlushDrawQueue(); PolyDrawerWaitCycles.Clock(); DrawerThreads::WaitForWorkers(); @@ -90,21 +80,19 @@ void PolyRenderer::RenderViewToCanvas(AActor *actor, DCanvas *canvas, int x, int viewwidth = width; RenderTarget = canvas; + RenderToCanvas = true; R_SetWindow(Viewpoint, Viewwindow, 12, width, height, height, true); //viewport->SetViewport(&Thread, width, height, Viewwindow.WidescreenRatio); viewwindowx = x; viewwindowy = y; viewactive = true; - canvas->Lock(true); - RenderActorView(actor, dontmaplines); Threads.MainThread()->FlushDrawQueue(); DrawerThreads::WaitForWorkers(); - canvas->Unlock(); - - RenderTarget = screen; + RenderTarget = nullptr; + RenderToCanvas = false; R_ExecuteSetViewSize(Viewpoint, Viewwindow); float trueratio; ActiveRatio(width, height, &trueratio); @@ -186,7 +174,7 @@ void PolyRenderer::SetSceneViewport() { using namespace swrenderer; - if (RenderTarget == screen) // Rendering to screen + if (!RenderToCanvas) // Rendering to screen { int height; if (screenblocks >= 10) @@ -209,7 +197,6 @@ void PolyRenderer::SetupPerspectiveMatrix() if (!bDidSetup) { - InitGLRMapinfoData(); bDidSetup = true; } diff --git a/src/polyrenderer/poly_renderer.h b/src/polyrenderer/poly_renderer.h index 19ee8bd6fa..f13dd0fe36 100644 --- a/src/polyrenderer/poly_renderer.h +++ b/src/polyrenderer/poly_renderer.h @@ -49,7 +49,7 @@ class PolyRenderer public: PolyRenderer(); - void RenderView(player_t *player); + void RenderView(player_t *player, DCanvas *target); void RenderViewToCanvas(AActor *actor, DCanvas *canvas, int x, int y, int width, int height, bool dontmaplines); void RenderRemainingPlayerSprites(); @@ -61,6 +61,7 @@ public: PolyRenderThreads Threads; DCanvas *RenderTarget = nullptr; + bool RenderToCanvas = false; FViewWindow Viewwindow; FRenderViewpoint Viewpoint; PolyLightVisibility Light; diff --git a/src/polyrenderer/scene/poly_decal.cpp b/src/polyrenderer/scene/poly_decal.cpp index 9c3afd67c6..d98e6a4771 100644 --- a/src/polyrenderer/scene/poly_decal.cpp +++ b/src/polyrenderer/scene/poly_decal.cpp @@ -58,8 +58,9 @@ void RenderPolyDecal::Render(PolyRenderThread *thread, const PolyClipPlane &clip // Calculate unclipped position and UV coordinates - double edge_left = tex->LeftOffset * decal->ScaleX; - double edge_right = (tex->GetWidth() - tex->LeftOffset) * decal->ScaleX; + // decals should not use renderer specific offsets. + double edge_left = tex->GetLeftOffset(0) * decal->ScaleX; + double edge_right = (tex->GetWidth() - tex->GetLeftOffset(0)) * decal->ScaleX; DVector2 angvec = (line->v2->fPos() - line->v1->fPos()).Unit(); DVector2 normal = { angvec.Y, -angvec.X }; diff --git a/src/polyrenderer/scene/poly_playersprite.cpp b/src/polyrenderer/scene/poly_playersprite.cpp index d5064400dd..cf0f808a76 100644 --- a/src/polyrenderer/scene/poly_playersprite.cpp +++ b/src/polyrenderer/scene/poly_playersprite.cpp @@ -34,7 +34,6 @@ EXTERN_CVAR(Bool, r_drawplayersprites) EXTERN_CVAR(Bool, r_deathcamera) EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor) -EXTERN_CVAR(Bool, r_shadercolormaps) void RenderPolyPlayerSprites::Render(PolyRenderThread *thread) { @@ -180,7 +179,8 @@ void RenderPolyPlayerSprites::RenderRemainingSprites() DTA_FillColor, sprite.FillColor, DTA_SpecialColormap, sprite.special, DTA_ColorOverlay, sprite.overlay.d, - DTA_ColormapStyle, sprite.usecolormapstyle ? &sprite.colormapstyle : nullptr, + DTA_Color, sprite.LightColor | 0xff000000, // the color here does not have a valid alpha component. + DTA_Desaturate, sprite.Desaturate, TAG_DONE); } @@ -218,6 +218,9 @@ void RenderPolyPlayerSprites::RenderSprite(PolyRenderThread *thread, DPSprite *p const auto &viewwindow = PolyRenderer::Instance()->Viewwindow; DCanvas *renderTarget = PolyRenderer::Instance()->RenderTarget; + // Force it to use software rendering when drawing to a canvas texture. + bool renderToCanvas = PolyRenderer::Instance()->RenderToCanvas; + sprframe = &SpriteFrames[sprdef->spriteframes + pspr->GetFrame()]; picnum = sprframe->Texture[0]; @@ -261,7 +264,7 @@ void RenderPolyPlayerSprites::RenderSprite(PolyRenderThread *thread, DPSprite *p double pspriteyscale = pspritexscale * yaspectMul; double pspritexiscale = 1 / pspritexscale; - int tleft = tex->GetScaledLeftOffset(); + int tleft = tex->GetScaledLeftOffsetPo(); int twidth = tex->GetScaledWidth(); // calculate edges of the shape @@ -286,16 +289,16 @@ void RenderPolyPlayerSprites::RenderSprite(PolyRenderThread *thread, DPSprite *p vis.renderflags = owner->renderflags; - vis.texturemid = (BASEYCENTER - sy) * tex->Scale.Y + tex->TopOffset; + vis.texturemid = (BASEYCENTER - sy) * tex->Scale.Y + tex->GetTopOffsetPo(); - if (viewpoint.camera->player && (renderTarget != screen || + if (viewpoint.camera->player && (renderToCanvas || viewheight == renderTarget->GetHeight() || (renderTarget->GetWidth() > (BASEXCENTER * 2)))) { // Adjust PSprite for fullscreen views AWeapon *weapon = dyn_cast(pspr->GetCaller()); if (weapon != nullptr && weapon->YAdjust != 0) { - if (renderTarget != screen || viewheight == renderTarget->GetHeight()) + if (renderToCanvas || viewheight == renderTarget->GetHeight()) { vis.texturemid -= weapon->YAdjust; } @@ -385,13 +388,6 @@ void RenderPolyPlayerSprites::RenderSprite(PolyRenderThread *thread, DPSprite *p noaccel = true; } } - // If we're drawing with a special colormap, but shaders for them are disabled, do - // not accelerate. - if (!r_shadercolormaps && (vis.Light.BaseColormap >= &SpecialSWColormaps[0] && - vis.Light.BaseColormap <= &SpecialSWColormaps.Last())) - { - noaccel = true; - } // If drawing with a BOOM colormap, disable acceleration. if (vis.Light.BaseColormap == &NormalLight && NormalLight.Maps != realcolormaps.Maps) { @@ -417,7 +413,7 @@ void RenderPolyPlayerSprites::RenderSprite(PolyRenderThread *thread, DPSprite *p // Check for hardware-assisted 2D. If it's available, and this sprite is not // fuzzy, don't draw it until after the switch to 2D mode. - if (!noaccel && renderTarget == screen && (DFrameBuffer *)screen->Accel2D) + if (!noaccel && !renderToCanvas) { FRenderStyle style = vis.RenderStyle; style.CheckFuzz(); @@ -448,19 +444,12 @@ void RenderPolyPlayerSprites::RenderSprite(PolyRenderThread *thread, DPSprite *p { accelSprite.special = PolyCameraLight::Instance()->ShaderColormap(); } - else if (colormap_to_use->Color == PalEntry(255, 255, 255) && - colormap_to_use->Desaturate == 0) + else { accelSprite.overlay = colormap_to_use->Fade; accelSprite.overlay.a = uint8_t(vis.Light.ColormapNum * 255 / NUMCOLORMAPS); - } - else - { - accelSprite.usecolormapstyle = true; - accelSprite.colormapstyle.Color = colormap_to_use->Color; - accelSprite.colormapstyle.Fade = colormap_to_use->Fade; - accelSprite.colormapstyle.Desaturate = colormap_to_use->Desaturate; - accelSprite.colormapstyle.FadeLevel = vis.Light.ColormapNum / float(NUMCOLORMAPS); + accelSprite.LightColor = colormap_to_use->Color; + accelSprite.Desaturate = (uint8_t)clamp(colormap_to_use->Desaturate, 0, 255); } AcceleratedSprites.Push(accelSprite); @@ -512,7 +501,7 @@ void PolyNoAccelPlayerSprite::Render(PolyRenderThread *thread) y1 = centerY - texturemid * yscale; y2 = y1 + pic->GetHeight() * yscale; } - args.Draw(thread, x1, x2, y1, y2, 0.0f, 1.0f, 0.0f, 1.0f); + args.Draw(thread, viewwindowx + x1, viewwindowx + x2, viewwindowy + y1, viewwindowy + y2, 0.0f, 1.0f, 0.0f, 1.0f); } ///////////////////////////////////////////////////////////////////////////// diff --git a/src/polyrenderer/scene/poly_playersprite.h b/src/polyrenderer/scene/poly_playersprite.h index 8e3e9aa7a1..010c1c7bed 100644 --- a/src/polyrenderer/scene/poly_playersprite.h +++ b/src/polyrenderer/scene/poly_playersprite.h @@ -83,8 +83,8 @@ public: bool flip = false; FSpecialColormap *special = nullptr; PalEntry overlay = 0; - FColormapStyle colormapstyle; - bool usecolormapstyle = false; + PalEntry LightColor = 0xffffffff; + uint8_t Desaturate = 0; }; class RenderPolyPlayerSprites diff --git a/src/polyrenderer/scene/poly_sprite.cpp b/src/polyrenderer/scene/poly_sprite.cpp index d3310e614b..65e50ea33d 100644 --- a/src/polyrenderer/scene/poly_sprite.cpp +++ b/src/polyrenderer/scene/poly_sprite.cpp @@ -63,9 +63,9 @@ bool RenderPolySprite::GetLine(AActor *thing, DVector2 &left, DVector2 &right) double offsetX; if (flipTextureX) - offsetX = (tex->GetWidth() - tex->LeftOffset) * thingxscalemul; + offsetX = (tex->GetWidth() - tex->GetLeftOffsetPo()) * thingxscalemul; else - offsetX = tex->LeftOffset * thingxscalemul; + offsetX = tex->GetLeftOffsetPo() * thingxscalemul; left = DVector2(pos.X - viewpoint.Sin * offsetX, pos.Y + viewpoint.Cos * offsetX); right = DVector2(left.X + viewpoint.Sin * spriteWidth, left.Y - viewpoint.Cos * spriteWidth); @@ -110,7 +110,7 @@ void RenderPolySprite::Render(PolyRenderThread *thread, const PolyClipPlane &cli double thingyscalemul = thing->Scale.Y / tex->Scale.Y; double spriteHeight = thingyscalemul * tex->GetHeight(); - posZ -= (tex->GetHeight() - tex->TopOffset) * thingyscalemul; + posZ -= (tex->GetHeight() - tex->GetTopOffsetPo()) * thingyscalemul; posZ = PerformSpriteClipAdjustment(thing, thingpos, spriteHeight, posZ); //double depth = 1.0; diff --git a/src/polyrenderer/scene/poly_wallsprite.cpp b/src/polyrenderer/scene/poly_wallsprite.cpp index 6c793313ed..f46ce331a8 100644 --- a/src/polyrenderer/scene/poly_wallsprite.cpp +++ b/src/polyrenderer/scene/poly_wallsprite.cpp @@ -56,7 +56,7 @@ void RenderPolyWallSprite::Render(PolyRenderThread *thread, const PolyClipPlane // Determine left and right edges of sprite. The sprite's angle is its normal, // so the edges are 90 degrees each side of it. double x2 = tex->GetScaledWidth() * spriteScale.X; - double x1 = tex->GetScaledLeftOffset() * spriteScale.X; + double x1 = tex->GetScaledLeftOffsetPo() * spriteScale.X; DVector2 left, right; left.X = pos.X - x1 * angcos; left.Y = pos.Y - x1 * angsin; diff --git a/src/portal.cpp b/src/portal.cpp index 9978d32841..2268f8e8e7 100644 --- a/src/portal.cpp +++ b/src/portal.cpp @@ -57,13 +57,6 @@ // simulation recurions maximum CVAR(Int, sv_portal_recursions, 4, CVAR_ARCHIVE|CVAR_SERVERINFO) -FDisplacementTable Displacements; -FPortalBlockmap PortalBlockmap; - -TArray linePortals; -TArray linkedPortals; // only the linked portals, this is used to speed up looking for them in P_CollectConnectedGroups. - - DEFINE_FIELD(FSectorPortal, mType); DEFINE_FIELD(FSectorPortal, mFlags); DEFINE_FIELD(FSectorPortal, mPartner); @@ -117,14 +110,14 @@ static void BuildBlockmap() auto bmapwidth = level.blockmap.bmapwidth; auto bmapheight = level.blockmap.bmapheight; - PortalBlockmap.Clear(); - PortalBlockmap.Create(bmapwidth, bmapheight); + level.PortalBlockmap.Clear(); + level.PortalBlockmap.Create(bmapwidth, bmapheight); for (int y = 0; y < bmapheight; y++) { for (int x = 0; x < bmapwidth; x++) { int *list = level.blockmap.GetLines(x, y); - FPortalBlock &block = PortalBlockmap(x, y); + FPortalBlock &block = level.PortalBlockmap(x, y); while (*list != -1) { @@ -132,14 +125,14 @@ static void BuildBlockmap() FLinePortal *port = ld->getPortal(); if (port && port->mType != PORTT_VISUAL) { - PortalBlockmap.containsLines = true; + level.PortalBlockmap.containsLines = true; block.portallines.Push(ld); block.neighborContainsLines = true; if (ld->getPortal()->mType == PORTT_LINKED) block.containsLinkedPortals = true; - if (x > 0) PortalBlockmap(x - 1, y).neighborContainsLines = true; - if (y > 0) PortalBlockmap(x, y - 1).neighborContainsLines = true; - if (x < PortalBlockmap.dx - 1) PortalBlockmap(x + 1, y).neighborContainsLines = true; - if (y < PortalBlockmap.dy - 1) PortalBlockmap(x, y + 1).neighborContainsLines = true; + if (x > 0) level.PortalBlockmap(x - 1, y).neighborContainsLines = true; + if (y > 0) level.PortalBlockmap(x, y - 1).neighborContainsLines = true; + if (x < level.PortalBlockmap.dx - 1) level.PortalBlockmap(x + 1, y).neighborContainsLines = true; + if (y < level.PortalBlockmap.dy - 1) level.PortalBlockmap(x, y + 1).neighborContainsLines = true; } else { @@ -150,7 +143,7 @@ static void BuildBlockmap() yes |= ld->backsector->PortalIsLinked(sector_t::ceiling) || ld->backsector->PortalIsLinked(sector_t::floor); } block.containsLinkedPortals |= yes; - PortalBlockmap.hasLinkedSectorPortals |= yes; + level.PortalBlockmap.hasLinkedSectorPortals |= yes; } } @@ -168,9 +161,9 @@ static void BuildBlockmap() void FLinePortalTraverse::AddLineIntercepts(int bx, int by) { - if (by < 0 || by >= PortalBlockmap.dy || bx < 0 || bx >= PortalBlockmap.dx) return; + if (by < 0 || by >= level.PortalBlockmap.dy || bx < 0 || bx >= level.PortalBlockmap.dx) return; - FPortalBlock &block = PortalBlockmap(bx, by); + FPortalBlock &block = level.PortalBlockmap(bx, by); for (unsigned i = 0; iargs[0]); - line->portalindex = linePortals.Reserve(1); - FLinePortal *port = &linePortals.Last(); + line->portalindex = level.linePortals.Reserve(1); + FLinePortal *port = &level.linePortals.Last(); memset(port, 0, sizeof(FLinePortal)); port->mOrigin = line; @@ -321,8 +314,8 @@ void P_SpawnLinePortal(line_t* line) { if (tagManager.GetFirstLineID(&ln) == mytag && ln.args[0] == 1 && ln.special == Line_SetPortal) { - line->portalindex = linePortals.Reserve(1); - FLinePortal *port = &linePortals.Last(); + line->portalindex = level.linePortals.Reserve(1); + FLinePortal *port = &level.linePortals.Last(); memset(port, 0, sizeof(FLinePortal)); port->mOrigin = line; @@ -332,8 +325,8 @@ void P_SpawnLinePortal(line_t* line) port->mDefFlags = PORTF_TYPEINTERACTIVE; // we need to create the backlink here, too. - ln.portalindex = linePortals.Reserve(1); - port = &linePortals.Last(); + ln.portalindex = level.linePortals.Reserve(1); + port = &level.linePortals.Last(); memset(port, 0, sizeof(FLinePortal)); port->mOrigin = &ln; @@ -388,7 +381,7 @@ void P_UpdatePortal(FLinePortal *port) port->mFlags = port->mDefFlags; if (port->mType == PORTT_LINKED) { - if (linePortals[port->mDestination->portalindex].mType != PORTT_LINKED) + if (level.linePortals[port->mDestination->portalindex].mType != PORTT_LINKED) { port->mType = PORTT_INTERACTIVE; // linked portals must be two-way. } @@ -412,13 +405,13 @@ void P_UpdatePortal(FLinePortal *port) void P_CollectLinkedPortals() { - linkedPortals.Clear(); - for (unsigned i = 0; i < linePortals.Size(); i++) + level.linkedPortals.Clear(); + for (unsigned i = 0; i < level.linePortals.Size(); i++) { - FLinePortal * port = &linePortals[i]; + FLinePortal * port = &level.linePortals[i]; if (port->mType == PORTT_LINKED) { - linkedPortals.Push(port); + level.linkedPortals.Push(port); } } } @@ -431,9 +424,9 @@ void P_CollectLinkedPortals() void P_FinalizePortals() { - for (unsigned i = 0; i < linePortals.Size(); i++) + for (unsigned i = 0; i < level.linePortals.Size(); i++) { - FLinePortal * port = &linePortals[i]; + FLinePortal * port = &level.linePortals[i]; P_UpdatePortal(port); } P_CollectLinkedPortals(); @@ -449,8 +442,8 @@ void P_FinalizePortals() static bool ChangePortalLine(line_t *line, int destid) { - if (line->portalindex >= linePortals.Size()) return false; - FLinePortal *port = &linePortals[line->portalindex]; + if (line->portalindex >= level.linePortals.Size()) return false; + FLinePortal *port = &level.linePortals[line->portalindex]; if (port->mType == PORTT_LINKED) return false; // linked portals cannot be changed. if (destid == 0) port->mDestination = nullptr; port->mDestination = FindDestination(line, destid); @@ -460,7 +453,7 @@ static bool ChangePortalLine(line_t *line, int destid) } else if (port->mType == PORTT_INTERACTIVE) { - FLinePortal *portd = port->mDestination->portalindex < linePortals.Size()? &linePortals[port->mDestination->portalindex] : nullptr; + FLinePortal *portd = port->mDestination->portalindex < level.linePortals.Size()? &level.linePortals[port->mDestination->portalindex] : nullptr; if (portd != nullptr && portd->mType == PORTT_INTERACTIVE && portd->mDestination == line) { // this is a 2-way interactive portal @@ -510,10 +503,12 @@ bool P_ChangePortal(line_t *ln, int thisid, int destid) void P_ClearPortals() { - Displacements.Create(1); - linePortals.Clear(); - linkedPortals.Clear(); + level.Displacements.Create(1); + level.linePortals.Clear(); + level.linkedPortals.Clear(); level.sectorPortals.Resize(2); + level.PortalBlockmap.Clear(); + // The first entry must always be the default skybox. This is what every sector gets by default. memset(&level.sectorPortals[0], 0, sizeof(level.sectorPortals[0])); level.sectorPortals[0].mType = PORTS_SKYVIEWPOINT; @@ -522,6 +517,25 @@ void P_ClearPortals() memset(&level.sectorPortals[1], 0, sizeof(level.sectorPortals[0])); level.sectorPortals[1].mType = PORTS_SKYVIEWPOINT; level.sectorPortals[1].mFlags = PORTSF_SKYFLATONLY; + + // also clear the render data + for (auto &sub : level.subsectors) + { + for (int j = 0; j<2; j++) + { + if (sub.portalcoverage[j].subsectors != nullptr) + { + delete[] sub.portalcoverage[j].subsectors; + sub.portalcoverage[j].subsectors = nullptr; + } + } + } + for (unsigned i = 0; i= PortalBlockmap.dx || blocky >= PortalBlockmap.dy || !PortalBlockmap(blockx, blocky).neighborContainsLines) return dest; + if (blockx < 0 || blocky < 0 || blockx >= level.PortalBlockmap.dx || blocky >= level.PortalBlockmap.dy || !level.PortalBlockmap(blockx, blocky).neighborContainsLines) return dest; } bool repeat; @@ -867,14 +881,14 @@ static void AddDisplacementForPortal(FSectorPortal *portal) portal->mType = PORTS_PORTAL; return; } - if (thisgroup <= 0 || thisgroup >= Displacements.size || othergroup <= 0 || othergroup >= Displacements.size) + if (thisgroup <= 0 || thisgroup >= level.Displacements.size || othergroup <= 0 || othergroup >= level.Displacements.size) { Printf("Portal between sectors %d and %d has invalid group and will be disabled\n", portal->mOrigin->sectornum, portal->mDestination->sectornum); portal->mType = PORTS_PORTAL; return; } - FDisplacement & disp = Displacements(thisgroup, othergroup); + FDisplacement & disp = level.Displacements(thisgroup, othergroup); if (!disp.isSet) { disp.pos = portal->mDisplacement; @@ -899,17 +913,17 @@ static void AddDisplacementForPortal(FLinePortal *portal) if (thisgroup == othergroup) { Printf("Portal between lines %d and %d has both sides in same group\n", portal->mOrigin->Index(), portal->mDestination->Index()); - portal->mType = linePortals[portal->mDestination->portalindex].mType = PORTT_TELEPORT; + portal->mType = level.linePortals[portal->mDestination->portalindex].mType = PORTT_TELEPORT; return; } - if (thisgroup <= 0 || thisgroup >= Displacements.size || othergroup <= 0 || othergroup >= Displacements.size) + if (thisgroup <= 0 || thisgroup >= level.Displacements.size || othergroup <= 0 || othergroup >= level.Displacements.size) { Printf("Portal between lines %d and %d has invalid group\n", portal->mOrigin->Index(), portal->mDestination->Index()); - portal->mType = linePortals[portal->mDestination->portalindex].mType = PORTT_TELEPORT; + portal->mType = level.linePortals[portal->mDestination->portalindex].mType = PORTT_TELEPORT; return; } - FDisplacement & disp = Displacements(thisgroup, othergroup); + FDisplacement & disp = level.Displacements(thisgroup, othergroup); if (!disp.isSet) { disp.pos = portal->mDisplacement; @@ -920,7 +934,7 @@ static void AddDisplacementForPortal(FLinePortal *portal) if (disp.pos != portal->mDisplacement) { Printf("Portal between lines %d and %d has displacement mismatch\n", portal->mOrigin->Index(), portal->mDestination->Index()); - portal->mType = linePortals[portal->mDestination->portalindex].mType = PORTT_TELEPORT; + portal->mType = level.linePortals[portal->mDestination->portalindex].mType = PORTT_TELEPORT; return; } } @@ -943,19 +957,19 @@ static bool ConnectGroups() do { changed = false; - for (int x = 1; x < Displacements.size; x++) + for (int x = 1; x < level.Displacements.size; x++) { - for (int y = 1; y < Displacements.size; y++) + for (int y = 1; y < level.Displacements.size; y++) { - FDisplacement &dispxy = Displacements(x, y); + FDisplacement &dispxy = level.Displacements(x, y); if (dispxy.isSet) { - for (int z = 1; z < Displacements.size; z++) + for (int z = 1; z < level.Displacements.size; z++) { - FDisplacement &dispyz = Displacements(y, z); + FDisplacement &dispyz = level.Displacements(y, z); if (dispyz.isSet) { - FDisplacement &dispxz = Displacements(x, z); + FDisplacement &dispxz = level.Displacements(x, z); if (dispxz.isSet) { if (dispxy.pos.X + dispyz.pos.X != dispxz.pos.X || dispxy.pos.Y + dispyz.pos.Y != dispxz.pos.Y) @@ -1034,25 +1048,25 @@ void P_CreateLinkedPortals() if (CollectSectors(id, orgs[i]->mDestination)) id++; } } - for (unsigned i = 0; i < linePortals.Size(); i++) + for (unsigned i = 0; i < level.linePortals.Size(); i++) { - if (linePortals[i].mType == PORTT_LINKED) + if (level.linePortals[i].mType == PORTT_LINKED) { - if (linePortals[i].mDestination == nullptr) + if (level.linePortals[i].mDestination == nullptr) { - Printf("Linked portal on line %d is unconnected and will be disabled\n", linePortals[i].mOrigin->Index()); - linePortals[i].mOrigin->portalindex = UINT_MAX; - linePortals[i].mType = PORTT_VISUAL; + Printf("Linked portal on line %d is unconnected and will be disabled\n", level.linePortals[i].mOrigin->Index()); + level.linePortals[i].mOrigin->portalindex = UINT_MAX; + level.linePortals[i].mType = PORTT_VISUAL; } else { - if (CollectSectors(id, linePortals[i].mOrigin->frontsector)) id++; - if (CollectSectors(id, linePortals[i].mDestination->frontsector)) id++; + if (CollectSectors(id, level.linePortals[i].mOrigin->frontsector)) id++; + if (CollectSectors(id, level.linePortals[i].mDestination->frontsector)) id++; } } } - Displacements.Create(id); + level.Displacements.Create(id); // Check for leftover sectors that connect to a portal for (auto &sec : level.sectors) { @@ -1069,20 +1083,20 @@ void P_CreateLinkedPortals() { AddDisplacementForPortal(orgs[i]); } - for (unsigned i = 0; i < linePortals.Size(); i++) + for (unsigned i = 0; i < level.linePortals.Size(); i++) { - if (linePortals[i].mType == PORTT_LINKED) + if (level.linePortals[i].mType == PORTT_LINKED) { - AddDisplacementForPortal(&linePortals[i]); + AddDisplacementForPortal(&level.linePortals[i]); } } - for (int x = 1; x < Displacements.size; x++) + for (int x = 1; x < level.Displacements.size; x++) { - for (int y = x + 1; y < Displacements.size; y++) + for (int y = x + 1; y < level.Displacements.size; y++) { - FDisplacement &dispxy = Displacements(x, y); - FDisplacement &dispyx = Displacements(y, x); + FDisplacement &dispxy = level.Displacements(x, y); + FDisplacement &dispyx = level.Displacements(y, x); if (dispxy.isSet && dispyx.isSet && (dispxy.pos.X != -dispyx.pos.X || dispxy.pos.Y != -dispyx.pos.Y)) { @@ -1121,7 +1135,7 @@ void P_CreateLinkedPortals() } // reject would just get in the way when checking sight through portals. - if (Displacements.size > 1) + if (level.Displacements.size > 1) { level.rejectmatrix.Reset(); } @@ -1162,7 +1176,7 @@ void P_CreateLinkedPortals() if (sec.PortalIsLinked(sector_t::floor)) sec.planes[sector_t::floor].Flags |= PLANEF_LINKED; if (sec.PortalIsLinked(sector_t::ceiling)) sec.planes[sector_t::ceiling].Flags |= PLANEF_LINKED; } - if (linkedPortals.Size() > 0) + if (level.linkedPortals.Size() > 0) { // We need to relink all actors that may touch a linked line portal TThinkerIterator it; @@ -1203,14 +1217,14 @@ bool P_CollectConnectedGroups(int startgroup, const DVector3 &position, double u bool retval = false; out.inited = true; - processMask.setSize(Displacements.size); - if (Displacements.size == 1) + processMask.setSize(level.Displacements.size); + if (level.Displacements.size == 1) { processMask.setBit(startgroup); return false; } - if (linkedPortals.Size() != 0) + if (level.linkedPortals.Size() != 0) { processMask.clear(); foundPortals.Clear(); @@ -1219,17 +1233,17 @@ bool P_CollectConnectedGroups(int startgroup, const DVector3 &position, double u processMask.setBit(thisgroup); //out.Add(thisgroup); - for (unsigned i = 0; i < linkedPortals.Size(); i++) + for (unsigned i = 0; i < level.linkedPortals.Size(); i++) { - line_t *ld = linkedPortals[i]->mOrigin; + line_t *ld = level.linkedPortals[i]->mOrigin; int othergroup = ld->frontsector->PortalGroup; - FDisplacement &disp = Displacements(thisgroup, othergroup); + FDisplacement &disp = level.Displacements(thisgroup, othergroup); if (!disp.isSet) continue; // no connection. FBoundingBox box(position.X + disp.pos.X, position.Y + disp.pos.Y, checkradius); - if (!box.inRange(ld) || box.BoxOnLineSide(linkedPortals[i]->mOrigin) != -1) continue; // not touched - foundPortals.Push(linkedPortals[i]); + if (!box.inRange(ld) || box.BoxOnLineSide(level.linkedPortals[i]->mOrigin) != -1) continue; // not touched + foundPortals.Push(level.linkedPortals[i]); } bool foundone = true; while (foundone) @@ -1256,7 +1270,7 @@ bool P_CollectConnectedGroups(int startgroup, const DVector3 &position, double u while (!wsec->PortalBlocksMovement(sector_t::ceiling) && upperz > wsec->GetPortalPlaneZ(sector_t::ceiling)) { int othergroup = wsec->GetOppositePortalGroup(sector_t::ceiling); - DVector2 pos = Displacements.getOffset(startgroup, othergroup) + position; + DVector2 pos = level.Displacements.getOffset(startgroup, othergroup) + position; if (processMask.getBit(othergroup)) break; processMask.setBit(othergroup); out.Add(othergroup | FPortalGroupArray::UPPER); @@ -1267,21 +1281,21 @@ bool P_CollectConnectedGroups(int startgroup, const DVector3 &position, double u while (!wsec->PortalBlocksMovement(sector_t::floor) && position.Z < wsec->GetPortalPlaneZ(sector_t::floor)) { int othergroup = wsec->GetOppositePortalGroup(sector_t::floor); - DVector2 pos = Displacements.getOffset(startgroup, othergroup) + position; + DVector2 pos = level.Displacements.getOffset(startgroup, othergroup) + position; if (processMask.getBit(othergroup)) break; processMask.setBit(othergroup); out.Add(othergroup | FPortalGroupArray::LOWER); wsec = P_PointInSector(pos); // get lower sector at the exact spot we want to check and repeat retval = true; } - if (out.method == FPortalGroupArray::PGA_Full3d && PortalBlockmap.hasLinkedSectorPortals) + if (out.method == FPortalGroupArray::PGA_Full3d && level.PortalBlockmap.hasLinkedSectorPortals) { groupsToCheck.Clear(); groupsToCheck.Push(startgroup); int thisgroup = startgroup; for (unsigned i = 0; i < groupsToCheck.Size();i++) { - DVector2 disp = Displacements.getOffset(startgroup, thisgroup & ~FPortalGroupArray::FLAT); + DVector2 disp = level.Displacements.getOffset(startgroup, thisgroup & ~FPortalGroupArray::FLAT); FBoundingBox box(position.X + disp.X, position.Y + disp.Y, checkradius); FBlockLinesIterator it(box); line_t *ld; @@ -1344,11 +1358,11 @@ bool P_CollectConnectedGroups(int startgroup, const DVector3 &position, double u CCMD(dumplinktable) { - for (int x = 1; x < Displacements.size; x++) + for (int x = 1; x < level.Displacements.size; x++) { - for (int y = 1; y < Displacements.size; y++) + for (int y = 1; y < level.Displacements.size; y++) { - FDisplacement &disp = Displacements(x, y); + FDisplacement &disp = level.Displacements(x, y); Printf("%c%c(%6d, %6d)", TEXTCOLOR_ESCAPE, 'C' + disp.indirect, int(disp.pos.X), int(disp.pos.Y)); } Printf("\n"); diff --git a/src/portal.h b/src/portal.h index d8eda7a1e1..f194c3886e 100644 --- a/src/portal.h +++ b/src/portal.h @@ -75,8 +75,6 @@ struct FDisplacementTable } }; -extern FDisplacementTable Displacements; - //============================================================================ // @@ -129,8 +127,6 @@ struct FPortalBlockmap } }; -extern FPortalBlockmap PortalBlockmap; - //============================================================================ // @@ -177,6 +173,8 @@ enum // All information about a line-to-line portal (all types) // //============================================================================ +struct FLinePortalSpan; +struct vertex_t; struct FLinePortal { @@ -191,9 +189,17 @@ struct FLinePortal double mSinRot; double mCosRot; portnode_t *lineportal_thinglist; + FLinePortalSpan *mGroup; +}; + +struct FLinePortalSpan +{ + // defines the complete span of connected colinear line portals, if they are of type PORTT_LINKED. + vertex_t *v1 = nullptr, *v2 = nullptr; // vertices, from v1 to v2 + TArray lines; + int validcount = 0; }; -extern TArray linePortals; //============================================================================ // @@ -236,6 +242,24 @@ struct FSectorPortal } }; +//============================================================================ +// +// This groups all sector portals with identical offset. +// +//============================================================================ + +struct GLSectorStackPortal; +struct FSectorPortalGroup +{ + DVector2 mDisplacement; + int plane; + GLSectorStackPortal *glportal; // for quick access to the render data. This is only valid during BSP traversal! + + GLSectorStackPortal *GetRenderState(); +}; + + + //============================================================================ // // Functions @@ -249,10 +273,6 @@ bool P_ChangePortal(line_t *ln, int thisid, int destid); void P_CreateLinkedPortals(); bool P_CollectConnectedGroups(int startgroup, const DVector3 &position, double upperz, double checkradius, FPortalGroupArray &out); void P_CollectLinkedPortals(); -inline int P_NumPortalGroups() -{ - return Displacements.size; -} unsigned P_GetSkyboxPortal(AActor *actor); unsigned P_GetPortal(int type, int plane, sector_t *orgsec, sector_t *destsec, const DVector2 &displacement); unsigned P_GetStackPortal(AActor *point, int plane); @@ -265,6 +285,7 @@ void P_TranslatePortalVXVY(line_t* src, double &velx, double &vely); void P_TranslatePortalAngle(line_t* src, DAngle& angle); void P_TranslatePortalZ(line_t* src, double& vz); DVector2 P_GetOffsetPosition(double x, double y, double dx, double dy); +void InitPortalGroups(); #endif \ No newline at end of file diff --git a/src/posix/cocoa/sdlglvideo.h b/src/posix/cocoa/gl_sysfb.h similarity index 75% rename from src/posix/cocoa/sdlglvideo.h rename to src/posix/cocoa/gl_sysfb.h index 55e08c5839..b88570b641 100644 --- a/src/posix/cocoa/sdlglvideo.h +++ b/src/posix/cocoa/gl_sysfb.h @@ -1,8 +1,8 @@ /* - ** sdlglvideo.h + ** gl_sysfb.h ** **--------------------------------------------------------------------------- - ** Copyright 2012-2014 Alexey Lysiuk + ** Copyright 2012-2018 Alexey Lysiuk ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without @@ -31,33 +31,17 @@ ** */ - -// IMPORTANT NOTE! -// This file was intentially named sdlglvideo.h but it has nothing with SDL -// The name was selected to avoid spreding of changes over the project -// The same applies to SDLGLFB class -// See gl/system/gl_framebuffer.h for details about its usage - - -#ifndef COCOA_SDLGLVIDEO_H_INCLUDED -#define COCOA_SDLGLVIDEO_H_INCLUDED +#ifndef COCOA_GL_SYSFB_H_INCLUDED +#define COCOA_GL_SYSFB_H_INCLUDED #include "v_video.h" -#include "gl/shaders/gl_shader.h" -#include "gl/textures/gl_hwtexture.h" - - -class SDLGLFB : public DFrameBuffer +class SystemFrameBuffer : public DFrameBuffer { public: // This must have the same parameters as the Windows version, even if they are not used! - SDLGLFB(void *hMonitor, int width, int height, int, int, bool fullscreen, bool bgra); - ~SDLGLFB(); - - virtual bool Lock(bool buffered = true); - virtual void Unlock(); - virtual bool IsLocked(); + SystemFrameBuffer(void *hMonitor, int width, int height, int, int, bool fullscreen, bool bgra); + ~SystemFrameBuffer(); virtual bool IsFullscreen(); virtual void SetVSync(bool vsync); @@ -66,8 +50,8 @@ public: int GetClientHeight(); virtual int GetTrueHeight() { return GetClientHeight(); } + protected: - int m_Lock; bool UpdatePending; static const uint32_t GAMMA_CHANNEL_SIZE = 256; @@ -77,7 +61,7 @@ protected: bool m_supportsGamma; uint16_t m_originalGamma[GAMMA_TABLE_SIZE]; - SDLGLFB(); + SystemFrameBuffer(); void InitializeState(); @@ -88,4 +72,4 @@ protected: void ResetGammaTable(); }; -#endif // COCOA_SDLGLVIDEO_H_INCLUDED +#endif // COCOA_GL_SYSFB_H_INCLUDED diff --git a/src/posix/cocoa/i_video.mm b/src/posix/cocoa/i_video.mm index caf5292e4c..0c37453df0 100644 --- a/src/posix/cocoa/i_video.mm +++ b/src/posix/cocoa/i_video.mm @@ -31,7 +31,7 @@ ** */ -#include "gl/system/gl_load.h" +#include "gl_load/gl_load.h" #include "i_common.h" @@ -102,31 +102,10 @@ DFrameBuffer *CreateGLSWFrameBuffer(int width, int height, bool bgra, bool fullscreen); -int currentrenderer; - -CUSTOM_CVAR(Bool, vid_glswfb, true, CVAR_NOINITCALL | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) -{ - Printf("This won't take effect until " GAMENAME " is restarted.\n"); -} - EXTERN_CVAR(Bool, ticker ) EXTERN_CVAR(Bool, vid_vsync) EXTERN_CVAR(Bool, vid_hidpi) -CUSTOM_CVAR(Bool, swtruecolor, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) -{ - // Strictly speaking this doesn't require a mode switch, but it is the easiest - // way to force a CreateFramebuffer call without a lot of refactoring. - if (currentrenderer == 0) - { - extern int NewWidth, NewHeight, NewBits, DisplayBits; - NewWidth = screen->VideoWidth; - NewHeight = screen->VideoHeight; - NewBits = DisplayBits; - setmodeneeded = true; - } -} - CUSTOM_CVAR(Bool, fullscreen, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) { extern int NewWidth, NewHeight, NewBits, DisplayBits; @@ -142,31 +121,6 @@ CUSTOM_CVAR(Bool, vid_autoswitch, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_ Printf("You must restart " GAMENAME " to apply graphics switching mode\n"); } -CUSTOM_CVAR(Int, vid_renderer, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) -{ - // 0: Software renderer - // 1: OpenGL renderer - - if (self != currentrenderer) - { - switch (self) - { - case 0: - Printf("Switching to software renderer...\n"); - break; - case 1: - Printf("Switching to OpenGL renderer...\n"); - break; - default: - Printf("Unknown renderer (%d). Falling back to software renderer...\n", - static_cast(vid_renderer)); - self = 0; - break; - } - - Printf("You must restart " GAMENAME " to switch the renderer\n"); - } -} EXTERN_CVAR(Bool, gl_smooth_rendered) @@ -303,11 +257,12 @@ private: int m_width; int m_height; bool m_fullscreen; + bool m_bgra; bool m_hiDPI; void SetFullscreenMode(int width, int height); void SetWindowedMode(int width, int height); - void SetMode(int width, int height, bool fullscreen, bool hiDPI); + void SetMode(int width, int height, bool fullscreen, bool bgra, bool hiDPI); static CocoaVideo* GetInstance(); }; @@ -316,57 +271,6 @@ private: // --------------------------------------------------------------------------- -class CocoaFrameBuffer : public DFrameBuffer -{ -public: - CocoaFrameBuffer(int width, int height, bool bgra, bool fullscreen); - ~CocoaFrameBuffer(); - - virtual bool Lock(bool buffer); - virtual void Unlock(); - virtual void Update(); - - virtual PalEntry* GetPalette(); - virtual void GetFlashedPalette(PalEntry pal[256]); - virtual void UpdatePalette(); - - virtual bool SetGamma(float gamma); - virtual bool SetFlash(PalEntry rgb, int amount); - virtual void GetFlash(PalEntry &rgb, int &amount); - - virtual int GetPageCount(); - - virtual bool IsFullscreen(); - - virtual void SetVSync(bool vsync); - -private: - static const size_t BYTES_PER_PIXEL = 4; - - PalEntry m_palette[256]; - bool m_needPaletteUpdate; - - uint8_t m_gammaTable[3][256]; - float m_gamma; - bool m_needGammaUpdate; - - PalEntry m_flashColor; - int m_flashAmount; - - bool UpdatePending; - - uint8_t* m_pixelBuffer; - GLuint m_texture; - - void Flip(); - - void UpdateColors(); -}; - - -// --------------------------------------------------------------------------- - - EXTERN_CVAR(Float, Gamma) CUSTOM_CVAR(Float, rgamma, 1.0f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) @@ -403,10 +307,6 @@ extern id appCtrl; namespace { -cycle_t BlitCycles; -cycle_t FlipCycles; - - CocoaWindow* CreateCocoaWindow(const NSUInteger styleMask) { static const CGFloat TEMP_WIDTH = VideoModes[0].width - 1; @@ -460,26 +360,19 @@ CocoaVideo::CocoaVideo() , m_width(-1) , m_height(-1) , m_fullscreen(false) +, m_bgra(false) , m_hiDPI(false) { memset(&m_modeIterator, 0, sizeof m_modeIterator); - extern void gl_CalculateCPUSpeed(); - gl_CalculateCPUSpeed(); - // Create OpenGL pixel format NSOpenGLPixelFormatAttribute defaultProfile = NSOpenGLProfileVersion3_2Core; - if (1 == vid_renderer && NSAppKitVersionNumber < AppKit10_9) + if (NSAppKitVersionNumber < AppKit10_9) { // There is no support for OpenGL 3.3 before Mavericks defaultProfile = NSOpenGLProfileVersionLegacy; } - else if (0 == vid_renderer && 0 == vid_glswfb) - { - // Software renderer uses OpenGL 2.1 for blitting - defaultProfile = NSOpenGLProfileVersionLegacy; - } else if (const char* const glversion = Args->CheckValue("-glversion")) { // Check for explicit version specified in command line @@ -564,9 +457,9 @@ DFrameBuffer* CocoaVideo::CreateFrameBuffer(const int width, const int height, c if (NULL != old) { - if (width == m_width && height == m_height && bgra == old->IsBgra()) + if (width == m_width && height == m_height && bgra == m_bgra) { - SetMode(width, height, fullscreen, vid_hidpi); + SetMode(width, height, fullscreen, bgra, vid_hidpi); return old; } @@ -582,29 +475,11 @@ DFrameBuffer* CocoaVideo::CreateFrameBuffer(const int width, const int height, c DFrameBuffer* fb = NULL; - if (1 == currentrenderer) - { - fb = new OpenGLFrameBuffer(NULL, width, height, 32, 60, fullscreen); - } - else if (vid_glswfb) - { - fb = CreateGLSWFrameBuffer(width, height, bgra, fullscreen); - - if (!fb->IsValid()) - { - delete fb; - - fb = new CocoaFrameBuffer(width, height, bgra, fullscreen); - } - } - else - { - fb = new CocoaFrameBuffer(width, height, bgra, fullscreen); - } + fb = new OpenGLFrameBuffer(NULL, width, height, 32, 60, fullscreen); fb->SetFlash(flashColor, flashAmount); - SetMode(width, height, fullscreen, vid_hidpi); + SetMode(width, height, fullscreen, bgra, vid_hidpi); return fb; } @@ -626,7 +501,7 @@ void CocoaVideo::UseHiDPI(const bool hiDPI) { if (CocoaVideo* const video = GetInstance()) { - video->SetMode(video->m_width, video->m_height, video->m_fullscreen, hiDPI); + video->SetMode(video->m_width, video->m_height, video->m_fullscreen, video->m_bgra, hiDPI); } } @@ -733,9 +608,10 @@ void CocoaVideo::SetWindowedMode(const int width, const int height) [m_window exitAppOnClose]; } -void CocoaVideo::SetMode(const int width, const int height, const bool fullscreen, const bool hiDPI) +void CocoaVideo::SetMode(const int width, const int height, const bool fullscreen, const bool bgra, const bool hiDPI) { if (fullscreen == m_fullscreen + && bgra == m_bgra && width == m_width && height == m_height && hiDPI == m_hiDPI) @@ -772,9 +648,10 @@ void CocoaVideo::SetMode(const int width, const int height, const bool fullscree [m_window makeKeyAndOrderFront:nil]; } - m_fullscreen = fullscreen; m_width = width; m_height = height; + m_fullscreen = fullscreen; + m_bgra = bgra; m_hiDPI = hiDPI; } @@ -788,268 +665,8 @@ CocoaVideo* CocoaVideo::GetInstance() // --------------------------------------------------------------------------- -CocoaFrameBuffer::CocoaFrameBuffer(int width, int height, bool bgra, bool fullscreen) +SystemFrameBuffer::SystemFrameBuffer(void*, const int width, const int height, int, int, const bool fullscreen, bool bgra) : DFrameBuffer(width, height, bgra) -, m_needPaletteUpdate(false) -, m_gamma(0.0f) -, m_needGammaUpdate(false) -, m_flashAmount(0) -, UpdatePending(false) -, m_pixelBuffer(new uint8_t[width * height * BYTES_PER_PIXEL]) -, m_texture(0) -{ - static bool isOpenGLInitialized; - - if (!isOpenGLInitialized) - { - if (ogl_LoadFunctions() == ogl_LOAD_FAILED) - { - I_FatalError("Failed to load OpenGL functions."); - } - isOpenGLInitialized = true; - } - - glEnable(GL_TEXTURE_RECTANGLE_ARB); - - glGenTextures(1, &m_texture); - glBindTexture(GL_TEXTURE_RECTANGLE_ARB, m_texture); - - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0.0, width, height, 0.0, -1.0, 1.0); - - GPfx.SetFormat(32, 0x000000FF, 0x0000FF00, 0x00FF0000); - - for (size_t i = 0; i < 256; ++i) - { - m_gammaTable[0][i] = m_gammaTable[1][i] = m_gammaTable[2][i] = i; - } - - memcpy(m_palette, GPalette.BaseColors, sizeof(PalEntry) * 256); - UpdateColors(); - - SetVSync(vid_vsync); -} - - -CocoaFrameBuffer::~CocoaFrameBuffer() -{ - glBindTexture(GL_TEXTURE_2D, 0); - glDeleteTextures(1, &m_texture); - - delete[] m_pixelBuffer; -} - -int CocoaFrameBuffer::GetPageCount() -{ - return 1; -} - -bool CocoaFrameBuffer::Lock(bool buffered) -{ - return DSimpleCanvas::Lock(buffered); -} - -void CocoaFrameBuffer::Unlock() -{ - if (UpdatePending && LockCount == 1) - { - Update(); - } - else if (--LockCount <= 0) - { - Buffer = NULL; - LockCount = 0; - } -} - -void CocoaFrameBuffer::Update() -{ - if (LockCount != 1) - { - if (LockCount > 0) - { - UpdatePending = true; - --LockCount; - } - return; - } - - DrawRateStuff(); - - Buffer = NULL; - LockCount = 0; - UpdatePending = false; - - BlitCycles.Reset(); - FlipCycles.Reset(); - BlitCycles.Clock(); - - if (IsBgra()) - { - CopyWithGammaBgra(m_pixelBuffer, Width * BYTES_PER_PIXEL, m_gammaTable[0], m_gammaTable[1], m_gammaTable[2], m_flashColor, m_flashAmount); - } - else - { - GPfx.Convert(MemBuffer, Pitch, m_pixelBuffer, Width * BYTES_PER_PIXEL, - Width, Height, FRACUNIT, FRACUNIT, 0, 0); - } - - FlipCycles.Clock(); - Flip(); - FlipCycles.Unclock(); - - BlitCycles.Unclock(); - - if (m_needGammaUpdate) - { - CalcGamma(rgamma == 0.0f ? m_gamma : m_gamma * rgamma, m_gammaTable[0]); - CalcGamma(ggamma == 0.0f ? m_gamma : m_gamma * ggamma, m_gammaTable[1]); - CalcGamma(bgamma == 0.0f ? m_gamma : m_gamma * bgamma, m_gammaTable[2]); - - m_needGammaUpdate = false; - m_needPaletteUpdate = true; - } - - if (m_needPaletteUpdate) - { - m_needPaletteUpdate = false; - UpdateColors(); - } -} - -void CocoaFrameBuffer::UpdateColors() -{ - PalEntry palette[256]; - - for (size_t i = 0; i < 256; ++i) - { - palette[i].r = m_gammaTable[0][m_palette[i].r]; - palette[i].g = m_gammaTable[1][m_palette[i].g]; - palette[i].b = m_gammaTable[2][m_palette[i].b]; - } - - if (0 != m_flashAmount) - { - DoBlending(palette, palette, 256, - m_gammaTable[0][m_flashColor.r], - m_gammaTable[1][m_flashColor.g], - m_gammaTable[2][m_flashColor.b], - m_flashAmount); - } - - GPfx.SetPalette(palette); -} - -PalEntry* CocoaFrameBuffer::GetPalette() -{ - return m_palette; -} - -void CocoaFrameBuffer::UpdatePalette() -{ - m_needPaletteUpdate = true; -} - -bool CocoaFrameBuffer::SetGamma(float gamma) -{ - m_gamma = gamma; - m_needGammaUpdate = true; - - return true; -} - -bool CocoaFrameBuffer::SetFlash(PalEntry rgb, int amount) -{ - m_flashColor = rgb; - m_flashAmount = amount; - m_needPaletteUpdate = true; - - return true; -} - -void CocoaFrameBuffer::GetFlash(PalEntry &rgb, int &amount) -{ - rgb = m_flashColor; - amount = m_flashAmount; -} - -void CocoaFrameBuffer::GetFlashedPalette(PalEntry pal[256]) -{ - memcpy(pal, m_palette, sizeof m_palette); - - if (0 != m_flashAmount) - { - DoBlending(pal, pal, 256, - m_flashColor.r, m_flashColor.g, m_flashColor.b, - m_flashAmount); - } -} - -bool CocoaFrameBuffer::IsFullscreen() -{ - return CocoaVideo::IsFullscreen(); -} - -void CocoaFrameBuffer::SetVSync(bool vsync) -{ - const GLint value = vsync ? 1 : 0; - - [[NSOpenGLContext currentContext] setValues:&value - forParameter:NSOpenGLCPSwapInterval]; -} - -void CocoaFrameBuffer::Flip() -{ - assert(NULL != screen); - - if (rbOpts.dirty) - { - glViewport(rbOpts.shiftX, rbOpts.shiftY, rbOpts.width, rbOpts.height); - - // TODO: Figure out why the following glClear() call is needed - // to avoid drawing of garbage in fullscreen mode when - // in-game's aspect ratio is different from display one - glClear(GL_COLOR_BUFFER_BIT); - - rbOpts.dirty = false; - } - - const GLenum format = IsBgra() ? GL_BGRA : GL_RGBA; - glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, Width, Height, 0, format, GL_UNSIGNED_BYTE, m_pixelBuffer); - - glBegin(GL_QUADS); - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - glTexCoord2f(0.0f, 0.0f); - glVertex2f(0.0f, 0.0f); - glTexCoord2f(Width, 0.0f); - glVertex2f(Width, 0.0f); - glTexCoord2f(Width, Height); - glVertex2f(Width, Height); - glTexCoord2f(0.0f, Height); - glVertex2f(0.0f, Height); - glEnd(); - - glFlush(); - - [[NSOpenGLContext currentContext] flushBuffer]; -} - - -// --------------------------------------------------------------------------- - - -SDLGLFB::SDLGLFB(void*, const int width, const int height, int, int, const bool fullscreen, bool bgra) -: DFrameBuffer(width, height, bgra) -, m_Lock(0) , UpdatePending(false) { CGGammaValue gammaTable[GAMMA_TABLE_SIZE]; @@ -1068,48 +685,20 @@ SDLGLFB::SDLGLFB(void*, const int width, const int height, int, int, const bool } } -SDLGLFB::SDLGLFB() +SystemFrameBuffer::SystemFrameBuffer() { } -SDLGLFB::~SDLGLFB() +SystemFrameBuffer::~SystemFrameBuffer() { } - -bool SDLGLFB::Lock(bool buffered) -{ - m_Lock++; - - Buffer = MemBuffer; - - return true; -} - -void SDLGLFB::Unlock() -{ - if (UpdatePending && 1 == m_Lock) - { - Update(); - } - else if (--m_Lock <= 0) - { - m_Lock = 0; - } -} - -bool SDLGLFB::IsLocked() -{ - return m_Lock > 0; -} - - -bool SDLGLFB::IsFullscreen() +bool SystemFrameBuffer::IsFullscreen() { return CocoaVideo::IsFullscreen(); } -void SDLGLFB::SetVSync(bool vsync) +void SystemFrameBuffer::SetVSync(bool vsync) { const GLint value = vsync ? 1 : 0; @@ -1118,32 +707,21 @@ void SDLGLFB::SetVSync(bool vsync) } -void SDLGLFB::InitializeState() +void SystemFrameBuffer::InitializeState() { } -bool SDLGLFB::CanUpdate() +bool SystemFrameBuffer::CanUpdate() { - if (m_Lock != 1) - { - if (m_Lock > 0) - { - UpdatePending = true; - --m_Lock; - } - - return false; - } - return true; } -void SDLGLFB::SwapBuffers() +void SystemFrameBuffer::SwapBuffers() { [[NSOpenGLContext currentContext] flushBuffer]; } -void SDLGLFB::SetGammaTable(uint16_t* table) +void SystemFrameBuffer::SetGammaTable(uint16_t* table) { if (m_supportsGamma) { @@ -1159,7 +737,7 @@ void SDLGLFB::SetGammaTable(uint16_t* table) } } -void SDLGLFB::ResetGammaTable() +void SystemFrameBuffer::ResetGammaTable() { if (m_supportsGamma) { @@ -1167,7 +745,7 @@ void SDLGLFB::ResetGammaTable() } } -int SDLGLFB::GetClientWidth() +int SystemFrameBuffer::GetClientWidth() { NSView *view = [[NSOpenGLContext currentContext] view]; NSRect backingBounds = [view convertRectToBacking: [view bounds]]; @@ -1175,7 +753,7 @@ int SDLGLFB::GetClientWidth() return clientWidth > 0 ? clientWidth : Width; } -int SDLGLFB::GetClientHeight() +int SystemFrameBuffer::GetClientHeight() { NSView *view = [[NSOpenGLContext currentContext] view]; NSRect backingBounds = [view convertRectToBacking: [view bounds]]; @@ -1187,14 +765,6 @@ int SDLGLFB::GetClientHeight() // --------------------------------------------------------------------------- -ADD_STAT(blit) -{ - FString result; - result.Format("blit=%04.1f ms flip=%04.1f ms", BlitCycles.TimeMS(), FlipCycles.TimeMS()); - return result; -} - - IVideo* Video; @@ -1225,31 +795,9 @@ void I_InitGraphics() } -static void I_DeleteRenderer() -{ - delete Renderer; - Renderer = NULL; -} - -void I_CreateRenderer() -{ - currentrenderer = vid_renderer; - - if (NULL == Renderer) - { - extern FRenderer* gl_CreateInterface(); - - Renderer = 1 == currentrenderer - ? gl_CreateInterface() - : new FSoftwareRenderer; - atterm(I_DeleteRenderer); - } -} - - DFrameBuffer* I_SetMode(int &width, int &height, DFrameBuffer* old) { - return Video->CreateFrameBuffer(width, height, swtruecolor, fullscreen, old); + return Video->CreateFrameBuffer(width, height, false, fullscreen, old); } bool I_CheckResolution(const int width, const int height, const int bits) @@ -1325,22 +873,6 @@ void I_SetFPSLimit(int limit) { } -CUSTOM_CVAR(Int, vid_maxfps, 200, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -{ - if (vid_maxfps < TICRATE && vid_maxfps != 0) - { - vid_maxfps = TICRATE; - } - else if (vid_maxfps > 1000) - { - vid_maxfps = 1000; - } - else if (cl_capfps == 0) - { - I_SetFPSLimit(vid_maxfps); - } -} - CUSTOM_CVAR(Bool, vid_hidpi, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) { CocoaVideo::UseHiDPI(self); diff --git a/src/posix/hardware.h b/src/posix/hardware.h index 3c06cb6c6d..5f10dc25fc 100644 --- a/src/posix/hardware.h +++ b/src/posix/hardware.h @@ -86,7 +86,6 @@ class IVideo void I_InitGraphics (); void I_ShutdownGraphics (); -void I_CreateRenderer(); extern Semaphore FPSLimitSemaphore; void I_SetFPSLimit(int limit); diff --git a/src/posix/sdl/gl_sysfb.h b/src/posix/sdl/gl_sysfb.h new file mode 100644 index 0000000000..d68492e59c --- /dev/null +++ b/src/posix/sdl/gl_sysfb.h @@ -0,0 +1,55 @@ +#ifndef __POSIX_SDL_GL_SYSFB_H__ +#define __POSIX_SDL_GL_SYSFB_H__ + +#include + +#include "v_video.h" + +class SystemFrameBuffer : public DFrameBuffer +{ + typedef DFrameBuffer Super; + +public: + // this must have the same parameters as the Windows version, even if they are not used! + SystemFrameBuffer (void *hMonitor, int width, int height, int, int, bool fullscreen, bool bgra); + ~SystemFrameBuffer (); + + void ForceBuffering (bool force); + + bool IsFullscreen (); + + virtual void SetVSync( bool vsync ); + void SwapBuffers(); + + void NewRefreshRate (); + + friend class SDLGLVideo; + + int GetClientWidth(); + int GetClientHeight(); + + SDL_Window *GetSDLWindow() { return Screen; } + + virtual int GetTrueHeight() { return GetClientHeight(); } + +protected: + bool CanUpdate(); + void SetGammaTable(uint16_t *tbl); + void ResetGammaTable(); + void InitializeState(); + + SystemFrameBuffer () {} + uint8_t GammaTable[3][256]; + bool UpdatePending; + + SDL_Window *Screen; + + SDL_GLContext GLContext; + + void UpdateColors (); + + Uint16 m_origGamma[3][256]; + bool m_supportsGamma; +}; + +#endif // __POSIX_SDL_GL_SYSFB_H__ diff --git a/src/posix/sdl/hardware.cpp b/src/posix/sdl/hardware.cpp index 5e7ba4f1e5..0ae4d8dedb 100644 --- a/src/posix/sdl/hardware.cpp +++ b/src/posix/sdl/hardware.cpp @@ -43,17 +43,15 @@ #include "c_console.h" #include "c_cvars.h" #include "c_dispatch.h" -#include "sdlvideo.h" #include "v_text.h" #include "doomstat.h" #include "m_argv.h" -#include "sdlglvideo.h" +#include "gl_sysfb.h" #include "r_renderer.h" #include "swrenderer/r_swrenderer.h" EXTERN_CVAR (Bool, ticker) EXTERN_CVAR (Bool, fullscreen) -EXTERN_CVAR (Bool, swtruecolor) EXTERN_CVAR (Float, vid_winscale) IVideo *Video; @@ -62,32 +60,6 @@ extern int NewWidth, NewHeight, NewBits, DisplayBits; bool V_DoModeSetup (int width, int height, int bits); void I_RestartRenderer(); -int currentrenderer; - -// [ZDoomGL] -CUSTOM_CVAR (Int, vid_renderer, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) -{ - // 0: Software renderer - // 1: OpenGL renderer - - if (self != currentrenderer) - { - switch (self) - { - case 0: - Printf("Switching to software renderer...\n"); - break; - case 1: - Printf("Switching to OpenGL renderer...\n"); - break; - default: - Printf("Unknown renderer (%d). Falling back to software renderer...\n", (int) vid_renderer); - self = 0; // make sure to actually switch to the software renderer - break; - } - Printf("You must restart " GAMENAME " to switch the renderer\n"); - } -} void I_ShutdownGraphics () { @@ -117,9 +89,9 @@ void I_InitGraphics () val.Bool = !!Args->CheckParm ("-devparm"); ticker.SetGenericRepDefault (val, CVAR_Bool); - - //currentrenderer = vid_renderer; - Video = new SDLGLVideo(0); + + extern IVideo *gl_CreateVideo(); + Video = gl_CreateVideo(); if (Video == NULL) I_FatalError ("Failed to initialize display"); @@ -129,23 +101,6 @@ void I_InitGraphics () Video->SetWindowedScale (vid_winscale); } -static void I_DeleteRenderer() -{ - if (Renderer != NULL) delete Renderer; -} - -void I_CreateRenderer() -{ - currentrenderer = vid_renderer; - if (Renderer == NULL) - { - if (currentrenderer==1) Renderer = gl_CreateInterface(); - else Renderer = new FSoftwareRenderer; - atterm(I_DeleteRenderer); - } -} - - /** Remaining code is common to Win32 and Linux **/ // VIDEO WRAPPERS --------------------------------------------------------- @@ -165,7 +120,7 @@ DFrameBuffer *I_SetMode (int &width, int &height, DFrameBuffer *old) fs = fullscreen; break; } - DFrameBuffer *res = Video->CreateFrameBuffer (width, height, swtruecolor, fs, old); + DFrameBuffer *res = Video->CreateFrameBuffer (width, height, false, fs, old); /* Right now, CreateFrameBuffer cannot return NULL if (res == NULL) @@ -301,37 +256,8 @@ void I_SetFPSLimit(int limit) } #endif -CUSTOM_CVAR (Int, vid_maxfps, 200, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -{ - if (vid_maxfps < TICRATE && vid_maxfps != 0) - { - vid_maxfps = TICRATE; - } - else if (vid_maxfps > 1000) - { - vid_maxfps = 1000; - } - else if (cl_capfps == 0) - { - I_SetFPSLimit(vid_maxfps); - } -} - extern int NewWidth, NewHeight, NewBits, DisplayBits; -CUSTOM_CVAR(Bool, swtruecolor, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL) -{ - // Strictly speaking this doesn't require a mode switch, but it is the easiest - // way to force a CreateFramebuffer call without a lot of refactoring. - if (currentrenderer == 0) - { - NewWidth = screen->VideoWidth; - NewHeight = screen->VideoHeight; - NewBits = DisplayBits; - setmodeneeded = true; - } -} - CUSTOM_CVAR (Bool, fullscreen, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL) { NewWidth = screen->VideoWidth; diff --git a/src/posix/sdl/sdlglvideo.cpp b/src/posix/sdl/sdlglvideo.cpp index bb8b40dec1..60152f15c9 100644 --- a/src/posix/sdl/sdlglvideo.cpp +++ b/src/posix/sdl/sdlglvideo.cpp @@ -46,17 +46,14 @@ #include "c_console.h" #include "videomodes.h" -#include "sdlglvideo.h" -#include "sdlvideo.h" +#include "hardware.h" +#include "gl_sysfb.h" #include "gl/system/gl_system.h" #include "r_defs.h" -#include "gl/gl_functions.h" -//#include "gl/gl_intern.h" #include "gl/renderer/gl_renderer.h" #include "gl/system/gl_framebuffer.h" #include "gl/shaders/gl_shader.h" -#include "gl/utility/gl_templates.h" #include "gl/textures/gl_material.h" #include "gl/system/gl_cvars.h" @@ -71,12 +68,10 @@ // EXTERNAL DATA DECLARATIONS ---------------------------------------------- extern IVideo *Video; -// extern int vid_renderer; EXTERN_CVAR (Float, Gamma) EXTERN_CVAR (Int, vid_adapter) EXTERN_CVAR (Int, vid_displaybits) -EXTERN_CVAR (Int, vid_renderer) EXTERN_CVAR (Int, vid_maxfps) EXTERN_CVAR (Bool, cl_capfps) @@ -89,27 +84,43 @@ CUSTOM_CVAR(Bool, gl_debug, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINI Printf("This won't take effect until " GAMENAME " is restarted.\n"); } #ifdef __arm__ -CUSTOM_CVAR(Bool, vid_glswfb, false, CVAR_NOINITCALL) -{ - Printf("This won't take effect until " GAMENAME " is restarted.\n"); -} CUSTOM_CVAR(Bool, gl_es, false, CVAR_NOINITCALL) { Printf("This won't take effect until " GAMENAME " is restarted.\n"); } #else -CUSTOM_CVAR(Bool, vid_glswfb, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) -{ - Printf("This won't take effect until " GAMENAME " is restarted.\n"); -} CUSTOM_CVAR(Bool, gl_es, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) { Printf("This won't take effect until " GAMENAME " is restarted.\n"); } #endif +CVAR (Int, vid_adapter, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) + // PRIVATE DATA DEFINITIONS ------------------------------------------------ +class SDLGLVideo : public IVideo +{ +public: + SDLGLVideo (int parm); + ~SDLGLVideo (); + + EDisplayType GetDisplayType () { return DISPLAY_Both; } + void SetWindowedScale (float scale); + + DFrameBuffer *CreateFrameBuffer (int width, int height, bool bgra, bool fs, DFrameBuffer *old); + + void StartModeIterator (int bits, bool fs); + bool NextMode (int *width, int *height, bool *letterbox); + bool SetResolution (int width, int height, int bits); + + void SetupPixelFormat(bool allowsoftware, int multisample, const int *glver); + +private: + int IteratorMode; + int IteratorBits; +}; + // CODE -------------------------------------------------------------------- SDLGLVideo::SDLGLVideo (int parm) @@ -157,7 +168,7 @@ DFrameBuffer *SDLGLVideo::CreateFrameBuffer (int width, int height, bool bgra, b if (old != NULL) { // Reuse the old framebuffer if its attributes are the same - SDLBaseFB *fb = static_cast (old); + SystemFrameBuffer *fb = static_cast (old); if (fb->Width == width && fb->Height == height) { @@ -178,24 +189,7 @@ DFrameBuffer *SDLGLVideo::CreateFrameBuffer (int width, int height, bool bgra, b // flashAmount = 0; } - SDLBaseFB *fb; - if (vid_renderer == 1) - { - fb = new OpenGLFrameBuffer(0, width, height, 32, 60, fullscreen); - } - else if (vid_glswfb == 0) - { - fb = new SDLFB(width, height, bgra, fullscreen, nullptr); - } - else - { - fb = (SDLBaseFB*)CreateGLSWFrameBuffer(width, height, bgra, fullscreen); - if (!fb->IsValid()) - { - delete fb; - fb = new SDLFB(width, height, bgra, fullscreen, nullptr); - } - } + SystemFrameBuffer *fb = new OpenGLFrameBuffer(0, width, height, 32, 60, fullscreen); retry = 0; @@ -206,13 +200,8 @@ DFrameBuffer *SDLGLVideo::CreateFrameBuffer (int width, int height, bool bgra, b // 3. Try in the opposite screen mode with the closest size // This is a somewhat confusing mass of recursion here. - while (fb == NULL || !fb->IsValid ()) + while (fb == NULL) { - if (fb != NULL) - { - delete fb; - } - switch (retry) { case 0: @@ -239,7 +228,7 @@ DFrameBuffer *SDLGLVideo::CreateFrameBuffer (int width, int height, bool bgra, b } ++retry; - fb = static_cast(CreateFrameBuffer (width, height, false, fullscreen, NULL)); + fb = static_cast(CreateFrameBuffer (width, height, false, fullscreen, NULL)); } // fb->SetFlash (flashColor, flashAmount); @@ -316,10 +305,16 @@ void SDLGLVideo::SetupPixelFormat(bool allowsoftware, int multisample, const int } +IVideo *gl_CreateVideo() +{ + return new SDLGLVideo(0); +} + + // FrameBuffer implementation ----------------------------------------------- -SDLGLFB::SDLGLFB (void *, int width, int height, int, int, bool fullscreen, bool bgra) - : SDLBaseFB (width, height, bgra) +SystemFrameBuffer::SystemFrameBuffer (void *, int width, int height, int, int, bool fullscreen, bool bgra) + : DFrameBuffer (width, height, bgra) { // NOTE: Core profiles were added with GL 3.2, so there's no sense trying // to set core 3.1 or 3.0. We could try a forward-compatible context @@ -332,7 +327,6 @@ SDLGLFB::SDLGLFB (void *, int width, int height, int, int, bool fullscreen, bool int glveridx = 0; int i; - m_Lock=0; UpdatePending = false; const char *version = Args->CheckValue("-glversion"); @@ -383,7 +377,7 @@ SDLGLFB::SDLGLFB (void *, int width, int height, int, int, bool fullscreen, bool } } -SDLGLFB::~SDLGLFB () +SystemFrameBuffer::~SystemFrameBuffer () { if (Screen) { @@ -401,25 +395,16 @@ SDLGLFB::~SDLGLFB () -void SDLGLFB::InitializeState() +void SystemFrameBuffer::InitializeState() { } -bool SDLGLFB::CanUpdate () +bool SystemFrameBuffer::CanUpdate () { - if (m_Lock != 1) - { - if (m_Lock > 0) - { - UpdatePending = true; - --m_Lock; - } - return false; - } return true; } -void SDLGLFB::SetGammaTable(uint16_t *tbl) +void SystemFrameBuffer::SetGammaTable(uint16_t *tbl) { if (m_supportsGamma) { @@ -427,7 +412,7 @@ void SDLGLFB::SetGammaTable(uint16_t *tbl) } } -void SDLGLFB::ResetGammaTable() +void SystemFrameBuffer::ResetGammaTable() { if (m_supportsGamma) { @@ -435,47 +420,12 @@ void SDLGLFB::ResetGammaTable() } } -bool SDLGLFB::Lock(bool buffered) -{ - m_Lock++; - Buffer = MemBuffer; - return true; -} - -bool SDLGLFB::Lock () -{ - return Lock(false); -} - -void SDLGLFB::Unlock () -{ - if (UpdatePending && m_Lock == 1) - { - Update (); - } - else if (--m_Lock <= 0) - { - m_Lock = 0; - } -} - -bool SDLGLFB::IsLocked () -{ - return m_Lock>0;// true; -} - -bool SDLGLFB::IsFullscreen () +bool SystemFrameBuffer::IsFullscreen () { return (SDL_GetWindowFlags (Screen) & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0; } - -bool SDLGLFB::IsValid () -{ - return DFrameBuffer::IsValid() && Screen != NULL; -} - -void SDLGLFB::SetVSync( bool vsync ) +void SystemFrameBuffer::SetVSync( bool vsync ) { #if defined (__APPLE__) const GLint value = vsync ? 1 : 0; @@ -493,11 +443,11 @@ void SDLGLFB::SetVSync( bool vsync ) #endif } -void SDLGLFB::NewRefreshRate () +void SystemFrameBuffer::NewRefreshRate () { } -void SDLGLFB::SwapBuffers() +void SystemFrameBuffer::SwapBuffers() { #if !defined(__APPLE__) && !defined(__OpenBSD__) if (vid_maxfps && !cl_capfps) @@ -509,51 +459,31 @@ void SDLGLFB::SwapBuffers() SDL_GL_SwapWindow (Screen); } -int SDLGLFB::GetClientWidth() +int SystemFrameBuffer::GetClientWidth() { int width = 0; SDL_GL_GetDrawableSize(Screen, &width, nullptr); return width; } -int SDLGLFB::GetClientHeight() +int SystemFrameBuffer::GetClientHeight() { int height = 0; SDL_GL_GetDrawableSize(Screen, nullptr, &height); return height; } -void SDLGLFB::ScaleCoordsFromWindow(int16_t &x, int16_t &y) -{ - int w, h; - SDL_GetWindowSize (Screen, &w, &h); - // Detect if we're doing scaling in the Window and adjust the mouse - // coordinates accordingly. This could be more efficent, but I - // don't think performance is an issue in the menus. - if(IsFullscreen()) - { - int realw = w, realh = h; - ScaleWithAspect (realw, realh, SCREENWIDTH, SCREENHEIGHT); - if (realw != SCREENWIDTH || realh != SCREENHEIGHT) - { - double xratio = (double)SCREENWIDTH/realw; - double yratio = (double)SCREENHEIGHT/realh; - if (realw < w) - { - x = (x - (w - realw)/2)*xratio; - y *= yratio; - } - else - { - y = (y - (h - realh)/2)*yratio; - x *= xratio; - } - } - } +// each platform has its own specific version of this function. +void I_SetWindowTitle(const char* caption) +{ + auto window = static_cast(screen)->GetSDLWindow(); + if (caption) + SDL_SetWindowTitle(window, caption); else { - x = (int16_t)(x*Width/w); - y = (int16_t)(y*Height/h); + FString default_caption; + default_caption.Format(GAMESIG " %s (%s)", GetVersionString(), GetGitTime()); + SDL_SetWindowTitle(window, default_caption); } } diff --git a/src/posix/sdl/sdlglvideo.h b/src/posix/sdl/sdlglvideo.h deleted file mode 100644 index 2dce3aeed5..0000000000 --- a/src/posix/sdl/sdlglvideo.h +++ /dev/null @@ -1,99 +0,0 @@ -#ifndef __SDLGLVIDEO_H__ -#define __SDLGLVIDEO_H__ - -#include "hardware.h" -#include "v_video.h" -#include -#include "gl/system/gl_system.h" - -EXTERN_CVAR (Float, dimamount) -EXTERN_CVAR (Color, dimcolor) - -struct FRenderer; -FRenderer *gl_CreateInterface(); - -class SDLGLVideo : public IVideo -{ - public: - SDLGLVideo (int parm); - ~SDLGLVideo (); - - EDisplayType GetDisplayType () { return DISPLAY_Both; } - void SetWindowedScale (float scale); - - DFrameBuffer *CreateFrameBuffer (int width, int height, bool bgra, bool fs, DFrameBuffer *old); - - void StartModeIterator (int bits, bool fs); - bool NextMode (int *width, int *height, bool *letterbox); - bool SetResolution (int width, int height, int bits); - - void SetupPixelFormat(bool allowsoftware, int multisample, const int *glver); - -private: - int IteratorMode; - int IteratorBits; -}; - -class SDLBaseFB : public DFrameBuffer -{ - typedef DFrameBuffer Super; -public: - using DFrameBuffer::DFrameBuffer; - virtual SDL_Window *GetSDLWindow() = 0; - - friend class SDLGLVideo; -}; - -class SDLGLFB : public SDLBaseFB -{ - typedef SDLBaseFB Super; -public: - // this must have the same parameters as the Windows version, even if they are not used! - SDLGLFB (void *hMonitor, int width, int height, int, int, bool fullscreen, bool bgra); - ~SDLGLFB (); - - void ForceBuffering (bool force); - bool Lock(bool buffered); - bool Lock (); - void Unlock(); - bool IsLocked (); - - bool IsValid (); - bool IsFullscreen (); - - virtual void SetVSync( bool vsync ); - void SwapBuffers(); - - void NewRefreshRate (); - - friend class SDLGLVideo; - - int GetClientWidth(); - int GetClientHeight(); - - virtual void ScaleCoordsFromWindow(int16_t &x, int16_t &y); - - SDL_Window *GetSDLWindow() override { return Screen; } - - virtual int GetTrueHeight() { return GetClientHeight(); } -protected: - bool CanUpdate(); - void SetGammaTable(uint16_t *tbl); - void ResetGammaTable(); - void InitializeState(); - - SDLGLFB () {} - uint8_t GammaTable[3][256]; - bool UpdatePending; - - SDL_Window *Screen; - - SDL_GLContext GLContext; - - void UpdateColors (); - - int m_Lock; - Uint16 m_origGamma[3][256]; - bool m_supportsGamma; -}; -#endif diff --git a/src/posix/sdl/sdlvideo.cpp b/src/posix/sdl/sdlvideo.cpp deleted file mode 100644 index 8cae687397..0000000000 --- a/src/posix/sdl/sdlvideo.cpp +++ /dev/null @@ -1,568 +0,0 @@ -/* -** sdlvideo.cpp -** -**--------------------------------------------------------------------------- -** Copyright 2005-2016 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -// HEADER FILES ------------------------------------------------------------ - -#include "doomtype.h" - -#include "templates.h" -#include "i_system.h" -#include "i_video.h" -#include "v_video.h" -#include "v_pfx.h" -#include "stats.h" -#include "v_palette.h" -#include "sdlvideo.h" -#include "swrenderer/r_swrenderer.h" -#include "version.h" - -#include - -#ifdef __APPLE__ -#include -#endif // __APPLE__ - -// MACROS ------------------------------------------------------------------ - -// TYPES ------------------------------------------------------------------- - -struct MiniModeInfo -{ - uint16_t Width, Height; -}; - -// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- - -// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- - -// EXTERNAL DATA DECLARATIONS ---------------------------------------------- - -extern IVideo *Video; -extern bool GUICapture; - -EXTERN_CVAR (Float, Gamma) -EXTERN_CVAR (Int, vid_maxfps) -EXTERN_CVAR (Bool, cl_capfps) -EXTERN_CVAR (Bool, vid_vsync) - -// PUBLIC DATA DEFINITIONS ------------------------------------------------- - -CVAR (Int, vid_adapter, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) - -CVAR (Int, vid_displaybits, 32, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) - -CVAR (Bool, vid_forcesurface, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) - -CUSTOM_CVAR (Float, rgamma, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -{ - if (screen != NULL) - { - screen->SetGamma (Gamma); - } -} -CUSTOM_CVAR (Float, ggamma, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -{ - if (screen != NULL) - { - screen->SetGamma (Gamma); - } -} -CUSTOM_CVAR (Float, bgamma, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -{ - if (screen != NULL) - { - screen->SetGamma (Gamma); - } -} - -// PRIVATE DATA DEFINITIONS ------------------------------------------------ - -static cycle_t BlitCycles; -static cycle_t SDLFlipCycles; - -// CODE -------------------------------------------------------------------- - -// FrameBuffer implementation ----------------------------------------------- - -SDLFB::SDLFB (int width, int height, bool bgra, bool fullscreen, SDL_Window *oldwin) - : SDLBaseFB (width, height, bgra) -{ - int i; - - NeedPalUpdate = false; - NeedGammaUpdate = false; - UpdatePending = false; - NotPaletted = false; - FlashAmount = 0; - - if (oldwin) - { - // In some cases (Mac OS X fullscreen) SDL2 doesn't like having multiple windows which - // appears to inevitably happen while compositor animations are running. So lets try - // to reuse the existing window. - Screen = oldwin; - SDL_SetWindowSize (Screen, width, height); - SetFullscreen (fullscreen); - } - else - { - FString caption; - caption.Format(GAMESIG " %s (%s)", GetVersionString(), GetGitTime()); - - Screen = SDL_CreateWindow (caption, - SDL_WINDOWPOS_UNDEFINED_DISPLAY(vid_adapter), SDL_WINDOWPOS_UNDEFINED_DISPLAY(vid_adapter), - width, height, (fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0)|SDL_WINDOW_RESIZABLE); - - if (Screen == NULL) - return; - } - - Renderer = NULL; - Texture = NULL; - ResetSDLRenderer (); - - for (i = 0; i < 256; i++) - { - GammaTable[0][i] = GammaTable[1][i] = GammaTable[2][i] = i; - } - - memcpy (SourcePalette, GPalette.BaseColors, sizeof(PalEntry)*256); - UpdateColors (); - -#ifdef __APPLE__ - SetVSync (vid_vsync); -#endif -} - - -SDLFB::~SDLFB () -{ - if (Renderer) - { - if (Texture) - SDL_DestroyTexture (Texture); - SDL_DestroyRenderer (Renderer); - } - - if(Screen) - { - SDL_DestroyWindow (Screen); - } -} - -bool SDLFB::IsValid () -{ - return DFrameBuffer::IsValid() && Screen != NULL; -} - -int SDLFB::GetPageCount () -{ - return 1; -} - -bool SDLFB::Lock (bool buffered) -{ - return DSimpleCanvas::Lock (); -} - -bool SDLFB::Relock () -{ - return DSimpleCanvas::Lock (); -} - -void SDLFB::Unlock () -{ - if (UpdatePending && LockCount == 1) - { - Update (); - } - else if (--LockCount <= 0) - { - Buffer = NULL; - LockCount = 0; - } -} - -void SDLFB::Update () -{ - if (LockCount != 1) - { - if (LockCount > 0) - { - UpdatePending = true; - --LockCount; - } - return; - } - - DrawRateStuff (); - -#if !defined(__APPLE__) && !defined(__OpenBSD__) - if(vid_maxfps && !cl_capfps) - { - SEMAPHORE_WAIT(FPSLimitSemaphore) - } -#endif - - Buffer = NULL; - LockCount = 0; - UpdatePending = false; - - BlitCycles.Reset(); - SDLFlipCycles.Reset(); - BlitCycles.Clock(); - - void *pixels; - int pitch; - if (UsingRenderer) - { - if (SDL_LockTexture (Texture, NULL, &pixels, &pitch)) - return; - } - else - { - if (SDL_LockSurface (Surface)) - return; - - pixels = Surface->pixels; - pitch = Surface->pitch; - } - - if (Bgra) - { - CopyWithGammaBgra(pixels, pitch, GammaTable[0], GammaTable[1], GammaTable[2], Flash, FlashAmount); - } - else if (NotPaletted) - { - GPfx.Convert (MemBuffer, Pitch, - pixels, pitch, Width, Height, - FRACUNIT, FRACUNIT, 0, 0); - } - else - { - if (pitch == Pitch) - { - memcpy (pixels, MemBuffer, Width*Height); - } - else - { - for (int y = 0; y < Height; ++y) - { - memcpy ((uint8_t *)pixels+y*pitch, MemBuffer+y*Pitch, Width); - } - } - } - - if (UsingRenderer) - { - SDL_UnlockTexture (Texture); - - SDLFlipCycles.Clock(); - SDL_RenderClear(Renderer); - SDL_RenderCopy(Renderer, Texture, NULL, NULL); - SDL_RenderPresent(Renderer); - SDLFlipCycles.Unclock(); - } - else - { - SDL_UnlockSurface (Surface); - - SDLFlipCycles.Clock(); - SDL_UpdateWindowSurface (Screen); - SDLFlipCycles.Unclock(); - } - - BlitCycles.Unclock(); - - if (NeedGammaUpdate) - { - bool Windowed = false; - NeedGammaUpdate = false; - CalcGamma ((Windowed || rgamma == 0.f) ? Gamma : (Gamma * rgamma), GammaTable[0]); - CalcGamma ((Windowed || ggamma == 0.f) ? Gamma : (Gamma * ggamma), GammaTable[1]); - CalcGamma ((Windowed || bgamma == 0.f) ? Gamma : (Gamma * bgamma), GammaTable[2]); - NeedPalUpdate = true; - } - - if (NeedPalUpdate) - { - NeedPalUpdate = false; - UpdateColors (); - } -} - -void SDLFB::UpdateColors () -{ - if (NotPaletted) - { - PalEntry palette[256]; - - for (int i = 0; i < 256; ++i) - { - palette[i].r = GammaTable[0][SourcePalette[i].r]; - palette[i].g = GammaTable[1][SourcePalette[i].g]; - palette[i].b = GammaTable[2][SourcePalette[i].b]; - } - if (FlashAmount) - { - DoBlending (palette, palette, - 256, GammaTable[0][Flash.r], GammaTable[1][Flash.g], GammaTable[2][Flash.b], - FlashAmount); - } - GPfx.SetPalette (palette); - } - else - { - SDL_Color colors[256]; - - for (int i = 0; i < 256; ++i) - { - colors[i].r = GammaTable[0][SourcePalette[i].r]; - colors[i].g = GammaTable[1][SourcePalette[i].g]; - colors[i].b = GammaTable[2][SourcePalette[i].b]; - } - if (FlashAmount) - { - DoBlending ((PalEntry *)colors, (PalEntry *)colors, - 256, GammaTable[2][Flash.b], GammaTable[1][Flash.g], GammaTable[0][Flash.r], - FlashAmount); - } - SDL_SetPaletteColors (Surface->format->palette, colors, 0, 256); - } -} - -PalEntry *SDLFB::GetPalette () -{ - return SourcePalette; -} - -void SDLFB::UpdatePalette () -{ - NeedPalUpdate = true; -} - -bool SDLFB::SetGamma (float gamma) -{ - Gamma = gamma; - NeedGammaUpdate = true; - return true; -} - -bool SDLFB::SetFlash (PalEntry rgb, int amount) -{ - Flash = rgb; - FlashAmount = amount; - NeedPalUpdate = true; - return true; -} - -void SDLFB::GetFlash (PalEntry &rgb, int &amount) -{ - rgb = Flash; - amount = FlashAmount; -} - -// Q: Should I gamma adjust the returned palette? -void SDLFB::GetFlashedPalette (PalEntry pal[256]) -{ - memcpy (pal, SourcePalette, 256*sizeof(PalEntry)); - if (FlashAmount) - { - DoBlending (pal, pal, 256, Flash.r, Flash.g, Flash.b, FlashAmount); - } -} - -void SDLFB::SetFullscreen (bool fullscreen) -{ - if (IsFullscreen() == fullscreen) - return; - - SDL_SetWindowFullscreen (Screen, fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); - if (!fullscreen) - { - // Restore proper window size - SDL_SetWindowSize (Screen, Width, Height); - } - - ResetSDLRenderer (); -} - -bool SDLFB::IsFullscreen () -{ - return (SDL_GetWindowFlags (Screen) & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0; -} - -void SDLFB::ResetSDLRenderer () -{ - if (Renderer) - { - if (Texture) - SDL_DestroyTexture (Texture); - SDL_DestroyRenderer (Renderer); - } - - UsingRenderer = !vid_forcesurface; - if (UsingRenderer) - { - Renderer = SDL_CreateRenderer (Screen, -1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_TARGETTEXTURE| - (vid_vsync ? SDL_RENDERER_PRESENTVSYNC : 0)); - if (!Renderer) - return; - - SDL_SetRenderDrawColor(Renderer, 0, 0, 0, 255); - - Uint32 fmt; - if (Bgra) - { - fmt = SDL_PIXELFORMAT_ARGB8888; - } - else - { - switch (vid_displaybits) - { - default: fmt = SDL_PIXELFORMAT_ARGB8888; break; - case 30: fmt = SDL_PIXELFORMAT_ARGB2101010; break; - case 24: fmt = SDL_PIXELFORMAT_RGB888; break; - case 16: fmt = SDL_PIXELFORMAT_RGB565; break; - case 15: fmt = SDL_PIXELFORMAT_ARGB1555; break; - } - } - Texture = SDL_CreateTexture (Renderer, fmt, SDL_TEXTUREACCESS_STREAMING, Width, Height); - - { - NotPaletted = true; - - Uint32 format; - SDL_QueryTexture(Texture, &format, NULL, NULL, NULL); - - Uint32 Rmask, Gmask, Bmask, Amask; - int bpp; - SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); - GPfx.SetFormat (bpp, Rmask, Gmask, Bmask); - } - } - else - { - Surface = SDL_GetWindowSurface (Screen); - - if (Surface->format->palette == NULL) - { - NotPaletted = true; - GPfx.SetFormat (Surface->format->BitsPerPixel, Surface->format->Rmask, Surface->format->Gmask, Surface->format->Bmask); - } - else - NotPaletted = false; - } - - // In fullscreen, set logical size according to animorphic ratio. - // Windowed modes are rendered to fill the window (usually 1:1) - if (IsFullscreen ()) - { - int w, h; - SDL_GetWindowSize (Screen, &w, &h); - ScaleWithAspect (w, h, Width, Height); - SDL_RenderSetLogicalSize (Renderer, w, h); - } -} - -void SDLFB::SetVSync (bool vsync) -{ -#ifdef __APPLE__ - if (CGLContextObj context = CGLGetCurrentContext()) - { - // Apply vsync for native backend only (where OpenGL context is set) - const GLint value = vsync ? 1 : 0; - CGLSetParameter(context, kCGLCPSwapInterval, &value); - } -#else - ResetSDLRenderer (); -#endif // __APPLE__ -} - -void SDLFB::ScaleCoordsFromWindow(int16_t &x, int16_t &y) -{ - int w, h; - SDL_GetWindowSize (Screen, &w, &h); - - // Detect if we're doing scaling in the Window and adjust the mouse - // coordinates accordingly. This could be more efficent, but I - // don't think performance is an issue in the menus. - if(IsFullscreen()) - { - int realw = w, realh = h; - ScaleWithAspect (realw, realh, SCREENWIDTH, SCREENHEIGHT); - if (realw != SCREENWIDTH || realh != SCREENHEIGHT) - { - double xratio = (double)SCREENWIDTH/realw; - double yratio = (double)SCREENHEIGHT/realh; - if (realw < w) - { - x = (x - (w - realw)/2)*xratio; - y *= yratio; - } - else - { - y = (y - (h - realh)/2)*yratio; - x *= xratio; - } - } - } - else - { - x = (int16_t)(x*Width/w); - y = (int16_t)(y*Height/h); - } -} - -ADD_STAT (blit) -{ - FString out; - out.Format ("blit=%04.1f ms flip=%04.1f ms", - BlitCycles.TimeMS(), SDLFlipCycles.TimeMS()); - return out; -} - -// each platform has its own specific version of this function. -void I_SetWindowTitle(const char* caption) -{ - auto Screen = static_cast(screen)->GetSDLWindow(); - if (caption) - SDL_SetWindowTitle(static_cast(screen)->GetSDLWindow(), caption); - else - { - FString default_caption; - default_caption.Format(GAMESIG " %s (%s)", GetVersionString(), GetGitTime()); - SDL_SetWindowTitle(static_cast(screen)->GetSDLWindow(), default_caption); - } -} - diff --git a/src/posix/sdl/sdlvideo.h b/src/posix/sdl/sdlvideo.h deleted file mode 100644 index 31a168aa64..0000000000 --- a/src/posix/sdl/sdlvideo.h +++ /dev/null @@ -1,60 +0,0 @@ -#include "hardware.h" -#include "v_video.h" -#include "sdlglvideo.h" - -class SDLFB : public SDLBaseFB -{ - typedef SDLBaseFB Super; -public: - SDLFB(int width, int height, bool bgra, bool fullscreen, SDL_Window *oldwin); - ~SDLFB(); - - bool Lock(bool buffer); - void Unlock(); - bool Relock(); - void ForceBuffering(bool force); - bool IsValid(); - void Update(); - PalEntry *GetPalette(); - void GetFlashedPalette(PalEntry pal[256]); - void UpdatePalette(); - bool SetGamma(float gamma); - bool SetFlash(PalEntry rgb, int amount); - void GetFlash(PalEntry &rgb, int &amount); - void SetFullscreen(bool fullscreen); - int GetPageCount(); - bool IsFullscreen(); - - friend class SDLGLVideo; - - virtual void SetVSync(bool vsync); - virtual void ScaleCoordsFromWindow(int16_t &x, int16_t &y); - - SDL_Window *GetSDLWindow() override { return Screen; } - -private: - PalEntry SourcePalette[256]; - uint8_t GammaTable[3][256]; - PalEntry Flash; - int FlashAmount; - float Gamma; - bool UpdatePending; - - SDL_Window *Screen; - SDL_Renderer *Renderer; - union - { - SDL_Texture *Texture; - SDL_Surface *Surface; - }; - - bool UsingRenderer; - bool NeedPalUpdate; - bool NeedGammaUpdate; - bool NotPaletted; - - void UpdateColors(); - void ResetSDLRenderer(); - - SDLFB() {} -}; diff --git a/src/r_data/a_dynlightdata.cpp b/src/r_data/a_dynlightdata.cpp new file mode 100644 index 0000000000..b9c09a6908 --- /dev/null +++ b/src/r_data/a_dynlightdata.cpp @@ -0,0 +1,268 @@ +/* +** _gl_dynlight.cpp +** Light definitions for actors. +** +**--------------------------------------------------------------------------- +** Copyright 2003 Timothy Stump +** Copyright 2005 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + + +#include +#include "i_system.h" +#include "doomtype.h" +#include "c_cvars.h" +#include "c_dispatch.h" +#include "m_random.h" +#include "sc_man.h" +#include "templates.h" +#include "w_wad.h" +#include "gi.h" +#include "r_state.h" +#include "stats.h" +#include "zstring.h" +#include "d_dehacked.h" +#include "v_text.h" +#include "g_levellocals.h" +#include "a_dynlight.h" +#include "textures/skyboxtexture.h" + + +//========================================================================== +// +// Dehacked aliasing +// +//========================================================================== + +inline PClassActor * GetRealType(PClassActor * ti) +{ + PClassActor *rep = ti->GetReplacement(false); + if (rep != ti && rep != NULL && rep->IsDescendantOf(NAME_DehackedPickup)) + { + return rep; + } + return ti; +} + +TDeletingArray LightDefaults; + +//----------------------------------------------------------------------------- +// +// +// +//----------------------------------------------------------------------------- + +FLightDefaults::FLightDefaults(FName name, ELightType type) +{ + m_Name = name; + m_type = type; +} + +void FLightDefaults::ApplyProperties(ADynamicLight * light) const +{ + auto oldtype = light->lighttype; + + light->lighttype = m_type; + light->specialf1 = m_Param; + light->SetOffset(m_Pos); + light->halo = m_halo; + for (int a = 0; a < 3; a++) light->args[a] = clamp((int)(m_Args[a]), 0, 255); + light->args[LIGHT_INTENSITY] = m_Args[LIGHT_INTENSITY]; + light->args[LIGHT_SECONDARY_INTENSITY] = m_Args[LIGHT_SECONDARY_INTENSITY]; + light->lightflags &= ~(LF_ADDITIVE | LF_SUBTRACTIVE | LF_DONTLIGHTSELF); + if (m_subtractive) light->lightflags |= LF_SUBTRACTIVE; + if (m_additive) light->lightflags |= LF_ADDITIVE; + if (m_dontlightself) light->lightflags |= LF_DONTLIGHTSELF; + if (m_dontlightactors) light->lightflags |= LF_DONTLIGHTACTORS; + if (m_spot) + light->lightflags |= LF_SPOT; + light->SpotInnerAngle = m_spotInnerAngle; + light->SpotOuterAngle = m_spotOuterAngle; + light->m_tickCount = 0; + if (m_type == PulseLight) + { + float pulseTime = float(m_Param / TICRATE); + + light->m_lastUpdate = level.maptime; + if (m_swapped) light->m_cycler.SetParams(float(light->args[LIGHT_SECONDARY_INTENSITY]), float(light->args[LIGHT_INTENSITY]), pulseTime, oldtype == PulseLight); + else light->m_cycler.SetParams(float(light->args[LIGHT_INTENSITY]), float(light->args[LIGHT_SECONDARY_INTENSITY]), pulseTime, oldtype == PulseLight); + light->m_cycler.ShouldCycle(true); + light->m_cycler.SetCycleType(CYCLE_Sin); + light->m_currentRadius = (float)light->m_cycler.GetVal(); + if (light->m_currentRadius <= 0) light->m_currentRadius = 1; + light->swapped = m_swapped; + } + + switch (m_attenuate) + { + case 0: light->lightflags &= ~LF_ATTENUATE; break; + case 1: light->lightflags |= LF_ATTENUATE; break; + default: if (level.flags3 & LEVEL3_ATTENUATE) light->lightflags |= LF_ATTENUATE; else light->lightflags &= ~LF_ATTENUATE; break; + } + } + + +//========================================================================== +// +// light definition file parser +// +//========================================================================== + + +extern int ScriptDepth; + +void AddLightDefaults(FLightDefaults *defaults) +{ + FLightDefaults *temp; + unsigned int i; + + // remove duplicates + for (i = 0; i < LightDefaults.Size(); i++) + { + temp = LightDefaults[i]; + if (temp->GetName() == defaults->GetName()) + { + delete temp; + LightDefaults.Delete(i); + break; + } + } + + LightDefaults.Push(defaults); +} + +//========================================================================== +// +// +// +//========================================================================== + +FInternalLightAssociation::FInternalLightAssociation(FLightAssociation * asso) +{ + + m_AssocLight=NULL; + for(unsigned int i=0;iGetName() == asso->Light()) + { + m_AssocLight = LightDefaults[i]; + break; + } + } + + m_sprite=-1; + m_frame = -1; + for (unsigned i = 0; i < sprites.Size (); ++i) + { + if (strncmp (sprites[i].name, asso->FrameName(), 4) == 0) + { + m_sprite = (int)i; + break; + } + } + + // Only handle lights for full frames. + // I won't bother with special lights for single rotations + // because there is no decent use for them! + if (strlen(asso->FrameName())==5 || asso->FrameName()[5]=='0') + { + m_frame = toupper(asso->FrameName()[4])-'A'; + } +} + +//========================================================================== +// +// State lights +// +//========================================================================== +static TArray ParsedStateLights; +TArray StateLights; + +//========================================================================== +// +// +// +//========================================================================== + +void InitializeActorLights(TArray &LightAssociations) +{ + for(unsigned int i=0;iLight() != nullptr) + ti->ActorInfo()->LightAssociations.Push(iasso); + } + } + + StateLights.Resize(ParsedStateLights.Size()+1); + for(unsigned i=0; iGetName() == ParsedStateLights[i]) + { + StateLights[i] = LightDefaults[j]; + break; + } + } + } + else StateLights[i] = NULL; + } + StateLights[StateLights.Size()-1] = NULL; // terminator + ParsedStateLights.Clear(); + ParsedStateLights.ShrinkToFit(); +} + +//========================================================================== +// +// +// +//========================================================================== + +void AddStateLight(FState *State, const char *lname) +{ + if (State->Light == 0) + { + ParsedStateLights.Push(NAME_None); + State->Light = ParsedStateLights.Push(FName(lname)); + } + else + { + ParsedStateLights.Push(FName(lname)); + } +} diff --git a/src/r_data/gldefs.cpp b/src/r_data/gldefs.cpp new file mode 100644 index 0000000000..92c7a91d76 --- /dev/null +++ b/src/r_data/gldefs.cpp @@ -0,0 +1,1589 @@ +/* +** gldefs.cpp +** GLDEFS parser +** +**--------------------------------------------------------------------------- +** Copyright 2003 Timothy Stump +** Copyright 2005-2018 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ +#include +#include "i_system.h" +#include "doomtype.h" +#include "c_cvars.h" +#include "c_dispatch.h" +#include "m_random.h" +#include "sc_man.h" +#include "templates.h" +#include "w_wad.h" +#include "gi.h" +#include "r_state.h" +#include "stats.h" +#include "zstring.h" +#include "d_dehacked.h" +#include "v_text.h" +#include "g_levellocals.h" +#include "a_dynlight.h" +#include "textures/skyboxtexture.h" +#include "gl/shaders/gl_postprocessshader.h" + +void AddLightDefaults(FLightDefaults *defaults); +void AddLightAssociation(const char *actor, const char *frame, const char *light); +void InitializeActorLights(TArray &LightAssociations); + +extern TArray usershaders; +extern TDeletingArray LightDefaults; + + +//----------------------------------------------------------------------------- +// +// ParseVavoomSkybox +// +//----------------------------------------------------------------------------- + +static void ParseVavoomSkybox() +{ + int lump = Wads.CheckNumForName("SKYBOXES"); + + if (lump < 0) return; + + FScanner sc(lump); + while (sc.GetString()) + { + int facecount=0; + int maplump = -1; + bool error = false; + FSkyBox * sb = new FSkyBox; + sb->Name = sc.String; + sb->Name.ToUpper(); + sb->fliptop = true; + sc.MustGetStringName("{"); + while (!sc.CheckString("}")) + { + if (facecount<6) + { + sc.MustGetStringName("{"); + sc.MustGetStringName("map"); + sc.MustGetString(); + + maplump = Wads.CheckNumForFullName(sc.String, true); + + FTexture *tex = TexMan.FindTexture(sc.String, ETextureType::Wall, FTextureManager::TEXMAN_TryAny); + if (tex == NULL) + { + sc.ScriptMessage("Texture '%s' not found in Vavoom skybox '%s'\n", sc.String, sb->Name.GetChars()); + error = true; + } + sb->faces[facecount] = tex; + sc.MustGetStringName("}"); + } + facecount++; + } + if (facecount != 6) + { + sc.ScriptError("%s: Skybox definition requires 6 faces", sb->Name.GetChars()); + } + sb->SetSize(); + if (!error) TexMan.AddTexture(sb); + } +} + + + +//========================================================================== +// +// light definition keywords +// +//========================================================================== + + +static const char *LightTags[]= +{ + "color", + "size", + "secondarySize", + "offset", + "chance", + "interval", + "scale", + "frame", + "light", + "{", + "}", + "subtractive", + "additive", + "halo", + "dontlightself", + "attenuate", + "dontlightactors", + "spot", + nullptr +}; + + +enum { + LIGHTTAG_COLOR, + LIGHTTAG_SIZE, + LIGHTTAG_SECSIZE, + LIGHTTAG_OFFSET, + LIGHTTAG_CHANCE, + LIGHTTAG_INTERVAL, + LIGHTTAG_SCALE, + LIGHTTAG_FRAME, + LIGHTTAG_LIGHT, + LIGHTTAG_OPENBRACE, + LIGHTTAG_CLOSEBRACE, + LIGHTTAG_SUBTRACTIVE, + LIGHTTAG_ADDITIVE, + LIGHTTAG_HALO, + LIGHTTAG_DONTLIGHTSELF, + LIGHTTAG_ATTENUATE, + LIGHTTAG_DONTLIGHTACTORS, + LIGHTTAG_SPOT +}; + +//========================================================================== +// +// Top level keywords +// +//========================================================================== + +// these are the core types available in the *DEFS lump +static const char *CoreKeywords[]= +{ + "pointlight", + "pulselight", + "flickerlight", + "flickerlight2", + "sectorlight", + "object", + "clearlights", + "shader", + "clearshaders", + "skybox", + "glow", + "brightmap", + "disable_fullbright", + "hardwareshader", + "detail", + "#include", + "material", + nullptr +}; + + +enum +{ + LIGHT_POINT, + LIGHT_PULSE, + LIGHT_FLICKER, + LIGHT_FLICKER2, + LIGHT_SECTOR, + LIGHT_OBJECT, + LIGHT_CLEAR, + TAG_SHADER, + TAG_CLEARSHADERS, + TAG_SKYBOX, + TAG_GLOW, + TAG_BRIGHTMAP, + TAG_DISABLE_FB, + TAG_HARDWARESHADER, + TAG_DETAIL, + TAG_INCLUDE, + TAG_MATERIAL +}; + +//========================================================================== +// +// GLDEFS parser +// +//========================================================================== + +class GLDefsParser +{ + FScanner sc; + int workingLump; + int ScriptDepth = 0; + TArray &LightAssociations; + + //========================================================================== + // + // This is only here so any shader definition for ZDoomGL can be skipped + // There is no functionality for this stuff! + // + //========================================================================== + + bool ParseShader() + { + int ShaderDepth = 0; + + if (sc.GetString()) + { + char *tmp; + + tmp = strstr(sc.String, "{"); + while (tmp) + { + ShaderDepth++; + tmp++; + tmp = strstr(tmp, "{"); + } + + tmp = strstr(sc.String, "}"); + while (tmp) + { + ShaderDepth--; + tmp++; + tmp = strstr(tmp, "}"); + } + + if (ShaderDepth == 0) return true; + } + return false; + } + + //========================================================================== + // + // Parses a GLBoom+ detail texture definition + // + // Syntax is this: + // detail + // { + // (walls | flats) [default_detail_name [width [height [offset_x [offset_y]]]]] + // { + // texture_name [detail_name [width [height [offset_x [offset_y]]]]] + // } + // } + // This merely parses the block and returns no error if valid. The feature + // is not actually implemented, so nothing else happens. + // + // The semantics of this are too horrible to comprehend (default detail texture???) + // so if this ever gets done, the parser will look different. + //========================================================================== + + void ParseDetailTexture() + { + while (!sc.CheckToken('}')) + { + sc.MustGetString(); + if (sc.Compare("walls") || sc.Compare("flats")) + { + if (!sc.CheckToken('{')) + { + sc.MustGetString(); // Default detail texture + if (sc.CheckFloat()) // Width + if (sc.CheckFloat()) // Height + if (sc.CheckFloat()) // OffsX + if (sc.CheckFloat()) // OffsY + { + // Nothing + } + } + else sc.UnGet(); + sc.MustGetToken('{'); + while (!sc.CheckToken('}')) + { + sc.MustGetString(); // Texture + if (sc.GetString()) // Detail texture + { + if (sc.CheckFloat()) // Width + if (sc.CheckFloat()) // Height + if (sc.CheckFloat()) // OffsX + if (sc.CheckFloat()) // OffsY + { + // Nothing + } + } + else sc.UnGet(); + } + } + } + } + + + //========================================================================== + // + // + // + //========================================================================== + + float ParseFloat(FScanner &sc) + { + sc.MustGetFloat(); + return float(sc.Float); + } + + + int ParseInt(FScanner &sc) + { + sc.MustGetNumber(); + return sc.Number; + } + + + char *ParseString(FScanner &sc) + { + sc.GetString(); + return sc.String; + } + + + void ParseTriple(FScanner &sc, float floatVal[3]) + { + for (int i = 0; i < 3; i++) + { + floatVal[i] = ParseFloat(sc); + } + } + + + //----------------------------------------------------------------------------- + // + // + // + //----------------------------------------------------------------------------- + + void AddLightAssociation(const char *actor, const char *frame, const char *light) + { + FLightAssociation *temp; + unsigned int i; + FLightAssociation assoc(actor, frame, light); + + for (i = 0; i < LightAssociations.Size(); i++) + { + temp = &LightAssociations[i]; + if (temp->ActorName() == assoc.ActorName()) + { + if (strcmp(temp->FrameName(), assoc.FrameName()) == 0) + { + temp->ReplaceLightName(assoc.Light()); + return; + } + } + } + + LightAssociations.Push(assoc); + } + + //----------------------------------------------------------------------------- + // + // Note: The different light type parsers really could use some consolidation... + // + //----------------------------------------------------------------------------- + + void ParsePointLight() + { + int type; + float floatTriple[3]; + int intVal; + FLightDefaults *defaults; + + // get name + sc.GetString(); + FName name = sc.String; + + // check for opening brace + sc.GetString(); + if (sc.Compare("{")) + { + defaults = new FLightDefaults(name, PointLight); + ScriptDepth++; + while (ScriptDepth) + { + sc.GetString(); + type = sc.MatchString(LightTags); + switch (type) + { + case LIGHTTAG_OPENBRACE: + ScriptDepth++; + break; + case LIGHTTAG_CLOSEBRACE: + ScriptDepth--; + break; + case LIGHTTAG_COLOR: + ParseTriple(sc, floatTriple); + defaults->SetArg(LIGHT_RED, clamp((int)(floatTriple[0] * 255), 0, 255)); + defaults->SetArg(LIGHT_GREEN, clamp((int)(floatTriple[1] * 255), 0, 255)); + defaults->SetArg(LIGHT_BLUE, clamp((int)(floatTriple[2] * 255), 0, 255)); + break; + case LIGHTTAG_OFFSET: + ParseTriple(sc, floatTriple); + defaults->SetOffset(floatTriple); + break; + case LIGHTTAG_SIZE: + intVal = clamp(ParseInt(sc), 1, 1024); + defaults->SetArg(LIGHT_INTENSITY, intVal); + break; + case LIGHTTAG_SUBTRACTIVE: + defaults->SetSubtractive(ParseInt(sc) != 0); + break; + case LIGHTTAG_ADDITIVE: + defaults->SetAdditive(ParseInt(sc) != 0); + break; + case LIGHTTAG_HALO: + defaults->SetHalo(ParseInt(sc) != 0); + break; + case LIGHTTAG_DONTLIGHTSELF: + defaults->SetDontLightSelf(ParseInt(sc) != 0); + break; + case LIGHTTAG_ATTENUATE: + defaults->SetAttenuate(ParseInt(sc) != 0); + break; + case LIGHTTAG_DONTLIGHTACTORS: + defaults->SetDontLightActors(ParseInt(sc) != 0); + break; + case LIGHTTAG_SPOT: + { + float innerAngle = ParseFloat(sc); + float outerAngle = ParseFloat(sc); + defaults->SetSpot(true); + defaults->SetSpotInnerAngle(innerAngle); + defaults->SetSpotOuterAngle(outerAngle); + } + break; + default: + sc.ScriptError("Unknown tag: %s\n", sc.String); + } + } + AddLightDefaults(defaults); + } + else + { + sc.ScriptError("Expected '{'.\n"); + } + } + + //----------------------------------------------------------------------------- + // + // + // + //----------------------------------------------------------------------------- + + void ParsePulseLight() + { + int type; + float floatVal, floatTriple[3]; + int intVal; + FLightDefaults *defaults; + + // get name + sc.GetString(); + FName name = sc.String; + + // check for opening brace + sc.GetString(); + if (sc.Compare("{")) + { + defaults = new FLightDefaults(name, PulseLight); + ScriptDepth++; + while (ScriptDepth) + { + sc.GetString(); + type = sc.MatchString(LightTags); + switch (type) + { + case LIGHTTAG_OPENBRACE: + ScriptDepth++; + break; + case LIGHTTAG_CLOSEBRACE: + ScriptDepth--; + break; + case LIGHTTAG_COLOR: + ParseTriple(sc, floatTriple); + defaults->SetArg(LIGHT_RED, clamp((int)(floatTriple[0] * 255), 0, 255)); + defaults->SetArg(LIGHT_GREEN, clamp((int)(floatTriple[1] * 255), 0, 255)); + defaults->SetArg(LIGHT_BLUE, clamp((int)(floatTriple[2] * 255), 0, 255)); + break; + case LIGHTTAG_OFFSET: + ParseTriple(sc, floatTriple); + defaults->SetOffset(floatTriple); + break; + case LIGHTTAG_SIZE: + intVal = clamp(ParseInt(sc), 1, 1024); + defaults->SetArg(LIGHT_INTENSITY, intVal); + break; + case LIGHTTAG_SECSIZE: + intVal = clamp(ParseInt(sc), 1, 1024); + defaults->SetArg(LIGHT_SECONDARY_INTENSITY, intVal); + break; + case LIGHTTAG_INTERVAL: + floatVal = ParseFloat(sc); + defaults->SetParameter(floatVal * TICRATE); + break; + case LIGHTTAG_SUBTRACTIVE: + defaults->SetSubtractive(ParseInt(sc) != 0); + break; + case LIGHTTAG_HALO: + defaults->SetHalo(ParseInt(sc) != 0); + break; + case LIGHTTAG_DONTLIGHTSELF: + defaults->SetDontLightSelf(ParseInt(sc) != 0); + break; + case LIGHTTAG_ATTENUATE: + defaults->SetAttenuate(ParseInt(sc) != 0); + break; + case LIGHTTAG_DONTLIGHTACTORS: + defaults->SetDontLightActors(ParseInt(sc) != 0); + break; + case LIGHTTAG_SPOT: + { + float innerAngle = ParseFloat(sc); + float outerAngle = ParseFloat(sc); + defaults->SetSpot(true); + defaults->SetSpotInnerAngle(innerAngle); + defaults->SetSpotOuterAngle(outerAngle); + } + break; + default: + sc.ScriptError("Unknown tag: %s\n", sc.String); + } + } + defaults->OrderIntensities(); + + AddLightDefaults(defaults); + } + else + { + sc.ScriptError("Expected '{'.\n"); + } + } + + + //----------------------------------------------------------------------------- + // + // + // + //----------------------------------------------------------------------------- + + void ParseFlickerLight() + { + int type; + float floatVal, floatTriple[3]; + int intVal; + FLightDefaults *defaults; + + // get name + sc.GetString(); + FName name = sc.String; + + // check for opening brace + sc.GetString(); + if (sc.Compare("{")) + { + defaults = new FLightDefaults(name, FlickerLight); + ScriptDepth++; + while (ScriptDepth) + { + sc.GetString(); + type = sc.MatchString(LightTags); + switch (type) + { + case LIGHTTAG_OPENBRACE: + ScriptDepth++; + break; + case LIGHTTAG_CLOSEBRACE: + ScriptDepth--; + break; + case LIGHTTAG_COLOR: + ParseTriple(sc, floatTriple); + defaults->SetArg(LIGHT_RED, clamp((int)(floatTriple[0] * 255), 0, 255)); + defaults->SetArg(LIGHT_GREEN, clamp((int)(floatTriple[1] * 255), 0, 255)); + defaults->SetArg(LIGHT_BLUE, clamp((int)(floatTriple[2] * 255), 0, 255)); + break; + case LIGHTTAG_OFFSET: + ParseTriple(sc, floatTriple); + defaults->SetOffset(floatTriple); + break; + case LIGHTTAG_SIZE: + intVal = clamp(ParseInt(sc), 1, 1024); + defaults->SetArg(LIGHT_INTENSITY, intVal); + break; + case LIGHTTAG_SECSIZE: + intVal = clamp(ParseInt(sc), 1, 1024); + defaults->SetArg(LIGHT_SECONDARY_INTENSITY, intVal); + break; + case LIGHTTAG_CHANCE: + floatVal = ParseFloat(sc); + defaults->SetParameter(floatVal*360.); + break; + case LIGHTTAG_SUBTRACTIVE: + defaults->SetSubtractive(ParseInt(sc) != 0); + break; + case LIGHTTAG_HALO: + defaults->SetHalo(ParseInt(sc) != 0); + break; + case LIGHTTAG_DONTLIGHTSELF: + defaults->SetDontLightSelf(ParseInt(sc) != 0); + break; + case LIGHTTAG_ATTENUATE: + defaults->SetAttenuate(ParseInt(sc) != 0); + break; + case LIGHTTAG_DONTLIGHTACTORS: + defaults->SetDontLightActors(ParseInt(sc) != 0); + break; + case LIGHTTAG_SPOT: + { + float innerAngle = ParseFloat(sc); + float outerAngle = ParseFloat(sc); + defaults->SetSpot(true); + defaults->SetSpotInnerAngle(innerAngle); + defaults->SetSpotOuterAngle(outerAngle); + } + break; + default: + sc.ScriptError("Unknown tag: %s\n", sc.String); + } + } + defaults->OrderIntensities(); + AddLightDefaults(defaults); + } + else + { + sc.ScriptError("Expected '{'.\n"); + } + } + + + //----------------------------------------------------------------------------- + // + // + // + //----------------------------------------------------------------------------- + + void ParseFlickerLight2() + { + int type; + float floatVal, floatTriple[3]; + int intVal; + FLightDefaults *defaults; + + // get name + sc.GetString(); + FName name = sc.String; + + // check for opening brace + sc.GetString(); + if (sc.Compare("{")) + { + defaults = new FLightDefaults(name, RandomFlickerLight); + ScriptDepth++; + while (ScriptDepth) + { + sc.GetString(); + type = sc.MatchString(LightTags); + switch (type) + { + case LIGHTTAG_OPENBRACE: + ScriptDepth++; + break; + case LIGHTTAG_CLOSEBRACE: + ScriptDepth--; + break; + case LIGHTTAG_COLOR: + ParseTriple(sc, floatTriple); + defaults->SetArg(LIGHT_RED, clamp((int)(floatTriple[0] * 255), 0, 255)); + defaults->SetArg(LIGHT_GREEN, clamp((int)(floatTriple[1] * 255), 0, 255)); + defaults->SetArg(LIGHT_BLUE, clamp((int)(floatTriple[2] * 255), 0, 255)); + break; + case LIGHTTAG_OFFSET: + ParseTriple(sc, floatTriple); + defaults->SetOffset(floatTriple); + break; + case LIGHTTAG_SIZE: + intVal = clamp(ParseInt(sc), 1, 1024); + defaults->SetArg(LIGHT_INTENSITY, intVal); + break; + case LIGHTTAG_SECSIZE: + intVal = clamp(ParseInt(sc), 1, 1024); + defaults->SetArg(LIGHT_SECONDARY_INTENSITY, intVal); + break; + case LIGHTTAG_INTERVAL: + floatVal = ParseFloat(sc); + defaults->SetParameter(floatVal * 360.); + break; + case LIGHTTAG_SUBTRACTIVE: + defaults->SetSubtractive(ParseInt(sc) != 0); + break; + case LIGHTTAG_HALO: + defaults->SetHalo(ParseInt(sc) != 0); + break; + case LIGHTTAG_DONTLIGHTSELF: + defaults->SetDontLightSelf(ParseInt(sc) != 0); + break; + case LIGHTTAG_ATTENUATE: + defaults->SetAttenuate(ParseInt(sc) != 0); + break; + case LIGHTTAG_DONTLIGHTACTORS: + defaults->SetDontLightActors(ParseInt(sc) != 0); + break; + case LIGHTTAG_SPOT: + { + float innerAngle = ParseFloat(sc); + float outerAngle = ParseFloat(sc); + defaults->SetSpot(true); + defaults->SetSpotInnerAngle(innerAngle); + defaults->SetSpotOuterAngle(outerAngle); + } + break; + default: + sc.ScriptError("Unknown tag: %s\n", sc.String); + } + } + if (defaults->GetArg(LIGHT_SECONDARY_INTENSITY) < defaults->GetArg(LIGHT_INTENSITY)) + { + int v = defaults->GetArg(LIGHT_SECONDARY_INTENSITY); + defaults->SetArg(LIGHT_SECONDARY_INTENSITY, defaults->GetArg(LIGHT_INTENSITY)); + defaults->SetArg(LIGHT_INTENSITY, v); + } + AddLightDefaults(defaults); + } + else + { + sc.ScriptError("Expected '{'.\n"); + } + } + + + //----------------------------------------------------------------------------- + // + // + // + //----------------------------------------------------------------------------- + + void ParseSectorLight() + { + int type; + float floatVal; + float floatTriple[3]; + FLightDefaults *defaults; + + // get name + sc.GetString(); + FName name = sc.String; + + // check for opening brace + sc.GetString(); + if (sc.Compare("{")) + { + defaults = new FLightDefaults(name, SectorLight); + ScriptDepth++; + while (ScriptDepth) + { + sc.GetString(); + type = sc.MatchString(LightTags); + switch (type) + { + case LIGHTTAG_OPENBRACE: + ScriptDepth++; + break; + case LIGHTTAG_CLOSEBRACE: + ScriptDepth--; + break; + case LIGHTTAG_COLOR: + ParseTriple(sc, floatTriple); + defaults->SetArg(LIGHT_RED, clamp((int)(floatTriple[0] * 255), 0, 255)); + defaults->SetArg(LIGHT_GREEN, clamp((int)(floatTriple[1] * 255), 0, 255)); + defaults->SetArg(LIGHT_BLUE, clamp((int)(floatTriple[2] * 255), 0, 255)); + break; + case LIGHTTAG_OFFSET: + ParseTriple(sc, floatTriple); + defaults->SetOffset(floatTriple); + break; + case LIGHTTAG_SCALE: + floatVal = ParseFloat(sc); + defaults->SetArg(LIGHT_SCALE, clamp((int)(floatVal * 255), 1, 1024)); + break; + case LIGHTTAG_SUBTRACTIVE: + defaults->SetSubtractive(ParseInt(sc) != 0); + break; + case LIGHTTAG_HALO: + defaults->SetHalo(ParseInt(sc) != 0); + break; + case LIGHTTAG_DONTLIGHTSELF: + defaults->SetDontLightSelf(ParseInt(sc) != 0); + break; + case LIGHTTAG_ATTENUATE: + defaults->SetAttenuate(ParseInt(sc) != 0); + break; + case LIGHTTAG_DONTLIGHTACTORS: + defaults->SetDontLightActors(ParseInt(sc) != 0); + break; + case LIGHTTAG_SPOT: + { + float innerAngle = ParseFloat(sc); + float outerAngle = ParseFloat(sc); + defaults->SetSpot(true); + defaults->SetSpotInnerAngle(innerAngle); + defaults->SetSpotOuterAngle(outerAngle); + } + break; + default: + sc.ScriptError("Unknown tag: %s\n", sc.String); + } + } + AddLightDefaults(defaults); + } + else + { + sc.ScriptError("Expected '{'.\n"); + } + } + + //----------------------------------------------------------------------------- + // + // + // + //----------------------------------------------------------------------------- + + void ParseFrame(const FString &name) + { + int type, startDepth; + FString frameName; + + // get name + sc.GetString(); + if (strlen(sc.String) > 8) + { + sc.ScriptError("Name longer than 8 characters: %s\n", sc.String); + } + frameName = sc.String; + + startDepth = ScriptDepth; + + // check for opening brace + sc.GetString(); + if (sc.Compare("{")) + { + ScriptDepth++; + while (ScriptDepth > startDepth) + { + sc.GetString(); + type = sc.MatchString(LightTags); + switch (type) + { + case LIGHTTAG_OPENBRACE: + ScriptDepth++; + break; + case LIGHTTAG_CLOSEBRACE: + ScriptDepth--; + break; + case LIGHTTAG_LIGHT: + ParseString(sc); + AddLightAssociation(name, frameName, sc.String); + break; + default: + sc.ScriptError("Unknown tag: %s\n", sc.String); + } + } + } + else + { + sc.ScriptError("Expected '{'.\n"); + } + } + + //----------------------------------------------------------------------------- + // + // + // + //----------------------------------------------------------------------------- + + void ParseObject() + { + int type; + FString name; + + // get name + sc.GetString(); + name = sc.String; + if (!PClass::FindActor(name)) + sc.ScriptMessage("Warning: dynamic lights attached to non-existent actor %s\n", name.GetChars()); + + // check for opening brace + sc.GetString(); + if (sc.Compare("{")) + { + ScriptDepth++; + while (ScriptDepth) + { + sc.GetString(); + type = sc.MatchString(LightTags); + switch (type) + { + case LIGHTTAG_OPENBRACE: + ScriptDepth++; + break; + case LIGHTTAG_CLOSEBRACE: + ScriptDepth--; + break; + case LIGHTTAG_FRAME: + ParseFrame(name); + break; + default: + sc.ScriptError("Unknown tag: %s\n", sc.String); + } + } + } + else + { + sc.ScriptError("Expected '{'.\n"); + } + } + + + //----------------------------------------------------------------------------- + // + // + // + //----------------------------------------------------------------------------- + + void ParseGldefSkybox() + { + int facecount=0; + + sc.MustGetString(); + + FSkyBox * sb = new FSkyBox; + sb->Name = sc.String; + sb->Name.ToUpper(); + if (sc.CheckString("fliptop")) + { + sb->fliptop = true; + } + sc.MustGetStringName("{"); + while (!sc.CheckString("}")) + { + sc.MustGetString(); + if (facecount<6) + { + sb->faces[facecount] = TexMan[TexMan.GetTexture(sc.String, ETextureType::Wall, FTextureManager::TEXMAN_TryAny|FTextureManager::TEXMAN_Overridable)]; + } + facecount++; + } + if (facecount != 3 && facecount != 6) + { + sc.ScriptError("%s: Skybox definition requires either 3 or 6 faces", sb->Name.GetChars()); + } + sb->SetSize(); + TexMan.AddTexture(sb); + } + + //=========================================================================== + // + // Reads glow definitions from GLDEFS + // + //=========================================================================== + + void ParseGlow() + { + sc.MustGetStringName("{"); + while (!sc.CheckString("}")) + { + sc.MustGetString(); + if (sc.Compare("FLATS")) + { + sc.MustGetStringName("{"); + while (!sc.CheckString("}")) + { + sc.MustGetString(); + FTextureID flump=TexMan.CheckForTexture(sc.String, ETextureType::Flat,FTextureManager::TEXMAN_TryAny); + FTexture *tex = TexMan[flump]; + if (tex) tex->bAutoGlowing = tex->bGlowing = tex->bFullbright = true; + } + } + else if (sc.Compare("WALLS")) + { + sc.MustGetStringName("{"); + while (!sc.CheckString("}")) + { + sc.MustGetString(); + FTextureID flump=TexMan.CheckForTexture(sc.String, ETextureType::Wall,FTextureManager::TEXMAN_TryAny); + FTexture *tex = TexMan[flump]; + if (tex) tex->bAutoGlowing = tex->bGlowing = tex->bFullbright = true; + } + } + else if (sc.Compare("TEXTURE")) + { + sc.SetCMode(true); + sc.MustGetString(); + FTextureID flump=TexMan.CheckForTexture(sc.String, ETextureType::Flat,FTextureManager::TEXMAN_TryAny); + FTexture *tex = TexMan[flump]; + sc.MustGetStringName(","); + sc.MustGetString(); + PalEntry color = V_GetColor(NULL, sc.String); + //sc.MustGetStringName(","); + //sc.MustGetNumber(); + if (sc.CheckString(",")) + { + if (sc.CheckNumber()) + { + if (tex) tex->GlowHeight = sc.Number; + if (!sc.CheckString(",")) goto skip_fb; + } + + sc.MustGetStringName("fullbright"); + if (tex) tex->bFullbright = true; + } + skip_fb: + sc.SetCMode(false); + + if (tex && color != 0) + { + tex->bAutoGlowing = false; + tex->bGlowing = true; + tex->GlowColor = color; + } + } + } + } + + + //========================================================================== + // + // Parses a brightmap definition + // + //========================================================================== + + void ParseBrightmap() + { + ETextureType type = ETextureType::Any; + bool disable_fullbright=false; + bool thiswad = false; + bool iwad = false; + FTexture *bmtex = NULL; + + sc.MustGetString(); + if (sc.Compare("texture")) type = ETextureType::Wall; + else if (sc.Compare("flat")) type = ETextureType::Flat; + else if (sc.Compare("sprite")) type = ETextureType::Sprite; + else sc.UnGet(); + + sc.MustGetString(); + FTextureID no = TexMan.CheckForTexture(sc.String, type, FTextureManager::TEXMAN_TryAny | FTextureManager::TEXMAN_Overridable); + FTexture *tex = TexMan[no]; + + sc.MustGetToken('{'); + while (!sc.CheckToken('}')) + { + sc.MustGetString(); + if (sc.Compare("disablefullbright")) + { + // This can also be used without a brightness map to disable + // fullbright in rotations that only use brightness maps on + // other angles. + disable_fullbright = true; + } + else if (sc.Compare("thiswad")) + { + // only affects textures defined in the WAD containing the definition file. + thiswad = true; + } + else if (sc.Compare ("iwad")) + { + // only affects textures defined in the IWAD. + iwad = true; + } + else if (sc.Compare ("map")) + { + sc.MustGetString(); + + if (bmtex != NULL) + { + Printf("Multiple brightmap definitions in texture %s\n", tex? tex->Name.GetChars() : "(null)"); + } + + bmtex = TexMan.FindTexture(sc.String, ETextureType::Any, FTextureManager::TEXMAN_TryAny); + + if (bmtex == NULL) + Printf("Brightmap '%s' not found in texture '%s'\n", sc.String, tex? tex->Name.GetChars() : "(null)"); + } + } + if (!tex) + { + return; + } + if (thiswad || iwad) + { + bool useme = false; + int lumpnum = tex->GetSourceLump(); + + if (lumpnum != -1) + { + if (iwad && Wads.GetLumpFile(lumpnum) <= Wads.GetIwadNum()) useme = true; + if (thiswad && Wads.GetLumpFile(lumpnum) == workingLump) useme = true; + } + if (!useme) return; + } + + if (bmtex != NULL) + { + /* I do not think this is needed any longer + if (tex->bWarped != 0) + { + Printf("Cannot combine warping with brightmap on texture '%s'\n", tex->Name.GetChars()); + return; + } + */ + + bmtex->bMasked = false; + tex->Brightmap = bmtex; + } + tex->bDisableFullbright = disable_fullbright; + } + + + //========================================================================== + // + // Parses a material definition + // + //========================================================================== + + void ParseMaterial() + { + ETextureType type = ETextureType::Any; + bool disable_fullbright = false; + bool disable_fullbright_specified = false; + bool thiswad = false; + bool iwad = false; + + FTexture *textures[6]; + const char *keywords[7] = { "brightmap", "normal", "specular", "metallic", "roughness", "ao", nullptr }; + const char *notFound[6] = { "Brightmap", "Normalmap", "Specular texture", "Metallic texture", "Roughness texture", "Ambient occlusion texture" }; + memset(textures, 0, sizeof(textures)); + + sc.MustGetString(); + if (sc.Compare("texture")) type = ETextureType::Wall; + else if (sc.Compare("flat")) type = ETextureType::Flat; + else if (sc.Compare("sprite")) type = ETextureType::Sprite; + else sc.UnGet(); + + sc.MustGetString(); + FTextureID no = TexMan.CheckForTexture(sc.String, type, FTextureManager::TEXMAN_TryAny | FTextureManager::TEXMAN_Overridable); + FTexture *tex = TexMan[no]; + + sc.MustGetToken('{'); + while (!sc.CheckToken('}')) + { + sc.MustGetString(); + if (sc.Compare("disablefullbright")) + { + // This can also be used without a brightness map to disable + // fullbright in rotations that only use brightness maps on + // other angles. + disable_fullbright = true; + disable_fullbright_specified = true; + } + else if (sc.Compare("thiswad")) + { + // only affects textures defined in the WAD containing the definition file. + thiswad = true; + } + else if (sc.Compare ("iwad")) + { + // only affects textures defined in the IWAD. + iwad = true; + } + else if (sc.Compare("glossiness")) + { + sc.MustGetFloat(); + if (tex) + tex->Glossiness = (float)sc.Float; + } + else if (sc.Compare("specularlevel")) + { + sc.MustGetFloat(); + if (tex) + tex->SpecularLevel = (float)sc.Float; + } + else + { + for (int i = 0; keywords[i] != nullptr; i++) + { + if (sc.Compare (keywords[i])) + { + sc.MustGetString(); + if (textures[i]) + Printf("Multiple %s definitions in texture %s\n", keywords[i], tex? tex->Name.GetChars() : "(null)"); + textures[i] = TexMan.FindTexture(sc.String, ETextureType::Any, FTextureManager::TEXMAN_TryAny); + if (!textures[i]) + Printf("%s '%s' not found in texture '%s'\n", notFound[i], sc.String, tex? tex->Name.GetChars() : "(null)"); + break; + } + } + } + } + if (!tex) + { + return; + } + if (thiswad || iwad) + { + bool useme = false; + int lumpnum = tex->GetSourceLump(); + + if (lumpnum != -1) + { + if (iwad && Wads.GetLumpFile(lumpnum) <= Wads.GetIwadNum()) useme = true; + if (thiswad && Wads.GetLumpFile(lumpnum) == workingLump) useme = true; + } + if (!useme) return; + } + + FTexture **bindings[6] = + { + &tex->Brightmap, + &tex->Normal, + &tex->Specular, + &tex->Metallic, + &tex->Roughness, + &tex->AmbientOcclusion + }; + for (int i = 0; keywords[i] != nullptr; i++) + { + if (textures[i]) + { + textures[i]->bMasked = false; + *bindings[i] = textures[i]; + } + } + + if (disable_fullbright_specified) + tex->bDisableFullbright = disable_fullbright; + } + + + //========================================================================== + // + // Parses a shader definition + // + //========================================================================== + + void ParseHardwareShader() + { + sc.MustGetString(); + if (sc.Compare("postprocess")) + { + sc.MustGetString(); + + PostProcessShader shaderdesc; + shaderdesc.Target = sc.String; + shaderdesc.Target.ToLower(); + + bool validTarget = false; + if (sc.Compare("beforebloom")) validTarget = true; + if (sc.Compare("scene")) validTarget = true; + if (sc.Compare("screen")) validTarget = true; + if (!validTarget) + sc.ScriptError("Invalid target '%s' for postprocess shader",sc.String); + + sc.MustGetToken('{'); + while (!sc.CheckToken('}')) + { + sc.MustGetString(); + if (sc.Compare("shader")) + { + sc.MustGetString(); + shaderdesc.ShaderLumpName = sc.String; + + sc.MustGetNumber(); + shaderdesc.ShaderVersion = sc.Number; + if (sc.Number > 450 || sc.Number < 330) + sc.ScriptError("Shader version must be in range 330 to 450!"); + } + else if (sc.Compare("name")) + { + sc.MustGetString(); + shaderdesc.Name = sc.String; + } + else if (sc.Compare("uniform")) + { + sc.MustGetString(); + FString uniformType = sc.String; + uniformType.ToLower(); + + sc.MustGetString(); + FString uniformName = sc.String; + + PostProcessUniformType parsedType = PostProcessUniformType::Undefined; + + if (uniformType.Compare("int") == 0) + parsedType = PostProcessUniformType::Int; + else if (uniformType.Compare("float") == 0) + parsedType = PostProcessUniformType::Float; + else if (uniformType.Compare("vec2") == 0) + parsedType = PostProcessUniformType::Vec2; + else if (uniformType.Compare("vec3") == 0) + parsedType = PostProcessUniformType::Vec3; + else + sc.ScriptError("Unrecognized uniform type '%s'", sc.String); + + if (parsedType != PostProcessUniformType::Undefined) + shaderdesc.Uniforms[uniformName].Type = parsedType; + } + else if (sc.Compare("texture")) + { + sc.MustGetString(); + FString textureName = sc.String; + + sc.MustGetString(); + FString textureSource = sc.String; + + shaderdesc.Textures[textureName] = textureSource; + } + else if (sc.Compare("enabled")) + { + shaderdesc.Enabled = true; + } + else + { + sc.ScriptError("Unknown keyword '%s'", sc.String); + } + } + + PostProcessShaders.Push(shaderdesc); + } + else + { + ETextureType type = ETextureType::Any; + + if (sc.Compare("texture")) type = ETextureType::Wall; + else if (sc.Compare("flat")) type = ETextureType::Flat; + else if (sc.Compare("sprite")) type = ETextureType::Sprite; + else sc.UnGet(); + + bool disable_fullbright = false; + bool thiswad = false; + bool iwad = false; + int maplump = -1; + FString maplumpname; + float speed = 1.f; + + sc.MustGetString(); + FTextureID no = TexMan.CheckForTexture(sc.String, type); + FTexture *tex = TexMan[no]; + + sc.MustGetToken('{'); + while (!sc.CheckToken('}')) + { + sc.MustGetString(); + if (sc.Compare("shader")) + { + sc.MustGetString(); + maplumpname = sc.String; + } + else if (sc.Compare("speed")) + { + sc.MustGetFloat(); + speed = float(sc.Float); + } + } + if (!tex) + { + return; + } + + if (maplumpname.IsNotEmpty()) + { + if (tex->bWarped != 0) + { + Printf("Cannot combine warping with hardware shader on texture '%s'\n", tex->Name.GetChars()); + return; + } + tex->shaderspeed = speed; + for (unsigned i = 0; i < usershaders.Size(); i++) + { + if (!usershaders[i].CompareNoCase(maplumpname)) + { + tex->shaderindex = i + FIRST_USER_SHADER; + return; + } + } + tex->shaderindex = usershaders.Push(maplumpname) + FIRST_USER_SHADER; + } + } + } + + + +public: + //========================================================================== + // + // + // + //========================================================================== + void DoParseDefs() + { + int recursion=0; + int lump, type; + + // Get actor class name. + while (true) + { + sc.SavePos(); + if (!sc.GetToken ()) + { + return; + } + type = sc.MatchString(CoreKeywords); + switch (type) + { + case TAG_INCLUDE: + { + sc.MustGetString(); + // This is not using sc.Open because it can print a more useful error message when done here + lump = Wads.CheckNumForFullName(sc.String, true); + if (lump==-1) + sc.ScriptError("Lump '%s' not found", sc.String); + + GLDefsParser newscanner(lump, LightAssociations); + newscanner.DoParseDefs(); + break; + } + case LIGHT_POINT: + ParsePointLight(); + break; + case LIGHT_PULSE: + ParsePulseLight(); + break; + case LIGHT_FLICKER: + ParseFlickerLight(); + break; + case LIGHT_FLICKER2: + ParseFlickerLight2(); + break; + case LIGHT_SECTOR: + ParseSectorLight(); + break; + case LIGHT_OBJECT: + ParseObject(); + break; + case LIGHT_CLEAR: + // This has been intentionally removed + break; + case TAG_SHADER: + ParseShader(); + break; + case TAG_CLEARSHADERS: + break; + case TAG_SKYBOX: + ParseGldefSkybox(); + break; + case TAG_GLOW: + ParseGlow(); + break; + case TAG_BRIGHTMAP: + ParseBrightmap(); + break; + case TAG_MATERIAL: + ParseMaterial(); + break; + case TAG_HARDWARESHADER: + ParseHardwareShader(); + break; + case TAG_DETAIL: + ParseDetailTexture(); + break; + case TAG_DISABLE_FB: + { + /* not implemented. + sc.MustGetString(); + const PClass *cls = PClass::FindClass(sc.String); + if (cls) GetDefaultByType(cls)->renderflags |= RF_NEVERFULLBRIGHT; + */ + } + break; + default: + sc.ScriptError("Error parsing defs. Unknown tag: %s.\n", sc.String); + break; + } + } + } + + GLDefsParser(int lumpnum, TArray &la) + : sc(lumpnum), workingLump(lumpnum), LightAssociations(la) + { + } +}; + +//========================================================================== +// +// +// +//========================================================================== + +void LoadGLDefs(const char *defsLump) +{ + TArray LightAssociations; + int workingLump, lastLump; + static const char *gldefsnames[] = { "GLDEFS", defsLump, nullptr }; + + lastLump = 0; + while ((workingLump = Wads.FindLumpMulti(gldefsnames, &lastLump)) != -1) + { + GLDefsParser sc(workingLump, LightAssociations); + sc.DoParseDefs(); + } + InitializeActorLights(LightAssociations); +} + + +//========================================================================== +// +// +// +//========================================================================== + +void ParseGLDefs() +{ + const char *defsLump = NULL; + + LightDefaults.Clear(); + //gl_DestroyUserShaders(); function says 'todo' + switch (gameinfo.gametype) + { + case GAME_Heretic: + defsLump = "HTICDEFS"; + break; + case GAME_Hexen: + defsLump = "HEXNDEFS"; + break; + case GAME_Strife: + defsLump = "STRFDEFS"; + break; + case GAME_Doom: + defsLump = "DOOMDEFS"; + break; + case GAME_Chex: + defsLump = "CHEXDEFS"; + break; + default: // silence GCC + break; + } + ParseVavoomSkybox(); + LoadGLDefs(defsLump); +} diff --git a/src/r_data/models/models_voxel.cpp b/src/r_data/models/models_voxel.cpp index 087b80657a..6b9e26d2e4 100644 --- a/src/r_data/models/models_voxel.cpp +++ b/src/r_data/models/models_voxel.cpp @@ -80,8 +80,7 @@ FVoxelTexture::FVoxelTexture(FVoxel *vox) WidthBits = 4; HeightBits = 4; WidthMask = 15; - gl_info.bNoFilter = true; - gl_info.bNoCompress = true; + bNoCompress = true; } //=========================================================================== @@ -307,7 +306,7 @@ void FVoxelModel::Initialize() FVoxelMipLevel *mip = &mVoxel->Mips[0]; for (int x = 0; x < mip->SizeX; x++) { - uint8_t *slabxoffs = &mip->SlabData[mip->OffsetX[x]]; + uint8_t *slabxoffs = &mip->GetSlabData(false)[mip->OffsetX[x]]; short *xyoffs = &mip->OffsetXY[x * (mip->SizeY + 1)]; for (int y = 0; y < mip->SizeY; y++) { diff --git a/src/gl/data/gl_portaldata.cpp b/src/r_data/portalgroups.cpp similarity index 77% rename from src/gl/data/gl_portaldata.cpp rename to src/r_data/portalgroups.cpp index a51d204300..a7f1b6daea 100644 --- a/src/gl/data/gl_portaldata.cpp +++ b/src/r_data/portalgroups.cpp @@ -19,12 +19,6 @@ // //-------------------------------------------------------------------------- // -/* -** gl_setup.cpp -** Initializes the data structures required by the GL renderer to handle -** a level -** -**/ #include "doomtype.h" #include "colormatcher.h" @@ -39,16 +33,14 @@ #include "g_level.h" #include "a_sharedglobal.h" #include "g_levellocals.h" +#include "r_utility.h" -#include "gl/renderer/gl_renderer.h" -#include "gl/data/gl_data.h" -#include "gl/data/gl_vertexbuffer.h" -#include "gl/scene/gl_clipper.h" -#include "gl/scene/gl_portal.h" -#include "gl/dynlights/gl_dynlight.h" -#include "gl/dynlights/gl_glow.h" -#include "gl/utility/gl_clock.h" -#include "gl/gl_functions.h" + +//========================================================================== +// +// Helper types for portal grouping +// +//========================================================================== struct FPortalID { @@ -69,25 +61,8 @@ struct FPortalSector }; typedef TArray FPortalSectors; - typedef TMap FPortalMap; -TArray glSectorPortals; -TArray linePortalToGL; -TArray glLinePortals; - -//========================================================================== -// -// -// -//========================================================================== - -GLSectorStackPortal *FPortal::GetRenderState() -{ - if (glportal == NULL) glportal = new GLSectorStackPortal(this); - return glportal; -} - //========================================================================== // // this is left as fixed_t because the nodes also are, it makes no sense @@ -305,10 +280,16 @@ struct FCoverageBuilder //========================================================================== // // Calculate portal coverage for a single subsector +// This data is used by the clipper to free up the ranges covered by a portal. +// +// This also gets called by the render hack code because ZDoom was really lax +// with its stacked sector things and allowed partial tagging of affected sectors +// Any such sector will only be found during rendering and must create its +// coverage info then. // //========================================================================== -void gl_BuildPortalCoverage(FPortalCoverage *coverage, subsector_t *subsector, const DVector2 &displacement) +void BuildPortalCoverage(FPortalCoverage *coverage, subsector_t *subsector, const DVector2 &displacement) { TArray shape; double centerx=0, centery=0; @@ -332,7 +313,7 @@ void gl_BuildPortalCoverage(FPortalCoverage *coverage, subsector_t *subsector, c //========================================================================== // -// portal initialization +// // //========================================================================== @@ -355,15 +336,20 @@ static void CollectPortalSectors(FPortalMap &collection) } } -void gl_InitPortals() +//========================================================================== +// +// group sector portals by displacement +// The renderer can handle such a group in one go to avoid multiple +// BSP traversals +// +//========================================================================== + +static void GroupSectorPortals() { FPortalMap collection; - if (level.nodes.Size() == 0) return; - - CollectPortalSectors(collection); - glSectorPortals.Clear(); + level.portalGroups.Clear(); FPortalMap::Iterator it(collection); FPortalMap::Pair *pair; @@ -371,31 +357,31 @@ void gl_InitPortals() int planeflags = 0; while (it.NextPair(pair)) { - for(unsigned i=0;iValue.Size(); i++) + for (unsigned i = 0; i < pair->Value.Size(); i++) { if (pair->Value[i].mPlane == sector_t::floor) planeflags |= 1; else if (pair->Value[i].mPlane == sector_t::ceiling) planeflags |= 2; } - for (int i=1;i<=2;i<<=1) + for (int i = 1; i <= 2; i <<= 1) { - // add separate glSectorPortals for floor and ceiling. + // add separate portals for floor and ceiling. if (planeflags & i) { - FPortal *portal = new FPortal; + FSectorPortalGroup *portal = new FSectorPortalGroup; portal->mDisplacement = pair->Key.mDisplacement; - portal->plane = (i==1? sector_t::floor : sector_t::ceiling); /**/ + portal->plane = (i == 1 ? sector_t::floor : sector_t::ceiling); /**/ portal->glportal = NULL; - glSectorPortals.Push(portal); - for(unsigned j=0;jValue.Size(); j++) + level.portalGroups.Push(portal); + for (unsigned j = 0; j < pair->Value.Size(); j++) { sector_t *sec = pair->Value[j].mSub; int plane = pair->Value[j].mPlane; if (portal->plane == plane) { - for(int k=0;ksubsectorcount; k++) + for (int k = 0; k < sec->subsectorcount; k++) { subsector_t *sub = sec->subsectors[k]; - gl_BuildPortalCoverage(&sub->portalcoverage[plane], sub, pair->Key.mDisplacement); + BuildPortalCoverage(&sub->portalcoverage[plane], sub, pair->Key.mDisplacement); } sec->portals[plane] = portal; } @@ -403,30 +389,38 @@ void gl_InitPortals() } } } +} - // Now group the line glSectorPortals (each group must be a continuous set of colinear linedefs with no gaps) - glLinePortals.Clear(); - linePortalToGL.Clear(); +//========================================================================== +// +// Group the line portals +// Each group must be a continuous set of colinear linedefs with no gaps +// +//========================================================================== + +static void GroupLinePortals() +{ + level.linePortalSpans.Clear(); TArray tempindex; - tempindex.Reserve(linePortals.Size()); - memset(&tempindex[0], -1, linePortals.Size() * sizeof(int)); + tempindex.Reserve(level.linePortals.Size()); + memset(&tempindex[0], -1, level.linePortals.Size() * sizeof(int)); - for (unsigned i = 0; i < linePortals.Size(); i++) + for (unsigned i = 0; i < level.linePortals.Size(); i++) { - auto port = linePortals[i]; + auto port = level.linePortals[i]; bool gotsome; if (tempindex[i] == -1) { - tempindex[i] = glLinePortals.Size(); - line_t *pSrcLine = linePortals[i].mOrigin; - line_t *pLine = linePortals[i].mDestination; - FGLLinePortal &glport = glLinePortals[glLinePortals.Reserve(1)]; - glport.lines.Push(&linePortals[i]); + tempindex[i] = level.linePortalSpans.Size(); + line_t *pSrcLine = level.linePortals[i].mOrigin; + line_t *pLine = level.linePortals[i].mDestination; + FLinePortalSpan &glport = level.linePortalSpans[level.linePortalSpans.Reserve(1)]; + glport.lines.Push(&level.linePortals[i]); - // We cannot do this grouping for non-linked glSectorPortals because they can be changed at run time. - if (linePortals[i].mType == PORTT_LINKED && pLine != nullptr) + // We cannot do this grouping for non-linked portals because they can be changed at run time. + if (level.linePortals[i].mType == PORTT_LINKED && pLine != nullptr) { glport.v1 = pLine->v1; glport.v2 = pLine->v2; @@ -434,13 +428,13 @@ void gl_InitPortals() { // now collect all other colinear lines connected to this one. We run this loop as long as it still finds a match gotsome = false; - for (unsigned j = 0; j < linePortals.Size(); j++) + for (unsigned j = 0; j < level.linePortals.Size(); j++) { if (tempindex[j] == -1) { - line_t *pSrcLine2 = linePortals[j].mOrigin; - line_t *pLine2 = linePortals[j].mDestination; - // angular precision is intentionally reduced to 32 bit BAM to account for precision problems (otherwise many not perfectly horizontal or vertical glSectorPortals aren't found here.) + line_t *pSrcLine2 = level.linePortals[j].mOrigin; + line_t *pLine2 = level.linePortals[j].mDestination; + // angular precision is intentionally reduced to 32 bit BAM to account for precision problems (otherwise many not perfectly horizontal or vertical portals aren't found here.) unsigned srcang = pSrcLine->Delta().Angle().BAMs(); unsigned dstang = pLine->Delta().Angle().BAMs(); if ((pSrcLine->v2 == pSrcLine2->v1 && pLine->v1 == pLine2->v2) || @@ -456,7 +450,7 @@ void gl_InitPortals() tempindex[j] = tempindex[i]; if (pLine->v1 == pLine2->v2) glport.v1 = pLine2->v1; else glport.v2 = pLine2->v2; - glport.lines.Push(&linePortals[j]); + glport.lines.Push(&level.linePortals[j]); } } } @@ -465,30 +459,36 @@ void gl_InitPortals() } } } - linePortalToGL.Resize(linePortals.Size()); - for (unsigned i = 0; i < linePortals.Size(); i++) + + // Final assignment can only be done when all allocations are finished. Otherwise the array may be moved. + for (unsigned i = 0; i < level.linePortals.Size(); i++) { - linePortalToGL[i] = &glLinePortals[tempindex[i]]; - /* - Printf("portal at line %d translates to GL portal %d, range = %f,%f to %f,%f\n", - int(linePortals[i].mOrigin - lines), tempindex[i], linePortalToGL[i]->v1->fixX() / 65536., linePortalToGL[i]->v1->fixY() / 65536., linePortalToGL[i]->v2->fixX() / 65536., linePortalToGL[i]->v2->fixY() / 65536.); - */ + level.linePortals[i].mGroup = &level.linePortalSpans[tempindex[i]]; } } +void InitPortalGroups() +{ + if (level.nodes.Size() == 0) return; + + GroupSectorPortals(); + GroupLinePortals(); +} + CCMD(dumpportals) { - for(unsigned i=0;imDisplacement.X; - double ydisp = glSectorPortals[i]->mDisplacement.Y; - Printf(PRINT_LOG, "Portal #%d, %s, displacement = (%f,%f)\n", i, glSectorPortals[i]->plane==0? "floor":"ceiling", + auto p = level.portalGroups[i]; + double xdisp = p->mDisplacement.X; + double ydisp = p->mDisplacement.Y; + Printf(PRINT_LOG, "Portal #%d, %s, displacement = (%f,%f)\n", i, p->plane==0? "floor":"ceiling", xdisp, ydisp); Printf(PRINT_LOG, "Coverage:\n"); for(auto &sub : level.subsectors) { - FPortal *port = sub.render_sector->GetGLPortal(glSectorPortals[i]->plane); - if (port == glSectorPortals[i]) + auto port = sub.render_sector->GetPortalGroup(p->plane); + if (port == p) { Printf(PRINT_LOG, "\tSubsector %d (%d):\n\t\t", sub.Index(), sub.render_sector->sectornum); for(unsigned k = 0;k< sub.numlines; k++) @@ -496,7 +496,7 @@ CCMD(dumpportals) Printf(PRINT_LOG, "(%.3f,%.3f), ", sub.firstline[k].v1->fX() + xdisp, sub.firstline[k].v1->fY() + ydisp); } Printf(PRINT_LOG, "\n\t\tCovered by subsectors:\n"); - FPortalCoverage *cov = &sub.portalcoverage[glSectorPortals[i]->plane]; + FPortalCoverage *cov = &sub.portalcoverage[p->plane]; for(int l = 0;l< cov->sscount; l++) { subsector_t *csub = &level.subsectors[cov->subsectors[l]]; diff --git a/src/r_data/r_translate.cpp b/src/r_data/r_translate.cpp index 5f17c90027..28a480b3db 100644 --- a/src/r_data/r_translate.cpp +++ b/src/r_data/r_translate.cpp @@ -52,6 +52,7 @@ #include "r_state.h" #include "vm.h" #include "v_text.h" +#include "m_crc32.h" #include "gi.h" #include "stats.h" @@ -103,6 +104,38 @@ static bool IndexOutOfRange(const int start1, const int end1, const int start2, return IndexOutOfRange(start2, end2) || outOfRange; } + + +TArray FUniquePalette::AllPalettes; + +//---------------------------------------------------------------------------- +// +// Helper class to deal with frequently changing translations from ACS +// +//---------------------------------------------------------------------------- + +bool FUniquePalette::Update() +{ + PalData pd; + + memset(pd.pe, 0, sizeof(pd.pe)); + memcpy(pd.pe, remap->Palette, remap->NumEntries * sizeof(*remap->Palette)); + pd.crc32 = CalcCRC32((uint8_t*)pd.pe, sizeof(pd.pe)); + for (unsigned int i = 0; i< AllPalettes.Size(); i++) + { + if (pd.crc32 == AllPalettes[i].crc32) + { + if (!memcmp(pd.pe, AllPalettes[i].pe, sizeof(pd.pe))) + { + Index = 1 + i; + return true; + } + } + } + Index = 1 + AllPalettes.Push(pd); + return true; +} + /****************************************************/ /****************************************************/ @@ -133,6 +166,23 @@ FRemapTable::~FRemapTable() // //---------------------------------------------------------------------------- +int FRemapTable::GetUniqueIndex() +{ + if (Inactive) return 0; + if (Native == nullptr) + { + Native = new FUniquePalette(this); + Native->Update(); + } + return Native->GetIndex(); +} + +//---------------------------------------------------------------------------- +// +// +// +//---------------------------------------------------------------------------- + void FRemapTable::Alloc(int count) { Remap = (uint8_t *)M_Malloc(count*sizeof(*Remap) + count*sizeof(*Palette)); @@ -356,21 +406,6 @@ void FRemapTable::UpdateNative() // //---------------------------------------------------------------------------- -FNativePalette *FRemapTable::GetNative() -{ - if (Native == NULL) - { - Native = screen->CreatePalette(this); - } - return Native; -} - -//---------------------------------------------------------------------------- -// -// -// -//---------------------------------------------------------------------------- - bool FRemapTable::AddIndexRange(int start, int end, int pal1, int pal2) { if (IndexOutOfRange(start, end, pal1, pal2)) diff --git a/src/r_data/r_translate.h b/src/r_data/r_translate.h index da69745a47..8e704a5d34 100644 --- a/src/r_data/r_translate.h +++ b/src/r_data/r_translate.h @@ -4,7 +4,6 @@ #include "doomtype.h" #include "tarray.h" -class FNativePalette; class FSerializer; enum @@ -31,6 +30,34 @@ enum EStandardTranslations STD_Grayscale = 9, // desaturated version of the palette. }; +struct FRemapTable; + +class FUniquePalette +{ + friend struct FRemapTable; + struct PalData + { + int crc32; + PalEntry pe[256]; + }; + static TArray AllPalettes; + + int Index; + FRemapTable *remap; + + FUniquePalette(FRemapTable *r) { remap = r; Index = -1; } + +public: + + static PalEntry *GetPalette(unsigned int index) + { + return index > 0 && index <= AllPalettes.Size() ? AllPalettes[index - 1].pe : NULL; + } + bool Update(); + int GetIndex() const { return Index; } +}; + + struct FRemapTable { FRemapTable(int count=256); @@ -42,7 +69,6 @@ struct FRemapTable void MakeIdentity(); void KillNative(); void UpdateNative(); - FNativePalette *GetNative(); bool IsIdentity() const; void Serialize(FSerializer &arc); static void StaticSerializeTranslations(FSerializer &arc); @@ -53,10 +79,11 @@ struct FRemapTable bool AddTint(int start, int end, int r, int g, int b, int amount); bool AddToTranslation(const char * range); int StoreTranslation(int slot); + int GetUniqueIndex(); uint8_t *Remap; // For the software renderer PalEntry *Palette; // The ideal palette this maps to - FNativePalette *Native; // The Palette stored in a HW texture + FUniquePalette *Native; // The index into the list of unique palettes (this is to avoid frequent texture recreation with changing ACS translations) int NumEntries; // # of elements in this table (usually 256) bool Inactive; // This table is inactive and should be treated as if it was passed as NULL diff --git a/src/gl/data/gl_setup.cpp b/src/r_data/renderinfo.cpp similarity index 69% rename from src/gl/data/gl_setup.cpp rename to src/r_data/renderinfo.cpp index 35c33199ae..38e159f27f 100644 --- a/src/gl/data/gl_setup.cpp +++ b/src/r_data/renderinfo.cpp @@ -21,8 +21,8 @@ // /* ** gl_setup.cpp -** Initializes the data structures required by the GL renderer to handle -** a level +** Initializes the data structures required by the hardware renderer to handle +** render hacks and optimization. ** **/ @@ -42,168 +42,171 @@ #include "g_level.h" #include "g_levellocals.h" -#include "gl/renderer/gl_renderer.h" -#include "gl/data/gl_data.h" -#include "gl/data/gl_vertexbuffer.h" -#include "gl/dynlights/gl_dynlight.h" -#include "gl/dynlights/gl_glow.h" -#include "gl/utility/gl_clock.h" -#include "gl/gl_functions.h" - -void InitGLRMapinfoData(); - //========================================================================== // -// +// Map section generation +// Map sections are physically separated parts of the map. +// If the player is in section A, any map part in other sections can +// often be quickly discarded to improve performance. // //========================================================================== -static TArray MapSectionCollector; -static void DoSetMapSection(subsector_t *sub, int num) +struct MapSectionGenerator { - MapSectionCollector.Resize(1); - MapSectionCollector[0] = sub; - sub->mapsection = num; - for (unsigned a = 0; a < MapSectionCollector.Size(); a++) + struct cvertex_t { - sub = MapSectionCollector[a]; - for (uint32_t i = 0; i < sub->numlines; i++) + double X, Y; + + operator int() const { return xs_FloorToInt(X) + 65536 * xs_FloorToInt(Y); } + bool operator!= (const cvertex_t &other) const { return fabs(X - other.X) >= EQUAL_EPSILON || fabs(Y - other.Y) >= EQUAL_EPSILON; } + cvertex_t& operator =(const vertex_t *v) { X = v->fX(); Y = v->fY(); return *this; } + }; + + typedef TMap FSectionVertexMap; + TArray MapSectionCollector; + + //========================================================================== + // + // + // + //========================================================================== + + void DoSetMapSection(subsector_t *sub, int num) + { + MapSectionCollector.Resize(1); + MapSectionCollector[0] = sub; + sub->mapsection = num; + for (unsigned a = 0; a < MapSectionCollector.Size(); a++) { - seg_t * seg = sub->firstline + i; - - if (seg->PartnerSeg) + sub = MapSectionCollector[a]; + for (uint32_t i = 0; i < sub->numlines; i++) { - subsector_t * sub2 = seg->PartnerSeg->Subsector; + seg_t * seg = sub->firstline + i; - if (sub2->mapsection != num) + if (seg->PartnerSeg) { - assert(sub2->mapsection == 0); - sub2->mapsection = num; - MapSectionCollector.Push(sub2); + subsector_t * sub2 = seg->PartnerSeg->Subsector; + + if (sub2->mapsection != num) + { + assert(sub2->mapsection == 0); + sub2->mapsection = num; + MapSectionCollector.Push(sub2); + } } } } + MapSectionCollector.Clear(); } - MapSectionCollector.Clear(); -} -//========================================================================== -// -// Merge sections. This is needed in case the map contains errors -// like overlapping lines resulting in abnormal subsectors. -// -// This function ensures that any vertex position can only be in one section. -// -//========================================================================== + //========================================================================== + // + // Merge sections. This is needed in case the map contains errors + // like overlapping lines resulting in abnormal subsectors. + // + // This function ensures that any vertex position can only be in one section. + // + //========================================================================== -struct cvertex_t -{ - double X, Y; - operator int() const { return xs_FloorToInt(X) + 65536 * xs_FloorToInt(Y); } - bool operator!= (const cvertex_t &other) const { return fabs(X - other.X) >= EQUAL_EPSILON || fabs(Y - other.Y) >= EQUAL_EPSILON; } - cvertex_t& operator =(const vertex_t *v) { X = v->fX(); Y = v->fY(); return *this; } -}; - -typedef TMap FSectionVertexMap; - -static int MergeMapSections(int num) -{ - FSectionVertexMap vmap; - FSectionVertexMap::Pair *pair; - TArray sectmap; - TArray sectvalid; - sectmap.Resize(num); - sectvalid.Resize(num); - for (int i = 0; i < num; i++) + int MergeMapSections(int num) { - sectmap[i] = -1; - sectvalid[i] = true; - } - int mergecount = 1; - - - cvertex_t vt; - - // first step: Set mapsection for all vertex positions. - for (auto &seg : level.segs) - { - int section = seg.Subsector->mapsection; - for (int j = 0; j < 2; j++) + FSectionVertexMap vmap; + FSectionVertexMap::Pair *pair; + TArray sectmap; + TArray sectvalid; + sectmap.Resize(num); + sectvalid.Resize(num); + for (int i = 0; i < num; i++) { - vt = j == 0 ? seg.v1 : seg.v2; - vmap[vt] = section; + sectmap[i] = -1; + sectvalid[i] = true; } - } + int mergecount = 1; - // second step: Check if any seg references more than one mapsection, either by subsector or by vertex - for (auto &seg : level.segs) - { - int section = seg.Subsector->mapsection; - for (int j = 0; j < 2; j++) + + cvertex_t vt; + + // first step: Set mapsection for all vertex positions. + for (auto &seg : level.segs) { - vt = j == 0 ? seg.v1 : seg.v2; - int vsection = vmap[vt]; - - if (vsection != section) + int section = seg.Subsector->mapsection; + for (int j = 0; j < 2; j++) { - // These 2 sections should be merged - for (auto &sub : level.subsectors) - { - if (sub.mapsection == vsection) sub.mapsection = section; - } - FSectionVertexMap::Iterator it(vmap); - while (it.NextPair(pair)) - { - if (pair->Value == vsection) pair->Value = section; - } - sectvalid[vsection - 1] = false; + vt = j == 0 ? seg.v1 : seg.v2; + vmap[vt] = section; } } - } - for (int i = 0; i < num; i++) - { - if (sectvalid[i]) sectmap[i] = mergecount++; - } - for (auto &sub : level.subsectors) - { - sub.mapsection = sectmap[sub.mapsection - 1]; - assert(sub.mapsection != -1); - } - return mergecount - 1; -} -//========================================================================== -// -// -// -//========================================================================== + // second step: Check if any seg references more than one mapsection, either by subsector or by vertex + for (auto &seg : level.segs) + { + int section = seg.Subsector->mapsection; + for (int j = 0; j < 2; j++) + { + vt = j == 0 ? seg.v1 : seg.v2; + int vsection = vmap[vt]; -static void SetMapSections() -{ - bool set; - int num = 0; - do - { - set = false; + if (vsection != section) + { + // These 2 sections should be merged + for (auto &sub : level.subsectors) + { + if (sub.mapsection == vsection) sub.mapsection = section; + } + FSectionVertexMap::Iterator it(vmap); + while (it.NextPair(pair)) + { + if (pair->Value == vsection) pair->Value = section; + } + sectvalid[vsection - 1] = false; + } + } + } + for (int i = 0; i < num; i++) + { + if (sectvalid[i]) sectmap[i] = mergecount++; + } for (auto &sub : level.subsectors) { - if (sub.mapsection == 0) + sub.mapsection = sectmap[sub.mapsection - 1]; + assert(sub.mapsection != -1); + } + return mergecount - 1; + } + + //========================================================================== + // + // + // + //========================================================================== + + void SetMapSections() + { + bool set; + int num = 0; + do + { + set = false; + for (auto &sub : level.subsectors) { - num++; - DoSetMapSection(&sub, num); - set = true; - break; + if (sub.mapsection == 0) + { + num++; + DoSetMapSection(&sub, num); + set = true; + break; + } } } + while (set); + num = MergeMapSections(num); + level.NumMapSections = num; + #ifdef DEBUG + Printf("%d map sections found\n", num); + #endif } - while (set); - num = MergeMapSections(num); - currentmapsection.Resize(1 + num/8); -#ifdef DEBUG - Printf("%d map sections found\n", num); -#endif -} +}; //========================================================================== // @@ -286,7 +289,8 @@ static void PrepareSectorData() } } } - SetMapSections(); + MapSectionGenerator msg; + msg.SetMapSections(); } //========================================================================== @@ -533,7 +537,7 @@ static void PrepareSegs() // //========================================================================== -void gl_PreprocessLevel() +void InitRenderInfo() { PrepareSegs(); PrepareSectorData(); @@ -570,69 +574,13 @@ void gl_PreprocessLevel() } delete[] checkmap; - gl_InitPortals(); - - if (GLRenderer != NULL) - { - GLRenderer->SetupLevel(); - } - #if 0 gl_CreateSections(); #endif - - InitGLRMapinfoData(); } -//========================================================================== -// -// Cleans up all the GL data for the last level -// -//========================================================================== - -void gl_CleanLevelData() -{ - // Dynamic lights must be destroyed before the sector information here is deleted. - TThinkerIterator it(STAT_DLIGHT); - AActor * mo=it.Next(); - while (mo) - { - AActor * next = it.Next(); - mo->Destroy(); - mo=next; - } - - if (level.sides.Size() > 0 && level.sides[0].segs) - { - delete [] level.sides[0].segs; - level.sides[0].segs = NULL; - } - if (level.sectors.Size() > 0 && level.sectors[0].subsectors) - { - delete [] level.sectors[0].subsectors; - level.sectors[0].subsectors = nullptr; - } - for (auto &sub : level.subsectors) - { - for(int j=0;j<2;j++) - { - if (sub.portalcoverage[j].subsectors != NULL) - { - delete [] sub.portalcoverage[j].subsectors; - sub.portalcoverage[j].subsectors = NULL; - } - } - } - for(unsigned i=0;i 0) return &SlabDataRemapped[0]; + return SlabData; +} + //========================================================================== // // FVoxel Constructor @@ -410,6 +422,8 @@ FVoxel::~FVoxel() void FVoxel::CreateBgraSlabData() { + if (Bgramade) return; + Bgramade = true; for (int i = 0; i < NumMips; ++i) { int size = Mips[i].OffsetX[Mips[i].SizeX]; @@ -464,14 +478,20 @@ void FVoxel::CreateBgraSlabData() void FVoxel::Remap() { + if (Remapped) return; + Remapped = true; if (Palette != NULL) { uint8_t *remap = GetVoxelRemap(Palette); for (int i = 0; i < NumMips; ++i) { - RemapVoxelSlabs((kvxslab_t *)Mips[i].SlabData, Mips[i].OffsetX[Mips[i].SizeX], remap); + int size = Mips[i].OffsetX[Mips[i].SizeX]; + if (size <= 0) continue; + + Mips[i].SlabDataRemapped.Resize(size); + memcpy(&Mips[i].SlabDataRemapped [0], Mips[i].SlabData, size); + RemapVoxelSlabs((kvxslab_t *)&Mips[i].SlabDataRemapped[0], Mips[i].OffsetX[Mips[i].SizeX], remap); } - RemovePalette(); } } diff --git a/src/r_data/voxels.h b/src/r_data/voxels.h index 57ae41a1f6..eac1b39eec 100644 --- a/src/r_data/voxels.h +++ b/src/r_data/voxels.h @@ -23,6 +23,8 @@ struct kvxslab_bgra_t uint32_t col[1/*zleng*/];// color data from top to bottom }; +struct FVoxel; + struct FVoxelMipLevel { FVoxelMipLevel(); @@ -34,17 +36,27 @@ struct FVoxelMipLevel DVector3 Pivot; int *OffsetX; short *OffsetXY; - uint8_t *SlabData; +private: + uint8_t *SlabData; + TArray SlabDataRemapped; +public: TArray SlabDataBgra; + + uint8_t *GetSlabData(bool wantpaletted) const; + + friend FVoxel *R_LoadKVX(int lumpnum); + friend struct FVoxel; }; struct FVoxel { int LumpNum; int NumMips; - int VoxelIndex; // Needed by GZDoom + int VoxelIndex; uint8_t *Palette; FVoxelMipLevel Mips[MAXVOXMIPS]; + bool Remapped = false; + bool Bgramade = false; FVoxel(); ~FVoxel(); diff --git a/src/r_defs.h b/src/r_defs.h index 6a3dfac762..00062f6686 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -45,7 +45,7 @@ struct FLightNode; struct FGLSection; class FSerializer; -struct FPortal; +struct FSectorPortalGroup; struct FSectorPortal; struct FLinePortal; struct seg_t; @@ -138,6 +138,7 @@ struct vertex_t } int Index() const; + void RecalcVertexHeights(); angle_t viewangle; // precalculated angle for clipping @@ -662,6 +663,9 @@ public: FSectorPortal *ValidatePortal(int which); void CheckPortalPlane(int plane); + int CheckSpriteGlow(int lightlevel, const DVector3 &pos); + bool GetWallGlow(float *topglowcolor, float *bottomglowcolor); + enum { @@ -1074,7 +1078,7 @@ public: int subsectorcount; // list of subsectors double transdoorheight; // for transparent door hacks subsector_t ** subsectors; - FPortal * portals[2]; // floor and ceiling portals + FSectorPortalGroup * portals[2]; // floor and ceiling portals enum { @@ -1088,7 +1092,7 @@ public: float GetReflect(int pos) { return gl_plane_reflection_i? reflect[pos] : 0; } bool VBOHeightcheck(int pos) const { return vboheight[pos] == GetPlaneTexZ(pos); } - FPortal *GetGLPortal(int plane) { return portals[plane]; } + FSectorPortalGroup *GetPortalGroup(int plane) { return portals[plane]; } enum { @@ -1417,6 +1421,8 @@ struct FPortalCoverage int sscount; }; +void BuildPortalCoverage(FPortalCoverage *coverage, subsector_t *subsector, const DVector2 &displacement); + struct subsector_t { sector_t *sector; diff --git a/src/r_renderer.h b/src/r_renderer.h index 54952bc29d..975fe76bfb 100644 --- a/src/r_renderer.h +++ b/src/r_renderer.h @@ -4,7 +4,8 @@ #include struct FRenderer; -extern FRenderer *Renderer; +extern FRenderer *SWRenderer; + class FSerializer; class FTexture; class AActor; @@ -12,49 +13,36 @@ class player_t; struct sector_t; class FCanvasTexture; class FileWriter; +class DCanvas; struct FRenderer { - FRenderer() - { - Renderer = this; - } - - virtual ~FRenderer() - { - Renderer = NULL; - } + virtual ~FRenderer() {} // precache one texture virtual void Precache(uint8_t *texhitlist, TMap &actorhitlist) = 0; // render 3D view - virtual void RenderView(player_t *player) = 0; - - // Remap voxel palette - virtual void RemapVoxels() {} + virtual void RenderView(player_t *player, DCanvas *target) = 0; // renders view to a savegame picture - virtual void WriteSavePic (player_t *player, FileWriter *file, int width, int height) = 0; + virtual void WriteSavePic(player_t *player, FileWriter *file, int width, int height) = 0; + + // render to a camera texture + virtual void RenderTextureView(FCanvasTexture *tex, AActor *viewpoint, double fov) = 0; // draws player sprites with hardware acceleration (only useful for software rendering) - virtual void DrawRemainingPlayerSprites() {} + virtual void DrawRemainingPlayerSprites() = 0; - // notify the renderer that serialization of the curent level is about to start/end - virtual void StartSerialize(FSerializer &arc) {} - virtual void EndSerialize(FSerializer &arc) {} + // set up the colormap for a newly loaded level. + virtual void SetColormap() = 0; - virtual int GetMaxViewPitch(bool down) = 0; // return value is in plain degrees + virtual void OnModeSet() = 0; - virtual void OnModeSet () {} virtual void SetClearColor(int color) = 0; - virtual void Init() = 0; - virtual void RenderTextureView (FCanvasTexture *tex, AActor *viewpoint, double fov) = 0; - virtual void PreprocessLevel() {} - virtual void CleanLevelData() {} - virtual bool RequireGLNodes() { return false; } - virtual uint32_t GetCaps() { return 0; } + virtual void Init() = 0; + }; diff --git a/src/r_utility.cpp b/src/r_utility.cpp index 9461e30461..abde8f8ade 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -266,7 +266,6 @@ void R_SetWindow (FRenderViewpoint &viewpoint, FViewWindow &viewwindow, int wind void R_ExecuteSetViewSize (FRenderViewpoint &viewpoint, FViewWindow &viewwindow) { setsizeneeded = false; - V_SetBorderNeedRefresh(); R_SetWindow (viewpoint, viewwindow, setblocks, SCREENWIDTH, SCREENHEIGHT, StatusBar->GetTopOfStatusbar()); @@ -393,6 +392,15 @@ subsector_t *R_PointInSubsector (fixed_t x, fixed_t y) return (subsector_t *)((uint8_t *)node - 1); } +//========================================================================== +// +// +// +//========================================================================== + +FRenderer *CreateSWRenderer(); + + //========================================================================== // // R_Init @@ -404,13 +412,15 @@ void R_Init () atterm (R_Shutdown); StartScreen->Progress(); - // Colormap init moved back to InitPalette() - //R_InitColormaps (); - //StartScreen->Progress(); - R_InitTranslationTables (); R_SetViewSize (screenblocks); - Renderer->Init(); + + if (SWRenderer == NULL) + { + SWRenderer = CreateSWRenderer(); + } + + SWRenderer->Init(); } //========================================================================== @@ -421,6 +431,8 @@ void R_Init () static void R_Shutdown () { + if (SWRenderer != nullptr) delete SWRenderer; + SWRenderer = nullptr; R_DeinitTranslationTables(); R_DeinitColormaps (); FCanvasTextureInfo::EmptyList(); @@ -511,7 +523,7 @@ void R_InterpolateView (FRenderViewpoint &viewpoint, player_t *player, double Fr } else { - DVector2 disp = Displacements.getOffset(oldgroup, newgroup); + DVector2 disp = level.Displacements.getOffset(oldgroup, newgroup); viewpoint.Pos = iview->Old.Pos + (iview->New.Pos - iview->Old.Pos - disp) * Frac; viewpoint.Path[0] = viewpoint.Path[1] = iview->New.Pos; } @@ -1000,7 +1012,8 @@ void R_SetupFrame (FRenderViewpoint &viewpoint, FViewWindow &viewwindow, AActor { color = pr_hom(); } - Renderer->SetClearColor(color); + screen->SetClearColor(color); + SWRenderer->SetClearColor(color); } } @@ -1063,7 +1076,8 @@ DEFINE_ACTION_FUNCTION(_TexMan, SetCameraToTexture) PARAM_STRING(texturename); // [ZZ] there is no point in having this as FTextureID because it's easier to refer to a cameratexture by name and it isn't executed too often to cache it. PARAM_FLOAT(fov); FTextureID textureid = TexMan.CheckForTexture(texturename, ETextureType::Wall, FTextureManager::TEXMAN_Overridable); - FCanvasTextureInfo::Add(viewpoint, textureid, fov); + if (textureid.isValid()) + FCanvasTextureInfo::Add(viewpoint, textureid, fov); return 0; } @@ -1083,7 +1097,7 @@ void FCanvasTextureInfo::UpdateAll () { if (probe->Viewpoint != NULL && probe->Texture->bNeedsUpdate) { - Renderer->RenderTextureView(probe->Texture, probe->Viewpoint, probe->FOV); + screen->RenderTextureView(probe->Texture, probe->Viewpoint, probe->FOV); } } } diff --git a/src/s_sound.cpp b/src/s_sound.cpp index a41663c3a2..69a559de36 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -297,7 +297,6 @@ void S_NoiseDebug (void) } chan = (FSoundChan *)((size_t)chan->PrevChan - myoffsetof(FSoundChan, NextChan)); } - V_SetBorderNeedRefresh(); } static FString LastLocalSndInfo; @@ -732,7 +731,7 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector, if(type == SOURCE_Unattached) { sector_t *sec = P_PointInSector(pt[0], pt[2]); - DVector2 disp = Displacements.getOffset(pgroup, sec->PortalGroup); + DVector2 disp = level.Displacements.getOffset(pgroup, sec->PortalGroup); pos->X = pt[0] - (float)disp.X; pos->Y = !(chanflags & CHAN_LISTENERZ) ? pt[1] : (float)listenpos.Z; pos->Z = pt[2] - (float)disp.Y; @@ -749,7 +748,7 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector, //assert(actor != NULL); if (actor != NULL) { - DVector2 disp = Displacements.getOffset(pgroup, actor->Sector->PortalGroup); + DVector2 disp = level.Displacements.getOffset(pgroup, actor->Sector->PortalGroup); DVector3 posi = actor->Pos() - disp; *pos = { (float)posi.X, (float)posi.Z, (float)posi.Y }; } @@ -759,7 +758,7 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector, assert(sector != NULL); if (sector != NULL) { - DVector2 disp = Displacements.getOffset(pgroup, sector->PortalGroup); + DVector2 disp = level.Displacements.getOffset(pgroup, sector->PortalGroup); if (chanflags & CHAN_AREA) { // listener must be reversely offset to calculate the proper sound origin. @@ -781,7 +780,7 @@ static void CalcPosVel(int type, const AActor *actor, const sector_t *sector, assert(poly != NULL); if (poly != NULL) { - DVector2 disp = Displacements.getOffset(pgroup, poly->CenterSubsector->sector->PortalGroup); + DVector2 disp = level.Displacements.getOffset(pgroup, poly->CenterSubsector->sector->PortalGroup); CalcPolyobjSoundOrg(listenpos + disp, poly, *pos); pos->X += (float)disp.X; pos->Z += (float)disp.Y; diff --git a/src/stats.h b/src/stats.h index 86a5b8f1c6..e9f11aed0e 100644 --- a/src/stats.h +++ b/src/stats.h @@ -117,6 +117,11 @@ inline unsigned __int64 rdtsc() { return __rdtsc(); } +#elif defined __APPLE__ && (defined __i386__ || defined __x86_64__) +inline uint64_t rdtsc() +{ + return __builtin_ia32_rdtsc(); +} #else inline uint64_t rdtsc() { @@ -165,7 +170,7 @@ public: Counter -= time; } - void Unclock() + void Unclock(bool checkvar = true) { int64_t time = rdtsc(); Counter += time; @@ -192,6 +197,21 @@ private: #endif +class glcycle_t : public cycle_t +{ +public: + static bool active; + void Clock() + { + if (active) cycle_t::Clock(); + } + + void Unclock() + { + if (active) cycle_t::Unclock(); + } +}; + class FStat { public: diff --git a/src/swrenderer/drawers/r_draw.cpp b/src/swrenderer/drawers/r_draw.cpp index 8db9d3be8d..9049c949a3 100644 --- a/src/swrenderer/drawers/r_draw.cpp +++ b/src/swrenderer/drawers/r_draw.cpp @@ -81,7 +81,7 @@ namespace swrenderer uint32_t particle_texture[NUM_PARTICLE_TEXTURES][PARTICLE_TEXTURE_SIZE * PARTICLE_TEXTURE_SIZE]; - short zeroarray[MAXWIDTH]; + short zeroarray[MAXWIDTH] = { 0 }; short screenheightarray[MAXWIDTH]; void R_InitShadeMaps() @@ -193,7 +193,7 @@ namespace swrenderer void R_UpdateFuzzPosFrameStart() { - if (r_fuzzscale || r_polyrenderer) + if (r_fuzzscale || V_IsPolyRenderer()) { static int next_random = 0; @@ -207,7 +207,7 @@ namespace swrenderer void R_UpdateFuzzPos(const SpriteDrawerArgs &args) { - if (!r_fuzzscale && !r_polyrenderer) + if (!r_fuzzscale && !V_IsPolyRenderer()) { int yl = MAX(args.FuzzY1(), 1); int yh = MIN(args.FuzzY2(), fuzzviewheight); @@ -224,7 +224,7 @@ namespace swrenderer auto rendertarget = args.Viewport()->RenderTarget; if (rendertarget->IsBgra()) { - uint32_t *destorg = (uint32_t*)rendertarget->GetBuffer(); + uint32_t *destorg = (uint32_t*)rendertarget->GetPixels(); destorg += viewwindowx + viewwindowy * rendertarget->GetPitch(); uint32_t *dest = (uint32_t*)args.Dest(); int offset = (int)(ptrdiff_t)(dest - destorg); @@ -233,7 +233,7 @@ namespace swrenderer } else { - uint8_t *destorg = rendertarget->GetBuffer(); + uint8_t *destorg = rendertarget->GetPixels(); destorg += viewwindowx + viewwindowy * rendertarget->GetPitch(); uint8_t *dest = (uint8_t*)args.Dest(); int offset = (int)(ptrdiff_t)(dest - destorg); @@ -248,7 +248,7 @@ namespace swrenderer auto rendertarget = args.Viewport()->RenderTarget; if (rendertarget->IsBgra()) { - uint32_t *destorg = (uint32_t*)rendertarget->GetBuffer(); + uint32_t *destorg = (uint32_t*)rendertarget->GetPixels(); destorg += viewwindowx + viewwindowy * rendertarget->GetPitch(); uint32_t *dest = (uint32_t*)args.Dest(); int offset = (int)(ptrdiff_t)(dest - destorg); @@ -257,7 +257,7 @@ namespace swrenderer } else { - uint8_t *destorg = rendertarget->GetBuffer(); + uint8_t *destorg = rendertarget->GetPixels(); destorg += viewwindowx + viewwindowy * rendertarget->GetPitch(); uint8_t *dest = (uint8_t*)args.Dest(); int offset = (int)(ptrdiff_t)(dest - destorg); diff --git a/src/swrenderer/drawers/r_draw_pal.cpp b/src/swrenderer/drawers/r_draw_pal.cpp index 5910e4f744..b77a83ec69 100644 --- a/src/swrenderer/drawers/r_draw_pal.cpp +++ b/src/swrenderer/drawers/r_draw_pal.cpp @@ -3074,7 +3074,7 @@ namespace swrenderer void DrawVoxelBlocksPalCommand::Execute(DrawerThread *thread) { int destpitch = args.Viewport()->RenderTarget->GetPitch(); - uint8_t *destorig = args.Viewport()->RenderTarget->GetBuffer(); + uint8_t *destorig = args.Viewport()->RenderTarget->GetPixels(); const uint8_t *colormap = args.Colormap(args.Viewport()); for (int i = 0; i < blockcount; i++) diff --git a/src/swrenderer/drawers/r_draw_rgba.cpp b/src/swrenderer/drawers/r_draw_rgba.cpp index e9685e874d..23066986d7 100644 --- a/src/swrenderer/drawers/r_draw_rgba.cpp +++ b/src/swrenderer/drawers/r_draw_rgba.cpp @@ -719,6 +719,7 @@ namespace swrenderer ///////////////////////////////////////////////////////////////////////////// +#if 0 ApplySpecialColormapRGBACommand::ApplySpecialColormapRGBACommand(FSpecialColormap *colormap, DFrameBuffer *screen) { buffer = screen->GetBuffer(); @@ -869,6 +870,7 @@ namespace swrenderer count--; } } +#endif #endif ///////////////////////////////////////////////////////////////////////////// @@ -938,7 +940,7 @@ namespace swrenderer void DrawVoxelBlocksRGBACommand::Execute(DrawerThread *thread) { int pitch = args.Viewport()->RenderTarget->GetPitch(); - uint8_t *destorig = args.Viewport()->RenderTarget->GetBuffer(); + uint8_t *destorig = args.Viewport()->RenderTarget->GetPixels(); DrawSprite32Command drawer(args); drawer.args.dc_texturefracx = 0; diff --git a/src/swrenderer/drawers/r_draw_rgba.h b/src/swrenderer/drawers/r_draw_rgba.h index 6676486b22..ee23a3efe6 100644 --- a/src/swrenderer/drawers/r_draw_rgba.h +++ b/src/swrenderer/drawers/r_draw_rgba.h @@ -175,6 +175,7 @@ namespace swrenderer FString DebugInfo() override; }; +#if 0 class ApplySpecialColormapRGBACommand : public DrawerCommand { uint8_t *buffer; @@ -193,6 +194,7 @@ namespace swrenderer void Execute(DrawerThread *thread) override; FString DebugInfo() override { return "ApplySpecialColormapRGBACommand"; } }; +#endif template class DrawerBlendCommand : public CommandType diff --git a/src/swrenderer/r_all.cpp b/src/swrenderer/r_all.cpp index 91586be6fe..8eaf961f62 100644 --- a/src/swrenderer/r_all.cpp +++ b/src/swrenderer/r_all.cpp @@ -1,6 +1,5 @@ #include "r_memory.cpp" #include "r_renderthread.cpp" -#include "r_swcanvas.cpp" #include "r_swrenderer.cpp" #include "r_swcolormaps.cpp" #include "drawers/r_draw.cpp" diff --git a/src/swrenderer/r_swcanvas.h b/src/swrenderer/r_swcanvas.h deleted file mode 100644 index 3d8135c2f1..0000000000 --- a/src/swrenderer/r_swcanvas.h +++ /dev/null @@ -1,22 +0,0 @@ - -#pragma once - -#include "v_video.h" -#include "r_data/colormaps.h" - -class SWCanvas -{ -public: - static void DrawTexture(DCanvas *canvas, FTexture *img, DrawParms &parms); - static void FillSimplePoly(DCanvas *canvas, FTexture *tex, FVector2 *points, int npoints, - double originx, double originy, double scalex, double scaley, DAngle rotation, - const FColormap &colormap, PalEntry flatcolor, int lightlevel, int bottomclip); - static void DrawLine(DCanvas *canvas, int x0, int y0, int x1, int y1, int palColor, uint32_t realcolor); - static void DrawPixel(DCanvas *canvas, int x, int y, int palColor, uint32_t realcolor); - static void Clear(DCanvas *canvas, int left, int top, int right, int bottom, int palcolor, uint32_t color); - static void Dim(DCanvas *canvas, PalEntry color, float damount, int x1, int y1, int w, int h); - -private: - static void PUTTRANSDOT(DCanvas *canvas, int xx, int yy, int basecolor, int level); - static int PalFromRGB(uint32_t rgb); -}; diff --git a/src/swrenderer/r_swrenderer.cpp b/src/swrenderer/r_swrenderer.cpp index 25b3539d1b..b64fd5399e 100644 --- a/src/swrenderer/r_swrenderer.cpp +++ b/src/swrenderer/r_swrenderer.cpp @@ -37,6 +37,7 @@ #include "swrenderer/things/r_playersprite.h" #include "swrenderer/scene/r_scene.h" #include "swrenderer/scene/r_light.h" +#include "swrenderer/r_swcolormaps.h" #include "v_palette.h" #include "v_video.h" #include "m_png.h" @@ -59,43 +60,29 @@ CUSTOM_CVAR (Bool, cl_oldfreelooklimit, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG players[consoleplayer].SendPitchLimits(); } -EXTERN_CVAR(Bool, r_shadercolormaps) EXTERN_CVAR(Float, maxviewpitch) // [SP] CVAR from OpenGL Renderer EXTERN_CVAR(Bool, r_drawvoxels) -CUSTOM_CVAR(Bool, r_polyrenderer, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) -{ - if (self == 1 && !hasglnodes) - { - Printf("No GL BSP detected. You must restart the map before rendering will be correct\n"); - } - - if (usergame) - { - // [SP] Update pitch limits to the netgame/gamesim. - players[consoleplayer].SendPitchLimits(); - } -} - using namespace swrenderer; FSoftwareRenderer::FSoftwareRenderer() { } -FSoftwareRenderer::~FSoftwareRenderer() -{ -} - void FSoftwareRenderer::Init() { - mScene.Init(); - InitSWColorMaps(); + R_InitShadeMaps(); + InitSWColorMaps(); +} + +FRenderer *CreateSWRenderer() +{ + return new FSoftwareRenderer; } void FSoftwareRenderer::PrecacheTexture(FTexture *tex, int cache) { - bool isbgra = screen->IsBgra(); + bool isbgra = V_IsTrueColor(); if (tex != NULL) { @@ -170,13 +157,13 @@ void FSoftwareRenderer::Precache(uint8_t *texhitlist, TMap & } } -void FSoftwareRenderer::RenderView(player_t *player) +void FSoftwareRenderer::RenderView(player_t *player, DCanvas *target) { - if (r_polyrenderer) + if (V_IsPolyRenderer()) { PolyRenderer::Instance()->Viewpoint = r_viewpoint; PolyRenderer::Instance()->Viewwindow = r_viewwindow; - PolyRenderer::Instance()->RenderView(player); + PolyRenderer::Instance()->RenderView(player, target); r_viewpoint = PolyRenderer::Instance()->Viewpoint; r_viewwindow = PolyRenderer::Instance()->Viewwindow; } @@ -184,7 +171,7 @@ void FSoftwareRenderer::RenderView(player_t *player) { mScene.MainThread()->Viewport->viewpoint = r_viewpoint; mScene.MainThread()->Viewport->viewwindow = r_viewwindow; - mScene.RenderView(player); + mScene.RenderView(player, target); r_viewpoint = mScene.MainThread()->Viewport->viewpoint; r_viewwindow = mScene.MainThread()->Viewport->viewwindow; } @@ -192,22 +179,13 @@ void FSoftwareRenderer::RenderView(player_t *player) FCanvasTextureInfo::UpdateAll(); } -void FSoftwareRenderer::RemapVoxels() -{ - for (unsigned i=0; iCreateBgraSlabData(); - Voxels[i]->Remap(); - } -} - void FSoftwareRenderer::WriteSavePic (player_t *player, FileWriter *file, int width, int height) { DSimpleCanvas pic(width, height, false); PalEntry palette[256]; // Take a snapshot of the player's view - if (r_polyrenderer) + if (V_IsPolyRenderer()) { PolyRenderer::Instance()->Viewpoint = r_viewpoint; PolyRenderer::Instance()->Viewwindow = r_viewwindow; @@ -224,12 +202,12 @@ void FSoftwareRenderer::WriteSavePic (player_t *player, FileWriter *file, int wi r_viewwindow = mScene.MainThread()->Viewport->viewwindow; } screen->GetFlashedPalette (palette); - M_CreatePNG (file, pic.GetBuffer(), palette, SS_PAL, width, height, pic.GetPitch(), Gamma); + M_CreatePNG (file, pic.GetPixels(), palette, SS_PAL, width, height, pic.GetPitch(), Gamma); } void FSoftwareRenderer::DrawRemainingPlayerSprites() { - if (!r_polyrenderer) + if (!V_IsPolyRenderer()) { mScene.MainThread()->Viewport->viewpoint = r_viewpoint; mScene.MainThread()->Viewport->viewwindow = r_viewwindow; @@ -247,21 +225,11 @@ void FSoftwareRenderer::DrawRemainingPlayerSprites() } } -int FSoftwareRenderer::GetMaxViewPitch(bool down) -{ - int MAX_DN_ANGLE = MIN(56, (int)maxviewpitch); // Max looking down angle - int MAX_UP_ANGLE = MIN(32, (int)maxviewpitch); // Max looking up angle - return (r_polyrenderer) ? int(maxviewpitch) : (down ? MAX_DN_ANGLE : ((cl_oldfreelooklimit) ? MAX_UP_ANGLE : MAX_DN_ANGLE)); -} - -bool FSoftwareRenderer::RequireGLNodes() -{ - return true; -} - void FSoftwareRenderer::OnModeSet () { - mScene.ScreenResized(); + // This does not work if the SW renderer is not in use. + if (!V_IsHardwareRenderer()) + mScene.ScreenResized(); } void FSoftwareRenderer::SetClearColor(int color) @@ -271,9 +239,9 @@ void FSoftwareRenderer::SetClearColor(int color) void FSoftwareRenderer::RenderTextureView (FCanvasTexture *tex, AActor *viewpoint, double fov) { - auto renderTarget = r_polyrenderer ? PolyRenderer::Instance()->RenderTarget : mScene.MainThread()->Viewport->RenderTarget; - auto &cameraViewpoint = r_polyrenderer ? PolyRenderer::Instance()->Viewpoint : mScene.MainThread()->Viewport->viewpoint; - auto &cameraViewwindow = r_polyrenderer ? PolyRenderer::Instance()->Viewwindow : mScene.MainThread()->Viewport->viewwindow; + auto renderTarget = V_IsPolyRenderer() ? PolyRenderer::Instance()->RenderTarget : mScene.MainThread()->Viewport->RenderTarget; + auto &cameraViewpoint = V_IsPolyRenderer() ? PolyRenderer::Instance()->Viewpoint : mScene.MainThread()->Viewport->viewpoint; + auto &cameraViewwindow = V_IsPolyRenderer() ? PolyRenderer::Instance()->Viewwindow : mScene.MainThread()->Viewport->viewwindow; // Grab global state shared with rest of zdoom cameraViewpoint = r_viewpoint; @@ -289,7 +257,7 @@ void FSoftwareRenderer::RenderTextureView (FCanvasTexture *tex, AActor *viewpoin DAngle savedfov = cameraViewpoint.FieldOfView; R_SetFOV (cameraViewpoint, fov); - if (r_polyrenderer) + if (V_IsPolyRenderer()) PolyRenderer::Instance()->RenderViewToCanvas(viewpoint, Canvas, 0, 0, tex->GetWidth(), tex->GetHeight(), tex->bFirstUpdate); else mScene.RenderViewToCanvas(viewpoint, Canvas, 0, 0, tex->GetWidth(), tex->GetHeight(), tex->bFirstUpdate); @@ -298,24 +266,24 @@ void FSoftwareRenderer::RenderTextureView (FCanvasTexture *tex, AActor *viewpoin if (Canvas->IsBgra()) { - if (Pixels == Canvas->GetBuffer()) + if (Pixels == Canvas->GetPixels()) { FTexture::FlipSquareBlockBgra((uint32_t*)Pixels, tex->GetWidth(), tex->GetHeight()); } else { - FTexture::FlipNonSquareBlockBgra((uint32_t*)Pixels, (const uint32_t*)Canvas->GetBuffer(), tex->GetWidth(), tex->GetHeight(), Canvas->GetPitch()); + FTexture::FlipNonSquareBlockBgra((uint32_t*)Pixels, (const uint32_t*)Canvas->GetPixels(), tex->GetWidth(), tex->GetHeight(), Canvas->GetPitch()); } } else { - if (Pixels == Canvas->GetBuffer()) + if (Pixels == Canvas->GetPixels()) { FTexture::FlipSquareBlockRemap(Pixels, tex->GetWidth(), tex->GetHeight(), GPalette.Remap); } else { - FTexture::FlipNonSquareBlockRemap(Pixels, Canvas->GetBuffer(), tex->GetWidth(), tex->GetHeight(), Canvas->GetPitch(), GPalette.Remap); + FTexture::FlipNonSquareBlockRemap(Pixels, Canvas->GetPixels(), tex->GetWidth(), tex->GetHeight(), Canvas->GetPitch(), GPalette.Remap); } } @@ -351,49 +319,15 @@ void FSoftwareRenderer::RenderTextureView (FCanvasTexture *tex, AActor *viewpoin r_viewwindow = cameraViewwindow; } -void FSoftwareRenderer::PreprocessLevel() +void FSoftwareRenderer::SetColormap() { // This just sets the default colormap for the spftware renderer. NormalLight.Maps = realcolormaps.Maps; NormalLight.ChangeColor(PalEntry(255, 255, 255), 0); NormalLight.ChangeFade(level.fadeto); - if (level.fadeto == 0) { SetDefaultColormap(level.info->FadeTable); - if (level.flags & LEVEL_HASFADETABLE) - { - // This should really be done differently. - level.fadeto = 0xff939393; //[SP] Hexen True-color compatibility, just use gray. - for (auto &s : level.sectors) - { - s.Colormap.FadeColor = level.fadeto; - } - } } } -void FSoftwareRenderer::CleanLevelData() -{ -} - -uint32_t FSoftwareRenderer::GetCaps() -{ - ActorRenderFeatureFlags FlagSet = 0; - - if (r_polyrenderer) - FlagSet |= RFF_POLYGONAL | RFF_TILTPITCH | RFF_SLOPE3DFLOORS; - else - { - FlagSet |= RFF_UNCLIPPEDTEX; - if (r_drawvoxels) - FlagSet |= RFF_VOXELS; - } - - if (screen && screen->IsBgra()) - FlagSet |= RFF_TRUECOLOR; - else - FlagSet |= RFF_COLORMAP; - - return (uint32_t)FlagSet; -} diff --git a/src/swrenderer/r_swrenderer.h b/src/swrenderer/r_swrenderer.h index 19f75758f5..3843d58169 100644 --- a/src/swrenderer/r_swrenderer.h +++ b/src/swrenderer/r_swrenderer.h @@ -7,16 +7,12 @@ struct FSoftwareRenderer : public FRenderer { FSoftwareRenderer(); - ~FSoftwareRenderer(); // precache textures void Precache(uint8_t *texhitlist, TMap &actorhitlist) override; // render 3D view - void RenderView(player_t *player) override; - - // Remap voxel palette - void RemapVoxels() override; + void RenderView(player_t *player, DCanvas *target) override; // renders view to a savegame picture void WriteSavePic (player_t *player, FileWriter *file, int width, int height) override; @@ -24,21 +20,17 @@ struct FSoftwareRenderer : public FRenderer // draws player sprites with hardware acceleration (only useful for software rendering) void DrawRemainingPlayerSprites() override; - int GetMaxViewPitch(bool down) override; - bool RequireGLNodes() override; - void OnModeSet() override; void SetClearColor(int color) override; - void Init() override; void RenderTextureView (FCanvasTexture *tex, AActor *viewpoint, double fov) override; - void PreprocessLevel() override; - void CleanLevelData() override; - - uint32_t GetCaps() override; + void SetColormap() override; + void Init() override; private: void PrecacheTexture(FTexture *tex, int cache); swrenderer::RenderScene mScene; }; + +FRenderer *CreateSWRenderer(); diff --git a/src/swrenderer/scene/r_light.cpp b/src/swrenderer/scene/r_light.cpp index 022f2745fb..c120c22ebe 100644 --- a/src/swrenderer/scene/r_light.cpp +++ b/src/swrenderer/scene/r_light.cpp @@ -42,7 +42,6 @@ #include "swrenderer/scene/r_light.h" #include "swrenderer/viewport/r_viewport.h" -CVAR(Bool, r_shadercolormaps, true, CVAR_ARCHIVE) EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor) namespace swrenderer @@ -69,17 +68,10 @@ namespace swrenderer if (player->fixedcolormap >= 0 && player->fixedcolormap < (int)SpecialColormaps.Size()) { realfixedcolormap = &SpecialColormaps[player->fixedcolormap]; - if (renderTarget == screen && (renderTarget->IsBgra() || ((DFrameBuffer *)screen->Accel2D && r_shadercolormaps))) - { - // Render everything fullbright. The copy to video memory will - // apply the special colormap, so it won't be restricted to the - // palette. - fixedcolormap = &realcolormaps; - } - else - { - fixedcolormap = &SpecialSWColormaps[player->fixedcolormap]; - } + // Render everything fullbright. The copy to video memory will + // apply the special colormap, so it won't be restricted to the + // palette. + fixedcolormap = &realcolormaps; } else if (player->fixedlightlevel >= 0 && player->fixedlightlevel < NUMCOLORMAPS) { diff --git a/src/swrenderer/scene/r_opaque_pass.cpp b/src/swrenderer/scene/r_opaque_pass.cpp index b9484f6245..a3e1b1bd97 100644 --- a/src/swrenderer/scene/r_opaque_pass.cpp +++ b/src/swrenderer/scene/r_opaque_pass.cpp @@ -884,9 +884,8 @@ namespace swrenderer void RenderOpaquePass::ClearClip() { - // clip ceiling to console bottom fillshort(floorclip, viewwidth, viewheight); - fillshort(ceilingclip, viewwidth, !screen->Accel2D && ConBottom > viewwindowy && !Thread->Viewport->RenderingToCanvas() ? (ConBottom - viewwindowy) : 0); + fillshort(ceilingclip, viewwidth, 0); } void RenderOpaquePass::AddSprites(sector_t *sec, int lightlevel, WaterFakeSide fakeside, bool foggy, FDynamicColormap *basecolormap) diff --git a/src/swrenderer/scene/r_portal.cpp b/src/swrenderer/scene/r_portal.cpp index a22232dbf7..46e6e83574 100644 --- a/src/swrenderer/scene/r_portal.cpp +++ b/src/swrenderer/scene/r_portal.cpp @@ -69,7 +69,9 @@ #include "swrenderer/r_renderthread.h" CVAR(Int, r_portal_recursions, 4, CVAR_ARCHIVE) -CVAR(Bool, r_highlight_portals, false, CVAR_ARCHIVE) +#if 0 +CVAR(Bool, r_highlight_portals, false, 0) +#endif CVAR(Bool, r_skyboxes, true, 0) // Avoid infinite recursion with stacked sectors by limiting them. @@ -300,7 +302,7 @@ namespace swrenderer if (viewport->RenderTarget->IsBgra()) { - uint32_t *dest = (uint32_t*)viewport->RenderTarget->GetBuffer() + x + Ytop * spacing; + uint32_t *dest = (uint32_t*)viewport->RenderTarget->GetPixels() + x + Ytop * spacing; uint32_t c = GPalette.BaseColors[color].d; for (int y = Ytop; y <= Ybottom; y++) @@ -311,7 +313,7 @@ namespace swrenderer } else { - uint8_t *dest = viewport->RenderTarget->GetBuffer() + x + Ytop * spacing; + uint8_t *dest = viewport->RenderTarget->GetPixels() + x + Ytop * spacing; for (int y = Ytop; y <= Ybottom; y++) { @@ -321,8 +323,10 @@ namespace swrenderer } } +#if 0 if (r_highlight_portals) RenderLinePortalHighlight(pds); +#endif return; } @@ -462,9 +466,11 @@ namespace swrenderer Thread->Clip3D->LeaveSkybox(); // pop 3D floor height map CurrentPortalUniq = prevuniq2; +#if 0 // draw a red line around a portal if it's being highlighted if (r_highlight_portals) RenderLinePortalHighlight(pds); +#endif CurrentPortal = prevpds; MirrorFlags = prevmf; @@ -474,6 +480,7 @@ namespace swrenderer viewpoint.Path[1] = savedpath[1]; } +#if 0 void RenderPortal::RenderLinePortalHighlight(PortalDrawseg* pds) { // [ZZ] NO OVERFLOW CHECKS HERE @@ -515,6 +522,7 @@ namespace swrenderer else *(pixels + Ybottom * viewport->RenderTarget->GetPitch() + x) = color; } } +#endif void RenderPortal::CopyStackedViewParameters() { diff --git a/src/swrenderer/scene/r_scene.cpp b/src/swrenderer/scene/r_scene.cpp index d18d0200ad..8fffe32af3 100644 --- a/src/swrenderer/scene/r_scene.cpp +++ b/src/swrenderer/scene/r_scene.cpp @@ -63,7 +63,6 @@ void PeekThreadedErrorPane(); #endif -EXTERN_CVAR(Bool, r_shadercolormaps) EXTERN_CVAR(Int, r_clearbuffer) CVAR(Bool, r_scene_multithreaded, false, 0); @@ -88,10 +87,11 @@ namespace swrenderer clearcolor = color; } - void RenderScene::RenderView(player_t *player) + void RenderScene::RenderView(player_t *player, DCanvas *target) { auto viewport = MainThread()->Viewport.get(); - viewport->RenderTarget = screen; + viewport->RenderTarget = target; + viewport->RenderingToCanvas = false; int width = SCREENWIDTH; int height = SCREENHEIGHT; @@ -105,13 +105,13 @@ namespace swrenderer { if (!viewport->RenderTarget->IsBgra()) { - memset(viewport->RenderTarget->GetBuffer(), clearcolor, viewport->RenderTarget->GetPitch() * viewport->RenderTarget->GetHeight()); + memset(viewport->RenderTarget->GetPixels(), clearcolor, viewport->RenderTarget->GetPitch() * viewport->RenderTarget->GetHeight()); } else { uint32_t bgracolor = GPalette.BaseColors[clearcolor].d; int size = viewport->RenderTarget->GetPitch() * viewport->RenderTarget->GetHeight(); - uint32_t *dest = (uint32_t *)viewport->RenderTarget->GetBuffer(); + uint32_t *dest = (uint32_t *)viewport->RenderTarget->GetPixels(); for (int i = 0; i < size; i++) dest[i] = bgracolor; } @@ -119,14 +119,6 @@ namespace swrenderer RenderActorView(player->mo); - // Apply special colormap if the target cannot do it - if (CameraLight::Instance()->ShaderColormap() && viewport->RenderTarget->IsBgra() && !(r_shadercolormaps && screen->Accel2D)) - { - auto queue = std::make_shared(MainThread()->FrameMemory.get()); - queue->Push(CameraLight::Instance()->ShaderColormap(), screen); - DrawerThreads::Execute(queue); - } - DrawerWaitCycles.Clock(); DrawerThreads::WaitForWorkers(); DrawerWaitCycles.Unclock(); @@ -174,13 +166,6 @@ namespace swrenderer MainThread()->Viewport->viewpoint.camera->renderflags = savedflags; interpolator.RestoreInterpolations(); - - // If we don't want shadered colormaps, NULL it now so that the - // copy to the screen does not use a special colormap shader. - if (!r_shadercolormaps && !MainThread()->Viewport->RenderTarget->IsBgra()) - { - CameraLight::Instance()->ClearShaderColormap(); - } } void RenderScene::RenderPSprites() @@ -359,6 +344,7 @@ namespace swrenderer viewwidth = width; viewport->RenderTarget = canvas; + viewport->RenderingToCanvas = true; R_SetWindow(MainThread()->Viewport->viewpoint, MainThread()->Viewport->viewwindow, 12, width, height, height, true); viewwindowx = x; @@ -373,7 +359,8 @@ namespace swrenderer DrawerThreads::WaitForWorkers(); DrawerWaitCycles.Unclock(); - viewport->RenderTarget = screen; + viewport->RenderTarget = nullptr; + viewport->RenderingToCanvas = false; R_ExecuteSetViewSize(MainThread()->Viewport->viewpoint, MainThread()->Viewport->viewwindow); float trueratio; @@ -383,23 +370,18 @@ namespace swrenderer viewactive = savedviewactive; } + void RenderScene::ScreenResized() { auto viewport = MainThread()->Viewport.get(); - viewport->RenderTarget = screen; int width = SCREENWIDTH; int height = SCREENHEIGHT; + viewport->RenderTarget = new DCanvas(width, height, V_IsTrueColor()); // Some code deeper down needs something valid here, so give it a dummy canvas. float trueratio; ActiveRatio(width, height, &trueratio); viewport->SetViewport(MainThread(), SCREENWIDTH, SCREENHEIGHT, trueratio); - } - - void RenderScene::Init() - { - // viewwidth / viewheight are set by the defaults - fillshort(zeroarray, MAXWIDTH, 0); - - R_InitShadeMaps(); + delete viewport->RenderTarget; + viewport->RenderTarget = nullptr; } void RenderScene::Deinit() diff --git a/src/swrenderer/scene/r_scene.h b/src/swrenderer/scene/r_scene.h index a5fd57bec5..d3b8613c09 100644 --- a/src/swrenderer/scene/r_scene.h +++ b/src/swrenderer/scene/r_scene.h @@ -44,13 +44,12 @@ namespace swrenderer RenderScene(); ~RenderScene(); - void Init(); void ScreenResized(); void Deinit(); void SetClearColor(int color); - void RenderView(player_t *player); + void RenderView(player_t *player, DCanvas *target); void RenderViewToCanvas(AActor *actor, DCanvas *canvas, int x, int y, int width, int height, bool dontmaplines = false); bool DontMapLines() const { return dontmaplines; } diff --git a/src/swrenderer/things/r_decal.cpp b/src/swrenderer/things/r_decal.cpp index ee5b10aebe..1f9dbf6a74 100644 --- a/src/swrenderer/things/r_decal.cpp +++ b/src/swrenderer/things/r_decal.cpp @@ -142,7 +142,7 @@ namespace swrenderer // pretty much the same as what R_AddLine() does. double edge_right = WallSpriteTile->GetWidth(); - double edge_left = WallSpriteTile->LeftOffset; + double edge_left = WallSpriteTile->GetLeftOffset(0); // decals should not use renderer-specific offsets. edge_right = (edge_right - edge_left) * decal->ScaleX; edge_left *= decal->ScaleX; @@ -233,7 +233,7 @@ namespace swrenderer } yscale = decal->ScaleY; - texturemid = WallSpriteTile->TopOffset + (zpos - thread->Viewport->viewpoint.Pos.Z) / yscale; + texturemid = WallSpriteTile->GetTopOffset(0) + (zpos - thread->Viewport->viewpoint.Pos.Z) / yscale; // Clip sprite to drawseg x1 = MAX(clipper->x1, x1); diff --git a/src/swrenderer/things/r_playersprite.cpp b/src/swrenderer/things/r_playersprite.cpp index 240f8e0c2e..722576a5d2 100644 --- a/src/swrenderer/things/r_playersprite.cpp +++ b/src/swrenderer/things/r_playersprite.cpp @@ -68,7 +68,6 @@ EXTERN_CVAR(Bool, r_drawplayersprites) EXTERN_CVAR(Bool, r_deathcamera) -EXTERN_CVAR(Bool, r_shadercolormaps) EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor) namespace swrenderer @@ -265,7 +264,7 @@ namespace swrenderer double pspriteyscale = pspritexscale * viewport->BaseYaspectMul * ((double)SCREENHEIGHT / SCREENWIDTH) * r_viewwindow.WidescreenRatio; double pspritexiscale = 1 / pspritexscale; - int tleft = tex->GetScaledLeftOffset(); + int tleft = tex->GetScaledLeftOffset(0); int twidth = tex->GetScaledWidth(); // calculate edges of the shape @@ -288,16 +287,19 @@ namespace swrenderer vis.renderflags = owner->renderflags; - vis.texturemid = (BASEYCENTER - sy) * tex->Scale.Y + tex->TopOffset; + vis.texturemid = (BASEYCENTER - sy) * tex->Scale.Y + tex->GetTopOffset(0); - if (Thread->Viewport->viewpoint.camera->player && (viewport->RenderTarget != screen || + // Force it to use software rendering when drawing to a canvas texture. + bool renderToCanvas = viewport->RenderingToCanvas; + + if (Thread->Viewport->viewpoint.camera->player && (renderToCanvas || viewheight == viewport->RenderTarget->GetHeight() || (viewport->RenderTarget->GetWidth() > (BASEXCENTER * 2)))) { // Adjust PSprite for fullscreen views AWeapon *weapon = dyn_cast(pspr->GetCaller()); if (weapon != nullptr && weapon->YAdjust != 0) { - if (viewport->RenderTarget != screen || viewheight == viewport->RenderTarget->GetHeight()) + if (renderToCanvas || viewheight == viewport->RenderTarget->GetHeight()) { vis.texturemid -= weapon->YAdjust; } @@ -388,13 +390,7 @@ namespace swrenderer noaccel = true; } } - // If we're drawing with a special colormap, but shaders for them are disabled, do - // not accelerate. - if (!r_shadercolormaps && (vis.Light.BaseColormap >= &SpecialSWColormaps[0] && - vis.Light.BaseColormap <= &SpecialSWColormaps.Last())) - { - noaccel = true; - } + // If drawing with a BOOM colormap, disable acceleration. if (vis.Light.BaseColormap == &NormalLight && NormalLight.Maps != realcolormaps.Maps) { @@ -420,7 +416,7 @@ namespace swrenderer // Check for hardware-assisted 2D. If it's available, and this sprite is not // fuzzy, don't draw it until after the switch to 2D mode. - if (!noaccel && viewport->RenderTarget == screen && (DFrameBuffer *)screen->Accel2D) + if (!noaccel && !renderToCanvas) { FRenderStyle style = vis.RenderStyle; style.CheckFuzz(); @@ -451,19 +447,12 @@ namespace swrenderer { accelSprite.special = CameraLight::Instance()->ShaderColormap(); } - else if (colormap_to_use->Color == PalEntry(255, 255, 255) && - colormap_to_use->Desaturate == 0) + else { accelSprite.overlay = colormap_to_use->Fade; accelSprite.overlay.a = uint8_t(vis.Light.ColormapNum * 255 / NUMCOLORMAPS); - } - else - { - accelSprite.usecolormapstyle = true; - accelSprite.colormapstyle.Color = colormap_to_use->Color; - accelSprite.colormapstyle.Fade = colormap_to_use->Fade; - accelSprite.colormapstyle.Desaturate = colormap_to_use->Desaturate; - accelSprite.colormapstyle.FadeLevel = vis.Light.ColormapNum / float(NUMCOLORMAPS); + accelSprite.LightColor = colormap_to_use->Color; + accelSprite.Desaturate = (uint8_t)clamp(colormap_to_use->Desaturate, 0, 255); } AcceleratedSprites.Push(accelSprite); @@ -496,7 +485,8 @@ namespace swrenderer DTA_FillColor, sprite.FillColor, DTA_SpecialColormap, sprite.special, DTA_ColorOverlay, sprite.overlay.d, - DTA_ColormapStyle, sprite.usecolormapstyle ? &sprite.colormapstyle : nullptr, + DTA_Color, sprite.LightColor | 0xff000000, // the color here does not have a valid alpha component. + DTA_Desaturate, sprite.Desaturate, TAG_DONE); } diff --git a/src/swrenderer/things/r_playersprite.h b/src/swrenderer/things/r_playersprite.h index 3dbfd6edb4..64dd661725 100644 --- a/src/swrenderer/things/r_playersprite.h +++ b/src/swrenderer/things/r_playersprite.h @@ -75,8 +75,8 @@ namespace swrenderer bool flip = false; FSpecialColormap *special = nullptr; PalEntry overlay = 0; - FColormapStyle colormapstyle; - bool usecolormapstyle = false; + PalEntry LightColor = 0xffffffff; + uint8_t Desaturate = 0; }; class RenderPlayerSprites diff --git a/src/swrenderer/things/r_sprite.cpp b/src/swrenderer/things/r_sprite.cpp index be26ad7c2e..8f1a060cd1 100644 --- a/src/swrenderer/things/r_sprite.cpp +++ b/src/swrenderer/things/r_sprite.cpp @@ -101,7 +101,7 @@ namespace swrenderer } // [RH] Added scaling - int scaled_to = tex->GetScaledTopOffset(); + int scaled_to = tex->GetScaledTopOffsetSW(); int scaled_bo = scaled_to - tex->GetScaledHeight(); double gzt = pos.Z + spriteScale.Y * scaled_to; double gzb = pos.Z + spriteScale.Y * scaled_bo; @@ -153,7 +153,7 @@ namespace swrenderer // calculate edges of the shape const double thingxscalemul = spriteScale.X / tex->Scale.X; - tx -= ((renderflags & RF_XFLIP) ? (tex->GetWidth() - tex->LeftOffset - 1) : tex->LeftOffset) * thingxscalemul; + tx -= ((renderflags & RF_XFLIP) ? (tex->GetWidth() - tex->GetLeftOffsetSW() - 1) : tex->GetLeftOffsetSW()) * thingxscalemul; double dtx1 = tx * xscale; int x1 = viewport->viewwindow.centerx + xs_RoundToInt(dtx1); @@ -181,7 +181,7 @@ namespace swrenderer vis->yscale = float(viewport->InvZtoScale * yscale / tz); vis->idepth = float(1 / tz); vis->floorclip = thing->Floorclip / yscale; - vis->texturemid = tex->TopOffset - (viewport->viewpoint.Pos.Z - pos.Z + thing->Floorclip) / yscale; + vis->texturemid = tex->GetTopOffsetSW() - (viewport->viewpoint.Pos.Z - pos.Z + thing->Floorclip) / yscale; vis->x1 = x1 < renderportal->WindowLeft ? renderportal->WindowLeft : x1; vis->x2 = x2 > renderportal->WindowRight ? renderportal->WindowRight : x2; //vis->Angle = thing->Angles.Yaw; diff --git a/src/swrenderer/things/r_voxel.cpp b/src/swrenderer/things/r_voxel.cpp index a3c12a8655..f10840c09b 100644 --- a/src/swrenderer/things/r_voxel.cpp +++ b/src/swrenderer/things/r_voxel.cpp @@ -338,7 +338,7 @@ namespace swrenderer } if (k >= voxobj->NumMips) k = voxobj->NumMips - 1; - mip = &voxobj->Mips[k]; if (mip->SlabData == NULL) return; + mip = &voxobj->Mips[k]; if (mip->GetSlabData(false) == NULL) return; minslabz >>= k; maxslabz >>= k; @@ -391,6 +391,8 @@ namespace swrenderer yoff = (abs(gxinc) + abs(gyinc)) >> 1; bool useSlabDataBgra = !drawerargs.DrawerNeedsPalInput() && viewport->RenderTarget->IsBgra(); + if (!useSlabDataBgra) voxobj->Remap(); + else voxobj->CreateBgraSlabData(); int coverageX1 = this->x2; int coverageX2 = this->x1; @@ -462,7 +464,8 @@ namespace swrenderer for (x = xs; x != xe; x += xi) { - uint8_t *slabxoffs = &mip->SlabData[mip->OffsetX[x]]; + auto SlabData = mip->GetSlabData(true); + uint8_t *slabxoffs = &SlabData[mip->OffsetX[x]]; short *xyoffs = &mip->OffsetXY[x * (mip->SizeY + 1)]; nx = FixedMul(ggxstart + ggxinc[x], viewport->viewingrangerecip) + x1; @@ -588,7 +591,7 @@ namespace swrenderer // // We can find the same slab column by calculating the offset from the start of SlabData // and use that to offset into the BGRA version of the same data. - columnColors = (const uint8_t *)(&mip->SlabDataBgra[0] + (ptrdiff_t)(col - mip->SlabData)); + columnColors = (const uint8_t *)(&mip->SlabDataBgra[0] + (ptrdiff_t)(col - SlabData)); } // Find top and bottom pixels that match and draw them as one strip @@ -687,7 +690,7 @@ namespace swrenderer kvxslab_t *RenderVoxel::GetSlabStart(const FVoxelMipLevel &mip, int x, int y) { - return (kvxslab_t *)&mip.SlabData[mip.OffsetX[x] + (int)mip.OffsetXY[x * (mip.SizeY + 1) + y]]; + return (kvxslab_t *)&mip.GetSlabData(true)[mip.OffsetX[x] + (int)mip.OffsetXY[x * (mip.SizeY + 1) + y]]; } kvxslab_t *RenderVoxel::GetSlabEnd(const FVoxelMipLevel &mip, int x, int y) diff --git a/src/swrenderer/things/r_wallsprite.cpp b/src/swrenderer/things/r_wallsprite.cpp index f44d88e2a5..a9f8154251 100644 --- a/src/swrenderer/things/r_wallsprite.cpp +++ b/src/swrenderer/things/r_wallsprite.cpp @@ -84,7 +84,7 @@ namespace swrenderer // Determine left and right edges of sprite. The sprite's angle is its normal, // so the edges are 90 degrees each side of it. x2 = pic->GetScaledWidth(); - x1 = pic->GetScaledLeftOffset(); + x1 = pic->GetScaledLeftOffsetSW(); x1 *= scale.X; x2 *= scale.X; @@ -107,7 +107,7 @@ namespace swrenderer // but right now, I just want to get them drawing. tz = (pos.X - thread->Viewport->viewpoint.Pos.X) * thread->Viewport->viewpoint.TanCos + (pos.Y - thread->Viewport->viewpoint.Pos.Y) * thread->Viewport->viewpoint.TanSin; - int scaled_to = pic->GetScaledTopOffset(); + int scaled_to = pic->GetScaledTopOffsetSW(); int scaled_bo = scaled_to - pic->GetScaledHeight(); gzt = pos.Z + scale.Y * scaled_to; gzb = pos.Z + scale.Y * scaled_bo; diff --git a/src/swrenderer/viewport/r_viewport.cpp b/src/swrenderer/viewport/r_viewport.cpp index f9eb35f968..57994d8995 100644 --- a/src/swrenderer/viewport/r_viewport.cpp +++ b/src/swrenderer/viewport/r_viewport.cpp @@ -95,7 +95,7 @@ namespace swrenderer { int virtheight, virtwidth, virtwidth2, virtheight2; - if (!RenderingToCanvas()) + if (!RenderingToCanvas) { // Set r_viewsize cvar to reflect the current view size UCVarValue value; char temp[16]; @@ -183,7 +183,7 @@ namespace swrenderer int pitch = RenderTarget->GetPitch(); int pixelsize = RenderTarget->IsBgra() ? 4 : 1; - return RenderTarget->GetBuffer() + (x + y * pitch) * pixelsize; + return RenderTarget->GetPixels() + (x + y * pitch) * pixelsize; } void RenderViewport::InitTextureMapping() diff --git a/src/swrenderer/viewport/r_viewport.h b/src/swrenderer/viewport/r_viewport.h index d9e337f0b9..7709e57014 100644 --- a/src/swrenderer/viewport/r_viewport.h +++ b/src/swrenderer/viewport/r_viewport.h @@ -27,6 +27,7 @@ namespace swrenderer Mat4f WorldToClip; DCanvas *RenderTarget = nullptr; + bool RenderingToCanvas = false; FViewWindow viewwindow; FRenderViewpoint viewpoint; @@ -52,8 +53,6 @@ namespace swrenderer uint8_t *GetDest(int x, int y); - bool RenderingToCanvas() const { return RenderTarget != screen; } - DVector3 PointWorldToView(const DVector3 &worldPos) const; DVector3 PointWorldToScreen(const DVector3 &worldPos) const; DVector3 PointViewToScreen(const DVector3 &viewPos) const; diff --git a/src/tarray.h b/src/tarray.h index 63eeb4eed5..7d68e58c5a 100644 --- a/src/tarray.h +++ b/src/tarray.h @@ -1221,3 +1221,112 @@ protected: hash_t Position; }; + + +//========================================================================== +// +// an array to hold a small number of unique entries +// +//========================================================================== + +template class UniqueList +{ + TArray Array; + +public: + + T * Get(T * t) + { + for (unsigned i = 0; i bytes; + unsigned size; + +public: + void Resize(unsigned elem) + { + bytes.Resize((elem + 7) / 8); + size = elem; + } + + BitArray() : size(0) + { + } + + BitArray(const BitArray & arr) + { + bytes = arr.bytes; + size = arr.size; + } + + BitArray &operator=(const BitArray & arr) + { + bytes = arr.bytes; + size = arr.size; + return *this; + } + + BitArray(BitArray && arr) + { + bytes = std::move(arr.bytes); + size = arr.size; + arr.size = 0; + } + + BitArray &operator=(BitArray && arr) + { + bytes = std::move(arr.bytes); + size = arr.size; + arr.size = 0; + return *this; + } + + bool operator[](size_t index) const + { + return !!(bytes[index >> 3] & (1 << (index & 7))); + } + + void Set(size_t index) + { + bytes[index >> 3] |= (1 << (index & 7)); + } + + void Clear(size_t index) + { + bytes[index >> 3] &= ~(1 << (index & 7)); + } + + unsigned Size() const + { + return size; + } + + void Zero() + { + memset(&bytes[0], 0, bytes.Size()); + } +}; diff --git a/src/textures/automaptexture.cpp b/src/textures/formats/automaptexture.cpp similarity index 100% rename from src/textures/automaptexture.cpp rename to src/textures/formats/automaptexture.cpp diff --git a/src/textures/backdroptexture.cpp b/src/textures/formats/backdroptexture.cpp similarity index 100% rename from src/textures/backdroptexture.cpp rename to src/textures/formats/backdroptexture.cpp diff --git a/src/textures/formats/brightmaptexture.cpp b/src/textures/formats/brightmaptexture.cpp new file mode 100644 index 0000000000..feec1e422b --- /dev/null +++ b/src/textures/formats/brightmaptexture.cpp @@ -0,0 +1,100 @@ +/* +** brightmaptexture.cpp +** The texture class for colormap based brightmaps. +** +**--------------------------------------------------------------------------- +** Copyright 2006-2018 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +** +*/ + +#include "doomtype.h" +#include "files.h" +#include "w_wad.h" +#include "templates.h" +#include "i_system.h" +#include "r_data/r_translate.h" +#include "bitmap.h" +#include "colormatcher.h" +#include "c_dispatch.h" +#include "v_video.h" +#include "m_fixed.h" +#include "textures/textures.h" +#include "v_palette.h" + +class FBrightmapTexture : public FWorldTexture +{ +public: + FBrightmapTexture (FTexture *source); + + uint8_t *MakeTexture(FRenderStyle style) override; + int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) override; + bool UseBasePalette() override { return false; } + +protected: + FTexture *SourcePic; +}; + +//=========================================================================== +// +// fake brightness maps +// These are generated for textures affected by a colormap with +// fullbright entries. +// +//=========================================================================== + +FBrightmapTexture::FBrightmapTexture (FTexture *source) +{ + Name = ""; + SourcePic = source; + CopySize(source); + bNoDecals = source->bNoDecals; + Rotations = source->Rotations; + UseType = source->UseType; + bMasked = false; + id.SetInvalid(); + SourceLump = -1; +} + +uint8_t *FBrightmapTexture::MakeTexture(FRenderStyle style) +{ + // This function is only necessary to satisfy the parent class's interface. + // This will never be called. + return nullptr; +} + +int FBrightmapTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) +{ + SourcePic->CopyTrueColorTranslated(bmp, x, y, rotate, TexMan.GlobalBrightmap.Palette); + return 0; +} + +FTexture *CreateBrightmapTexture(FTexture *tex) +{ + return new FBrightmapTexture(tex); +} \ No newline at end of file diff --git a/src/textures/buildtexture.cpp b/src/textures/formats/buildtexture.cpp similarity index 99% rename from src/textures/buildtexture.cpp rename to src/textures/formats/buildtexture.cpp index 25c7868957..bc54a22ea6 100644 --- a/src/textures/buildtexture.cpp +++ b/src/textures/formats/buildtexture.cpp @@ -81,8 +81,8 @@ FBuildTexture::FBuildTexture(const FString &pathprefix, int tilenum, const uint8 PixelsAreStatic = 3; Width = width; Height = height; - LeftOffset = left; - TopOffset = top; + _LeftOffset[1] = _LeftOffset[0] = left; + _TopOffset[1] = _TopOffset[0] = top; CalcBitSize (); Name.Format("%sBTIL%04d", pathprefix.GetChars(), tilenum); UseType = ETextureType::Override; diff --git a/src/textures/canvastexture.cpp b/src/textures/formats/canvastexture.cpp similarity index 96% rename from src/textures/canvastexture.cpp rename to src/textures/formats/canvastexture.cpp index 85f9812af6..f207593f06 100644 --- a/src/textures/canvastexture.cpp +++ b/src/textures/formats/canvastexture.cpp @@ -44,7 +44,6 @@ FCanvasTexture::FCanvasTexture (const char *name, int width, int height) Name = name; Width = width; Height = height; - LeftOffset = TopOffset = 0; CalcBitSize (); bMasked = false; @@ -113,7 +112,6 @@ const uint32_t *FCanvasTexture::GetPixelsBgra() void FCanvasTexture::MakeTexture (FRenderStyle) // This ignores the render style because making it work as alpha texture is impractical. { Canvas = new DSimpleCanvas (Width, Height, false); - Canvas->Lock (); if (Width != Height || Width != Canvas->GetPitch()) { @@ -122,7 +120,7 @@ void FCanvasTexture::MakeTexture (FRenderStyle) // This ignores the render style } else { - Pixels = (uint8_t*)Canvas->GetBuffer(); + Pixels = (uint8_t*)Canvas->GetPixels(); bPixelsAllocated = false; } @@ -134,7 +132,6 @@ void FCanvasTexture::MakeTexture (FRenderStyle) // This ignores the render style void FCanvasTexture::MakeTextureBgra() { CanvasBgra = new DSimpleCanvas(Width, Height, true); - CanvasBgra->Lock(); if (Width != Height || Width != CanvasBgra->GetPitch()) { @@ -143,7 +140,7 @@ void FCanvasTexture::MakeTextureBgra() } else { - PixelsBgra = (uint32_t*)CanvasBgra->GetBuffer(); + PixelsBgra = (uint32_t*)CanvasBgra->GetPixels(); bPixelsAllocatedBgra = false; } diff --git a/src/textures/ddstexture.cpp b/src/textures/formats/ddstexture.cpp similarity index 99% rename from src/textures/ddstexture.cpp rename to src/textures/formats/ddstexture.cpp index 0ad95f4b85..a7ed985474 100644 --- a/src/textures/ddstexture.cpp +++ b/src/textures/formats/ddstexture.cpp @@ -290,8 +290,6 @@ FDDSTexture::FDDSTexture (FileReader &lump, int lumpnum, void *vsurfdesc) DDSURFACEDESC2 *surf = (DDSURFACEDESC2 *)vsurfdesc; UseType = ETextureType::MiscPatch; - LeftOffset = 0; - TopOffset = 0; bMasked = false; Width = uint16_t(surf->Width); diff --git a/src/textures/emptytexture.cpp b/src/textures/formats/emptytexture.cpp similarity index 100% rename from src/textures/emptytexture.cpp rename to src/textures/formats/emptytexture.cpp diff --git a/src/textures/flattexture.cpp b/src/textures/formats/flattexture.cpp similarity index 99% rename from src/textures/flattexture.cpp rename to src/textures/formats/flattexture.cpp index e3ea1ca897..d3506b2501 100644 --- a/src/textures/flattexture.cpp +++ b/src/textures/formats/flattexture.cpp @@ -92,6 +92,7 @@ FFlatTexture::FFlatTexture (int lumpnum) } bMasked = false; + bTranslucent = false; WidthBits = HeightBits = bits; Width = Height = 1 << bits; WidthMask = (1 << bits) - 1; diff --git a/src/textures/imgztexture.cpp b/src/textures/formats/imgztexture.cpp similarity index 96% rename from src/textures/imgztexture.cpp rename to src/textures/formats/imgztexture.cpp index 5b5237d0de..b2cc67baaa 100644 --- a/src/textures/imgztexture.cpp +++ b/src/textures/formats/imgztexture.cpp @@ -113,8 +113,8 @@ FIMGZTexture::FIMGZTexture (int lumpnum, uint16_t w, uint16_t h, int16_t l, int1 Wads.GetLumpName (Name, lumpnum); Width = w; Height = h; - LeftOffset = l; - TopOffset = t; + _LeftOffset[1] = _LeftOffset[0] = l; + _TopOffset[1] = _TopOffset[0] = t; isalpha = _isalpha; CalcBitSize (); } @@ -131,14 +131,6 @@ uint8_t *FIMGZTexture::MakeTexture (FRenderStyle style) const ImageHeader *imgz = (const ImageHeader *)lump.GetMem(); const uint8_t *data = (const uint8_t *)&imgz[1]; - if (Width != 0xFFFF) - { - Width = LittleShort(imgz->Width); - Height = LittleShort(imgz->Height); - LeftOffset = LittleShort(imgz->LeftOffset); - TopOffset = LittleShort(imgz->TopOffset); - } - uint8_t *dest_p; int dest_adv = Height; int dest_rew = Width * Height - 1; diff --git a/src/textures/jpegtexture.cpp b/src/textures/formats/jpegtexture.cpp similarity index 99% rename from src/textures/jpegtexture.cpp rename to src/textures/formats/jpegtexture.cpp index a9658014df..1bb05265b9 100644 --- a/src/textures/jpegtexture.cpp +++ b/src/textures/formats/jpegtexture.cpp @@ -250,8 +250,6 @@ FJPEGTexture::FJPEGTexture (int lumpnum, int width, int height) : FWorldTexture(NULL, lumpnum) { UseType = ETextureType::MiscPatch; - LeftOffset = 0; - TopOffset = 0; bMasked = false; Width = width; diff --git a/src/textures/md5check.cpp b/src/textures/formats/md5check.cpp similarity index 100% rename from src/textures/md5check.cpp rename to src/textures/formats/md5check.cpp diff --git a/src/textures/multipatchtexture.cpp b/src/textures/formats/multipatchtexture.cpp similarity index 98% rename from src/textures/multipatchtexture.cpp rename to src/textures/formats/multipatchtexture.cpp index 1fe6637b53..9cb93cfcb2 100644 --- a/src/textures/multipatchtexture.cpp +++ b/src/textures/formats/multipatchtexture.cpp @@ -1100,6 +1100,7 @@ FMultiPatchTexture::FMultiPatchTexture (FScanner &sc, ETextureType usetype) Height = sc.Number; UseType = usetype; + bool offset2set = false; if (sc.CheckString("{")) { while (!sc.CheckString("}")) @@ -1183,10 +1184,24 @@ FMultiPatchTexture::FMultiPatchTexture (FScanner &sc, ETextureType usetype) else if (sc.Compare("Offset")) { sc.MustGetNumber(); - LeftOffset = sc.Number; + _LeftOffset[0] = sc.Number; sc.MustGetStringName(","); sc.MustGetNumber(); - TopOffset = sc.Number; + _TopOffset[0] = sc.Number; + if (!offset2set) + { + _LeftOffset[1] = _LeftOffset[0]; + _TopOffset[1] = _TopOffset[0]; + } + } + else if (sc.Compare("Offset2")) + { + sc.MustGetNumber(); + _LeftOffset[1] = sc.Number; + sc.MustGetStringName(","); + sc.MustGetNumber(); + _TopOffset[1] = sc.Number; + offset2set = true; } else { @@ -1264,8 +1279,8 @@ void FMultiPatchTexture::ResolvePatches() Parts[i].Texture->bKeepAround = true; if (Inits[i].UseOffsets) { - Parts[i].OriginX -= Parts[i].Texture->LeftOffset; - Parts[i].OriginY -= Parts[i].Texture->TopOffset; + Parts[i].OriginX -= Parts[i].Texture->GetLeftOffset(0); + Parts[i].OriginY -= Parts[i].Texture->GetTopOffset(0); } } } diff --git a/src/textures/patchtexture.cpp b/src/textures/formats/patchtexture.cpp similarity index 98% rename from src/textures/patchtexture.cpp rename to src/textures/formats/patchtexture.cpp index eeb900266f..8b9045c0e7 100644 --- a/src/textures/patchtexture.cpp +++ b/src/textures/formats/patchtexture.cpp @@ -159,8 +159,8 @@ FPatchTexture::FPatchTexture (int lumpnum, patch_t * header, bool isalphatex) isalpha = isalphatex; Width = header->width; Height = header->height; - LeftOffset = header->leftoffset; - TopOffset = header->topoffset; + _LeftOffset[1] = _LeftOffset[0] = header->leftoffset; + _TopOffset[1] = _TopOffset[0] = header->topoffset; DetectBadPatches(); CalcBitSize (); } @@ -310,8 +310,8 @@ void FPatchTexture::DetectBadPatches () return; // More than one post in a column! } } - LeftOffset = 0; - TopOffset = 0; + _LeftOffset[1] = _LeftOffset[0] = 0; + _TopOffset[1] = _TopOffset[0] = 0; badflag = true; bMasked = false; // Hacked textures don't have transparent parts. } diff --git a/src/textures/pcxtexture.cpp b/src/textures/formats/pcxtexture.cpp similarity index 100% rename from src/textures/pcxtexture.cpp rename to src/textures/formats/pcxtexture.cpp diff --git a/src/textures/pngtexture.cpp b/src/textures/formats/pngtexture.cpp similarity index 99% rename from src/textures/pngtexture.cpp rename to src/textures/formats/pngtexture.cpp index 95dc3f3a63..71f906899f 100644 --- a/src/textures/pngtexture.cpp +++ b/src/textures/formats/pngtexture.cpp @@ -207,8 +207,6 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename int i; UseType = ETextureType::MiscPatch; - LeftOffset = 0; - TopOffset = 0; bMasked = false; Width = width; @@ -251,8 +249,8 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename Printf ("Y-Offset for PNG texture %s is bad: %d (0x%08x)\n", Wads.GetLumpFullName (lumpnum), ihoty, ihoty); ihoty = 0; } - LeftOffset = ihotx; - TopOffset = ihoty; + _LeftOffset[1] = _LeftOffset[0] = ihotx; + _TopOffset[1] = _TopOffset[0] = ihoty; } break; diff --git a/src/textures/rawpagetexture.cpp b/src/textures/formats/rawpagetexture.cpp similarity index 80% rename from src/textures/rawpagetexture.cpp rename to src/textures/formats/rawpagetexture.cpp index 50faa94b57..ffe0d7a220 100644 --- a/src/textures/rawpagetexture.cpp +++ b/src/textures/formats/rawpagetexture.cpp @@ -37,6 +37,8 @@ #include "files.h" #include "w_wad.h" #include "v_palette.h" +#include "gi.h" +#include "bitmap.h" #include "textures/textures.h" @@ -48,9 +50,11 @@ class FRawPageTexture : public FWorldTexture { + int mPaletteLump = -1; public: FRawPageTexture (int lumpnum); uint8_t *MakeTexture (FRenderStyle style) override; + int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) override; }; //========================================================================== @@ -159,6 +163,13 @@ FRawPageTexture::FRawPageTexture (int lumpnum) WidthBits = 8; HeightBits = 8; WidthMask = 255; + + // Special case hack for Heretic's E2 end pic. This is not going to be exposed as an editing feature because the implications would be horrible. + if (Name.CompareNoCase("E2END") == 0 && gameinfo.gametype == GAME_Heretic) + { + mPaletteLump = Wads.CheckNumForName("E2PAL"); + if (Wads.LumpLength(mPaletteLump) < 768) mPaletteLump = -1; + } } //========================================================================== @@ -179,6 +190,9 @@ uint8_t *FRawPageTexture::MakeTexture (FRenderStyle style) const uint8_t *remap = GetRemap(style); + // This does not handle the custom palette. + // User maps are encouraged to use a real image format when replacing E2END and the original could never be used anywhere else. + // Convert the source image from row-major to column-major format for (int y = 200; y != 0; --y) { @@ -188,8 +202,29 @@ uint8_t *FRawPageTexture::MakeTexture (FRenderStyle style) dest_p += 200; source_p++; } - dest_p -= 200*320-1; + dest_p -= 200 * 320 - 1; } return Pixels; } +int FRawPageTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) +{ + if (mPaletteLump < 0) return FTexture::CopyTrueColorPixels(bmp, x, y, rotate, inf); + else + { + FMemLump lump = Wads.ReadLump(SourceLump); + FMemLump plump = Wads.ReadLump(mPaletteLump); + const uint8_t *source = (const uint8_t *)lump.GetMem(); + const uint8_t *psource = (const uint8_t *)plump.GetMem(); + PalEntry paldata[256]; + for (auto & pe : paldata) + { + pe.r = *psource++; + pe.g = *psource++; + pe.b = *psource++; + pe.a = 255; + } + bmp->CopyPixelData(x, y, source, 320, 200, 1, 320, 0, paldata, inf); + } + +} diff --git a/src/textures/shadertexture.cpp b/src/textures/formats/shadertexture.cpp similarity index 98% rename from src/textures/shadertexture.cpp rename to src/textures/formats/shadertexture.cpp index 67d4db683a..cb42f25b88 100644 --- a/src/textures/shadertexture.cpp +++ b/src/textures/formats/shadertexture.cpp @@ -64,6 +64,8 @@ public: Width = vertical ? 2 : 256; Height = vertical ? 256 : 2; CalcBitSize(); + bMasked = false; + bTranslucent = false; PixelsAreStatic = 2; // The alpha buffer is static, but if this gets used as a regular texture, a separate buffer needs to be made. // Fill the column/row with shading values. diff --git a/src/textures/tgatexture.cpp b/src/textures/formats/tgatexture.cpp similarity index 100% rename from src/textures/tgatexture.cpp rename to src/textures/formats/tgatexture.cpp diff --git a/src/textures/warptexture.cpp b/src/textures/formats/warptexture.cpp similarity index 100% rename from src/textures/warptexture.cpp rename to src/textures/formats/warptexture.cpp diff --git a/src/textures/worldtexture.cpp b/src/textures/formats/worldtexture.cpp similarity index 100% rename from src/textures/worldtexture.cpp rename to src/textures/formats/worldtexture.cpp diff --git a/src/gl/textures/gl_hirestex.cpp b/src/textures/hires/hirestex.cpp similarity index 86% rename from src/gl/textures/gl_hirestex.cpp rename to src/textures/hires/hirestex.cpp index 51e66ad9b9..54d5a4c757 100644 --- a/src/gl/textures/gl_hirestex.cpp +++ b/src/textures/hires/hirestex.cpp @@ -20,19 +20,10 @@ //-------------------------------------------------------------------------- // /* -** Hires texture management +** external hires texture management (i.e. Doomsday style texture packs) ** */ -#ifdef _MSC_VER -#define F_OK 0 /* Check for file existence */ -#define W_OK 2 /* Check for write permission */ -#define R_OK 4 /* Check for read permission */ -#include -#else -#include -#endif - #include "w_wad.h" #include "m_png.h" #include "sbar.h" @@ -42,10 +33,12 @@ #include "doomstat.h" #include "d_main.h" #include "zstring.h" +#include "bitmap.h" #include "textures.h" #ifndef _WIN32 -#define _access(a,b) access(a,b) +#include +#define _access(a,b) access(a,b) #endif static int Doom2Wad = -1; @@ -67,7 +60,7 @@ static void SetDoom2Wad() // Checks for the presence of a hires texture replacement in a Doomsday style PK3 // //========================================================================== -int CheckDDPK3(FTexture *tex) +int FTexture::CheckDDPK3() { static const char * doom1texpath[]= { "data/jdoom/textures/doom/%s.%s", "data/jdoom/textures/doom-ult/%s.%s", "data/jdoom/textures/doom1/%s.%s", "data/jdoom/textures/%s.%s", NULL }; @@ -111,7 +104,7 @@ int CheckDDPK3(FTexture *tex) FString checkName; const char ** checklist; - ETextureType useType=tex->UseType; + ETextureType useType=UseType; if (useType==ETextureType::SkinSprite || useType==ETextureType::Decal || useType==ETextureType::FontChar) { @@ -165,7 +158,7 @@ int CheckDDPK3(FTexture *tex) for (const char ** extp=extensions; *extp; extp++) { - checkName.Format(*checklist, tex->Name.GetChars(), *extp); + checkName.Format(*checklist, Name.GetChars(), *extp); int lumpnum = Wads.CheckNumForFullName(checkName); if (lumpnum >= 0) return lumpnum; } @@ -180,7 +173,7 @@ int CheckDDPK3(FTexture *tex) // Checks for the presence of a hires texture replacement // //========================================================================== -int CheckExternalFile(FTexture *tex, bool & hascolorkey) +int FTexture::CheckExternalFile(bool & hascolorkey) { static const char * doom1texpath[]= { "%stextures/doom/doom1/%s.%s", "%stextures/doom/doom1/%s-ck.%s", @@ -292,7 +285,7 @@ int CheckExternalFile(FTexture *tex, bool & hascolorkey) FString checkName; const char ** checklist; - ETextureType useType = tex->UseType; + ETextureType useType = UseType; if (useType == ETextureType::SkinSprite || useType == ETextureType::Decal || useType == ETextureType::FontChar) { @@ -346,7 +339,7 @@ int CheckExternalFile(FTexture *tex, bool & hascolorkey) for (const char ** extp=extensions; *extp; extp++) { - checkName.Format(*checklist, progdir.GetChars(), tex->Name.GetChars(), *extp); + checkName.Format(*checklist, progdir.GetChars(), Name.GetChars(), *extp); if (_access(checkName, 0) == 0) { hascolorkey = !!strstr(checkName, "-ck."); @@ -358,4 +351,54 @@ int CheckExternalFile(FTexture *tex, bool & hascolorkey) return -3; } +//========================================================================== +// +// Checks for the presence of a hires texture replacement and loads it +// +//========================================================================== + +unsigned char *FTexture::LoadHiresTexture(int *width, int *height) +{ + if (HiresLump == -1) + { + bHiresHasColorKey = false; + HiresLump = CheckDDPK3(); + if (HiresLump < 0) HiresLump = CheckExternalFile(bHiresHasColorKey); + + if (HiresLump >= 0) + { + HiresTexture = FTexture::CreateTexture(HiresLump, ETextureType::Any); + HiresTexture->Name = ""; + TexMan.AddTexture(HiresTexture); // let the texture manager manage this. + } + } + if (HiresTexture != nullptr) + { + int w = HiresTexture->GetWidth(); + int h = HiresTexture->GetHeight(); + + unsigned char * buffer = new unsigned char[w*(h + 1) * 4]; + memset(buffer, 0, w * (h + 1) * 4); + + FBitmap bmp(buffer, w * 4, w, h); + + int trans = HiresTexture->CopyTrueColorPixels(&bmp, 0, 0); + HiresTexture->CheckTrans(buffer, w*h, trans); + + if (bHiresHasColorKey) + { + // This is a crappy Doomsday color keyed image + // We have to remove the key manually. :( + uint32_t * dwdata = (uint32_t*)buffer; + for (int i = (w*h); i>0; i--) + { + if (dwdata[i] == 0xffffff00 || dwdata[i] == 0xffff00ff) dwdata[i] = 0; + } + } + *width = w; + *height = h; + return buffer; + } + return nullptr; +} diff --git a/src/gl/hqnx/common.h b/src/textures/hires/hqnx/common.h similarity index 100% rename from src/gl/hqnx/common.h rename to src/textures/hires/hqnx/common.h diff --git a/src/gl/hqnx/hq2x.cpp b/src/textures/hires/hqnx/hq2x.cpp similarity index 100% rename from src/gl/hqnx/hq2x.cpp rename to src/textures/hires/hqnx/hq2x.cpp diff --git a/src/gl/hqnx/hq3x.cpp b/src/textures/hires/hqnx/hq3x.cpp similarity index 100% rename from src/gl/hqnx/hq3x.cpp rename to src/textures/hires/hqnx/hq3x.cpp diff --git a/src/gl/hqnx/hq4x.cpp b/src/textures/hires/hqnx/hq4x.cpp similarity index 100% rename from src/gl/hqnx/hq4x.cpp rename to src/textures/hires/hqnx/hq4x.cpp diff --git a/src/gl/hqnx/hqx.h b/src/textures/hires/hqnx/hqx.h similarity index 100% rename from src/gl/hqnx/hqx.h rename to src/textures/hires/hqnx/hqx.h diff --git a/src/gl/hqnx/init.cpp b/src/textures/hires/hqnx/init.cpp similarity index 100% rename from src/gl/hqnx/init.cpp rename to src/textures/hires/hqnx/init.cpp diff --git a/src/gl/hqnx_asm/hq2x_asm.cpp b/src/textures/hires/hqnx_asm/hq2x_asm.cpp similarity index 100% rename from src/gl/hqnx_asm/hq2x_asm.cpp rename to src/textures/hires/hqnx_asm/hq2x_asm.cpp diff --git a/src/gl/hqnx_asm/hq3x_asm.cpp b/src/textures/hires/hqnx_asm/hq3x_asm.cpp similarity index 100% rename from src/gl/hqnx_asm/hq3x_asm.cpp rename to src/textures/hires/hqnx_asm/hq3x_asm.cpp diff --git a/src/gl/hqnx_asm/hq4x_asm.cpp b/src/textures/hires/hqnx_asm/hq4x_asm.cpp similarity index 100% rename from src/gl/hqnx_asm/hq4x_asm.cpp rename to src/textures/hires/hqnx_asm/hq4x_asm.cpp diff --git a/src/gl/hqnx_asm/hqnx_asm.h b/src/textures/hires/hqnx_asm/hqnx_asm.h similarity index 100% rename from src/gl/hqnx_asm/hqnx_asm.h rename to src/textures/hires/hqnx_asm/hqnx_asm.h diff --git a/src/gl/hqnx_asm/hqnx_asm_Image.cpp b/src/textures/hires/hqnx_asm/hqnx_asm_Image.cpp similarity index 100% rename from src/gl/hqnx_asm/hqnx_asm_Image.cpp rename to src/textures/hires/hqnx_asm/hqnx_asm_Image.cpp diff --git a/src/gl/hqnx_asm/hqnx_asm_Image.h b/src/textures/hires/hqnx_asm/hqnx_asm_Image.h similarity index 100% rename from src/gl/hqnx_asm/hqnx_asm_Image.h rename to src/textures/hires/hqnx_asm/hqnx_asm_Image.h diff --git a/src/gl/textures/gl_hqresize.cpp b/src/textures/hires/hqresize.cpp similarity index 96% rename from src/gl/textures/gl_hqresize.cpp rename to src/textures/hires/hqresize.cpp index 7995c910de..c2cba11ece 100644 --- a/src/gl/textures/gl_hqresize.cpp +++ b/src/textures/hires/hqresize.cpp @@ -37,14 +37,13 @@ #include "gl/system/gl_system.h" #include "gl/system/gl_interface.h" #include "gl/renderer/gl_renderer.h" -#include "gl/textures/gl_texture.h" #include "c_cvars.h" -#include "gl/hqnx/hqx.h" +#include "hqnx/hqx.h" #ifdef HAVE_MMX -#include "gl/hqnx_asm/hqnx_asm.h" +#include "hqnx_asm/hqnx_asm.h" #endif -#include "gl/xbr/xbrz.h" -#include "gl/xbr/xbrz_old.h" +#include "xbr/xbrz.h" +#include "xbr/xbrz_old.h" #include "parallel_for.h" @@ -314,7 +313,7 @@ static void xbrzOldScale(size_t factor, const uint32_t* src, uint32_t* trg, int // the upsampled buffer. // //=========================================================================== -unsigned char *gl_CreateUpsampledTextureBuffer ( const FTexture *inputTexture, unsigned char *inputBuffer, const int inWidth, const int inHeight, int &outWidth, int &outHeight, bool hasAlpha ) +unsigned char *FTexture::CreateUpsampledTextureBuffer (unsigned char *inputBuffer, const int inWidth, const int inHeight, int &outWidth, int &outHeight, bool hasAlpha ) { // [BB] Make sure that outWidth and outHeight denote the size of // the returned buffer even if we don't upsample the input buffer. @@ -326,18 +325,18 @@ unsigned char *gl_CreateUpsampledTextureBuffer ( const FTexture *inputTexture, u return inputBuffer; // [BB] Don't try to upsample textures based off FCanvasTexture. - if ( inputTexture->bHasCanvas ) + if ( bHasCanvas ) return inputBuffer; // [BB] Don't upsample non-shader handled warped textures. Needs too much memory and time - if (gl.legacyMode && inputTexture->bWarped) + if (gl.legacyMode && bWarped) return inputBuffer; // already scaled? - if (inputTexture->Scale.X >= 2 && inputTexture->Scale.Y >= 2) + if (Scale.X >= 2 && Scale.Y >= 2) return inputBuffer; - switch (inputTexture->UseType) + switch (UseType) { case ETextureType::Sprite: case ETextureType::SkinSprite: diff --git a/src/gl/xbr/xbrz.cpp b/src/textures/hires/xbr/xbrz.cpp similarity index 100% rename from src/gl/xbr/xbrz.cpp rename to src/textures/hires/xbr/xbrz.cpp diff --git a/src/gl/xbr/xbrz.h b/src/textures/hires/xbr/xbrz.h similarity index 100% rename from src/gl/xbr/xbrz.h rename to src/textures/hires/xbr/xbrz.h diff --git a/src/gl/xbr/xbrz_config.h b/src/textures/hires/xbr/xbrz_config.h similarity index 100% rename from src/gl/xbr/xbrz_config.h rename to src/textures/hires/xbr/xbrz_config.h diff --git a/src/gl/xbr/xbrz_config_old.h b/src/textures/hires/xbr/xbrz_config_old.h similarity index 100% rename from src/gl/xbr/xbrz_config_old.h rename to src/textures/hires/xbr/xbrz_config_old.h diff --git a/src/gl/xbr/xbrz_old.cpp b/src/textures/hires/xbr/xbrz_old.cpp similarity index 100% rename from src/gl/xbr/xbrz_old.cpp rename to src/textures/hires/xbr/xbrz_old.cpp diff --git a/src/gl/xbr/xbrz_old.h b/src/textures/hires/xbr/xbrz_old.h similarity index 100% rename from src/gl/xbr/xbrz_old.h rename to src/textures/hires/xbr/xbrz_old.h diff --git a/src/textures/skyboxtexture.cpp b/src/textures/skyboxtexture.cpp index c851a91a11..943b1f4428 100644 --- a/src/textures/skyboxtexture.cpp +++ b/src/textures/skyboxtexture.cpp @@ -38,7 +38,7 @@ FSkyBox::FSkyBox() { faces[0]=faces[1]=faces[2]=faces[3]=faces[4]=faces[5]=NULL; UseType = ETextureType::Override; - gl_info.bSkybox = true; + bSkybox = true; fliptop = false; } @@ -108,96 +108,5 @@ bool FSkyBox::UseBasePalette() void FSkyBox::Unload () { - //for(int i=0;i<6;i++) if (faces[i]) faces[i]->Unload(); -} - -//----------------------------------------------------------------------------- -// -// -// -//----------------------------------------------------------------------------- - -void ParseGldefSkybox(FScanner &sc) -{ - int facecount=0; - - sc.MustGetString(); - - FSkyBox * sb = new FSkyBox; - sb->Name = sc.String; - sb->Name.ToUpper(); - if (sc.CheckString("fliptop")) - { - sb->fliptop = true; - } - sc.MustGetStringName("{"); - while (!sc.CheckString("}")) - { - sc.MustGetString(); - if (facecount<6) - { - sb->faces[facecount] = TexMan[TexMan.GetTexture(sc.String, ETextureType::Wall, FTextureManager::TEXMAN_TryAny|FTextureManager::TEXMAN_Overridable)]; - } - facecount++; - } - if (facecount != 3 && facecount != 6) - { - sc.ScriptError("%s: Skybox definition requires either 3 or 6 faces", sb->Name.GetChars()); - } - sb->SetSize(); - TexMan.AddTexture(sb); -} - -//----------------------------------------------------------------------------- -// -// gl_ParseVavoomSkybox -// -//----------------------------------------------------------------------------- - -void ParseVavoomSkybox() -{ - int lump = Wads.CheckNumForName("SKYBOXES"); - - if (lump < 0) return; - - FScanner sc(lump); - while (sc.GetString()) - { - int facecount=0; - int maplump = -1; - bool error = false; - FSkyBox * sb = new FSkyBox; - sb->Name = sc.String; - sb->Name.ToUpper(); - sb->fliptop = true; - sc.MustGetStringName("{"); - while (!sc.CheckString("}")) - { - if (facecount<6) - { - sc.MustGetStringName("{"); - sc.MustGetStringName("map"); - sc.MustGetString(); - - maplump = Wads.CheckNumForFullName(sc.String, true); - - FTexture *tex = TexMan.FindTexture(sc.String, ETextureType::Wall, FTextureManager::TEXMAN_TryAny); - if (tex == NULL) - { - sc.ScriptMessage("Texture '%s' not found in Vavoom skybox '%s'\n", sc.String, sb->Name.GetChars()); - error = true; - } - sb->faces[facecount] = tex; - sc.MustGetStringName("}"); - } - facecount++; - } - if (facecount != 6) - { - sc.ScriptError("%s: Skybox definition requires 6 faces", sb->Name.GetChars()); - } - sb->SetSize(); - if (!error) TexMan.AddTexture(sb); - } } diff --git a/src/textures/skyboxtexture.h b/src/textures/skyboxtexture.h index a6048ce583..79fb9da4d7 100644 --- a/src/textures/skyboxtexture.h +++ b/src/textures/skyboxtexture.h @@ -43,8 +43,3 @@ public: return fliptop; } }; - - -void ParseGldefSkybox(FScanner &sc); -void ParseVavoomSkybox(); - diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index 2d0349f86a..ac72a8027d 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -4,6 +4,7 @@ ** **--------------------------------------------------------------------------- ** Copyright 2004-2007 Randy Heit +** Copyright 2006-2018 Christoph Oelckers ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without @@ -47,13 +48,22 @@ #include "textures/textures.h" #include "v_palette.h" -typedef FTexture * (*CreateFunc)(FileReader & file, int lumpnum); +FTexture *CreateBrightmapTexture(FTexture*); -struct TexCreateInfo +// Make sprite offset adjustment user-configurable per renderer. +int r_spriteadjustSW, r_spriteadjustHW; +CUSTOM_CVAR(Int, r_spriteadjust, 2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) { - CreateFunc TryCreate; - ETextureType usetype; -}; + r_spriteadjustHW = !!(self & 2); + r_spriteadjustSW = !!(self & 1); + TexMan.SpriteAdjustChanged(); +} + +//========================================================================== +// +// +// +//========================================================================== uint8_t FTexture::GrayMap[256]; @@ -61,10 +71,25 @@ void FTexture::InitGrayMap() { for (int i = 0; i < 256; ++i) { - GrayMap[i] = ColorMatcher.Pick (i, i, i); + GrayMap[i] = ColorMatcher.Pick(i, i, i); } } + +//========================================================================== +// +// +// +//========================================================================== + +typedef FTexture * (*CreateFunc)(FileReader & file, int lumpnum); + +struct TexCreateInfo +{ + CreateFunc TryCreate; + ETextureType usetype; +}; + FTexture *IMGZTexture_TryCreate(FileReader &, int lumpnum); FTexture *PNGTexture_TryCreate(FileReader &, int lumpnum); FTexture *JPEGTexture_TryCreate(FileReader &, int lumpnum); @@ -144,14 +169,30 @@ FTexture * FTexture::CreateTexture (const char *name, int lumpnum, ETextureType return tex; } +//========================================================================== +// +// +// +//========================================================================== FTexture::FTexture (const char *name, int lumpnum) -: LeftOffset(0), TopOffset(0), + : WidthBits(0), HeightBits(0), Scale(1,1), SourceLump(lumpnum), UseType(ETextureType::Any), bNoDecals(false), bNoRemap0(false), bWorldPanning(false), - bMasked(true), bAlphaTexture(false), bHasCanvas(false), bWarped(0), bComplex(false), bMultiPatch(false), bKeepAround(false), + bMasked(true), bAlphaTexture(false), bHasCanvas(false), bWarped(0), bComplex(false), bMultiPatch(false), bKeepAround(false), bFullNameTexture(false), Rotations(0xFFFF), SkyOffset(0), Width(0), Height(0), WidthMask(0) { + bBrightmapChecked = false; + bGlowing = false; + bAutoGlowing = false; + bFullbright = false; + bDisableFullbright = false; + bSkybox = false; + bNoCompress = false; + bTranslucent = -1; + + + _LeftOffset[0] = _LeftOffset[1] = _TopOffset[0] = _TopOffset[1] = 0; id.SetInvalid(); if (name != NULL) { @@ -171,8 +212,9 @@ FTexture::FTexture (const char *name, int lumpnum) FTexture::~FTexture () { FTexture *link = Wads.GetLinkedTexture(SourceLump); - if (link == this) Wads.SetLinkedTexture(SourceLump, NULL); - KillNative(); + if (link == this) Wads.SetLinkedTexture(SourceLump, nullptr); + if (areas != nullptr) delete[] areas; + areas = nullptr; } void FTexture::Unload() @@ -180,6 +222,12 @@ void FTexture::Unload() PixelsBgra = std::vector(); } +//========================================================================== +// +// +// +//========================================================================== + const uint32_t *FTexture::GetColumnBgra(unsigned int column, const Span **spans_out) { const uint32_t *pixels = GetPixelsBgra(); @@ -207,6 +255,12 @@ const uint32_t *FTexture::GetPixelsBgra() return PixelsBgra.data(); } +//========================================================================== +// +// +// +//========================================================================== + bool FTexture::CheckModified (FRenderStyle) { return false; @@ -222,6 +276,12 @@ void FTexture::SetFrontSkyLayer () bNoRemap0 = true; } +//========================================================================== +// +// +// +//========================================================================== + void FTexture::CalcBitSize () { // WidthBits is rounded down, and HeightBits is rounded up @@ -249,6 +309,12 @@ void FTexture::CalcBitSize () HeightBits = i; } +//========================================================================== +// +// +// +//========================================================================== + FTexture::Span **FTexture::CreateSpans (const uint8_t *pixels) const { Span **spans, *span; @@ -348,6 +414,12 @@ void FTexture::FreeSpans (Span **spans) const M_Free (spans); } +//========================================================================== +// +// +// +//========================================================================== + void FTexture::GenerateBgraFromBitmap(const FBitmap &bitmap) { CreatePixelsBgraWithMipmaps(); @@ -390,6 +462,12 @@ int FTexture::MipmapLevels() const return MAX(widthbits, heightbits); } +//========================================================================== +// +// +// +//========================================================================== + void FTexture::GenerateBgraMipmaps() { struct Color4f @@ -511,6 +589,12 @@ void FTexture::GenerateBgraMipmaps() } } +//========================================================================== +// +// +// +//========================================================================== + void FTexture::GenerateBgraMipmapsFast() { uint32_t *src = PixelsBgra.data(); @@ -552,6 +636,12 @@ void FTexture::GenerateBgraMipmapsFast() } } +//========================================================================== +// +// +// +//========================================================================== + void FTexture::CopyToBlock (uint8_t *dest, int dwidth, int dheight, int xpos, int ypos, int rotate, const uint8_t *translation, FRenderStyle style) { const uint8_t *pixels = GetPixels(style); @@ -593,8 +683,12 @@ void FTexture::CopyToBlock (uint8_t *dest, int dwidth, int dheight, int xpos, in } } +//========================================================================== +// // Converts a texture between row-major and column-major format // by flipping it about the X=Y axis. +// +//========================================================================== void FTexture::FlipSquareBlock (uint8_t *block, int x, int y) { @@ -711,39 +805,11 @@ void FTexture::FlipNonSquareBlockRemap (uint8_t *dst, const uint8_t *src, int x, } } -FNativeTexture *FTexture::GetNative(FTextureFormat fmt, bool wrapping) -{ - if (Native[fmt] != NULL) - { - if (!Native[fmt]->CheckWrapping(wrapping)) - { // Texture's wrapping mode is not compatible. - // Destroy it and get a new one. - delete Native[fmt]; - } - else - { - if (CheckModified(DefaultRenderStyle())) - { - Native[fmt]->Update(); - } - return Native[fmt]; - } - } - Native[fmt] = screen->CreateTexture(this, fmt, wrapping); - return Native[fmt]; -} - -void FTexture::KillNative() -{ - for (auto &nat : Native) - { - if (nat != nullptr) - { - delete nat; - nat = nullptr; - } - } -} +//========================================================================== +// +// +// +//========================================================================== void FTexture::FillBuffer(uint8_t *buff, int pitch, int height, FTextureFormat fmt) { @@ -812,7 +878,13 @@ int FTexture::CopyTrueColorTranslated(FBitmap *bmp, int x, int y, int rotate, Pa return 0; } -bool FTexture::UseBasePalette() +//========================================================================== +// +// +// +//========================================================================== + +bool FTexture::UseBasePalette() { return true; } @@ -939,8 +1011,469 @@ int FTexture::CheckRealHeight() return maxy; } +//========================================================================== +// +// Search auto paths for extra material textures +// +//========================================================================== + +void FTexture::AddAutoMaterials() +{ + struct AutoTextureSearchPath + { + const char *path; + FTexture *FTexture::*pointer; + }; + + static AutoTextureSearchPath autosearchpaths[] = + { + { "brightmaps/", &FTexture::Brightmap }, // For backwards compatibility, only for short names + { "materials/brightmaps/", &FTexture::Brightmap }, + { "materials/normalmaps/", &FTexture::Normal }, + { "materials/specular/", &FTexture::Specular }, + { "materials/metallic/", &FTexture::Metallic }, + { "materials/roughness/", &FTexture::Roughness }, + { "materials/ao/", &FTexture::AmbientOcclusion } + }; + int startindex = bFullNameTexture ? 1 : 0; + FString searchname = Name; + + if (bFullNameTexture) + { + auto dot = searchname.LastIndexOf('.'); + auto slash = searchname.LastIndexOf('/'); + if (dot > slash) searchname.Truncate(dot); + } + + for (size_t i = 0; i < countof(autosearchpaths); i++) + { + auto &layer = autosearchpaths[i]; + if (this->*(layer.pointer) == nullptr) // only if no explicit assignment had been done. + { + FStringf lookup("%s%s%s", layer.path, bFullNameTexture ? "" : "auto/", searchname.GetChars()); + auto lump = Wads.CheckNumForFullName(lookup, false, ns_global, true); + if (lump != -1) + { + auto bmtex = TexMan.FindTexture(Wads.GetLumpFullName(lump), ETextureType::Any, FTextureManager::TEXMAN_TryAny); + if (bmtex != nullptr) + { + bmtex->bMasked = false; + this->*(layer.pointer) = bmtex; + } + } + } + } +} + +//=========================================================================== +// +// Checks if the texture has a default brightmap and creates it if so +// +//=========================================================================== +void FTexture::CreateDefaultBrightmap() +{ + if (!bBrightmapChecked) + { + // Check for brightmaps + if (UseBasePalette() && TexMan.HasGlobalBrightmap && + UseType != ETextureType::Decal && UseType != ETextureType::MiscPatch && UseType != ETextureType::FontChar && + Brightmap == NULL && bWarped == 0 + ) + { + // May have one - let's check when we use this texture + const uint8_t *texbuf = GetPixels(DefaultRenderStyle()); + const int white = ColorMatcher.Pick(255, 255, 255); + + int size = GetWidth() * GetHeight(); + for (int i = 0; i512) return false; + + startdraw = -1; + lendraw = 0; + for (y = 0; y 0) + { + FloatRect * rcs = new FloatRect[gapc]; + + for (x = 0; x < gapc; x++) + { + // gaps are stored as texture (u/v) coordinates + rcs[x].width = rcs[x].left = -1.0f; + rcs[x].top = (float)gaps[x][0] / (float)h; + rcs[x].height = (float)gaps[x][1] / (float)h; + } + areas = rcs; + } + else areas = nullptr; + areacount = gapc; + + return true; +} + +//---------------------------------------------------------------------------- +// +// +// +//---------------------------------------------------------------------------- + +void FTexture::CheckTrans(unsigned char * buffer, int size, int trans) +{ + if (bTranslucent == -1) + { + bTranslucent = trans; + if (trans == -1) + { + uint32_t * dwbuf = (uint32_t*)buffer; + for (int i = 0; i> 24; + + if (alpha != 0xff && alpha != 0) + { + bTranslucent = 1; + return; + } + } + bTranslucent = 0; + } + } +} + + +//=========================================================================== +// +// smooth the edges of transparent fields in the texture +// +//=========================================================================== + +#ifdef WORDS_BIGENDIAN +#define MSB 0 +#define SOME_MASK 0xffffff00 +#else +#define MSB 3 +#define SOME_MASK 0x00ffffff +#endif + +#define CHKPIX(ofs) (l1[(ofs)*4+MSB]==255 ? (( ((uint32_t*)l1)[0] = ((uint32_t*)l1)[ofs]&SOME_MASK), trans=true ) : false) + +bool FTexture::SmoothEdges(unsigned char * buffer, int w, int h) +{ + int x, y; + bool trans = buffer[MSB] == 0; // If I set this to false here the code won't detect textures + // that only contain transparent pixels. + bool semitrans = false; + unsigned char * l1; + + if (h <= 1 || w <= 1) return false; // makes (a) no sense and (b) doesn't work with this code! + + l1 = buffer; + + + if (l1[MSB] == 0 && !CHKPIX(1)) CHKPIX(w); + else if (l1[MSB]<255) semitrans = true; + l1 += 4; + for (x = 1; x= STRange_Min) + { + // Allow creation of desaturated or special-colormapped textures for the legacy renderer. + FCopyInfo inf = { OP_COPY, BLEND_NONE,{ 0 }, 0, 0 }; + if (translation >= STRange_Desaturate && translation < STRange_Desaturate + 31) // there are 31 ranges of desaturations available + { + inf.blend = (EBlend)(BLEND_DESATURATE1 + translation - STRange_Desaturate); + } + else if (translation >= STRange_Specialcolormap && translation < STRange_Specialcolormap + (int)SpecialColormaps.Size()) + { + inf.blend = (EBlend)(BLEND_SPECIALCOLORMAP1 + translation - STRange_Specialcolormap); + } + + int trans = CopyTrueColorPixels(&bmp, exx, exx, 0, translation >= STRange_Min ? &inf : nullptr); + CheckTrans(buffer, W*H, trans); + isTransparent = bTranslucent; + // alpha texture for legacy mode + if (translation == STRange_AlphaTexture) + { + for (int i = 0; i < W*H; i++) + { + int b = buffer[4 * i]; + int g = buffer[4 * i + 1]; + int r = buffer[4 * i + 2]; + int gray = Luminance(r, g, b); + buffer[4 * i] = 255; + buffer[4 * i + 1] = 255; + buffer[4 * i + 2] = 255; + buffer[4 * i + 3] = (buffer[4 * i + 3] * gray) >> 8; + } + } + } + else + { + // When using translations everything must be mapped to the base palette. + // so use CopyTrueColorTranslated + CopyTrueColorTranslated(&bmp, exx, exx, 0, FUniquePalette::GetPalette(translation)); + isTransparent = 0; + // This is not conclusive for setting the texture's transparency info. + } + + // [BB] The hqnx upsampling (not the scaleN one) destroys partial transparency, don't upsamle textures using it. + // [BB] Potentially upsample the buffer. + if (flags & CTF_ProcessData) + { + buffer = CreateUpsampledTextureBuffer(buffer, W, H, w, h, !!isTransparent); + ProcessData(buffer, w, h, false); + } + return buffer; +} + +//=========================================================================== +// +// Dummy texture for the 0-entry. +// +//=========================================================================== + +bool FTexture::GetTranslucency() +{ + if (bTranslucent == -1) + { + if (!bHasCanvas) + { + int w, h; + unsigned char *buffer = CreateTexBuffer(0, w, h); + delete[] buffer; + } + else + { + bTranslucent = 0; + } + } + return !!bTranslucent; +} + +//=========================================================================== +// +// empty stubs to be overloaded by child classes. +// +//=========================================================================== + +const uint8_t *FTexture::GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out) +{ + return nullptr; +} + +const uint8_t *FTexture::GetPixels(FRenderStyle style) +{ + return nullptr; +} + +//=========================================================================== +// +// Dummy texture for the 0-entry. +// +//=========================================================================== FDummyTexture::FDummyTexture () { @@ -959,17 +1492,6 @@ void FDummyTexture::SetSize (int width, int height) CalcBitSize (); } -// These only get called from the texture precacher which discards the result. -const uint8_t *FDummyTexture::GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out) -{ - return nullptr; -} - -const uint8_t *FDummyTexture::GetPixels(FRenderStyle style) -{ - return nullptr; -} - //========================================================================== // // Debug stuff diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index 6902170cca..c7dc35fd37 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -163,14 +163,19 @@ FTextureID FTextureManager::CheckForTexture (const char *name, ETextureType uset { return FTextureID(0); } - i = HashFirst[MakeKey (name) % HASH_SIZE]; - while (i != HASH_END) + for(i = HashFirst[MakeKey(name) % HASH_SIZE]; i != HASH_END; i = Textures[i].HashNext) { const FTexture *tex = Textures[i].Texture; - if (stricmp (tex->Name, name) == 0) + + if (stricmp (tex->Name, name) == 0 ) { + // If we look for short names, we must ignore any long name texture. + if ((flags & TEXMAN_ShortNameOnly) && tex->bFullNameTexture) + { + continue; + } // The name matches, so check the texture type if (usetype == ETextureType::Any) { @@ -210,7 +215,6 @@ FTextureID FTextureManager::CheckForTexture (const char *name, ETextureType uset } } } - i = Textures[i].HashNext; } if ((flags & TEXMAN_TryAny) && usetype != ETextureType::Any) @@ -242,6 +246,7 @@ FTextureID FTextureManager::CheckForTexture (const char *name, ETextureType uset tex = FTexture::CreateTexture("", lump, ETextureType::Override); if (tex != NULL) { + tex->AddAutoMaterials(); Wads.SetLinkedTexture(lump, tex); return AddTexture(tex); } @@ -581,8 +586,10 @@ void FTextureManager::AddHiresTextures (int wadnum) // Replace the entire texture and adjust the scaling and offset factors. newtex->bWorldPanning = true; newtex->SetScaledSize(oldtex->GetScaledWidth(), oldtex->GetScaledHeight()); - newtex->LeftOffset = int(oldtex->GetScaledLeftOffset() * newtex->Scale.X); - newtex->TopOffset = int(oldtex->GetScaledTopOffset() * newtex->Scale.Y); + newtex->_LeftOffset[0] = int(oldtex->GetScaledLeftOffset(0) * newtex->Scale.X); + newtex->_LeftOffset[1] = int(oldtex->GetScaledLeftOffset(1) * newtex->Scale.X); + newtex->_TopOffset[0] = int(oldtex->GetScaledTopOffset(0) * newtex->Scale.Y); + newtex->_TopOffset[1] = int(oldtex->GetScaledTopOffset(1) * newtex->Scale.Y); ReplaceTexture(tlist[i], newtex, true); } } @@ -671,8 +678,10 @@ void FTextureManager::LoadTextureDefs(int wadnum, const char *lumpname) // Replace the entire texture and adjust the scaling and offset factors. newtex->bWorldPanning = true; newtex->SetScaledSize(oldtex->GetScaledWidth(), oldtex->GetScaledHeight()); - newtex->LeftOffset = int(oldtex->GetScaledLeftOffset() * newtex->Scale.X); - newtex->TopOffset = int(oldtex->GetScaledTopOffset() * newtex->Scale.Y); + newtex->_LeftOffset[0] = int(oldtex->GetScaledLeftOffset(0) * newtex->Scale.X); + newtex->_LeftOffset[1] = int(oldtex->GetScaledLeftOffset(1) * newtex->Scale.X); + newtex->_TopOffset[0] = int(oldtex->GetScaledTopOffset(0) * newtex->Scale.Y); + newtex->_TopOffset[1] = int(oldtex->GetScaledTopOffset(1) * newtex->Scale.Y); ReplaceTexture(tlist[i], newtex, true); } } @@ -977,6 +986,7 @@ FTexture *CreateShaderTexture(bool, bool); void FTextureManager::Init() { DeleteAll(); + GenerateGlobalBrightmapFromColormap(); SpriteFrames.Clear(); //if (BuildTileFiles.Size() == 0) CountBuildTiles (); FTexture::InitGrayMap(); @@ -1040,6 +1050,12 @@ void FTextureManager::Init() FixAnimations(); InitSwitchList(); InitPalettedVersions(); + AdjustSpriteOffsets(); + // Add auto materials to each texture after everything has been set up. + for (auto &tex : Textures) + { + tex.Texture->AddAutoMaterials(); + } } //========================================================================== @@ -1052,7 +1068,6 @@ void FTextureManager::InitPalettedVersions() { int lump, lastlump = 0; - PalettedVersions.Clear(); while ((lump = Wads.FindLump("PALVERS", &lastlump)) != -1) { FScanner sc(lump); @@ -1072,7 +1087,10 @@ void FTextureManager::InitPalettedVersions() } if (pic1.isValid() && pic2.isValid()) { - PalettedVersions[pic1.GetIndex()] = pic2.GetIndex(); + FTexture *owner = TexMan[pic1]; + FTexture *owned = TexMan[pic2]; + + if (owner && owned) owner->PalVersion = owned; } } } @@ -1084,12 +1102,13 @@ void FTextureManager::InitPalettedVersions() // //========================================================================== +// fixme: The way this is used, it is mostly useless. FTextureID FTextureManager::PalCheck(FTextureID tex) { if (vid_nopalsubstitutions) return tex; - int *newtex = PalettedVersions.CheckKey(tex.GetIndex()); - if (newtex == NULL || *newtex == 0) return tex; - return *newtex; + auto ftex = operator[](tex); + if (ftex != nullptr && ftex->PalVersion != nullptr) return ftex->PalVersion->id; + return tex; } //=========================================================================== @@ -1188,6 +1207,154 @@ int FTextureManager::CountLumpTextures (int lumpnum) return 0; } +//----------------------------------------------------------------------------- +// +// Adjust sprite offsets for GL rendering (IWAD resources only) +// +//----------------------------------------------------------------------------- + +void FTextureManager::AdjustSpriteOffsets() +{ + int lump, lastlump = 0; + int sprid; + TMap donotprocess; + + int numtex = Wads.GetNumLumps(); + + for (int i = 0; i < numtex; i++) + { + if (Wads.GetLumpFile(i) > Wads.GetIwadNum()) break; // we are past the IWAD + if (Wads.GetLumpNamespace(i) == ns_sprites && Wads.GetLumpFile(i) == Wads.GetIwadNum()) + { + char str[9]; + Wads.GetLumpName(str, i); + str[8] = 0; + FTextureID texid = TexMan.CheckForTexture(str, ETextureType::Sprite, 0); + if (texid.isValid() && Wads.GetLumpFile(TexMan[texid]->SourceLump) > Wads.GetIwadNum()) + { + // This texture has been replaced by some PWAD. + memcpy(&sprid, str, 4); + donotprocess[sprid] = true; + } + } + } + + while ((lump = Wads.FindLump("SPROFS", &lastlump, false)) != -1) + { + FScanner sc; + sc.OpenLumpNum(lump); + sc.SetCMode(true); + int ofslumpno = Wads.GetLumpFile(lump); + while (sc.GetString()) + { + int x, y; + bool iwadonly = false; + bool forced = false; + FTextureID texno = TexMan.CheckForTexture(sc.String, ETextureType::Sprite); + sc.MustGetStringName(","); + sc.MustGetNumber(); + x = sc.Number; + sc.MustGetStringName(","); + sc.MustGetNumber(); + y = sc.Number; + if (sc.CheckString(",")) + { + sc.MustGetString(); + if (sc.Compare("iwad")) iwadonly = true; + if (sc.Compare("iwadforced")) forced = iwadonly = true; + } + if (texno.isValid()) + { + FTexture * tex = TexMan[texno]; + + int lumpnum = tex->GetSourceLump(); + // We only want to change texture offsets for sprites in the IWAD or the file this lump originated from. + if (lumpnum >= 0 && lumpnum < Wads.GetNumLumps()) + { + int wadno = Wads.GetLumpFile(lumpnum); + if ((iwadonly && wadno == Wads.GetIwadNum()) || (!iwadonly && wadno == ofslumpno)) + { + if (wadno == Wads.GetIwadNum() && !forced && iwadonly) + { + memcpy(&sprid, &tex->Name[0], 4); + if (donotprocess.CheckKey(sprid)) continue; // do not alter sprites that only get partially replaced. + } + tex->_LeftOffset[1] = x; + tex->_TopOffset[1] = y; + } + } + } + } + } +} + +//----------------------------------------------------------------------------- +// +// +// +//----------------------------------------------------------------------------- + +void FTextureManager::SpriteAdjustChanged() +{ + for (auto &texi : Textures) + { + auto tex = texi.Texture; + if (tex->GetLeftOffset(0) != tex->GetLeftOffset(1) || tex->GetTopOffset(0) != tex->GetTopOffset(1)) + { + tex->SetSpriteAdjust(); + } + } +} + +//=========================================================================== +// +// Examines the colormap to see if some of the colors have to be +// considered fullbright all the time. +// +//=========================================================================== + +void FTextureManager::GenerateGlobalBrightmapFromColormap() +{ + Wads.CheckNumForFullName("textures/tgapal", false, 0, true); + HasGlobalBrightmap = false; + int lump = Wads.CheckNumForName("COLORMAP"); + if (lump == -1) lump = Wads.CheckNumForName("COLORMAP", ns_colormaps); + if (lump == -1) return; + FMemLump cmap = Wads.ReadLump(lump); + uint8_t palbuffer[768]; + ReadPalette(Wads.CheckNumForName("PLAYPAL"), palbuffer); + + const unsigned char *cmapdata = (const unsigned char *)cmap.GetMem(); + const uint8_t *paldata = palbuffer; + + const int black = 0; + const int white = ColorMatcher.Pick(255, 255, 255); + + + GlobalBrightmap.MakeIdentity(); + memset(GlobalBrightmap.Remap, white, 256); + for (int i = 0; i<256; i++) GlobalBrightmap.Palette[i] = PalEntry(255, 255, 255, 255); + for (int j = 0; j<32; j++) + { + for (int i = 0; i<256; i++) + { + // the palette comparison should be for ==0 but that gives false positives with Heretic + // and Hexen. + if (cmapdata[i + j * 256] != i || (paldata[3 * i]<10 && paldata[3 * i + 1]<10 && paldata[3 * i + 2]<10)) + { + GlobalBrightmap.Remap[i] = black; + GlobalBrightmap.Palette[i] = PalEntry(255, 0, 0, 0); + } + } + } + for (int i = 0; i<256; i++) + { + HasGlobalBrightmap |= GlobalBrightmap.Remap[i] == white; + if (GlobalBrightmap.Remap[i] == white) DPrintf(DMSG_NOTIFY, "Marked color %d as fullbright\n", i); + } +} + + //========================================================================== // // @@ -1269,7 +1436,7 @@ DEFINE_ACTION_FUNCTION(_TexMan, GetScaledOffset) auto tex = TexMan.ByIndex(texid); if (tex != nullptr) { - ACTION_RETURN_VEC2(DVector2(tex->GetScaledLeftOffsetDouble(), tex->GetScaledTopOffsetDouble())); + ACTION_RETURN_VEC2(DVector2(tex->GetScaledLeftOffsetDouble(0), tex->GetScaledTopOffsetDouble(0))); } ACTION_RETURN_VEC2(DVector2(-1, -1)); } diff --git a/src/textures/textures.h b/src/textures/textures.h index 0cd5bcf71e..bfb675d6e8 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -38,12 +38,36 @@ #include "doomtype.h" #include "vectors.h" #include "v_palette.h" -#include "v_video.h" +#include "v_colortables.h" #include "colormatcher.h" #include "r_data/renderstyle.h" #include "r_data/r_translate.h" #include +enum MaterialShaderIndex +{ + SHADER_Default, + SHADER_Warp1, + SHADER_Warp2, + SHADER_Brightmap, + SHADER_Specular, + SHADER_SpecularBrightmap, + SHADER_PBR, + SHADER_PBRBrightmap, + SHADER_Paletted, + SHADER_NoTexture, + SHADER_BasicFuzz, + SHADER_SmoothFuzz, + SHADER_SwirlyFuzz, + SHADER_TranslucentFuzz, + SHADER_JaggedFuzz, + SHADER_NoiseFuzz, + SHADER_SmoothNoiseFuzz, + SHADER_SoftwareFuzz, + FIRST_USER_SHADER +}; + + struct FloatRect { float left,top; @@ -64,6 +88,23 @@ struct FloatRect } }; +// Special translation values for CreateTexBuffer +enum ESpecialTranslations : int32_t +{ + STRange_Min = 0x10000000, + STRange_Desaturate = 0x10000000, + STRange_Specialcolormap = 0x20000000, + STRange_AlphaTexture = 0x30000000 +}; + +enum ECreateTexBufferFlags +{ + CTF_CheckHires = 1, // use external hires replacement if found + CTF_Expand = 2, // create buffer with a one-pixel wide border + CTF_ProcessData = 4 // run postprocessing on the generated buffer. This is only needed when using the data for a hardware texture. +}; + + class FBitmap; struct FRemapTable; @@ -75,6 +116,7 @@ class FTextureManager; class FTerrainTypeArray; class FGLTexture; class FMaterial; +extern int r_spriteadjustSW, r_spriteadjustHW; class FNullTextureID : public FTextureID { @@ -159,29 +201,22 @@ enum FTextureFormat : uint32_t TEX_Pal, TEX_Gray, TEX_RGB, // Actually ARGB - /* - TEX_DXT1, - TEX_DXT2, - TEX_DXT3, - TEX_DXT4, - TEX_DXT5, - */ + TEX_Count }; -class FNativeTexture; - - - // Base texture class class FTexture { + public: static FTexture *CreateTexture(const char *name, int lumpnum, ETextureType usetype); static FTexture *CreateTexture(int lumpnum, ETextureType usetype); virtual ~FTexture (); + void AddAutoMaterials(); + unsigned char *CreateUpsampledTextureBuffer(unsigned char *inputBuffer, const int inWidth, const int inHeight, int &outWidth, int &outHeight, bool hasAlpha); - int16_t LeftOffset, TopOffset; + //int16_t LeftOffset, TopOffset; uint8_t WidthBits, HeightBits; @@ -190,6 +225,20 @@ public: int SourceLump; FTextureID id; + // None of the following pointers are owned by this texture, they are all controlled by the texture manager. + + // Paletted variant + FTexture *PalVersion = nullptr; + // External hires texture + FTexture *HiresTexture = nullptr; + // Material layers + FTexture *Brightmap = nullptr; + FTexture *Normal = nullptr; // Normal map texture + FTexture *Specular = nullptr; // Specular light texture for the diffuse+normal+specular light model + FTexture *Metallic = nullptr; // Metalness texture for the physically based rendering (PBR) light model + FTexture *Roughness = nullptr; // Roughness texture for PBR + FTexture *AmbientOcclusion = nullptr; // Ambient occlusion texture for PBR + FString Name; ETextureType UseType; // This texture's primary purpose @@ -205,9 +254,29 @@ public: // doing it per patch. uint8_t bMultiPatch:1; // This is a multipatch texture (we really could use real type info for textures...) uint8_t bKeepAround:1; // This texture was used as part of a multi-patch texture. Do not free it. + uint8_t bFullNameTexture : 1; + uint8_t bBrightmapChecked : 1; // Set to 1 if brightmap has been checked + uint8_t bGlowing : 1; // Texture glow color + uint8_t bAutoGlowing : 1; // Glow info is determined from texture image. + uint8_t bFullbright : 1; // always draw fullbright + uint8_t bDisableFullbright : 1; // This texture will not be displayed as fullbright sprite + uint8_t bSkybox : 1; // is a cubic skybox + uint8_t bNoCompress : 1; + int8_t bTranslucent : 2; + bool bHiresHasColorKey = false; // Support for old color-keyed Doomsday textures uint16_t Rotations; int16_t SkyOffset; + FloatRect *areas = nullptr; + int areacount = 0; + int GlowHeight = 128; + PalEntry GlowColor = 0; + int HiresLump = -1; // For external hires textures. + float Glossiness = 10.f; + float SpecularLevel = 0.1f; + float shaderspeed = 1.f; + int shaderindex = 0; + struct Span @@ -217,13 +286,13 @@ public: }; // Returns a single column of the texture - virtual const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out) = 0; + virtual const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out); // Returns a single column of the texture, in BGRA8 format virtual const uint32_t *GetColumnBgra(unsigned int column, const Span **spans_out); // Returns the whole texture, stored in column-major order - virtual const uint8_t *GetPixels(FRenderStyle style) = 0; + virtual const uint8_t *GetPixels(FRenderStyle style); // Returns the whole texture, stored in column-major order, in BGRA8 format virtual const uint32_t *GetPixelsBgra(); @@ -243,12 +312,6 @@ public: // Returns the native pixel format for this image virtual FTextureFormat GetFormat(); - // Returns a native 3D representation of the texture - FNativeTexture *GetNative(FTextureFormat fmt, bool wrapping); - - // Frees the native 3D representation of the texture - void KillNative(); - // Fill the native texture buffer with pixel data for this image virtual void FillBuffer(uint8_t *buff, int pitch, int height, FTextureFormat fmt); @@ -261,10 +324,33 @@ public: double GetScaledHeightDouble () { return Height / Scale.Y; } double GetScaleY() const { return Scale.Y; } - int GetScaledLeftOffset () { int foo = int((LeftOffset * 2) / Scale.X); return (foo >> 1) + (foo & 1); } - int GetScaledTopOffset () { int foo = int((TopOffset * 2) / Scale.Y); return (foo >> 1) + (foo & 1); } - double GetScaledLeftOffsetDouble() { return LeftOffset / Scale.X; } - double GetScaledTopOffsetDouble() { return TopOffset / Scale.Y; } + // Now with improved offset adjustment. + int GetLeftOffset(int adjusted) { return _LeftOffset[adjusted]; } + int GetTopOffset(int adjusted) { return _TopOffset[adjusted]; } + int GetScaledLeftOffset (int adjusted) { int foo = int((_LeftOffset[adjusted] * 2) / Scale.X); return (foo >> 1) + (foo & 1); } + int GetScaledTopOffset (int adjusted) { int foo = int((_TopOffset[adjusted] * 2) / Scale.Y); return (foo >> 1) + (foo & 1); } + double GetScaledLeftOffsetDouble(int adjusted) { return _LeftOffset[adjusted] / Scale.X; } + double GetScaledTopOffsetDouble(int adjusted) { return _TopOffset[adjusted] / Scale.Y; } + + // Interfaces for the different renderers. Everything that needs to check renderer-dependent offsets + // should use these, so that if changes are needed, this is the only place to edit. + + // For the original software renderer + int GetLeftOffsetSW() { return _LeftOffset[r_spriteadjustSW]; } + int GetTopOffsetSW() { return _TopOffset[r_spriteadjustSW]; } + int GetScaledLeftOffsetSW() { return GetScaledLeftOffset(r_spriteadjustSW); } + int GetScaledTopOffsetSW() { return GetScaledTopOffset(r_spriteadjustSW); } + + // For the softpoly renderer, in case it wants adjustment + int GetLeftOffsetPo() { return _LeftOffset[r_spriteadjustSW]; } + int GetTopOffsetPo() { return _TopOffset[r_spriteadjustSW]; } + int GetScaledLeftOffsetPo() { return GetScaledLeftOffset(r_spriteadjustSW); } + int GetScaledTopOffsetPo() { return GetScaledTopOffset(r_spriteadjustSW); } + + // For the hardware renderer + int GetLeftOffsetHW() { return _LeftOffset[r_spriteadjustHW]; } + int GetTopOffsetHW() { return _TopOffset[r_spriteadjustHW]; } + virtual void ResolvePatches() {} virtual void SetFrontSkyLayer(); @@ -282,8 +368,10 @@ public: { Width = BaseTexture->GetWidth(); Height = BaseTexture->GetHeight(); - TopOffset = BaseTexture->TopOffset; - LeftOffset = BaseTexture->LeftOffset; + _TopOffset[0] = BaseTexture->_TopOffset[0]; + _TopOffset[1] = BaseTexture->_TopOffset[1]; + _LeftOffset[0] = BaseTexture->_LeftOffset[0]; + _LeftOffset[1] = BaseTexture->_LeftOffset[1]; WidthBits = BaseTexture->WidthBits; HeightBits = BaseTexture->HeightBits; Scale = BaseTexture->Scale; @@ -296,8 +384,8 @@ public: protected: uint16_t Width, Height, WidthMask; + int16_t _LeftOffset[2], _TopOffset[2]; static uint8_t GrayMap[256]; - FNativeTexture *Native[TEX_Count] = { nullptr }; // keep a slot for each type, because some render modes do not work with the base texture uint8_t *GetRemap(FRenderStyle style, bool srcisgrayscale = false) { if (style.Flags & STYLEF_RedIsAlpha) @@ -356,13 +444,6 @@ protected: bNoDecals = other->bNoDecals; Rotations = other->Rotations; gl_info = other->gl_info; - gl_info.Brightmap = NULL; - gl_info.Normal = NULL; - gl_info.Specular = NULL; - gl_info.Metallic = NULL; - gl_info.Roughness = NULL; - gl_info.AmbientOcclusion = NULL; - gl_info.areas = NULL; } std::vector PixelsBgra; @@ -373,7 +454,16 @@ protected: void GenerateBgraMipmapsFast(); int MipmapLevels() const; + +public: + unsigned char * CreateTexBuffer(int translation, int & w, int & h, int flags = 0); + bool GetTranslucency(); + private: + int CheckDDPK3(); + int CheckExternalFile(bool & hascolorkey); + unsigned char *LoadHiresTexture(int *width, int *height); + bool bSWSkyColorDone = false; PalEntry FloorSkyColor; PalEntry CeilingSkyColor; @@ -386,54 +476,30 @@ public: static void FlipNonSquareBlockBgra (uint32_t *blockto, const uint32_t *blockfrom, int x, int y, int srcpitch); static void FlipNonSquareBlockRemap (uint8_t *blockto, const uint8_t *blockfrom, int x, int y, int srcpitch, const uint8_t *remap); - friend class FNativeTexture; - friend class OpenGLSWFrameBuffer; - public: - struct MiscGLInfo + struct GLTexInfo { - FMaterial *Material[2]; - FGLTexture *SystemTexture[2]; - FTexture *Brightmap; - FTexture *Normal; // Normal map texture - FTexture *Specular; // Specular light texture for the diffuse+normal+specular light model - FTexture *Metallic; // Metalness texture for the physically based rendering (PBR) light model - FTexture *Roughness; // Roughness texture for PBR - FTexture *AmbientOcclusion; // Ambient occlusion texture for PBR - float Glossiness; - float SpecularLevel; - PalEntry GlowColor; - int GlowHeight; - FloatRect *areas; - int areacount; - int shaderindex; - float shaderspeed; - int mIsTransparent:2; - bool bGlowing:1; // Texture glows - bool bAutoGlowing : 1; // Glow info is determined from texture image. - bool bFullbright:1; // always draw fullbright - bool bSkybox:1; // This is a skybox - char bBrightmapChecked:1; // Set to 1 if brightmap has been checked - bool bDisableFullbright:1; // This texture will not be displayed as fullbright sprite - bool bNoFilter:1; - bool bNoCompress:1; - bool bNoExpand:1; + FMaterial *Material[2] = { nullptr, nullptr }; + FGLTexture *SystemTexture[2] = { nullptr, nullptr }; + bool bNoExpand = false; - MiscGLInfo() throw (); - ~MiscGLInfo(); + ~GLTexInfo(); }; - MiscGLInfo gl_info; + GLTexInfo gl_info; void GetGlowColor(float *data); - bool isGlowing() { return gl_info.bGlowing; } - bool isFullbright() { return gl_info.bFullbright; } + bool isGlowing() { return bGlowing; } + bool isFullbright() { return bFullbright; } void CreateDefaultBrightmap(); bool FindHoles(const unsigned char * buffer, int w, int h); static bool SmoothEdges(unsigned char * buffer,int w, int h); void CheckTrans(unsigned char * buffer, int size, int trans); bool ProcessData(unsigned char * buffer, int w, int h, bool ispatch); int CheckRealHeight(); + void SetSpriteAdjust(); + + friend class FTextureManager; }; class FxAddSub; @@ -534,6 +600,7 @@ public: void AddTexturesForWad(int wadnum); void Init(); void DeleteAll(); + void SpriteAdjustChanged(); // Replaces one texture with another. The new texture will be assigned // the same name, slot, and use type as the texture it is replacing. @@ -559,6 +626,7 @@ private: // texture counting int CountTexturesX (); int CountLumpTextures (int lumpnum); + void AdjustSpriteOffsets(); // Build tiles void AddTiles (const FString &pathprefix, const void *, int translation); @@ -584,6 +652,7 @@ private: void ParseAnimatedDoor(FScanner &sc); void InitPalettedVersions(); + void GenerateGlobalBrightmapFromColormap(); // Switches @@ -603,7 +672,6 @@ private: int HashFirst[HASH_SIZE]; FTextureID DefaultTexture; TArray FirstTextureForFile; - TMap PalettedVersions; // maps from normal -> paletted version TArray > BuildTileData; TArray mAnimations; @@ -611,6 +679,8 @@ private: TArray mAnimatedDoors; public: + bool HasGlobalBrightmap; + FRemapTable GlobalBrightmap; short sintable[2048]; // for texture warping enum { @@ -642,8 +712,6 @@ class FDummyTexture : public FTexture { public: FDummyTexture (); - const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out) override; - const uint8_t *GetPixels(FRenderStyle style) override; void SetSize (int width, int height); }; diff --git a/src/v_2ddrawer.cpp b/src/v_2ddrawer.cpp new file mode 100644 index 0000000000..e860d80342 --- /dev/null +++ b/src/v_2ddrawer.cpp @@ -0,0 +1,511 @@ +// +//--------------------------------------------------------------------------- +// +// Copyright(C) 2016-2018 Christoph Oelckers +// All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see http://www.gnu.org/licenses/ +// +//-------------------------------------------------------------------------- +// +/* +** v_2ddrawer.h +** Device independent 2D draw list +** +**/ + +#include +#include "doomtype.h" +#include "templates.h" +#include "r_utility.h" +#include "v_video.h" + +EXTERN_CVAR(Float, transsouls) + + +//========================================================================== +// +// +// +//========================================================================== + +int F2DDrawer::AddCommand(const RenderCommand *data) +{ + if (mData.Size() > 0 && data->isCompatible(mData.Last())) + { + // Merge with the last command. + mData.Last().mIndexCount += data->mIndexCount; + mData.Last().mVertCount += data->mVertCount; + return mData.Size(); + } + else + { + return mData.Push(*data); + } +} + +//========================================================================== +// +// +// +//========================================================================== + +void F2DDrawer::AddIndices(int firstvert, int count, ...) +{ + va_list ap; + va_start(ap, count); + int addr = mIndices.Reserve(count); + for (int i = 0; i < count; i++) + { + mIndices[addr + i] = firstvert + va_arg(ap, int); + } +} + +//========================================================================== +// +// SetStyle +// +// Patterned after R_SetPatchStyle. +// +//========================================================================== + +bool F2DDrawer::SetStyle(FTexture *tex, DrawParms &parms, PalEntry &vertexcolor, RenderCommand &quad) +{ + auto fmt = tex->GetFormat(); + FRenderStyle style = parms.style; + float alpha; + bool stencilling; + + if (style.Flags & STYLEF_TransSoulsAlpha) + { + alpha = transsouls; + } + else if (style.Flags & STYLEF_Alpha1) + { + alpha = 1; + } + else + { + alpha = clamp(parms.Alpha, 0.f, 1.f); + } + + style.CheckFuzz(); + if (style.BlendOp == STYLEOP_Shadow || style.BlendOp == STYLEOP_Fuzz) + { + style = LegacyRenderStyles[STYLE_TranslucentStencil]; + alpha = 0.3f; + parms.fillcolor = 0; + } + else if (style.BlendOp == STYLEOP_FuzzOrAdd) + { + style.BlendOp = STYLEOP_Add; + } + else if (style.BlendOp == STYLEOP_FuzzOrSub) + { + style.BlendOp = STYLEOP_Sub; + } + else if (style.BlendOp == STYLEOP_FuzzOrRevSub) + { + style.BlendOp = STYLEOP_RevSub; + } + + stencilling = false; + + if (style.Flags & STYLEF_InvertOverlay) + { + // Only the overlay color is inverted, not the overlay alpha. + parms.colorOverlay.r = 255 - parms.colorOverlay.r; + parms.colorOverlay.g = 255 - parms.colorOverlay.g; + parms.colorOverlay.b = 255 - parms.colorOverlay.b; + } + + SetColorOverlay(parms.colorOverlay, alpha, vertexcolor, quad.mColor1); + + if (style.Flags & STYLEF_ColorIsFixed) + { + if (style.Flags & STYLEF_InvertSource) + { // Since the source color is a constant, we can invert it now + // without spending time doing it in the shader. + parms.fillcolor.r = 255 - parms.fillcolor.r; + parms.fillcolor.g = 255 - parms.fillcolor.g; + parms.fillcolor.b = 255 - parms.fillcolor.b; + style.Flags &= ~STYLEF_InvertSource; + } + if (parms.desaturate > 0) + { + // Desaturation can also be computed here without having to do it in the shader. + auto gray = parms.fillcolor.Luminance(); + auto notgray = 255 - gray; + parms.fillcolor.r = uint8_t((parms.fillcolor.r * notgray + gray * 255) / 255); + parms.fillcolor.g = uint8_t((parms.fillcolor.g * notgray + gray * 255) / 255); + parms.fillcolor.b = uint8_t((parms.fillcolor.b * notgray + gray * 255) / 255); + parms.desaturate = 0; + } + + // Set up the color mod to replace the color from the image data. + vertexcolor.r = parms.fillcolor.r; + vertexcolor.g = parms.fillcolor.g; + vertexcolor.b = parms.fillcolor.b; + + if (style.Flags & STYLEF_RedIsAlpha) + { + quad.mDrawMode = DTM_AlphaTexture; + } + else + { + quad.mDrawMode = DTM_Stencil; + } + } + else + { + if (style.Flags & STYLEF_RedIsAlpha) + { + quad.mDrawMode = DTM_AlphaTexture; + } + else if (style.Flags & STYLEF_InvertSource) + { + quad.mDrawMode = DTM_Invert; + } + + if (parms.specialcolormap != nullptr) + { // Emulate an invulnerability or similar colormap. + quad.mSpecialColormap = parms.specialcolormap; + quad.mColor1 = 0; // this disables the color overlay. + } + quad.mDesaturate = parms.desaturate; + } + // apply the element's own color. This is being blended with anything that came before. + vertexcolor = PalEntry((vertexcolor.a * parms.color.a) / 255, (vertexcolor.r * parms.color.r) / 255, (vertexcolor.g * parms.color.g) / 255, (vertexcolor.b * parms.color.b) / 255); + + if (!parms.masked) + { + // For DTM_AlphaTexture and DTM_Stencil the mask cannot be turned off because it would not yield a usable result. + if (quad.mDrawMode == DTM_Normal) quad.mDrawMode = DTM_Opaque; + else if (quad.mDrawMode == DTM_Invert) quad.mDrawMode = DTM_InvertOpaque; + } + quad.mRenderStyle = parms.style; // this contains the blend mode and blend equation settings. + return true; +} + +//========================================================================== +// +// Draws a texture +// +//========================================================================== + +void F2DDrawer::SetColorOverlay(PalEntry color, float alpha, PalEntry &vertexcolor, PalEntry &overlaycolor) +{ + if (color.a != 0 && (color & 0xffffff) != 0) + { + // overlay color uses premultiplied alpha. + int a = color.a * 256 / 255; + overlaycolor.r = (color.r * a) >> 8; + overlaycolor.g = (color.g * a) >> 8; + overlaycolor.b = (color.b * a) >> 8; + overlaycolor.a = 0; // The overlay gets added on top of the texture data so to preserve the pixel's alpha this must be 0. + } + else + { + overlaycolor = 0; + } + // Vertex intensity is the inverse of the overlay so that the shader can do a simple addition to combine them. + uint8_t light = 255 - color.a; + vertexcolor = PalEntry(int(alpha * 255), light, light, light); + + // The real color gets multiplied into vertexcolor later. +} + +//========================================================================== +// +// Draws a texture +// +//========================================================================== + +void F2DDrawer::AddTexture(FTexture *img, DrawParms &parms) +{ + if (parms.style.BlendOp == STYLEOP_None) return; // not supposed to be drawn. + + double xscale = parms.destwidth / parms.texwidth; + double yscale = parms.destheight / parms.texheight; + double x = parms.x - parms.left * xscale; + double y = parms.y - parms.top * yscale; + double w = parms.destwidth; + double h = parms.destheight; + double u1, v1, u2, v2; + PalEntry vertexcolor; + + RenderCommand dg; + + dg.mType = DrawTypeTriangles; + dg.mVertCount = 4; + dg.mTexture = img; + + dg.mTranslation = 0; + SetStyle(img, parms, vertexcolor, dg); + + if (!img->bHasCanvas && parms.remap != nullptr && !parms.remap->Inactive) + { + dg.mTranslation = parms.remap; + } + u1 = parms.srcx; + v1 = parms.srcy; + u2 = parms.srcx + parms.srcwidth; + v2 = parms.srcy + parms.srcheight; + + if (parms.flipX) + std::swap(u1, u2); + + if (parms.flipY) + std::swap(v1, v2); + + // This is crap. Only kept for backwards compatibility with scripts that may have used it. + // Note that this only works for unflipped full textures. + if (parms.windowleft > 0 || parms.windowright < parms.texwidth) + { + double wi = MIN(parms.windowright, parms.texwidth); + x += parms.windowleft * xscale; + w -= (parms.texwidth - wi + parms.windowleft) * xscale; + + u1 = float(u1 + parms.windowleft / parms.texwidth); + u2 = float(u2 - (parms.texwidth - wi) / parms.texwidth); + } + + if (x < (double)parms.lclip || y < (double)parms.uclip || x + w >(double)parms.rclip || y + h >(double)parms.dclip) + { + dg.mScissor[0] = parms.lclip; + dg.mScissor[1] = parms.uclip; + dg.mScissor[2] = parms.rclip; + dg.mScissor[3] = parms.dclip; + dg.mFlags |= DTF_Scissor; + } + else + { + memset(dg.mScissor, 0, sizeof(dg.mScissor)); + } + + dg.mVertCount = 4; + dg.mVertIndex = (int)mVertices.Reserve(4); + TwoDVertex *ptr = &mVertices[dg.mVertIndex]; + ptr->Set(x, y, 0, u1, v1, vertexcolor); ptr++; + ptr->Set(x, y + h, 0, u1, v2, vertexcolor); ptr++; + ptr->Set(x + w, y, 0, u2, v1, vertexcolor); ptr++; + ptr->Set(x + w, y + h, 0, u2, v2, vertexcolor); ptr++; + dg.mIndexIndex = mIndices.Size(); + dg.mIndexCount += 6; + AddIndices(dg.mVertIndex, 6, 0, 1, 2, 1, 3, 2); + AddCommand(&dg); +} + +//========================================================================== +// +// +// +//========================================================================== + +void F2DDrawer::AddPoly(FTexture *texture, FVector2 *points, int npoints, + double originx, double originy, double scalex, double scaley, + DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel) +{ + // Use an equation similar to player sprites to determine shade + + // Convert a light level into an unbounded colormap index (shade). + // Why the +12? I wish I knew, but experimentation indicates it + // is necessary in order to best reproduce Doom's original lighting. + double map = (NUMCOLORMAPS * 2.) - ((lightlevel + 12) * (NUMCOLORMAPS / 128.)); + double fadelevel = clamp((map - 12) / NUMCOLORMAPS, 0.0, 1.0); + + RenderCommand poly; + + poly.mType = DrawTypeTriangles; + poly.mTexture = texture; + poly.mRenderStyle = DefaultRenderStyle(); + poly.mFlags |= DTF_Wrap; + poly.mDesaturate = colormap.Desaturation; + + PalEntry color0; + double invfade = 1. - fadelevel; + + color0.r = uint8_t(colormap.LightColor.r * invfade); + color0.g = uint8_t(colormap.LightColor.g * invfade); + color0.b = uint8_t(colormap.LightColor.b * invfade); + color0.a = 255; + + poly.mColor1.a = 0; + poly.mColor1.r = uint8_t(colormap.FadeColor.r * fadelevel); + poly.mColor1.g = uint8_t(colormap.FadeColor.g * fadelevel); + poly.mColor1.b = uint8_t(colormap.FadeColor.b * fadelevel); + + bool dorotate = rotation != 0; + + float cosrot = (float)cos(rotation.Radians()); + float sinrot = (float)sin(rotation.Radians()); + + float uscale = float(1.f / (texture->GetScaledWidth() * scalex)); + float vscale = float(1.f / (texture->GetScaledHeight() * scaley)); + float ox = float(originx); + float oy = float(originy); + + poly.mVertCount = npoints; + poly.mVertIndex = (int)mVertices.Reserve(npoints); + for (int i = 0; i < npoints; ++i) + { + float u = points[i].X - 0.5f - ox; + float v = points[i].Y - 0.5f - oy; + if (dorotate) + { + float t = u; + u = t * cosrot - v * sinrot; + v = v * cosrot + t * sinrot; + } + mVertices[poly.mVertIndex+i].Set(points[i].X, points[i].Y, 0, u*uscale, v*vscale, color0); + } + poly.mIndexIndex = mIndices.Size(); + poly.mIndexCount += (npoints - 2) * 3; + + for (int i = 2; i < npoints; ++i) + { + AddIndices(poly.mVertIndex, 3, 0, i - 1, i); + } + + AddCommand(&poly); +} + +//========================================================================== +// +// +// +//========================================================================== + +void F2DDrawer::AddFlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin) +{ + float fU1, fU2, fV1, fV2; + + RenderCommand dg; + + dg.mType = DrawTypeTriangles; + dg.mRenderStyle = DefaultRenderStyle(); + dg.mTexture = src; + dg.mVertCount = 4; + dg.mTexture = src; + dg.mFlags = DTF_Wrap; + + // scaling is not used here. + if (!local_origin) + { + fU1 = float(left) / src->GetWidth(); + fV1 = float(top) / src->GetHeight(); + fU2 = float(right) / src->GetWidth(); + fV2 = float(bottom) / src->GetHeight(); + } + else + { + fU1 = 0; + fV1 = 0; + fU2 = float(right - left) / src->GetWidth(); + fV2 = float(bottom - top) / src->GetHeight(); + } + dg.mVertIndex = (int)mVertices.Reserve(4); + auto ptr = &mVertices[dg.mVertIndex]; + + ptr->Set(left, top, 0, fU1, fV1, 0xffffffff); ptr++; + ptr->Set(left, bottom, 0, fU1, fV2, 0xffffffff); ptr++; + ptr->Set(right, top, 0, fU2, fV1, 0xffffffff); ptr++; + ptr->Set(right, bottom, 0, fU2, fV2, 0xffffffff); ptr++; + dg.mIndexIndex = mIndices.Size(); + dg.mIndexCount += 6; + AddIndices(dg.mVertIndex, 6, 0, 1, 2, 1, 3, 2); + AddCommand(&dg); +} + + +//=========================================================================== +// +// +// +//=========================================================================== + +void F2DDrawer::AddColorOnlyQuad(int x1, int y1, int w, int h, PalEntry color, FRenderStyle *style) +{ + RenderCommand dg; + + dg.mType = DrawTypeTriangles; + dg.mVertCount = 4; + dg.mVertIndex = (int)mVertices.Reserve(4); + dg.mRenderStyle = style? *style : LegacyRenderStyles[STYLE_Translucent]; + auto ptr = &mVertices[dg.mVertIndex]; + ptr->Set(x1, y1, 0, 0, 0, color); ptr++; + ptr->Set(x1, y1 + h, 0, 0, 0, color); ptr++; + ptr->Set(x1 + w, y1, 0, 0, 0, color); ptr++; + ptr->Set(x1 + w, y1 + h, 0, 0, 0, color); ptr++; + dg.mIndexIndex = mIndices.Size(); + dg.mIndexCount += 6; + AddIndices(dg.mVertIndex, 6, 0, 1, 2, 1, 3, 2); + AddCommand(&dg); +} + +//========================================================================== +// +// +// +//========================================================================== + +void F2DDrawer::AddLine(int x1, int y1, int x2, int y2, int palcolor, uint32_t color) +{ + PalEntry p = color ? (PalEntry)color : GPalette.BaseColors[palcolor]; + p.a = 255; + + RenderCommand dg; + + dg.mType = DrawTypeLines; + dg.mRenderStyle = LegacyRenderStyles[STYLE_Translucent]; + dg.mVertCount = 2; + dg.mVertIndex = (int)mVertices.Reserve(2); + mVertices[dg.mVertIndex].Set(x1, y1, 0, 0, 0, p); + mVertices[dg.mVertIndex+1].Set(x2, y2, 0, 0, 0, p); + AddCommand(&dg); +} + +//========================================================================== +// +// +// +//========================================================================== + +void F2DDrawer::AddPixel(int x1, int y1, int palcolor, uint32_t color) +{ + PalEntry p = color ? (PalEntry)color : GPalette.BaseColors[palcolor]; + p.a = 255; + + RenderCommand dg; + + dg.mType = DrawTypePoints; + dg.mRenderStyle = LegacyRenderStyles[STYLE_Translucent]; + dg.mVertCount = 1; + dg.mVertIndex = (int)mVertices.Reserve(1); + mVertices[dg.mVertIndex].Set(x1, y1, 0, 0, 0, p); + AddCommand(&dg); +} + +//========================================================================== +// +// +// +//========================================================================== + +void F2DDrawer::Clear() +{ + mVertices.Clear(); + mIndices.Clear(); + mData.Clear(); +} diff --git a/src/v_2ddrawer.h b/src/v_2ddrawer.h new file mode 100644 index 0000000000..96fb51782a --- /dev/null +++ b/src/v_2ddrawer.h @@ -0,0 +1,138 @@ +#ifndef __2DDRAWER_H +#define __2DDRAWER_H + +#include "tarray.h" +#include "textures.h" +#include "v_palette.h" +#include "r_data/renderstyle.h" +#include "r_data/colormaps.h" + +struct DrawParms; + +class F2DDrawer +{ +public: + + enum EDrawType : uint8_t + { + DrawTypeTriangles, + DrawTypeLines, + DrawTypePoints, + }; + + enum ETextureDrawMode : uint8_t + { + DTM_Normal = 0, + DTM_Stencil = 1, + DTM_Opaque = 2, + DTM_Invert = 3, + DTM_AlphaTexture = 4, + DTM_InvertOpaque = 6, + }; + + enum ETextureFlags : uint8_t + { + DTF_Wrap = 1, + DTF_Scissor = 2, + }; + + + // This vertex type is hardware independent and needs conversion when put into a buffer. + struct TwoDVertex + { + float x, y, z; + float u, v; + PalEntry color0; + + void Set(float xx, float yy, float zz) + { + x = xx; + z = zz; + y = yy; + u = 0; + v = 0; + color0 = 0; + } + + void Set(double xx, double yy, double zz, double uu, double vv, PalEntry col) + { + x = (float)xx; + z = (float)zz; + y = (float)yy; + u = (float)uu; + v = (float)vv; + color0 = col; + } + + }; + + struct RenderCommand + { + EDrawType mType; + int mVertIndex; + int mVertCount; + int mIndexIndex; + int mIndexCount; + + FTexture *mTexture; + FRemapTable *mTranslation; + FSpecialColormap *mSpecialColormap; + int mScissor[4]; + int mDesaturate; + FRenderStyle mRenderStyle; + PalEntry mColor1; // Overlay color + ETextureDrawMode mDrawMode; + uint8_t mFlags; + + RenderCommand() + { + memset(this, 0, sizeof(*this)); + } + + // If these fields match, two draw commands can be batched. + bool isCompatible(const RenderCommand &other) const + { + return mTexture == other.mTexture && + mType == other.mType && + mTranslation == other.mTranslation && + mSpecialColormap == other.mSpecialColormap && + !memcmp(mScissor, other.mScissor, sizeof(mScissor)) && + mDesaturate == other.mDesaturate && + mRenderStyle == other.mRenderStyle && + mDrawMode == other.mDrawMode && + mFlags == other.mFlags && + mColor1 == other.mColor1; + + } + }; + + TArray mIndices; + TArray mVertices; + TArray mData; + + int AddCommand(const RenderCommand *data); + void AddIndices(int firstvert, int count, ...); + bool SetStyle(FTexture *tex, DrawParms &parms, PalEntry &color0, RenderCommand &quad); + void SetColorOverlay(PalEntry color, float alpha, PalEntry &vertexcolor, PalEntry &overlaycolor); + +public: + void AddTexture(FTexture *img, DrawParms &parms); + void AddPoly(FTexture *texture, FVector2 *points, int npoints, + double originx, double originy, double scalex, double scaley, + DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel); + void AddFlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin); + + void AddColorOnlyQuad(int left, int top, int width, int height, PalEntry color, FRenderStyle *style); + + void AddDim(PalEntry color, float damount, int x1, int y1, int w, int h); + void AddClear(int left, int top, int right, int bottom, int palcolor, uint32_t color); + + + void AddLine(int x1, int y1, int x2, int y2, int palcolor, uint32_t color); + void AddPixel(int x1, int y1, int palcolor, uint32_t color); + + void Clear(); +}; + + +#endif diff --git a/src/v_colortables.h b/src/v_colortables.h new file mode 100644 index 0000000000..42135229b9 --- /dev/null +++ b/src/v_colortables.h @@ -0,0 +1,52 @@ +#pragma once + +// extracted from v_video.h because this caused circular dependencies between v_video.h and textures.h + +// Translucency tables + +// RGB32k is a normal R5G5B5 -> palette lookup table. + +// Use a union so we can "overflow" without warnings. +// Otherwise, we get stuff like this from Clang (when compiled +// with -fsanitize=bounds) while running: +// src/v_video.cpp:390:12: runtime error: index 1068 out of bounds for type 'uint8_t [32]' +// src/r_draw.cpp:273:11: runtime error: index 1057 out of bounds for type 'uint8_t [32]' +union ColorTable32k +{ + uint8_t RGB[32][32][32]; + uint8_t All[32 *32 *32]; +}; +extern ColorTable32k RGB32k; + +// [SP] RGB666 support +union ColorTable256k +{ + uint8_t RGB[64][64][64]; + uint8_t All[64 *64 *64]; +}; +extern ColorTable256k RGB256k; + +// Col2RGB8 is a pre-multiplied palette for color lookup. It is stored in a +// special R10B10G10 format for efficient blending computation. +// --RRRRRrrr--BBBBBbbb--GGGGGggg-- at level 64 +// --------rrrr------bbbb------gggg at level 1 +extern uint32_t Col2RGB8[65][256]; + +// Col2RGB8_LessPrecision is the same as Col2RGB8, but the LSB for red +// and blue are forced to zero, so if the blend overflows, it won't spill +// over into the next component's value. +// --RRRRRrrr-#BBBBBbbb-#GGGGGggg-- at level 64 +// --------rrr#------bbb#------gggg at level 1 +extern uint32_t *Col2RGB8_LessPrecision[65]; + +// Col2RGB8_Inverse is the same as Col2RGB8_LessPrecision, except the source +// palette has been inverted. +extern uint32_t Col2RGB8_Inverse[65][256]; + +// "Magic" numbers used during the blending: +// --000001111100000111110000011111 = 0x01f07c1f +// -0111111111011111111101111111111 = 0x3FEFFBFF +// -1000000000100000000010000000000 = 0x40100400 +// ------10000000001000000000100000 = 0x40100400 >> 5 +// --11111-----11111-----11111----- = 0x40100400 - (0x40100400 >> 5) aka "white" +// --111111111111111111111111111111 = 0x3FFFFFFF diff --git a/src/v_draw.cpp b/src/v_draw.cpp index 35670abf93..f16f09d0db 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -32,8 +32,6 @@ ** */ -// #define NO_SWRENDER // set this if you want to exclude the software renderer. Without the software renderer software canvas drawing does nothing. - #include #include @@ -43,9 +41,6 @@ #include "r_defs.h" #include "r_utility.h" #include "r_renderer.h" -#ifndef NO_SWRENDER -#include "swrenderer/r_swcanvas.h" -#endif #include "r_data/r_translate.h" #include "doomstat.h" #include "v_palette.h" @@ -109,6 +104,12 @@ int CleanWidth, CleanHeight; int CleanXfac_1, CleanYfac_1, CleanWidth_1, CleanHeight_1; +//========================================================================== +// +// ZScript wrappers for inlines +// +//========================================================================== + DEFINE_ACTION_FUNCTION(_Screen, GetWidth) { PARAM_PROLOGUE; @@ -130,7 +131,13 @@ DEFINE_ACTION_FUNCTION(_Screen, PaletteColor) ACTION_RETURN_INT(index); } -void DCanvas::DrawTexture (FTexture *img, double x, double y, int tags_first, ...) +//========================================================================== +// +// Internal texture drawing function +// +//========================================================================== + +void DFrameBuffer::DrawTexture (FTexture *img, double x, double y, int tags_first, ...) { Va_List tags; va_start(tags.list, tags_first); @@ -145,9 +152,15 @@ void DCanvas::DrawTexture (FTexture *img, double x, double y, int tags_first, .. DrawTextureParms(img, parms); } +//========================================================================== +// +// ZScript texture drawing function +// +//========================================================================== + int ListGetInt(VMVa_List &tags); -void DCanvas::DrawTexture(FTexture *img, double x, double y, VMVa_List &args) +void DFrameBuffer::DrawTexture(FTexture *img, double x, double y, VMVa_List &args) { DrawParms parms; uint32_t tag = ListGetInt(args); @@ -172,19 +185,24 @@ DEFINE_ACTION_FUNCTION(_Screen, DrawTexture) return 0; } -void DCanvas::DrawTextureParms(FTexture *img, DrawParms &parms) -{ -#ifndef NO_SWRENDER - SWCanvas::DrawTexture(this, img, parms); -#endif +//========================================================================== +// +// common drawing function +// +//========================================================================== - if (ticdup != 0 && menuactive == MENU_Off) - { - NetUpdate(); - } +void DFrameBuffer::DrawTextureParms(FTexture *img, DrawParms &parms) +{ + m2DDrawer.AddTexture(img, parms); } -void DCanvas::SetClipRect(int x, int y, int w, int h) +//========================================================================== +// +// Clipping rect +// +//========================================================================== + +void DFrameBuffer::SetClipRect(int x, int y, int w, int h) { clipleft = clamp(x, 0, GetWidth()); clipwidth = clamp(w, -1, GetWidth() - x); @@ -210,7 +228,7 @@ DEFINE_ACTION_FUNCTION(_Screen, ClearClipRect) return 0; } -void DCanvas::GetClipRect(int *x, int *y, int *w, int *h) +void DFrameBuffer::GetClipRect(int *x, int *y, int *w, int *h) { if (x) *x = clipleft; if (y) *y = cliptop; @@ -240,7 +258,13 @@ DEFINE_ACTION_FUNCTION(_Screen, GetViewWindow) return MIN(numret, 4); } -bool DCanvas::SetTextureParms(DrawParms *parms, FTexture *img, double xx, double yy) const +//========================================================================== +// +// Draw parameter parsing +// +//========================================================================== + +bool DFrameBuffer::SetTextureParms(DrawParms *parms, FTexture *img, double xx, double yy) const { if (img != NULL) { @@ -250,11 +274,11 @@ bool DCanvas::SetTextureParms(DrawParms *parms, FTexture *img, double xx, double parms->texheight = img->GetScaledHeightDouble(); if (parms->top == INT_MAX || parms->fortext) { - parms->top = img->GetScaledTopOffset(); + parms->top = img->GetScaledTopOffset(0); } if (parms->left == INT_MAX || parms->fortext) { - parms->left = img->GetScaledLeftOffset(); + parms->left = img->GetScaledLeftOffset(0); } if (parms->destwidth == INT_MAX || parms->fortext) { @@ -322,6 +346,12 @@ bool DCanvas::SetTextureParms(DrawParms *parms, FTexture *img, double xx, double return false; } +//========================================================================== +// +// template helpers +// +//========================================================================== + static void ListEnd(Va_List &tags) { va_end(tags.list); @@ -387,8 +417,14 @@ static inline FColormapStyle * ListGetColormapStyle(VMVa_List &tags) return nullptr; } +//========================================================================== +// +// Main taglist parsing +// +//========================================================================== + template -bool DCanvas::ParseDrawTextureTags(FTexture *img, double x, double y, uint32_t tag, T& tags, DrawParms *parms, bool fortext) const +bool DFrameBuffer::ParseDrawTextureTags(FTexture *img, double x, double y, uint32_t tag, T& tags, DrawParms *parms, bool fortext) const { INTBOOL boolval; int intval; @@ -428,6 +464,7 @@ bool DCanvas::ParseDrawTextureTags(FTexture *img, double x, double y, uint32_t t parms->colorOverlay = 0; parms->alphaChannel = false; parms->flipX = false; + parms->flipY = false; parms->color = 0xffffffff; //parms->shadowAlpha = 0; parms->shadowColor = 0; @@ -438,12 +475,16 @@ bool DCanvas::ParseDrawTextureTags(FTexture *img, double x, double y, uint32_t t parms->masked = true; parms->bilinear = false; parms->specialcolormap = NULL; - parms->colormapstyle = NULL; + parms->desaturate = 0; parms->cleanmode = DTA_Base; parms->scalex = parms->scaley = 1; parms->cellx = parms->celly = 0; parms->maxstrlen = INT_MAX; parms->virtBottom = false; + parms->srcx = 0.; + parms->srcy = 0.; + parms->srcwidth = 1.; + parms->srcheight = 1.; // Parse the tag list for attributes. (For floating point attributes, // consider that the C ABI dictates that all floats be promoted to @@ -613,6 +654,26 @@ bool DCanvas::ParseDrawTextureTags(FTexture *img, double x, double y, uint32_t t parms->flipX = ListGetInt(tags); break; + case DTA_FlipY: + parms->flipY = ListGetInt(tags); + break; + + case DTA_SrcX: + parms->srcx = ListGetDouble(tags) / img->GetScaledWidthDouble(); + break; + + case DTA_SrcY: + parms->srcy = ListGetDouble(tags) / img->GetScaledHeightDouble(); + break; + + case DTA_SrcWidth: + parms->srcwidth = ListGetDouble(tags) / img->GetScaledWidthDouble(); + break; + + case DTA_SrcHeight: + parms->srcheight = ListGetDouble(tags) / img->GetScaledHeightDouble(); + break; + case DTA_TopOffset: assert(fortext == false); if (fortext) return false; @@ -756,8 +817,8 @@ bool DCanvas::ParseDrawTextureTags(FTexture *img, double x, double y, uint32_t t parms->specialcolormap = ListGetSpecialColormap(tags); break; - case DTA_ColormapStyle: - parms->colormapstyle = ListGetColormapStyle(tags); + case DTA_Desaturate: + parms->desaturate = ListGetInt(tags); break; case DTA_TextLen: @@ -836,10 +897,16 @@ bool DCanvas::ParseDrawTextureTags(FTexture *img, double x, double y, uint32_t t } // explicitly instantiate both versions for v_text.cpp. -template bool DCanvas::ParseDrawTextureTags(FTexture *img, double x, double y, uint32_t tag, Va_List& tags, DrawParms *parms, bool fortext) const; -template bool DCanvas::ParseDrawTextureTags(FTexture *img, double x, double y, uint32_t tag, VMVa_List& tags, DrawParms *parms, bool fortext) const; +template bool DFrameBuffer::ParseDrawTextureTags(FTexture *img, double x, double y, uint32_t tag, Va_List& tags, DrawParms *parms, bool fortext) const; +template bool DFrameBuffer::ParseDrawTextureTags(FTexture *img, double x, double y, uint32_t tag, VMVa_List& tags, DrawParms *parms, bool fortext) const; -void DCanvas::VirtualToRealCoords(double &x, double &y, double &w, double &h, +//========================================================================== +// +// Coordinate conversion +// +//========================================================================== + +void DFrameBuffer::VirtualToRealCoords(double &x, double &y, double &w, double &h, double vwidth, double vheight, bool vbottom, bool handleaspect) const { float myratio = handleaspect ? ActiveRatio (Width, Height) : (4.0f / 3.0f); @@ -899,7 +966,7 @@ DEFINE_ACTION_FUNCTION(_Screen, VirtualToRealCoords) return MIN(numret, 2); } -void DCanvas::VirtualToRealCoordsInt(int &x, int &y, int &w, int &h, +void DFrameBuffer::VirtualToRealCoordsInt(int &x, int &y, int &w, int &h, int vwidth, int vheight, bool vbottom, bool handleaspect) const { double dx, dy, dw, dh; @@ -915,7 +982,13 @@ void DCanvas::VirtualToRealCoordsInt(int &x, int &y, int &w, int &h, h = int(dy + dh + 0.5) - y; } -void DCanvas::FillBorder (FTexture *img) +//========================================================================== +// +// +// +//========================================================================== + +void DFrameBuffer::FillBorder (FTexture *img) { float myratio = ActiveRatio (Width, Height); @@ -961,11 +1034,15 @@ void DCanvas::FillBorder (FTexture *img) } } -void DCanvas::DrawLine(int x0, int y0, int x1, int y1, int palColor, uint32_t realcolor) +//========================================================================== +// +// Draw a line +// +//========================================================================== + +void DFrameBuffer::DrawLine(int x0, int y0, int x1, int y1, int palColor, uint32_t realcolor) { -#ifndef NO_SWRENDER - SWCanvas::DrawLine(this, x0, y0, x1, y1, palColor, realcolor); -#endif + m2DDrawer.AddLine(x0, y0, x1, y1, palColor, realcolor); } DEFINE_ACTION_FUNCTION(_Screen, DrawLine) @@ -981,11 +1058,15 @@ DEFINE_ACTION_FUNCTION(_Screen, DrawLine) return 0; } -void DCanvas::DrawPixel(int x, int y, int palColor, uint32_t realcolor) +//========================================================================== +// +// Draw a single pixel +// +//========================================================================== + +void DFrameBuffer::DrawPixel(int x, int y, int palColor, uint32_t realcolor) { -#ifndef NO_SWRENDER - SWCanvas::DrawPixel(this, x, y, palColor, realcolor); -#endif + m2DDrawer.AddPixel(x, y, palColor, realcolor); } //========================================================================== @@ -996,21 +1077,7 @@ void DCanvas::DrawPixel(int x, int y, int palColor, uint32_t realcolor) // //========================================================================== -void DCanvas::DoClear (int left, int top, int right, int bottom, int palcolor, uint32_t color) -{ -#ifndef NO_SWRENDER - if (palcolor < 0 && APART(color) != 255) - { - Dim(color, APART(color) / 255.f, left, top, right - left, bottom - top); - } - else - { - SWCanvas::Clear(this, left, top, right, bottom, palcolor, color); - } -#endif -} - -void DCanvas::Clear(int left, int top, int right, int bottom, int palcolor, uint32_t color) +void DFrameBuffer::Clear(int left, int top, int right, int bottom, int palcolor, uint32_t color) { if (clipwidth >= 0 && clipheight >= 0) { @@ -1034,7 +1101,12 @@ void DCanvas::Clear(int left, int top, int right, int bottom, int palcolor, uint right = left + w; bottom = top + h; } - DoClear(left, top, right, bottom, palcolor, color); + + if (palcolor >= 0 && color == 0) + { + color = GPalette.BaseColors[palcolor] | 0xff000000; + } + m2DDrawer.AddColorOnlyQuad(left, top, right - left, bottom - top, color | 0xFF000000, nullptr); } DEFINE_ACTION_FUNCTION(_Screen, Clear) @@ -1059,14 +1131,20 @@ DEFINE_ACTION_FUNCTION(_Screen, Clear) // //========================================================================== -void DCanvas::DoDim(PalEntry color, float damount, int x1, int y1, int w, int h) +void DFrameBuffer::DoDim(PalEntry color, float amount, int x1, int y1, int w, int h, FRenderStyle *style) { -#ifndef NO_SWRENDER - SWCanvas::Dim(this, color, damount, x1, y1, w, h); -#endif + if (amount <= 0) + { + return; + } + if (amount > 1) + { + amount = 1; + } + m2DDrawer.AddColorOnlyQuad(x1, y1, w, h, (color.d & 0xffffff) | (int(amount * 255) << 24), style); } -void DCanvas::Dim(PalEntry color, float damount, int x1, int y1, int w, int h) +void DFrameBuffer::Dim(PalEntry color, float damount, int x1, int y1, int w, int h, FRenderStyle *style) { if (clipwidth >= 0 && clipheight >= 0) { @@ -1086,7 +1164,7 @@ void DCanvas::Dim(PalEntry color, float damount, int x1, int y1, int w, int h) if (h > clipheight) h = clipheight; if (h <= 0) return; } - DoDim(color, damount, x1, y1, w, h); + DoDim(color, damount, x1, y1, w, h, style); } DEFINE_ACTION_FUNCTION(_Screen, Dim) @@ -1118,128 +1196,25 @@ DEFINE_ACTION_FUNCTION(_Screen, Dim) // //========================================================================== -void DCanvas::FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, +void DFrameBuffer::FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, double originx, double originy, double scalex, double scaley, DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel, int bottomclip) { -#ifndef NO_SWRENDER - SWCanvas::FillSimplePoly(this, tex, points, npoints, originx, originy, scalex, scaley, rotation, colormap, flatcolor, lightlevel, bottomclip); -#endif -} - - -/********************************/ -/* */ -/* Other miscellaneous routines */ -/* */ -/********************************/ - - -// -// V_DrawBlock -// Draw a linear block of pixels into the view buffer. -// -void DCanvas::DrawBlock (int x, int y, int _width, int _height, const uint8_t *src) const -{ - if (IsBgra()) - return; - - int srcpitch = _width; - int destpitch; - uint8_t *dest; - - if (ClipBox (x, y, _width, _height, src, srcpitch)) - { - return; // Nothing to draw - } - - destpitch = Pitch; - dest = Buffer + y*Pitch + x; - - do - { - memcpy (dest, src, _width); - src += srcpitch; - dest += destpitch; - } while (--_height); -} - -// -// V_GetBlock -// Gets a linear block of pixels from the view buffer. -// -void DCanvas::GetBlock (int x, int y, int _width, int _height, uint8_t *dest) const -{ - if (IsBgra()) - return; - - const uint8_t *src; - -#ifdef RANGECHECK - if (x<0 - ||x+_width > Width - || y<0 - || y+_height>Height) - { - I_Error ("Bad V_GetBlock"); - } -#endif - - src = Buffer + y*Pitch + x; - - while (_height--) - { - memcpy (dest, src, _width); - src += Pitch; - dest += _width; - } -} - -// Returns true if the box was completely clipped. False otherwise. -bool DCanvas::ClipBox (int &x, int &y, int &w, int &h, const uint8_t *&src, const int srcpitch) const -{ - if (x >= Width || y >= Height || x+w <= 0 || y+h <= 0) - { // Completely clipped off screen - return true; - } - if (x < 0) // clip left edge - { - src -= x; - w += x; - x = 0; - } - if (x+w > Width) // clip right edge - { - w = Width - x; - } - if (y < 0) // clip top edge - { - src -= y*srcpitch; - h += y; - y = 0; - } - if (y+h > Height) // clip bottom edge - { - h = Height - y; - } - return false; + m2DDrawer.AddPoly(tex, points, npoints, originx, originy, scalex, scaley, rotation, colormap, flatcolor, lightlevel); } //========================================================================== // -// V_SetBorderNeedRefresh +// DCanvas :: FlatFill // -// Flag the border as in need of updating. (Probably because something that -// was on top of it has changed. +// Fill an area with a texture. If local_origin is false, then the origin +// used for the wrapping is (0,0). Otherwise, (left,right) is used. // //========================================================================== -void V_SetBorderNeedRefresh() +void DFrameBuffer::FlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin) { - if (screen != NULL) - { - BorderNeedRefresh = screen->GetPageCount(); - } + m2DDrawer.AddFlatFill(left, top, right, bottom, src, local_origin); } //========================================================================== @@ -1251,7 +1226,7 @@ void V_SetBorderNeedRefresh() // //========================================================================== -void V_DrawFrame (int left, int top, int width, int height) +void DFrameBuffer::DrawFrame (int left, int top, int width, int height) { FTexture *p; const gameborder_t *border = &gameinfo.Border; @@ -1264,21 +1239,21 @@ void V_DrawFrame (int left, int top, int width, int height) // Draw top and bottom sides. p = TexMan[border->t]; - screen->FlatFill(left, top - p->GetHeight(), right, top, p, true); + FlatFill(left, top - p->GetHeight(), right, top, p, true); p = TexMan[border->b]; - screen->FlatFill(left, bottom, right, bottom + p->GetHeight(), p, true); + FlatFill(left, bottom, right, bottom + p->GetHeight(), p, true); // Draw left and right sides. p = TexMan[border->l]; - screen->FlatFill(left - p->GetWidth(), top, left, bottom, p, true); + FlatFill(left - p->GetWidth(), top, left, bottom, p, true); p = TexMan[border->r]; - screen->FlatFill(right, top, right + p->GetWidth(), bottom, p, true); + FlatFill(right, top, right + p->GetWidth(), bottom, p, true); // Draw beveled corners. - screen->DrawTexture (TexMan[border->tl], left-offset, top-offset, TAG_DONE); - screen->DrawTexture (TexMan[border->tr], left+width, top-offset, TAG_DONE); - screen->DrawTexture (TexMan[border->bl], left-offset, top+height, TAG_DONE); - screen->DrawTexture (TexMan[border->br], left+width, top+height, TAG_DONE); + DrawTexture (TexMan[border->tl], left-offset, top-offset, TAG_DONE); + DrawTexture (TexMan[border->tr], left+width, top-offset, TAG_DONE); + DrawTexture (TexMan[border->bl], left-offset, top+height, TAG_DONE); + DrawTexture (TexMan[border->br], left+width, top+height, TAG_DONE); } DEFINE_ACTION_FUNCTION(_Screen, DrawFrame) @@ -1288,17 +1263,17 @@ DEFINE_ACTION_FUNCTION(_Screen, DrawFrame) PARAM_INT(y); PARAM_INT(w); PARAM_INT(h); - V_DrawFrame(x, y, w, h); + screen->DrawFrame(x, y, w, h); return 0; } //========================================================================== // -// V_DrawBorder +// screen->DrawBorder // //========================================================================== -void V_DrawBorder (int x1, int y1, int x2, int y2) +void DFrameBuffer::DrawBorder (int x1, int y1, int x2, int y2) { FTextureID picnum; @@ -1313,11 +1288,11 @@ void V_DrawBorder (int x1, int y1, int x2, int y2) if (picnum.isValid()) { - screen->FlatFill (x1, y1, x2, y2, TexMan(picnum)); + FlatFill (x1, y1, x2, y2, TexMan(picnum)); } else { - screen->Clear (x1, y1, x2, y2, 0, 0); + Clear (x1, y1, x2, y2, 0, 0); } } @@ -1329,68 +1304,19 @@ void V_DrawBorder (int x1, int y1, int x2, int y2) // //========================================================================== -int BorderNeedRefresh; - - -static void V_DrawViewBorder (void) +void DFrameBuffer::DrawViewBorder (void) { - if (viewwidth == SCREENWIDTH) + if (viewwidth == Width) { return; } - V_DrawBorder (0, 0, SCREENWIDTH, viewwindowy); - V_DrawBorder (0, viewwindowy, viewwindowx, viewheight + viewwindowy); - V_DrawBorder (viewwindowx + viewwidth, viewwindowy, SCREENWIDTH, viewheight + viewwindowy); - V_DrawBorder (0, viewwindowy + viewheight, SCREENWIDTH, StatusBar->GetTopOfStatusbar()); + DrawBorder (0, 0, Width, viewwindowy); + DrawBorder (0, viewwindowy, viewwindowx, viewheight + viewwindowy); + DrawBorder (viewwindowx + viewwidth, viewwindowy, Width, viewheight + viewwindowy); + DrawBorder (0, viewwindowy + viewheight, Width, StatusBar->GetTopOfStatusbar()); - V_DrawFrame (viewwindowx, viewwindowy, viewwidth, viewheight); -} - -//========================================================================== -// -// R_DrawTopBorder -// -// Draws the top border around the view for different size windows -// -//========================================================================== - -static void V_DrawTopBorder () -{ - FTexture *p; - int offset; - - if (viewwidth == SCREENWIDTH) - return; - - offset = gameinfo.Border.offset; - - if (viewwindowy < 34) - { - V_DrawBorder (0, 0, viewwindowx, 34); - V_DrawBorder (viewwindowx, 0, viewwindowx + viewwidth, viewwindowy); - V_DrawBorder (viewwindowx + viewwidth, 0, SCREENWIDTH, 34); - p = TexMan(gameinfo.Border.t); - screen->FlatFill(viewwindowx, viewwindowy - p->GetHeight(), - viewwindowx + viewwidth, viewwindowy, p, true); - - p = TexMan(gameinfo.Border.l); - screen->FlatFill(viewwindowx - p->GetWidth(), viewwindowy, - viewwindowx, 35, p, true); - p = TexMan(gameinfo.Border.r); - screen->FlatFill(viewwindowx + viewwidth, viewwindowy, - viewwindowx + viewwidth + p->GetWidth(), 35, p, true); - - p = TexMan(gameinfo.Border.tl); - screen->DrawTexture (p, viewwindowx - offset, viewwindowy - offset, TAG_DONE); - - p = TexMan(gameinfo.Border.tr); - screen->DrawTexture (p, viewwindowx + viewwidth, viewwindowy - offset, TAG_DONE); - } - else - { - V_DrawBorder (0, 0, SCREENWIDTH, 34); - } + DrawFrame (viewwindowx, viewwindowy, viewwidth, viewheight); } //========================================================================== @@ -1401,24 +1327,11 @@ static void V_DrawTopBorder () // //========================================================================== -void V_RefreshViewBorder () +void DFrameBuffer::RefreshViewBorder () { if (setblocks < 10) { - if (BorderNeedRefresh) - { - BorderNeedRefresh--; - if (BorderTopRefresh) - { - BorderTopRefresh--; - } - V_DrawViewBorder(); - } - else if (BorderTopRefresh) - { - BorderTopRefresh--; - V_DrawTopBorder(); - } + DrawViewBorder(); } } diff --git a/src/v_font.cpp b/src/v_font.cpp index d8826d11c6..f352e06acd 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -417,7 +417,7 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count, charlumps[i] = pic; int height = pic->GetScaledHeight(); - int yoffs = pic->GetScaledTopOffset(); + int yoffs = pic->GetScaledTopOffset(0); if (yoffs > maxyoffs) { @@ -965,54 +965,6 @@ void FFont::LoadTranslations() delete[] luminosity; } -//========================================================================== -// -// FFont :: Preload -// -// Loads most of the 7-bit ASCII characters. In the case of D3DFB, this -// means all the characters of a font have a better chance of being packed -// into the same hardware texture. -// -// (Note that this is a rather dumb implementation. The atlasing should -// occur at a higher level, independently of the renderer being used.) -// -//========================================================================== - -void FFont::Preload() const -{ - // First and last char are the same? Wait until it's actually needed - // since nothing is gained by preloading now. - if (FirstChar == LastChar) - { - return; - } - for (int i = MAX(FirstChar, 0x21); i < MIN(LastChar, 0x7e); ++i) - { - int foo; - FTexture *pic = GetChar(i, &foo); - if (pic != NULL) - { - pic->GetNative(pic->GetFormat(), false); - } - } -} - -//========================================================================== -// -// FFont :: StaticPreloadFonts -// -// Preloads all the defined fonts. -// -//========================================================================== - -void FFont::StaticPreloadFonts() -{ - for (FFont *font = FirstFont; font != NULL; font = font->Next) - { - font->Preload(); - } -} - //========================================================================== // // FFont :: FFont - default constructor @@ -1761,8 +1713,8 @@ FFontChar2::FFontChar2 (int sourcelump, int sourcepos, int width, int height, in UseType = ETextureType::FontChar; Width = width; Height = height; - LeftOffset = leftofs; - TopOffset = topofs; + _LeftOffset[1] = _LeftOffset[0] = leftofs; + _TopOffset[1] = _TopOffset[0] = topofs; CalcBitSize (); } @@ -2012,7 +1964,7 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l if (pic != NULL) { int height = pic->GetScaledHeight(); - int yoffs = pic->GetScaledTopOffset(); + int yoffs = pic->GetScaledTopOffset(0); if (yoffs > maxyoffs) { diff --git a/src/v_font.h b/src/v_font.h index e1be6afb24..83ea5de195 100644 --- a/src/v_font.h +++ b/src/v_font.h @@ -90,11 +90,9 @@ public: int GetHeight () const { return FontHeight; } int GetDefaultKerning () const { return GlobalKerning; } virtual void LoadTranslations(); - void Preload() const; FName GetName() const { return FontName; } static FFont *FindFont(FName fontname); - static void StaticPreloadFonts(); // Return width of string in pixels (unscaled) int StringWidth (const uint8_t *str) const; diff --git a/src/v_text.cpp b/src/v_text.cpp index 06b09a2ef8..e0553ef017 100644 --- a/src/v_text.cpp +++ b/src/v_text.cpp @@ -132,7 +132,7 @@ int GetCharFromString(const uint8_t *&string) // //========================================================================== -void DCanvas::DrawChar (FFont *font, int normalcolor, double x, double y, int character, int tag_first, ...) +void DFrameBuffer::DrawChar (FFont *font, int normalcolor, double x, double y, int character, int tag_first, ...) { if (font == NULL) return; @@ -161,7 +161,7 @@ void DCanvas::DrawChar (FFont *font, int normalcolor, double x, double y, int ch } } -void DCanvas::DrawChar(FFont *font, int normalcolor, double x, double y, int character, VMVa_List &args) +void DFrameBuffer::DrawChar(FFont *font, int normalcolor, double x, double y, int character, VMVa_List &args) { if (font == NULL) return; @@ -208,7 +208,7 @@ DEFINE_ACTION_FUNCTION(_Screen, DrawChar) // //========================================================================== -void DCanvas::DrawTextCommon(FFont *font, int normalcolor, double x, double y, const char *string, DrawParms &parms) +void DFrameBuffer::DrawTextCommon(FFont *font, int normalcolor, double x, double y, const char *string, DrawParms &parms) { int w; const uint8_t *ch; @@ -281,7 +281,7 @@ void DCanvas::DrawTextCommon(FFont *font, int normalcolor, double x, double y, c } } -void DCanvas::DrawText(FFont *font, int normalcolor, double x, double y, const char *string, int tag_first, ...) +void DFrameBuffer::DrawText(FFont *font, int normalcolor, double x, double y, const char *string, int tag_first, ...) { Va_List tags; DrawParms parms; @@ -299,7 +299,7 @@ void DCanvas::DrawText(FFont *font, int normalcolor, double x, double y, const c DrawTextCommon(font, normalcolor, x, y, string, parms); } -void DCanvas::DrawText(FFont *font, int normalcolor, double x, double y, const char *string, VMVa_List &args) +void DFrameBuffer::DrawText(FFont *font, int normalcolor, double x, double y, const char *string, VMVa_List &args) { DrawParms parms; diff --git a/src/v_video.cpp b/src/v_video.cpp index 1ac815bc5f..51ef13e0a6 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -86,20 +86,47 @@ #include "r_videoscale.h" #include "i_time.h" +EXTERN_CVAR(Bool, cl_capfps) + +CUSTOM_CVAR(Int, vid_maxfps, 200, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +{ + if (vid_maxfps < TICRATE && vid_maxfps != 0) + { + vid_maxfps = TICRATE; + } + else if (vid_maxfps > 1000) + { + vid_maxfps = 1000; + } + else if (cl_capfps == 0) + { + I_SetFPSLimit(vid_maxfps); + } +} + +CUSTOM_CVAR(Int, vid_rendermode, 4, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) +{ + if (usergame) + { + // [SP] Update pitch limits to the netgame/gamesim. + players[consoleplayer].SendPitchLimits(); + } + screen->SetTextureFilterMode(); + + // No further checks needed. All this changes now is which scene drawer the render backend calls. +} + + + EXTERN_CVAR(Bool, r_blendmethod) int active_con_scale(); -FRenderer *Renderer; +FRenderer *SWRenderer; -EXTERN_CVAR (Bool, swtruecolor) EXTERN_CVAR (Bool, fullscreen) -#if defined(_DEBUG) && defined(_M_IX86) && !defined(__MINGW32__) -#define DBGBREAK { __asm int 3 } -#else -#define DBGBREAK -#endif +#define DBGBREAK assert(0) class DDummyFrameBuffer : public DFrameBuffer { @@ -111,7 +138,7 @@ public: Width = width; Height = height; } - bool Lock(bool buffered) { DBGBREAK; return false; } + // These methods should never be called. void Update() { DBGBREAK; } PalEntry *GetPalette() { DBGBREAK; return NULL; } void GetFlashedPalette(PalEntry palette[256]) { DBGBREAK; } @@ -119,13 +146,7 @@ public: bool SetGamma(float gamma) { Gamma = gamma; return true; } bool SetFlash(PalEntry rgb, int amount) { DBGBREAK; return false; } void GetFlash(PalEntry &rgb, int &amount) { DBGBREAK; } - int GetPageCount() { DBGBREAK; return 0; } bool IsFullscreen() { DBGBREAK; return 0; } -#ifdef _WIN32 - void PaletteChanged() {} - int QueryNewPalette() { return 0; } - bool Is8BitMode() { return false; } -#endif float Gamma; }; @@ -191,19 +212,6 @@ CUSTOM_CVAR (Int, vid_refreshrate, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) } } -CUSTOM_CVAR (Float, dimamount, -1.f, CVAR_ARCHIVE) -{ - if (self < 0.f && self != -1.f) - { - self = -1.f; - } - else if (self > 1.f) - { - self = 1.f; - } -} -CVAR (Color, dimcolor, 0xffd700, CVAR_ARCHIVE) - // [RH] Set true when vid_setmode command has been executed bool setmodeneeded = false; // [RH] Resolution to change to when setmodeneeded is true @@ -219,8 +227,6 @@ int NewWidth, NewHeight, NewBits; DCanvas::DCanvas (int _width, int _height, bool _bgra) { // Init member vars - Buffer = NULL; - LockCount = 0; Width = _width; Height = _height; Bgra = _bgra; @@ -236,122 +242,6 @@ DCanvas::~DCanvas () { } -//========================================================================== -// -// DCanvas :: IsValid -// -//========================================================================== - -bool DCanvas::IsValid () -{ - // A nun-subclassed DCanvas is never valid - return false; -} - -//========================================================================== -// -// DCanvas :: FlatFill -// -// Fill an area with a texture. If local_origin is false, then the origin -// used for the wrapping is (0,0). Otherwise, (left,right) is used. -// -//========================================================================== - -void DCanvas::FlatFill (int left, int top, int right, int bottom, FTexture *src, bool local_origin) -{ - int w = src->GetWidth(); - int h = src->GetHeight(); - - // Repeatedly draw the texture, left-to-right, top-to-bottom. - for (int y = local_origin ? top : (top / h * h); y < bottom; y += h) - { - for (int x = local_origin ? left : (left / w * w); x < right; x += w) - { - DrawTexture (src, x, y, - DTA_ClipLeft, left, - DTA_ClipRight, right, - DTA_ClipTop, top, - DTA_ClipBottom, bottom, - DTA_TopOffset, 0, - DTA_LeftOffset, 0, - TAG_DONE); - } - } -} - -//========================================================================== -// -// DCanvas :: Dim -// -// Applies a colored overlay to the entire screen, with the opacity -// determined by the dimamount cvar. -// -//========================================================================== - -void DCanvas::Dim (PalEntry color) -{ - PalEntry dimmer; - float amount; - - if (dimamount >= 0) - { - dimmer = PalEntry(dimcolor); - amount = dimamount; - } - else - { - dimmer = gameinfo.dimcolor; - amount = gameinfo.dimamount; - } - - if (gameinfo.gametype == GAME_Hexen && gamestate == GS_DEMOSCREEN) - { // On the Hexen title screen, the default dimming is not - // enough to make the menus readable. - amount = MIN (1.f, amount*2.f); - } - // Add the cvar's dimming on top of the color passed to the function - if (color.a != 0) - { - float dim[4] = { color.r/255.f, color.g/255.f, color.b/255.f, color.a/255.f }; - V_AddBlend (dimmer.r/255.f, dimmer.g/255.f, dimmer.b/255.f, amount, dim); - dimmer = PalEntry (uint8_t(dim[0]*255), uint8_t(dim[1]*255), uint8_t(dim[2]*255)); - amount = dim[3]; - } - Dim (dimmer, amount, 0, 0, Width, Height); -} - -//========================================================================== -// -// DCanvas :: GetScreenshotBuffer -// -// Returns a buffer containing the most recently displayed frame. The -// width and height of this buffer are the same as the canvas. -// -//========================================================================== - -void DCanvas::GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type, float &gamma) -{ - Lock(true); - buffer = GetBuffer(); - pitch = IsBgra() ? GetPitch() * 4 : GetPitch(); - color_type = IsBgra() ? SS_BGRA : SS_PAL; - gamma = Gamma; -} - -//========================================================================== -// -// DCanvas :: ReleaseScreenshotBuffer -// -// Releases the buffer obtained through GetScreenshotBuffer. These calls -// must not be nested. -// -//========================================================================== - -void DCanvas::ReleaseScreenshotBuffer() -{ - Unlock(); -} - //========================================================================== // // V_GetColorFromString @@ -638,7 +528,7 @@ static void BuildTransTable (const PalEntry *palette) // //========================================================================== -void DCanvas::CalcGamma (float gamma, uint8_t gammalookup[256]) +void DFrameBuffer::CalcGamma (float gamma, uint8_t gammalookup[256]) { // I found this formula on the web at // , @@ -663,7 +553,7 @@ void DCanvas::CalcGamma (float gamma, uint8_t gammalookup[256]) DSimpleCanvas::DSimpleCanvas (int width, int height, bool bgra) : DCanvas (width, height, bgra) { - MemBuffer = nullptr; + PixelBuffer = nullptr; Resize(width, height); } @@ -672,10 +562,10 @@ void DSimpleCanvas::Resize(int width, int height) Width = width; Height = height; - if (MemBuffer != NULL) + if (PixelBuffer != NULL) { - delete[] MemBuffer; - MemBuffer = NULL; + delete[] PixelBuffer; + PixelBuffer = NULL; } // Making the pitch a power of 2 is very bad for performance @@ -714,8 +604,8 @@ void DSimpleCanvas::Resize(int width, int height) } } int bytes_per_pixel = Bgra ? 4 : 1; - MemBuffer = new uint8_t[Pitch * height * bytes_per_pixel]; - memset (MemBuffer, 0, Pitch * height * bytes_per_pixel); + PixelBuffer = new uint8_t[Pitch * height * bytes_per_pixel]; + memset (PixelBuffer, 0, Pitch * height * bytes_per_pixel); } //========================================================================== @@ -726,52 +616,10 @@ void DSimpleCanvas::Resize(int width, int height) DSimpleCanvas::~DSimpleCanvas () { - if (MemBuffer != NULL) + if (PixelBuffer != NULL) { - delete[] MemBuffer; - MemBuffer = NULL; - } -} - -//========================================================================== -// -// DSimpleCanvas :: IsValid -// -//========================================================================== - -bool DSimpleCanvas::IsValid () -{ - return (MemBuffer != NULL); -} - -//========================================================================== -// -// DSimpleCanvas :: Lock -// -//========================================================================== - -bool DSimpleCanvas::Lock (bool) -{ - if (LockCount == 0) - { - Buffer = MemBuffer; - } - LockCount++; - return false; // System surfaces are never lost -} - -//========================================================================== -// -// DSimpleCanvas :: Unlock -// -//========================================================================== - -void DSimpleCanvas::Unlock () -{ - if (--LockCount <= 0) - { - LockCount = 0; - Buffer = NULL; // Enforce buffer access only between Lock/Unlock + delete[] PixelBuffer; + PixelBuffer = NULL; } } @@ -785,79 +633,18 @@ void DSimpleCanvas::Unlock () //========================================================================== DFrameBuffer::DFrameBuffer (int width, int height, bool bgra) - : DSimpleCanvas (ViewportScaledWidth(width, height), ViewportScaledHeight(width, height), bgra) + //: DCanvas { + Width = ViewportScaledWidth(width, height); + Height = ViewportScaledHeight(width, height); + Bgra = bgra; + LastMS = LastSec = FrameCount = LastCount = LastTic = 0; - Accel2D = false; VideoWidth = width; VideoHeight = height; } -//========================================================================== -// -// DFrameBuffer :: PostprocessBgra -// -// Copies data to destination buffer while performing gamma and flash. -// This is only needed if a target cannot do this with shaders. -// -//========================================================================== - -void DFrameBuffer::CopyWithGammaBgra(void *output, int pitch, const uint8_t *gammared, const uint8_t *gammagreen, const uint8_t *gammablue, PalEntry flash, int flash_amount) -{ - const uint8_t *gammatables[3] = { gammared, gammagreen, gammablue }; - - if (flash_amount > 0) - { - uint16_t inv_flash_amount = 256 - flash_amount; - uint16_t flash_red = flash.r * flash_amount; - uint16_t flash_green = flash.g * flash_amount; - uint16_t flash_blue = flash.b * flash_amount; - - for (int y = 0; y < Height; y++) - { - uint8_t *dest = (uint8_t*)output + y * pitch; - uint8_t *src = MemBuffer + y * Pitch * 4; - for (int x = 0; x < Width; x++) - { - uint16_t fg_red = src[2]; - uint16_t fg_green = src[1]; - uint16_t fg_blue = src[0]; - uint16_t red = (fg_red * inv_flash_amount + flash_red) >> 8; - uint16_t green = (fg_green * inv_flash_amount + flash_green) >> 8; - uint16_t blue = (fg_blue * inv_flash_amount + flash_blue) >> 8; - - dest[0] = gammatables[2][blue]; - dest[1] = gammatables[1][green]; - dest[2] = gammatables[0][red]; - dest[3] = 0xff; - - dest += 4; - src += 4; - } - } - } - else - { - for (int y = 0; y < Height; y++) - { - uint8_t *dest = (uint8_t*)output + y * pitch; - uint8_t *src = MemBuffer + y * Pitch * 4; - for (int x = 0; x < Width; x++) - { - dest[0] = gammatables[2][src[0]]; - dest[1] = gammatables[1][src[1]]; - dest[2] = gammatables[0][src[2]]; - dest[3] = 0xff; - - dest += 4; - src += 4; - } - } - } -} - - //========================================================================== // // DFrameBuffer :: DrawRateStuff @@ -904,38 +691,15 @@ void DFrameBuffer::DrawRateStuff () // draws little dots on the bottom of the screen if (ticker) { - int64_t i = I_GetTime(); - int64_t tics = i - LastTic; - uint8_t *buffer = GetBuffer(); + int64_t t = I_GetTime(); + int64_t tics = t - LastTic; - LastTic = i; + LastTic = t; if (tics > 20) tics = 20; - // Buffer can be NULL if we're doing hardware accelerated 2D - if (buffer != NULL) - { - if (IsBgra()) - { - uint32_t *buffer32 = (uint32_t*)buffer; - buffer32 += (GetHeight() - 1) * GetPitch(); - - for (i = 0; i < tics * 2; i += 2) buffer32[i] = 0xffffffff; - for (; i < 20 * 2; i += 2) buffer32[i] = 0xff000000; - } - else - { - buffer += (GetHeight() - 1) * GetPitch(); - - for (i = 0; i < tics * 2; i += 2) buffer[i] = 0xff; - for (; i < 20 * 2; i += 2) buffer[i] = 0x00; - } - } - else - { - int i; - for (i = 0; i < tics*2; i += 2) Clear(i, Height-1, i+1, Height, 255, 0); - for ( ; i < 20*2; i += 2) Clear(i, Height-1, i+1, Height, 0, 0); - } + int i; + for (i = 0; i < tics*2; i += 2) Clear(i, Height-1, i+1, Height, 255, 0); + for ( ; i < 20*2; i += 2) Clear(i, Height-1, i+1, Height, 0, 0); } // draws the palette for debugging @@ -1063,32 +827,6 @@ void FPaletteTester::MakeTexture() CurTranslation = t; } -//========================================================================== -// -// DFrameBuffer :: CopyFromBuff -// -// Copies pixels from main memory to video memory. This is only used by -// DDrawFB. -// -//========================================================================== - -void DFrameBuffer::CopyFromBuff (uint8_t *src, int srcPitch, int width, int height, uint8_t *dest) -{ - if (Pitch == width && Pitch == Width && srcPitch == width) - { - memcpy (dest, src, Width * Height); - } - else - { - for (int y = 0; y < height; y++) - { - memcpy (dest, src, width); - dest += Pitch; - src += srcPitch; - } - } -} - //========================================================================== // // DFrameBuffer :: SetVSync @@ -1142,48 +880,6 @@ bool DFrameBuffer::Begin2D (bool copy3d) return false; } -//========================================================================== -// -// DFrameBuffer :: DrawBlendingRect -// -// In hardware 2D modes, the blending rect needs to be drawn separately -// from transferring the 3D scene to video memory, because the weapon -// sprite is drawn on top of that. -// -//========================================================================== - -void DFrameBuffer::DrawBlendingRect() -{ -} - -//========================================================================== -// -// DFrameBuffer :: CreateTexture -// -// Creates a native texture for a game texture, if supported. -// The hardware renderer does not use this interface because it is -// far too limited -// -//========================================================================== - -FNativeTexture *DFrameBuffer::CreateTexture(FTexture *gametex, FTextureFormat fmt, bool wrapping) -{ - return NULL; -} - -//========================================================================== -// -// DFrameBuffer :: CreatePalette -// -// Creates a native palette from a remap table, if supported. -// -//========================================================================== - -FNativePalette *DFrameBuffer::CreatePalette(FRemapTable *remap) -{ - return NULL; -} - //========================================================================== // // DFrameBuffer :: WipeStartScreen @@ -1196,7 +892,7 @@ FNativePalette *DFrameBuffer::CreatePalette(FRemapTable *remap) bool DFrameBuffer::WipeStartScreen(int type) { - return wipe_StartScreen(type); + return false; } //========================================================================== @@ -1210,8 +906,6 @@ bool DFrameBuffer::WipeStartScreen(int type) void DFrameBuffer::WipeEndScreen() { - wipe_EndScreen(); - Unlock(); } //========================================================================== @@ -1226,8 +920,7 @@ void DFrameBuffer::WipeEndScreen() bool DFrameBuffer::WipeDo(int ticks) { - Lock(true); - return wipe_ScreenWipe(ticks); + return false; } //========================================================================== @@ -1238,7 +931,6 @@ bool DFrameBuffer::WipeDo(int ticks) void DFrameBuffer::WipeCleanup() { - wipe_Cleanup(); } //========================================================================== @@ -1251,31 +943,46 @@ void DFrameBuffer::GameRestart() { } -//=========================================================================== +//========================================================================== // -// +// DFrameBuffer :: GetCaps // -//=========================================================================== +//========================================================================== -FNativePalette::~FNativePalette() -{ -} +EXTERN_CVAR(Bool, r_drawvoxels) -FNativeTexture::~FNativeTexture() +uint32_t DFrameBuffer::GetCaps() { - // Remove link from the game texture - if (mGameTex != nullptr) + ActorRenderFeatureFlags FlagSet = 0; + + if (V_IsPolyRenderer()) + FlagSet |= RFF_POLYGONAL | RFF_TILTPITCH | RFF_SLOPE3DFLOORS; + else { - mGameTex->Native[mFormat] = nullptr; + FlagSet |= RFF_UNCLIPPEDTEX; + if (r_drawvoxels) + FlagSet |= RFF_VOXELS; } + if (V_IsTrueColor()) + FlagSet |= RFF_TRUECOLOR; + else + FlagSet |= RFF_COLORMAP; + + return (uint32_t)FlagSet; } -bool FNativeTexture::CheckWrapping(bool wrapping) +void DFrameBuffer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV) { - return true; + SWRenderer->RenderTextureView(tex, Viewpoint, FOV); } +void DFrameBuffer::WriteSavePic(player_t *player, FileWriter *file, int width, int height) +{ + SWRenderer->WriteSavePic(player, file, width, height); +} + + CCMD(clean) { Printf ("CleanXfac: %d\nCleanYfac: %d\n", CleanXfac, CleanYfac); @@ -1296,10 +1003,6 @@ bool V_DoModeSetup (int width, int height, int bits) screen = buff; screen->SetGamma (Gamma); - // Load fonts now so they can be packed into textures straight away, - // if D3DFB is being used for the display. - FFont::StaticPreloadFonts(); - DisplayBits = bits; V_UpdateModeSize(screen->GetWidth(), screen->GetHeight()); @@ -1353,7 +1056,9 @@ void V_UpdateModeSize (int width, int height) DisplayHeight = height; R_OldBlend = ~0; - Renderer->OnModeSet(); + + // the software renderer also needs to be notified + SWRenderer->OnModeSet(); } void V_OutputResized (int width, int height) @@ -1578,11 +1283,9 @@ void V_Init2() Printf ("Resolution: %d x %d\n", SCREENWIDTH, SCREENHEIGHT); screen->SetGamma (gamma); - Renderer->RemapVoxels(); FBaseCVar::ResetColors (); C_NewModeAdjust(); M_InitVideoModesMenu(); - V_SetBorderNeedRefresh(); setsizeneeded = true; } diff --git a/src/v_video.h b/src/v_video.h index aaa1492faa..030fba56f8 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -41,6 +41,8 @@ #include "dobject.h" #include "r_data/renderstyle.h" #include "c_cvars.h" +#include "v_colortables.h" +#include "v_2ddrawer.h" extern int CleanWidth, CleanHeight, CleanXfac, CleanYfac; extern int CleanWidth_1, CleanHeight_1, CleanXfac_1, CleanYfac_1; @@ -51,8 +53,32 @@ void V_UpdateModeSize (int width, int height); void V_OutputResized (int width, int height); void V_CalcCleanFacs (int designwidth, int designheight, int realwidth, int realheight, int *cleanx, int *cleany, int *cx1=NULL, int *cx2=NULL); +EXTERN_CVAR(Int, vid_rendermode) + +inline bool V_IsHardwareRenderer() +{ + return vid_rendermode == 4; +} + +inline bool V_IsSoftwareRenderer() +{ + return vid_rendermode < 2; +} + +inline bool V_IsPolyRenderer() +{ + return vid_rendermode == 2 || vid_rendermode == 3; +} + +inline bool V_IsTrueColor() +{ + return vid_rendermode == 1 || vid_rendermode == 3; +} + + class FTexture; struct FColormap; +class FileWriter; enum FTextureFormat : uint32_t; // TagItem definitions for DrawTexture. As far as I know, tag lists @@ -77,7 +103,7 @@ enum DTA_DestWidth, // width of area to draw to DTA_DestHeight, // height of area to draw to DTA_Alpha, // alpha value for translucency - DTA_FillColor, // color to stencil onto the destination (RGB is the color for truecolor drawers, A is the palette index for paletted drawers) + DTA_FillColor, // color to stencil onto the destination DTA_TranslationIndex, // translation table to recolor the source DTA_AlphaChannel, // bool: the source is an alpha channel; used with DTA_FillColor DTA_Clean, // bool: scale texture size and position by CleanXfac and CleanYfac @@ -108,8 +134,8 @@ enum DTA_RenderStyle, // same as render style for actors DTA_ColorOverlay, // uint32_t: ARGB to overlay on top of image; limited to black for software DTA_BilinearFilter, // bool: apply bilinear filtering to the image - DTA_SpecialColormap,// pointer to FSpecialColormapParameters (likely to be forever hardware-only) - DTA_ColormapStyle, // pointer to FColormapStyle (hardware-only) + DTA_SpecialColormap,// pointer to FSpecialColormapParameters + DTA_Desaturate, // explicit desaturation factor (does not do anything in Legacy OpenGL) DTA_Fullscreen, // Draw image fullscreen (same as DTA_VirtualWidth/Height with graphics size.) // floating point duplicates of some of the above: @@ -129,6 +155,12 @@ enum // New additions. DTA_Color, + DTA_FlipY, // bool: flip image vertically + DTA_SrcX, // specify a source rectangle (this supersedes the poorly implemented DTA_WindowLeft/Right + DTA_SrcY, + DTA_SrcWidth, + DTA_SrcHeight + }; enum @@ -162,12 +194,13 @@ struct DrawParms double top; double left; float Alpha; - uint32_t fillcolor; + PalEntry fillcolor; FRemapTable *remap; - uint32_t colorOverlay; + PalEntry colorOverlay; PalEntry color; INTBOOL alphaChannel; INTBOOL flipX; + INTBOOL flipY; //float shadowAlpha; int shadowColor; INTBOOL keepratio; @@ -175,12 +208,14 @@ struct DrawParms INTBOOL bilinear; FRenderStyle style; struct FSpecialColormap *specialcolormap; - struct FColormapStyle *colormapstyle; + int desaturate; int scalex, scaley; int cellx, celly; int maxstrlen; bool fortext; bool virtBottom; + double srcx, srcy; + double srcwidth, srcheight; }; struct Va_List @@ -206,111 +241,30 @@ public: virtual ~DCanvas (); // Member variable access - inline uint8_t *GetBuffer () const { return Buffer; } + inline uint8_t *GetPixels () const { return PixelBuffer; } inline int GetWidth () const { return Width; } inline int GetHeight () const { return Height; } inline int GetPitch () const { return Pitch; } inline bool IsBgra() const { return Bgra; } - virtual bool IsValid (); + // Note: pitch here is in pixels, not bytes. + bool SetBuffer(int width, int height, int pitch, uint8_t *buffer) + { + assert(buffer); + Width = width; + Height = height; + Pitch = pitch; + PixelBuffer = buffer; + return true; + } - // Access control - virtual bool Lock (bool buffered=true) = 0; // Returns true if the surface was lost since last time - virtual void Unlock () = 0; - virtual bool IsLocked () { return Buffer != NULL; } // Returns true if the surface is locked - - // Draw a linear block of pixels into the canvas - virtual void DrawBlock (int x, int y, int width, int height, const uint8_t *src) const; - - // Reads a linear block of pixels into the view buffer. - virtual void GetBlock (int x, int y, int width, int height, uint8_t *dest) const; - - // Dim the entire canvas for the menus - virtual void Dim (PalEntry color = 0); - - // Dim part of the canvas - virtual void Dim (PalEntry color, float amount, int x1, int y1, int w, int h) final; - virtual void DoDim(PalEntry color, float amount, int x1, int y1, int w, int h); - - // Fill an area with a texture - virtual void FlatFill (int left, int top, int right, int bottom, FTexture *src, bool local_origin=false); - - // Fill a simple polygon with a texture - virtual void FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, - double originx, double originy, double scalex, double scaley, DAngle rotation, - const FColormap &colormap, PalEntry flatcolor, int lightlevel, int bottomclip); - - // Set an area to a specified color - virtual void Clear (int left, int top, int right, int bottom, int palcolor, uint32_t color) final; - virtual void DoClear(int left, int top, int right, int bottom, int palcolor, uint32_t color); - - // Draws a line - virtual void DrawLine(int x0, int y0, int x1, int y1, int palColor, uint32_t realcolor); - - // Draws a single pixel - virtual void DrawPixel(int x, int y, int palcolor, uint32_t rgbcolor); - - // Calculate gamma table - void CalcGamma (float gamma, uint8_t gammalookup[256]); - - - // Retrieves a buffer containing image data for a screenshot. - // Hint: Pitch can be negative for upside-down images, in which case buffer - // points to the last row in the buffer, which will be the first row output. - virtual void GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type, float &gamma); - - // Releases the screenshot buffer. - virtual void ReleaseScreenshotBuffer(); - - // Text drawing functions ----------------------------------------------- - - // 2D Texture drawing - void ClearClipRect() { clipleft = cliptop = 0; clipwidth = clipheight = -1; } - void SetClipRect(int x, int y, int w, int h); - void GetClipRect(int *x, int *y, int *w, int *h); - - bool SetTextureParms(DrawParms *parms, FTexture *img, double x, double y) const; - void DrawTexture (FTexture *img, double x, double y, int tags, ...); - void DrawTexture(FTexture *img, double x, double y, VMVa_List &); - void FillBorder (FTexture *img); // Fills the border around a 4:3 part of the screen on non-4:3 displays - void VirtualToRealCoords(double &x, double &y, double &w, double &h, double vwidth, double vheight, bool vbottom=false, bool handleaspect=true) const; - - // Code that uses these (i.e. SBARINFO) should probably be evaluated for using doubles all around instead. - void VirtualToRealCoordsInt(int &x, int &y, int &w, int &h, int vwidth, int vheight, bool vbottom=false, bool handleaspect=true) const; - -#ifdef DrawText -#undef DrawText // See WinUser.h for the definition of DrawText as a macro -#endif - // 2D Text drawing - void DrawText(FFont *font, int normalcolor, double x, double y, const char *string, int tag_first, ...); - void DrawText(FFont *font, int normalcolor, double x, double y, const char *string, VMVa_List &args); - void DrawChar(FFont *font, int normalcolor, double x, double y, int character, int tag_first, ...); - void DrawChar(FFont *font, int normalcolor, double x, double y, int character, VMVa_List &args); protected: - uint8_t *Buffer; + uint8_t *PixelBuffer; int Width; int Height; int Pitch; - int LockCount; bool Bgra; - int clipleft = 0, cliptop = 0, clipwidth = -1, clipheight = -1; - - void DrawTextCommon(FFont *font, int normalcolor, double x, double y, const char *string, DrawParms &parms); - - bool ClipBox (int &left, int &top, int &width, int &height, const uint8_t *&src, const int srcpitch) const; - void DrawTextureV(FTexture *img, double x, double y, uint32_t tag, va_list tags) = delete; - virtual void DrawTextureParms(FTexture *img, DrawParms &parms); - - template - bool ParseDrawTextureTags(FTexture *img, double x, double y, uint32_t tag, T& tags, DrawParms *parms, bool fortext) const; - - DCanvas() {} - -private: - // Keep track of canvases, for automatic destruction at exit - DCanvas *Next; - static DCanvas *CanvasChain; }; // A canvas in system memory. @@ -321,54 +275,42 @@ class DSimpleCanvas : public DCanvas public: DSimpleCanvas (int width, int height, bool bgra); ~DSimpleCanvas (); - - bool IsValid (); - bool Lock (bool buffered=true); - void Unlock (); - -protected: void Resize(int width, int height); - - uint8_t *MemBuffer; - - DSimpleCanvas() {} }; -// This class represents a native texture, as opposed to an FTexture. -class FNativeTexture -{ -protected: - FTexture * mGameTex; - FTextureFormat mFormat; -public: - FNativeTexture(FTexture *tex, FTextureFormat fmt) : mGameTex(tex), mFormat(fmt) {} - virtual ~FNativeTexture(); - virtual bool Update() = 0; - virtual bool CheckWrapping(bool wrapping); -}; -// This class represents a texture lookup palette. -class FNativePalette -{ -public: - virtual ~FNativePalette(); - virtual bool Update() = 0; -}; +class FUniquePalette; // A canvas that represents the actual display. The video code is responsible // for actually implementing this. Built on top of SimpleCanvas, because it // needs a system memory buffer when buffered output is enabled. -class DFrameBuffer : public DSimpleCanvas +class DFrameBuffer { typedef DSimpleCanvas Super; +protected: + + void DrawTextureV(FTexture *img, double x, double y, uint32_t tag, va_list tags) = delete; + void DrawTextureParms(FTexture *img, DrawParms &parms); + + template + bool ParseDrawTextureTags(FTexture *img, double x, double y, uint32_t tag, T& tags, DrawParms *parms, bool fortext) const; + void DrawTextCommon(FFont *font, int normalcolor, double x, double y, const char *string, DrawParms &parms); + + F2DDrawer m2DDrawer; + int Width = 0; + int Height = 0; + bool Bgra = 0; + int clipleft = 0, cliptop = 0, clipwidth = -1, clipheight = -1; + public: DFrameBuffer (int width, int height, bool bgra); + virtual ~DFrameBuffer() {} - // Force the surface to use buffered output if true is passed. - virtual bool Lock (bool buffered) = 0; + inline int GetWidth() const { return Width; } + inline int GetHeight() const { return Height; } - // Make the surface visible. Also implies Unlock(). + // Make the surface visible. virtual void Update () = 0; // Return a pointer to 256 palette entries that can be written to. @@ -394,9 +336,6 @@ public: // Converse of SetFlash virtual void GetFlash (PalEntry &rgb, int &amount) = 0; - // Returns the number of video pages the frame buffer is using. - virtual int GetPageCount () = 0; - // Returns true if running fullscreen. virtual bool IsFullscreen () = 0; @@ -409,13 +348,11 @@ public: // Set the rect defining the area affected by blending. virtual void SetBlendingRect (int x1, int y1, int x2, int y2); - bool Accel2D; // If true, 2D drawing can be accelerated. - virtual bool LegacyHardware() const { return false; } // only for reporting SM1.4 support to the stat collector + // Delete any resources that need to be deleted after restarting with a different IWAD + virtual void CleanForRestart() {} + virtual void SetTextureFilterMode() {} - // Begin 2D drawing operations. This is like Update, but it doesn't end - // the scene, and it doesn't present the image yet. If you are going to - // be covering the entire screen with 2D elements, then pass false to - // avoid copying the software buffer to the screen. + // Begin 2D drawing operations. // Returns true if hardware-accelerated 2D has been entered, false if not. virtual bool Begin2D(bool copy3d); void End2D() { isIn2D = false; } @@ -423,22 +360,15 @@ public: // Returns true if Begin2D has been called and 2D drawing is now active bool HasBegun2D() { return isIn2D; } - // DrawTexture calls after Begin2D use native textures. - // Draws the blending rectangle over the viewwindow if in hardware- - // accelerated 2D mode. - virtual void DrawBlendingRect(); - - // Create a native texture from a game texture. - virtual FNativeTexture *CreateTexture(FTexture *gametex, FTextureFormat fmt, bool wrapping); - - // Create a palette texture from a remap/palette table. - virtual FNativePalette *CreatePalette(FRemapTable *remap); - - // Precaches or unloads a texture - // Report a game restart virtual void GameRestart(); + virtual void InitForLevel() {} + virtual void SetClearColor(int color) {} + virtual uint32_t GetCaps(); + virtual void RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV); + virtual void WriteSavePic(player_t *player, FileWriter *file, int width, int height); + virtual void RenderView(player_t *player) {} // Screen wiping virtual bool WipeStartScreen(int type); @@ -450,11 +380,72 @@ public: uint64_t GetLastFPS() const { return LastCount; } -#ifdef _WIN32 - virtual void PaletteChanged () = 0; - virtual int QueryNewPalette () = 0; - virtual bool Is8BitMode() = 0; + // 2D Texture drawing + void ClearClipRect() { clipleft = cliptop = 0; clipwidth = clipheight = -1; } + void SetClipRect(int x, int y, int w, int h); + void GetClipRect(int *x, int *y, int *w, int *h); + + virtual void Draw2D() {} + void Clear2D() { m2DDrawer.Clear(); } + + // Dim part of the canvas + void Dim(PalEntry color, float amount, int x1, int y1, int w, int h, FRenderStyle *style = nullptr); + void DoDim(PalEntry color, float amount, int x1, int y1, int w, int h, FRenderStyle *style = nullptr); + + // Fill an area with a texture + void FlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin = false); + + // Fill a simple polygon with a texture + void FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, + double originx, double originy, double scalex, double scaley, DAngle rotation, + const FColormap &colormap, PalEntry flatcolor, int lightlevel, int bottomclip); + + // Set an area to a specified color + void Clear(int left, int top, int right, int bottom, int palcolor, uint32_t color); + + // Draws a line + void DrawLine(int x0, int y0, int x1, int y1, int palColor, uint32_t realcolor); + + // Draws a single pixel + void DrawPixel(int x, int y, int palcolor, uint32_t rgbcolor); + + + bool SetTextureParms(DrawParms *parms, FTexture *img, double x, double y) const; + void DrawTexture(FTexture *img, double x, double y, int tags, ...); + void DrawTexture(FTexture *img, double x, double y, VMVa_List &); + void FillBorder(FTexture *img); // Fills the border around a 4:3 part of the screen on non-4:3 displays + void VirtualToRealCoords(double &x, double &y, double &w, double &h, double vwidth, double vheight, bool vbottom = false, bool handleaspect = true) const; + + // Code that uses these (i.e. SBARINFO) should probably be evaluated for using doubles all around instead. + void VirtualToRealCoordsInt(int &x, int &y, int &w, int &h, int vwidth, int vheight, bool vbottom = false, bool handleaspect = true) const; + + // Text drawing functions ----------------------------------------------- + +#ifdef DrawText +#undef DrawText // See WinUser.h for the definition of DrawText as a macro #endif + // 2D Text drawing + void DrawText(FFont *font, int normalcolor, double x, double y, const char *string, int tag_first, ...); + void DrawText(FFont *font, int normalcolor, double x, double y, const char *string, VMVa_List &args); + void DrawChar(FFont *font, int normalcolor, double x, double y, int character, int tag_first, ...); + void DrawChar(FFont *font, int normalcolor, double x, double y, int character, VMVa_List &args); + + void DrawFrame(int left, int top, int width, int height); + void DrawBorder(int x1, int y1, int x2, int y2); + void DrawViewBorder(); + void RefreshViewBorder(); + + // Calculate gamma table + void CalcGamma(float gamma, uint8_t gammalookup[256]); + + + // Retrieves a buffer containing image data for a screenshot. + // Hint: Pitch can be negative for upside-down images, in which case buffer + // points to the last row in the buffer, which will be the first row output. + virtual void GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type, float &gamma) {} + + // Releases the screenshot buffer. + virtual void ReleaseScreenshotBuffer() {} // The original size of the framebuffer as selected in the video menu. int VideoWidth = 0; @@ -463,8 +454,6 @@ public: protected: void DrawRateStuff (); - void CopyFromBuff (uint8_t *src, int srcPitch, int width, int height, uint8_t *dest); - void CopyWithGammaBgra(void *output, int pitch, const uint8_t *gammared, const uint8_t *gammagreen, const uint8_t *gammablue, PalEntry flash, int flash_amount); DFrameBuffer () {} @@ -483,54 +472,6 @@ extern DFrameBuffer *screen; EXTERN_CVAR (Float, Gamma) -// Translucency tables - -// RGB32k is a normal R5G5B5 -> palette lookup table. - -// Use a union so we can "overflow" without warnings. -// Otherwise, we get stuff like this from Clang (when compiled -// with -fsanitize=bounds) while running: -// src/v_video.cpp:390:12: runtime error: index 1068 out of bounds for type 'uint8_t [32]' -// src/r_draw.cpp:273:11: runtime error: index 1057 out of bounds for type 'uint8_t [32]' -union ColorTable32k -{ - uint8_t RGB[32][32][32]; - uint8_t All[32 *32 *32]; -}; -extern ColorTable32k RGB32k; - -// [SP] RGB666 support -union ColorTable256k -{ - uint8_t RGB[64][64][64]; - uint8_t All[64 *64 *64]; -}; -extern ColorTable256k RGB256k; - -// Col2RGB8 is a pre-multiplied palette for color lookup. It is stored in a -// special R10B10G10 format for efficient blending computation. -// --RRRRRrrr--BBBBBbbb--GGGGGggg-- at level 64 -// --------rrrr------bbbb------gggg at level 1 -extern uint32_t Col2RGB8[65][256]; - -// Col2RGB8_LessPrecision is the same as Col2RGB8, but the LSB for red -// and blue are forced to zero, so if the blend overflows, it won't spill -// over into the next component's value. -// --RRRRRrrr-#BBBBBbbb-#GGGGGggg-- at level 64 -// --------rrr#------bbb#------gggg at level 1 -extern uint32_t *Col2RGB8_LessPrecision[65]; - -// Col2RGB8_Inverse is the same as Col2RGB8_LessPrecision, except the source -// palette has been inverted. -extern uint32_t Col2RGB8_Inverse[65][256]; - -// "Magic" numbers used during the blending: -// --000001111100000111110000011111 = 0x01f07c1f -// -0111111111011111111101111111111 = 0x3FEFFBFF -// -1000000000100000000010000000000 = 0x40100400 -// ------10000000001000000000100000 = 0x40100400 >> 5 -// --11111-----11111-----11111----- = 0x40100400 - (0x40100400 >> 5) aka "white" -// --111111111111111111111111111111 = 0x3FFFFFFF // Allocates buffer screens, call before R_Init. void V_Init (bool restart); @@ -552,13 +493,6 @@ FString V_GetColorStringByName (const char *name, FScriptPosition *sc = nullptr) // Tries to get color by name, then by string int V_GetColor (const uint32_t *palette, const char *str, FScriptPosition *sc = nullptr); int V_GetColor(const uint32_t *palette, FScanner &sc); -void V_DrawFrame (int left, int top, int width, int height); - -// If the view size is not full screen, draws a border around it. -void V_DrawBorder (int x1, int y1, int x2, int y2); -void V_RefreshViewBorder (); - -void V_SetBorderNeedRefresh(); int CheckRatio (int width, int height, int *trueratio=NULL); static inline int CheckRatio (double width, double height) { return CheckRatio(int(width), int(height)); } diff --git a/src/vectors.h b/src/vectors.h index 95d7c5fdf7..ce1f043afc 100644 --- a/src/vectors.h +++ b/src/vectors.h @@ -272,7 +272,7 @@ struct TVector2 // Dot product - double operator | (const TVector2 &other) const + vec_t operator | (const TVector2 &other) const { return X*other.X + Y*other.Y; } @@ -1673,4 +1673,48 @@ typedef TRotator DRotator; typedef TMatrix3x3 DMatrix3x3; typedef TAngle DAngle; + +class Plane +{ +public: + void Set(FVector3 normal, float d) + { + m_normal = normal; + m_d = d; + } + + // same for a play-vector. Note that y and z are inversed. + void Set(DVector3 normal, double d) + { + m_normal = { (float)normal.X, (float)normal.Z, (float)normal.Y }; + m_d = (float)d; + } + + float DistToPoint(float x, float y, float z) + { + FVector3 p(x, y, z); + + return (m_normal | p) + m_d; + } + + + bool PointOnSide(float x, float y, float z) + { + return DistToPoint(x, y, z) < 0.f; + } + + bool PointOnSide(FVector3 &v) { return PointOnSide(v.X, v.Y, v.Z); } + bool ValidNormal() { return m_normal.LengthSquared() == 1.f; } + + float A() { return m_normal.X; } + float B() { return m_normal.Y; } + float C() { return m_normal.Z; } + float D() { return m_d; } + + const FVector3 &Normal() const { return m_normal; } +protected: + FVector3 m_normal; + float m_d; +}; + #endif diff --git a/src/w_wad.cpp b/src/w_wad.cpp index 31e65cd9bc..0976f5ed77 100644 --- a/src/w_wad.cpp +++ b/src/w_wad.cpp @@ -109,6 +109,7 @@ void uppercopy (char *to, const char *from) FWadCollection::FWadCollection () : FirstLumpIndex(NULL), NextLumpIndex(NULL), FirstLumpIndex_FullName(NULL), NextLumpIndex_FullName(NULL), + FirstLumpIndex_NoExt(NULL), NextLumpIndex_NoExt(NULL), NumLumps(0) { } @@ -140,11 +141,21 @@ void FWadCollection::DeleteAll () delete[] NextLumpIndex_FullName; NextLumpIndex_FullName = NULL; } + if (FirstLumpIndex_NoExt != NULL) + { + delete[] FirstLumpIndex_NoExt; + FirstLumpIndex_NoExt = NULL; + } + if (NextLumpIndex_NoExt != NULL) + { + delete[] NextLumpIndex_NoExt; + NextLumpIndex_NoExt = NULL; + } LumpInfo.Clear(); NumLumps = 0; - // we must count backward to enssure that embedded WADs are deleted before + // we must count backward to ensure that embedded WADs are deleted before // the ones that contain their data. for (int i = Files.Size() - 1; i >= 0; --i) { @@ -192,6 +203,8 @@ void FWadCollection::InitMultipleFiles (TArray &filenames) NextLumpIndex = new uint32_t[NumLumps]; FirstLumpIndex_FullName = new uint32_t[NumLumps]; NextLumpIndex_FullName = new uint32_t[NumLumps]; + FirstLumpIndex_NoExt = new uint32_t[NumLumps]; + NextLumpIndex_NoExt = new uint32_t[NumLumps]; InitHashChains (); LumpInfo.ShrinkToFit(); Files.ShrinkToFit(); @@ -533,7 +546,7 @@ int FWadCollection::GetNumForName (const char *name, int space) // //========================================================================== -int FWadCollection::CheckNumForFullName (const char *name, bool trynormal, int namespc) +int FWadCollection::CheckNumForFullName (const char *name, bool trynormal, int namespc, bool ignoreext) { uint32_t i; @@ -541,12 +554,19 @@ int FWadCollection::CheckNumForFullName (const char *name, bool trynormal, int n { return -1; } + uint32_t *fli = ignoreext ? FirstLumpIndex_NoExt : FirstLumpIndex_FullName; + uint32_t *nli = ignoreext ? NextLumpIndex_NoExt : NextLumpIndex_FullName; + auto len = strlen(name); - i = FirstLumpIndex_FullName[MakeKey(name) % NumLumps]; - - while (i != NULL_INDEX && stricmp(name, LumpInfo[i].lump->FullName)) + for (i = fli[MakeKey(name) % NumLumps]; i != NULL_INDEX; i = nli[i]) { - i = NextLumpIndex_FullName[i]; + if (strnicmp(name, LumpInfo[i].lump->FullName, len)) continue; + if (LumpInfo[i].lump->FullName[len] == 0) break; // this is a full match + if (ignoreext && LumpInfo[i].lump->FullName[len] == '.') + { + // is this the last '.' in the last path element, indicating that the remaining part of the name is only an extension? + if (strpbrk(LumpInfo[i].lump->FullName.GetChars() + len + 1, "./") == nullptr) break; + } } if (i != NULL_INDEX) return i; @@ -733,6 +753,8 @@ void FWadCollection::InitHashChains (void) memset (NextLumpIndex, 255, NumLumps*sizeof(NextLumpIndex[0])); memset (FirstLumpIndex_FullName, 255, NumLumps*sizeof(FirstLumpIndex_FullName[0])); memset (NextLumpIndex_FullName, 255, NumLumps*sizeof(NextLumpIndex_FullName[0])); + memset(FirstLumpIndex_NoExt, 255, NumLumps * sizeof(FirstLumpIndex_NoExt[0])); + memset(NextLumpIndex_NoExt, 255, NumLumps * sizeof(NextLumpIndex_NoExt[0])); // Now set up the chains for (i = 0; i < (unsigned)NumLumps; i++) @@ -748,6 +770,16 @@ void FWadCollection::InitHashChains (void) j = MakeKey(LumpInfo[i].lump->FullName) % NumLumps; NextLumpIndex_FullName[i] = FirstLumpIndex_FullName[j]; FirstLumpIndex_FullName[j] = i; + + FString nameNoExt = LumpInfo[i].lump->FullName; + auto dot = nameNoExt.LastIndexOf('.'); + auto slash = nameNoExt.LastIndexOf('/'); + if (dot > slash) nameNoExt.Truncate(dot); + + j = MakeKey(nameNoExt) % NumLumps; + NextLumpIndex_NoExt[i] = FirstLumpIndex_NoExt[j]; + FirstLumpIndex_NoExt[j] = i; + } } } diff --git a/src/w_wad.h b/src/w_wad.h index 9f33ac2c1c..30d73d33eb 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -135,7 +135,7 @@ public: inline int GetNumForName (const uint8_t *name) { return GetNumForName ((const char *)name); } inline int GetNumForName (const uint8_t *name, int ns) { return GetNumForName ((const char *)name, ns); } - int CheckNumForFullName (const char *name, bool trynormal = false, int namespc = ns_global); + int CheckNumForFullName (const char *name, bool trynormal = false, int namespc = ns_global, bool ignoreext = false); int CheckNumForFullName (const char *name, int wadfile); int GetNumForFullName (const char *name); @@ -194,6 +194,9 @@ protected: uint32_t *FirstLumpIndex_FullName; // The same information for fully qualified paths from .zips uint32_t *NextLumpIndex_FullName; + uint32_t *FirstLumpIndex_NoExt; // The same information for fully qualified paths from .zips + uint32_t *NextLumpIndex_NoExt; + uint32_t NumLumps; // Not necessarily the same as LumpInfo.Size() uint32_t NumWads; diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp index d60af2165f..1c2530646f 100644 --- a/src/wi_stuff.cpp +++ b/src/wi_stuff.cpp @@ -228,8 +228,8 @@ private: right = c[i]->GetScaledWidth(); bottom = c[i]->GetScaledHeight(); - left = lnodes[n].x - c[i]->GetScaledLeftOffset(); - top = lnodes[n].y - c[i]->GetScaledTopOffset(); + left = lnodes[n].x - c[i]->GetScaledLeftOffset(0); + top = lnodes[n].y - c[i]->GetScaledTopOffset(0); right += left; bottom += top; diff --git a/src/win32/fb_d3d9.cpp b/src/win32/fb_d3d9.cpp deleted file mode 100644 index 7e35c55b17..0000000000 --- a/src/win32/fb_d3d9.cpp +++ /dev/null @@ -1,3902 +0,0 @@ -/* -** fb_d3d9.cpp -** Code to let ZDoom use Direct3D 9 as a simple framebuffer -** -**--------------------------------------------------------------------------- -** Copyright 1998-2011 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -** This file does _not_ implement hardware-acclerated 3D rendering. It is -** just a means of getting the pixel data to the screen in a more reliable -** method on modern hardware by copying the entire frame to a texture, -** drawing that to the screen, and presenting. -** -** That said, it does implement hardware-accelerated 2D rendering. -*/ - -// HEADER FILES ------------------------------------------------------------ - -#ifdef _DEBUG -#define D3D_DEBUG_INFO -#endif -#define DIRECT3D_VERSION 0x0900 -#define WIN32_LEAN_AND_MEAN - -#include -#include - -#include - -#include "doomtype.h" - -#include "c_dispatch.h" -#include "templates.h" -#include "i_system.h" -#include "i_video.h" -#include "i_input.h" -#include "v_video.h" -#include "v_pfx.h" -#include "stats.h" -#include "doomerrors.h" -#include "r_data/r_translate.h" -#include "f_wipe.h" -#include "sbar.h" -#include "win32iface.h" -#include "win32swiface.h" -#include "doomstat.h" -#include "v_palette.h" -#include "w_wad.h" -#include "textures.h" -#include "r_data/colormaps.h" -#include "SkylineBinPack.h" -#include "swrenderer/scene/r_light.h" - -// MACROS ------------------------------------------------------------------ - -// The number of points for the vertex buffer. -#define NUM_VERTS 10240 - -// The number of indices for the index buffer. -#define NUM_INDEXES ((NUM_VERTS * 6) / 4) - -// The number of quads we can batch together. -#define MAX_QUAD_BATCH (NUM_INDEXES / 6) - -// The default size for a texture atlas. -#define DEF_ATLAS_WIDTH 512 -#define DEF_ATLAS_HEIGHT 512 - -// TYPES ------------------------------------------------------------------- - -struct D3DFB::PackedTexture -{ - D3DFB::Atlas *Owner; - - PackedTexture **Prev, *Next; - - // Pixels this image covers - RECT Area; - - // Texture coordinates for this image - float Left, Top, Right, Bottom; - - // Texture has extra space on the border? - bool Padded; -}; - -struct D3DFB::Atlas -{ - Atlas(D3DFB *fb, int width, int height, D3DFORMAT format); - ~Atlas(); - - PackedTexture *AllocateImage(const Rect &rect, bool padded); - void FreeBox(PackedTexture *box); - - SkylineBinPack Packer; - Atlas *Next; - IDirect3DTexture9 *Tex; - D3DFORMAT Format; - PackedTexture *UsedList; // Boxes that contain images - int Width, Height; - bool OneUse; -}; - -class D3DTex : public FNativeTexture -{ -public: - D3DTex(FTexture *tex, FTextureFormat fmt, D3DFB *fb, bool wrapping); - ~D3DTex(); - - D3DFB::PackedTexture *Box; - - D3DTex **Prev; - D3DTex *Next; - - bool IsGray; - - bool Create(D3DFB *fb, bool wrapping); - bool Update(); - bool CheckWrapping(bool wrapping); - D3DFORMAT GetTexFormat(); -}; - -class D3DPal : public FNativePalette -{ -public: - D3DPal(FRemapTable *remap, D3DFB *fb); - ~D3DPal(); - - D3DPal **Prev; - D3DPal *Next; - - IDirect3DTexture9 *Tex; - D3DCOLOR BorderColor; - bool DoColorSkip; - - bool Update(); - - FRemapTable *Remap; - int RoundedPaletteSize; -}; - -// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- - -// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- - -void DoBlending (const PalEntry *from, PalEntry *to, int count, int r, int g, int b, int a); - -// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- - -// EXTERNAL DATA DECLARATIONS ---------------------------------------------- - -extern HWND Window; -extern IVideo *Video; -extern BOOL AppActive; -extern int SessionState; -extern bool VidResizing; - -EXTERN_CVAR (Bool, fullscreen) -EXTERN_CVAR (Float, Gamma) -EXTERN_CVAR (Bool, vid_vsync) -EXTERN_CVAR (Float, transsouls) -EXTERN_CVAR (Int, vid_refreshrate) - -extern IDirect3D9 *D3D; - -extern cycle_t BlitCycles; - -// PRIVATE DATA DEFINITIONS ------------------------------------------------ - -const char *const D3DFB::ShaderNames[D3DFB::NUM_SHADERS] = -{ - "NormalColor.pso", - "NormalColorPal.pso", - "NormalColorInv.pso", - "NormalColorPalInv.pso", - - "RedToAlpha.pso", - "RedToAlphaInv.pso", - - "VertexColor.pso", - - "SpecialColormap.pso", - "SpecialColorMapPal.pso", - - "InGameColormap.pso", - "InGameColormapDesat.pso", - "InGameColormapInv.pso", - "InGameColormapInvDesat.pso", - "InGameColormapPal.pso", - "InGameColormapPalDesat.pso", - "InGameColormapPalInv.pso", - "InGameColormapPalInvDesat.pso", - - "BurnWipe.pso", - "GammaCorrection.pso", -}; - -// PUBLIC DATA DEFINITIONS ------------------------------------------------- - -CUSTOM_CVAR(Bool, vid_hw2d, true, CVAR_NOINITCALL) -{ - V_SetBorderNeedRefresh(); -} - -CVAR(Bool, d3d_antilag, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -CVAR(Int, d3d_showpacks, 0, 0) -CVAR(Bool, vid_hwaalines, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) - -// CODE -------------------------------------------------------------------- - -//========================================================================== -// -// D3DFB - Constructor -// -//========================================================================== - -D3DFB::D3DFB (UINT adapter, int width, int height, bool bgra, bool fullscreen) - : BaseWinFB (width, height, bgra) -{ - D3DPRESENT_PARAMETERS d3dpp; - - LastHR = 0; - - Adapter = adapter; - D3DDevice = NULL; - VertexBuffer = NULL; - IndexBuffer = NULL; - FBTexture = NULL; - TempRenderTexture = NULL; - RenderTexture[0] = NULL; - RenderTexture[1] = NULL; - InitialWipeScreen = NULL; - ScreenshotTexture = NULL; - ScreenshotSurface = NULL; - FinalWipeScreen = NULL; - PaletteTexture = NULL; - GammaTexture = NULL; - FrontCopySurface = NULL; - for (int i = 0; i < NUM_SHADERS; ++i) - { - Shaders[i] = NULL; - } - GammaShader = NULL; - BlockSurface[0] = NULL; - BlockSurface[1] = NULL; - VSync = vid_vsync; - BlendingRect.left = 0; - BlendingRect.top = 0; - BlendingRect.right = FBWidth; - BlendingRect.bottom = FBHeight; - In2D = 0; - Palettes = NULL; - Textures = NULL; - Accel2D = true; - GatheringWipeScreen = false; - ScreenWipe = NULL; - InScene = false; - QuadExtra = new BufferedTris[MAX_QUAD_BATCH]; - Atlases = NULL; - PixelDoubling = 0; - SkipAt = -1; - CurrRenderTexture = 0; - RenderTextureToggle = 0; - - Gamma = 1.0; - FlashColor0 = 0; - FlashColor1 = 0xFFFFFFFF; - FlashColor = 0; - FlashAmount = 0; - - NeedGammaUpdate = false; - NeedPalUpdate = false; - - if (MemBuffer == NULL) - { - return; - } - - memcpy(SourcePalette, GPalette.BaseColors, sizeof(PalEntry)*256); - - Windowed = !(static_cast(Video)->GoFullscreen(fullscreen)); - - TrueHeight = height; - if (fullscreen) - { - for (Win32Video::ModeInfo *mode = static_cast(Video)->m_Modes; mode != NULL; mode = mode->next) - { - if (mode->width == Width && mode->height == Height) - { - TrueHeight = mode->realheight; - PixelDoubling = mode->doubling; - break; - } - } - } - // Offset from top of screen to top of letterboxed screen - LBOffsetI = (TrueHeight - Height) / 2; - LBOffset = float(LBOffsetI); - - FillPresentParameters(&d3dpp, fullscreen, VSync); - - HRESULT hr; - - LOG("CreateDevice attempt 1 hwvp\n"); - if (FAILED(hr = D3D->CreateDevice(Adapter, D3DDEVTYPE_HAL, Window, - D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, &d3dpp, &D3DDevice)) && - (hr != D3DERR_DEVICELOST || D3DDevice == NULL)) - { - LOG2("CreateDevice returned hr %08x dev %p; attempt 2 swvp\n", hr, D3DDevice); - if (FAILED(D3D->CreateDevice(Adapter, D3DDEVTYPE_HAL, Window, - D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, &d3dpp, &D3DDevice)) && - (hr != D3DERR_DEVICELOST || D3DDevice == NULL)) - { - if (d3dpp.FullScreen_RefreshRateInHz != 0) - { - d3dpp.FullScreen_RefreshRateInHz = 0; - LOG2("CreateDevice returned hr %08x dev %p; attempt 3 (hwvp, default Hz)\n", hr, D3DDevice); - if (FAILED(hr = D3D->CreateDevice(Adapter, D3DDEVTYPE_HAL, Window, - D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, &d3dpp, &D3DDevice)) && - (hr != D3DERR_DEVICELOST || D3DDevice == NULL)) - { - LOG2("CreateDevice returned hr %08x dev %p; attempt 4 (swvp, default Hz)\n", hr, D3DDevice); - if (FAILED(D3D->CreateDevice(Adapter, D3DDEVTYPE_HAL, Window, - D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, &d3dpp, &D3DDevice)) && - hr != D3DERR_DEVICELOST) - { - D3DDevice = NULL; - } - } - } - } - } - LOG2("Final CreateDevice returned HR %08x and device %p\n", hr, D3DDevice); - LastHR = hr; - if (D3DDevice != NULL) - { - D3DADAPTER_IDENTIFIER9 adapter_id; - D3DDEVICE_CREATION_PARAMETERS create_params; - - if (FAILED(hr = D3DDevice->GetDeviceCaps(&DeviceCaps))) - { - memset(&DeviceCaps, 0, sizeof(DeviceCaps)); - } - if (SUCCEEDED(hr = D3DDevice->GetCreationParameters(&create_params)) && - SUCCEEDED(hr = D3D->GetAdapterIdentifier(create_params.AdapterOrdinal, 0, &adapter_id))) - { - // NVidia's drivers lie, claiming they don't support - // antialiased lines when, really, they do. - if (adapter_id.VendorId == 0x10de) - { - DeviceCaps.LineCaps |= D3DLINECAPS_ANTIALIAS; - } - // ATI's drivers apparently also lie, so screw this caps bit. - } - CreateResources(); - SetInitialState(); - } -} - -//========================================================================== -// -// D3DFB - Destructor -// -//========================================================================== - -D3DFB::~D3DFB () -{ - ReleaseResources(); - SAFE_RELEASE( D3DDevice ); - delete[] QuadExtra; -} - -//========================================================================== -// -// D3DFB :: SetInitialState -// -// Called after initial device creation and reset, when everything is set -// to D3D's defaults. -// -//========================================================================== - -void D3DFB::SetInitialState() -{ - AlphaBlendEnabled = FALSE; - AlphaBlendOp = D3DBLENDOP_ADD; - AlphaSrcBlend = D3DBLEND(0); - AlphaDestBlend = D3DBLEND(0); - - CurPixelShader = NULL; - memset(Constant, 0, sizeof(Constant)); - - for (unsigned i = 0; i < countof(Texture); ++i) - { - Texture[i] = NULL; - D3DDevice->SetSamplerState(i, D3DSAMP_ADDRESSU, (i == 1 && SM14) ? D3DTADDRESS_BORDER : D3DTADDRESS_CLAMP); - D3DDevice->SetSamplerState(i, D3DSAMP_ADDRESSV, (i == 1 && SM14) ? D3DTADDRESS_BORDER : D3DTADDRESS_CLAMP); - if (i > 1) - { - // Set linear filtering for the SM14 gamma texture. - D3DDevice->SetSamplerState(i, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - } - } - - NeedGammaUpdate = true; - NeedPalUpdate = true; - OldRenderTarget = NULL; - - if (!Windowed && SM14) - { - // Fix for Radeon 9000, possibly other R200s: When the device is - // reset, it resets the gamma ramp, but the driver apparently keeps a - // cached copy of the ramp that it doesn't update, so when - // SetGammaRamp is called later to handle the NeedGammaUpdate flag, - // it doesn't do anything, because the gamma ramp is the same as the - // one passed in the last call, even though the visible gamma ramp - // actually has changed. - // - // So here we force the gamma ramp to something absolutely horrible and - // trust that we will be able to properly set the gamma later when - // NeedGammaUpdate is handled. - D3DGAMMARAMP ramp; - memset(&ramp, 0, sizeof(ramp)); - D3DDevice->SetGammaRamp(0, 0, &ramp); - } - - // This constant is used for grayscaling weights (.xyz) and color inversion (.w) - float weights[4] = { 77/256.f, 143/256.f, 37/256.f, 1 }; - D3DDevice->SetPixelShaderConstantF(PSCONST_Weights, weights, 1); - - // D3DRS_ALPHATESTENABLE defaults to FALSE - // D3DRS_ALPHAREF defaults to 0 - D3DDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_NOTEQUAL); - AlphaTestEnabled = FALSE; - - CurBorderColor = 0; - - // Clear to black, just in case it wasn't done already. - D3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 0, 0); -} - -//========================================================================== -// -// D3DFB :: FillPresentParameters -// -//========================================================================== - -void D3DFB::FillPresentParameters (D3DPRESENT_PARAMETERS *pp, bool fullscreen, bool vsync) -{ - memset (pp, 0, sizeof(*pp)); - pp->Windowed = !fullscreen; - pp->SwapEffect = D3DSWAPEFFECT_DISCARD; - pp->BackBufferWidth = Width << PixelDoubling; - pp->BackBufferHeight = TrueHeight << PixelDoubling; - pp->BackBufferFormat = fullscreen ? D3DFMT_A8R8G8B8 : D3DFMT_UNKNOWN; - pp->BackBufferCount = 1; - pp->hDeviceWindow = Window; - pp->PresentationInterval = vsync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE; - if (fullscreen) - { - pp->FullScreen_RefreshRateInHz = vid_refreshrate; - } -} - -//========================================================================== -// -// D3DFB :: CreateResources -// -//========================================================================== - -bool D3DFB::CreateResources() -{ - Atlases = NULL; - if (!Windowed) - { - // Remove the window border in fullscreen mode - SetWindowLong (Window, GWL_STYLE, WS_POPUP|WS_VISIBLE|WS_SYSMENU); - } - else - { - // Resize the window to match desired dimensions - RECT rect = { 0, 0, Width, Height }; - AdjustWindowRectEx(&rect, WS_VISIBLE|WS_OVERLAPPEDWINDOW, FALSE, WS_EX_APPWINDOW); - int sizew = rect.right - rect.left; - int sizeh = rect.bottom - rect.top; - LOG2 ("Resize window to %dx%d\n", sizew, sizeh); - VidResizing = true; - // Make sure the window has a border in windowed mode - SetWindowLong(Window, GWL_STYLE, WS_VISIBLE|WS_OVERLAPPEDWINDOW); - if (GetWindowLong(Window, GWL_EXSTYLE) & WS_EX_TOPMOST) - { - // Direct3D 9 will apparently add WS_EX_TOPMOST to fullscreen windows, - // and removing it is a little tricky. Using SetWindowLongPtr to clear it - // will not do the trick, but sending the window behind everything will. - SetWindowPos(Window, HWND_BOTTOM, 0, 0, sizew, sizeh, - SWP_DRAWFRAME | SWP_NOCOPYBITS | SWP_NOMOVE); - SetWindowPos(Window, HWND_TOP, 0, 0, 0, 0, SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOSIZE); - } - else - { - SetWindowPos(Window, NULL, 0, 0, sizew, sizeh, - SWP_DRAWFRAME | SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOZORDER); - } - I_RestoreWindowedPos(); - VidResizing = false; - } - if (!LoadShaders()) - { - return false; - } - if (!CreateFBTexture() || - !CreatePaletteTexture()) - { - return false; - } - if (!CreateVertexes()) - { - return false; - } - CreateGammaTexture(); - CreateBlockSurfaces(); - return true; -} - -//========================================================================== -// -// D3DFB :: LoadShaders -// -// Returns true if all required shaders were loaded. (Gamma and burn wipe -// are the only ones not considered "required".) -// -//========================================================================== - -bool D3DFB::LoadShaders() -{ - static const char models[][4] = { "30/", "20/", "14/" }; - FString shaderdir, shaderpath; - unsigned model, i; - int lump; - - // We determine the best available model simply by trying them all in - // order of decreasing preference. - for (model = 0; model < countof(models); ++model) - { - shaderdir = "shaders/d3d/sm"; - shaderdir += models[model]; - for (i = 0; i < NUM_SHADERS; ++i) - { - shaderpath = shaderdir; - shaderpath += ShaderNames[i]; - lump = Wads.CheckNumForFullName(shaderpath); - if (lump >= 0) - { - FMemLump data = Wads.ReadLump(lump); - if (FAILED(D3DDevice->CreatePixelShader((DWORD *)data.GetMem(), &Shaders[i])) && - i < SHADER_BurnWipe) - { - break; - } - } - } - if (i == NUM_SHADERS) - { // Success! - SM14 = (model == countof(models) - 1); - return true; - } - // Failure. Release whatever managed to load (which is probably nothing.) - for (i = 0; i < NUM_SHADERS; ++i) - { - SAFE_RELEASE( Shaders[i] ); - } - } - return false; -} - -//========================================================================== -// -// D3DFB :: ReleaseResources -// -//========================================================================== - -void D3DFB::ReleaseResources () -{ - I_SaveWindowedPos (); - KillNativeTexs(); - KillNativePals(); - ReleaseDefaultPoolItems(); - SAFE_RELEASE( ScreenshotSurface ); - SAFE_RELEASE( ScreenshotTexture ); - SAFE_RELEASE( PaletteTexture ); - for (int i = 0; i < NUM_SHADERS; ++i) - { - SAFE_RELEASE( Shaders[i] ); - } - GammaShader = NULL; - if (ScreenWipe != NULL) - { - delete ScreenWipe; - ScreenWipe = NULL; - } - Atlas *pack, *next; - for (pack = Atlases; pack != NULL; pack = next) - { - next = pack->Next; - delete pack; - } - GatheringWipeScreen = false; -} - -//========================================================================== -// -// D3DFB :: ReleaseDefaultPoolItems -// -// Free resources created with D3DPOOL_DEFAULT. -// -//========================================================================== - -void D3DFB::ReleaseDefaultPoolItems() -{ - SAFE_RELEASE( FBTexture ); - SAFE_RELEASE( FinalWipeScreen ); - SAFE_RELEASE( RenderTexture[0] ); - SAFE_RELEASE( RenderTexture[1] ); - SAFE_RELEASE( InitialWipeScreen ); - SAFE_RELEASE( VertexBuffer ); - SAFE_RELEASE( IndexBuffer ); - SAFE_RELEASE( BlockSurface[0] ); - SAFE_RELEASE( BlockSurface[1] ); - SAFE_RELEASE( FrontCopySurface ); -} - -//========================================================================== -// -// D3DFB :: Reset -// -//========================================================================== - -bool D3DFB::Reset () -{ - D3DPRESENT_PARAMETERS d3dpp; - - ReleaseDefaultPoolItems(); - FillPresentParameters (&d3dpp, !Windowed, VSync); - if (!SUCCEEDED(D3DDevice->Reset (&d3dpp))) - { - if (d3dpp.FullScreen_RefreshRateInHz != 0) - { - d3dpp.FullScreen_RefreshRateInHz = 0; - if (!SUCCEEDED(D3DDevice->Reset (&d3dpp))) - { - return false; - } - } - else - { - return false; - } - } - LOG("Device was reset\n"); - if (!CreateFBTexture() || !CreateVertexes()) - { - return false; - } - CreateBlockSurfaces(); - SetInitialState(); - return true; -} - -//========================================================================== -// -// D3DFB :: CreateBlockSurfaces -// -// Create blocking surfaces for antilag. It's okay if these can't be -// created; antilag just won't work. -// -//========================================================================== - -void D3DFB::CreateBlockSurfaces() -{ - BlockNum = 0; - if (SUCCEEDED(D3DDevice->CreateOffscreenPlainSurface(16, 16, D3DFMT_A8R8G8B8, - D3DPOOL_DEFAULT, &BlockSurface[0], 0))) - { - if (FAILED(D3DDevice->CreateOffscreenPlainSurface(16, 16, D3DFMT_A8R8G8B8, - D3DPOOL_DEFAULT, &BlockSurface[1], 0))) - { - BlockSurface[0]->Release(); - BlockSurface[0] = NULL; - } - } -} - -//========================================================================== -// -// D3DFB :: KillNativePals -// -// Frees all native palettes. -// -//========================================================================== - -void D3DFB::KillNativePals() -{ - while (Palettes != NULL) - { - delete Palettes; - } -} - -//========================================================================== -// -// D3DFB :: KillNativeTexs -// -// Frees all native textures. -// -//========================================================================== - -void D3DFB::KillNativeTexs() -{ - while (Textures != NULL) - { - delete Textures; - } -} - -//========================================================================== -// -// D3DFB :: CreateFBTexture -// -// Creates the "Framebuffer" texture. With the advent of hardware-assisted -// 2D, this is something of a misnomer now. The FBTexture is only used for -// uploading the software 3D image to video memory so that it can be drawn -// to the real frame buffer. -// -// It also creates the TempRenderTexture, since this seemed like a -// convenient place to do so. -// -//========================================================================== - -bool D3DFB::CreateFBTexture () -{ - FBFormat = IsBgra() ? D3DFMT_A8R8G8B8 : D3DFMT_L8; - - if (FAILED(D3DDevice->CreateTexture(Width, Height, 1, D3DUSAGE_DYNAMIC, FBFormat, D3DPOOL_DEFAULT, &FBTexture, NULL))) - { - int pow2width, pow2height, i; - - for (i = 1; i < Width; i <<= 1) {} pow2width = i; - for (i = 1; i < Height; i <<= 1) {} pow2height = i; - - if (FAILED(D3DDevice->CreateTexture(pow2width, pow2height, 1, D3DUSAGE_DYNAMIC, FBFormat, D3DPOOL_DEFAULT, &FBTexture, NULL))) - { - return false; - } - else - { - FBWidth = pow2width; - FBHeight = pow2height; - } - } - else - { - FBWidth = Width; - FBHeight = Height; - } - RenderTextureToggle = 0; - RenderTexture[0] = NULL; - RenderTexture[1] = NULL; - if (FAILED(D3DDevice->CreateTexture(FBWidth, FBHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &RenderTexture[0], NULL))) - { - return false; - } - if (Windowed || PixelDoubling) - { - // Windowed or pixel doubling: Create another render texture so we can flip between them. - RenderTextureToggle = 1; - if (FAILED(D3DDevice->CreateTexture(FBWidth, FBHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &RenderTexture[1], NULL))) - { - return false; - } - } - else - { - // Fullscreen and not pixel doubling: Create a render target to have the back buffer copied to. - if (FAILED(D3DDevice->CreateRenderTarget(Width, Height, D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &FrontCopySurface, NULL))) - { - return false; - } - } - // Initialize the TempRenderTextures to black. - for (int i = 0; i <= RenderTextureToggle; ++i) - { - IDirect3DSurface9 *surf; - if (SUCCEEDED(RenderTexture[i]->GetSurfaceLevel(0, &surf))) - { - D3DDevice->ColorFill(surf, NULL, D3DCOLOR_XRGB(0,0,0)); - surf->Release(); - } - } - TempRenderTexture = RenderTexture[0]; - CurrRenderTexture = 0; - return true; -} - -//========================================================================== -// -// D3DFB :: CreatePaletteTexture -// -//========================================================================== - -bool D3DFB::CreatePaletteTexture () -{ - if (FAILED(D3DDevice->CreateTexture (256, 1, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &PaletteTexture, NULL))) - { - return false; - } - return true; -} - -//========================================================================== -// -// D3DFB :: CreateGammaTexture -// -//========================================================================== - -bool D3DFB::CreateGammaTexture () -{ - // If this fails, you just won't get gamma correction in a window - // on SM14 cards. - assert(GammaTexture == NULL); - if (SM14) - { - return SUCCEEDED(D3DDevice->CreateTexture(256, 1, 1, 0, D3DFMT_A8R8G8B8, - D3DPOOL_MANAGED, &GammaTexture, NULL)); - } - return false; -} - -//========================================================================== -// -// D3DFB :: CreateVertexes -// -//========================================================================== - -bool D3DFB::CreateVertexes () -{ - VertexPos = -1; - IndexPos = -1; - QuadBatchPos = -1; - BatchType = BATCH_None; - if (FAILED(D3DDevice->CreateVertexBuffer(sizeof(FBVERTEX)*NUM_VERTS, - D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_FBVERTEX, D3DPOOL_DEFAULT, &VertexBuffer, NULL))) - { - return false; - } - if (FAILED(D3DDevice->CreateIndexBuffer(sizeof(uint16_t)*NUM_INDEXES, - D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &IndexBuffer, NULL))) - { - return false; - } - return true; -} - -//========================================================================== -// -// D3DFB :: CalcFullscreenCoords -// -//========================================================================== - -void D3DFB::CalcFullscreenCoords (FBVERTEX verts[4], bool viewarea_only, bool can_double, D3DCOLOR color0, D3DCOLOR color1) const -{ - float offset = OldRenderTarget != NULL ? 0 : LBOffset; - float top = offset - 0.5f; - float texright = float(Width) / float(FBWidth); - float texbot = float(Height) / float(FBHeight); - float mxl, mxr, myt, myb, tmxl, tmxr, tmyt, tmyb; - - if (viewarea_only) - { // Just calculate vertices for the viewarea/BlendingRect - mxl = float(BlendingRect.left) - 0.5f; - mxr = float(BlendingRect.right) - 0.5f; - myt = float(BlendingRect.top) + top; - myb = float(BlendingRect.bottom) + top; - tmxl = float(BlendingRect.left) / float(Width) * texright; - tmxr = float(BlendingRect.right) / float(Width) * texright; - tmyt = float(BlendingRect.top) / float(Height) * texbot; - tmyb = float(BlendingRect.bottom) / float(Height) * texbot; - } - else - { // Calculate vertices for the whole screen - mxl = -0.5f; - mxr = float(Width << (can_double ? PixelDoubling : 0)) - 0.5f; - myt = top; - myb = float(Height << (can_double ? PixelDoubling : 0)) + top; - tmxl = 0; - tmxr = texright; - tmyt = 0; - tmyb = texbot; - } - - //{ mxl, myt, 0, 1, 0, 0xFFFFFFFF, tmxl, tmyt }, - //{ mxr, myt, 0, 1, 0, 0xFFFFFFFF, tmxr, tmyt }, - //{ mxr, myb, 0, 1, 0, 0xFFFFFFFF, tmxr, tmyb }, - //{ mxl, myb, 0, 1, 0, 0xFFFFFFFF, tmxl, tmyb }, - - verts[0].x = mxl; - verts[0].y = myt; - verts[0].z = 0; - verts[0].rhw = 1; - verts[0].color0 = color0; - verts[0].color1 = color1; - verts[0].tu = tmxl; - verts[0].tv = tmyt; - - verts[1].x = mxr; - verts[1].y = myt; - verts[1].z = 0; - verts[1].rhw = 1; - verts[1].color0 = color0; - verts[1].color1 = color1; - verts[1].tu = tmxr; - verts[1].tv = tmyt; - - verts[2].x = mxr; - verts[2].y = myb; - verts[2].z = 0; - verts[2].rhw = 1; - verts[2].color0 = color0; - verts[2].color1 = color1; - verts[2].tu = tmxr; - verts[2].tv = tmyb; - - verts[3].x = mxl; - verts[3].y = myb; - verts[3].z = 0; - verts[3].rhw = 1; - verts[3].color0 = color0; - verts[3].color1 = color1; - verts[3].tu = tmxl; - verts[3].tv = tmyb; -} - -//========================================================================== -// -// D3DFB :: GetPageCount -// -//========================================================================== - -int D3DFB::GetPageCount () -{ - return 1; -} - -//========================================================================== -// -// D3DFB :: PaletteChanged -// -//========================================================================== - -void D3DFB::PaletteChanged () -{ -} - -//========================================================================== -// -// D3DFB :: QueryNewPalette -// -//========================================================================== - -int D3DFB::QueryNewPalette () -{ - return 0; -} - -//========================================================================== -// -// D3DFB :: IsValid -// -//========================================================================== - -bool D3DFB::IsValid () -{ - return D3DDevice != NULL; -} - -//========================================================================== -// -// D3DFB :: GetHR -// -//========================================================================== - -HRESULT D3DFB::GetHR () -{ - return LastHR; -} - -//========================================================================== -// -// D3DFB :: IsFullscreen -// -//========================================================================== - -bool D3DFB::IsFullscreen () -{ - return !Windowed; -} - -//========================================================================== -// -// D3DFB :: Lock -// -//========================================================================== - -bool D3DFB::Lock (bool buffered) -{ - if (LockCount++ > 0) - { - return false; - } - assert (!In2D); - Accel2D = vid_hw2d; - Buffer = MemBuffer; - return false; -} - -//========================================================================== -// -// D3DFB :: Unlock -// -//========================================================================== - -void D3DFB::Unlock () -{ - LOG1 ("Unlock <%d>\n", LockCount); - - if (LockCount == 0) - { - return; - } - - if (UpdatePending && LockCount == 1) - { - Update (); - } - else if (--LockCount == 0) - { - Buffer = NULL; - } -} - -//========================================================================== -// -// D3DFB :: Update -// -// When In2D == 0: Copy buffer to screen and present -// When In2D == 1: Copy buffer to screen but do not present -// When In2D == 2: Set up for 2D drawing but do not draw anything -// When In2D == 3: Present and set In2D to 0 -// -//========================================================================== - -void D3DFB::Update () -{ - if (In2D == 3) - { - if (InScene) - { - DrawRateStuff(); - DrawPackedTextures(d3d_showpacks); - EndBatch(); // Make sure all batched primitives are drawn. - In2D = 0; - Flip(); - } - In2D = 0; - return; - } - - if (LockCount != 1) - { - I_FatalError ("Framebuffer must have exactly 1 lock to be updated"); - if (LockCount > 0) - { - UpdatePending = true; - --LockCount; - } - return; - } - - if (In2D == 0) - { - DrawRateStuff(); - } - - if (NeedGammaUpdate) - { - float psgamma[4]; - float igamma; - - NeedGammaUpdate = false; - igamma = 1 / Gamma; - if (!Windowed) - { - D3DGAMMARAMP ramp; - - for (int i = 0; i < 256; ++i) - { - ramp.blue[i] = ramp.green[i] = ramp.red[i] = WORD(65535.f * powf(i / 255.f, igamma)); - } - LOG("SetGammaRamp\n"); - D3DDevice->SetGammaRamp(0, D3DSGR_CALIBRATE, &ramp); - } - else - { - if (igamma != 1) - { - UpdateGammaTexture(igamma); - GammaShader = Shaders[SHADER_GammaCorrection]; - } - else - { - GammaShader = NULL; - } - } - psgamma[2] = psgamma[1] = psgamma[0] = igamma; - psgamma[3] = 0.5; // For SM14 version - D3DDevice->SetPixelShaderConstantF(PSCONST_Gamma, psgamma, 1); - } - - if (NeedPalUpdate) - { - UploadPalette(); - } - - BlitCycles.Reset(); - BlitCycles.Clock(); - - LockCount = 0; - HRESULT hr = D3DDevice->TestCooperativeLevel(); - if (FAILED(hr) && (hr != D3DERR_DEVICENOTRESET || !Reset())) - { - Sleep(1); - return; - } - Draw3DPart(In2D <= 1); - if (In2D == 0) - { - Flip(); - } - - BlitCycles.Unclock(); - //LOG1 ("cycles = %d\n", BlitCycles); - - Buffer = NULL; - UpdatePending = false; -} - -//========================================================================== -// -// D3DFB :: Flip -// -//========================================================================== - -void D3DFB::Flip() -{ - assert(InScene); - - DrawLetterbox(); - DoWindowedGamma(); - D3DDevice->EndScene(); - - CopyNextFrontBuffer(); - - // Attempt to counter input lag. - if (d3d_antilag && BlockSurface[0] != NULL) - { - D3DLOCKED_RECT lr; - volatile int dummy; - D3DDevice->ColorFill(BlockSurface[BlockNum], NULL, D3DCOLOR_ARGB(0xFF,0,0x20,0x50)); - BlockNum ^= 1; - if (!FAILED((BlockSurface[BlockNum]->LockRect(&lr, NULL, D3DLOCK_READONLY)))) - { - dummy = *(int *)lr.pBits; - BlockSurface[BlockNum]->UnlockRect(); - } - } - // Limiting the frame rate is as simple as waiting for the timer to signal this event. - I_FPSLimit(); - D3DDevice->Present(NULL, NULL, NULL, NULL); - InScene = false; - - if (RenderTextureToggle) - { - // Flip the TempRenderTexture to the other one now. - CurrRenderTexture ^= RenderTextureToggle; - TempRenderTexture = RenderTexture[CurrRenderTexture]; - } - - if (Windowed) - { - RECT box; - GetClientRect(Window, &box); - if (box.right > 0 && box.bottom > 0 && (Width != box.right || Height != box.bottom)) - { - Resize(box.right, box.bottom); - - TrueHeight = Height; - PixelDoubling = 0; - LBOffsetI = 0; - LBOffset = 0.0f; - Reset(); - - V_OutputResized(Width, Height); - } - } -} - -//========================================================================== -// -// D3DFB :: CopyNextFrontBuffer -// -// Duplicates the contents of the back buffer that will become the front -// buffer upon Present into FrontCopySurface so that we can get the -// contents of the display without wasting time in GetFrontBufferData(). -// -//========================================================================== - -void D3DFB::CopyNextFrontBuffer() -{ - IDirect3DSurface9 *backbuff; - - if (Windowed || PixelDoubling) - { - // Windowed mode or pixel doubling: TempRenderTexture has what we want - SAFE_RELEASE( FrontCopySurface ); - if (SUCCEEDED(TempRenderTexture->GetSurfaceLevel(0, &backbuff))) - { - FrontCopySurface = backbuff; - } - } - else - { - // Fullscreen, not pixel doubled: The back buffer has what we want, - // but it might be letter boxed. - if (SUCCEEDED(D3DDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuff))) - { - RECT srcrect = { 0, LBOffsetI, Width, LBOffsetI + Height }; - D3DDevice->StretchRect(backbuff, &srcrect, FrontCopySurface, NULL, D3DTEXF_NONE); - backbuff->Release(); - } - } -} - -//========================================================================== -// -// D3DFB :: PaintToWindow -// -//========================================================================== - -bool D3DFB::PaintToWindow () -{ - HRESULT hr; - - if (LockCount != 0) - { - return false; - } - hr = D3DDevice->TestCooperativeLevel(); - if (FAILED(hr)) - { - if (hr != D3DERR_DEVICENOTRESET || !Reset()) - { - Sleep (1); - return false; - } - } - Draw3DPart(true); - return true; -} - -//========================================================================== -// -// D3DFB :: Draw3DPart -// -// The software 3D part, to be exact. -// -//========================================================================== - -void D3DFB::Draw3DPart(bool copy3d) -{ - if (copy3d) - { - RECT texrect = { 0, 0, Width, Height }; - D3DLOCKED_RECT lockrect; - - if ((FBWidth == Width && FBHeight == Height && - SUCCEEDED(FBTexture->LockRect (0, &lockrect, NULL, D3DLOCK_DISCARD))) || - SUCCEEDED(FBTexture->LockRect (0, &lockrect, &texrect, 0))) - { - if (IsBgra() && FBFormat == D3DFMT_A8R8G8B8) - { - if (lockrect.Pitch == Pitch * sizeof(uint32_t) && Pitch == Width) - { - memcpy(lockrect.pBits, MemBuffer, Width * Height * sizeof(uint32_t)); - } - else - { - uint32_t *dest = (uint32_t *)lockrect.pBits; - uint32_t *src = (uint32_t*)MemBuffer; - for (int y = 0; y < Height; y++) - { - memcpy(dest, src, Width * sizeof(uint32_t)); - dest = reinterpret_cast(reinterpret_cast(dest) + lockrect.Pitch); - src += Pitch; - } - } - } - else if (!IsBgra() && FBFormat == D3DFMT_L8) - { - if (lockrect.Pitch == Pitch && Pitch == Width) - { - memcpy(lockrect.pBits, MemBuffer, Width * Height); - } - else - { - uint8_t *dest = (uint8_t *)lockrect.pBits; - uint8_t *src = (uint8_t *)MemBuffer; - for (int y = 0; y < Height; y++) - { - memcpy(dest, src, Width); - dest = reinterpret_cast(reinterpret_cast(dest) + lockrect.Pitch); - src += Pitch; - } - } - } - else - { - memset(lockrect.pBits, 0, lockrect.Pitch * Height); - } - FBTexture->UnlockRect (0); - } - } - InScene = true; - D3DDevice->BeginScene(); - D3DDevice->SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, vid_hwaalines); - assert(OldRenderTarget == NULL); - if (TempRenderTexture != NULL && - ((Windowed && TempRenderTexture != FinalWipeScreen) || GatheringWipeScreen || PixelDoubling)) - { - IDirect3DSurface9 *targetsurf; - if (SUCCEEDED(TempRenderTexture->GetSurfaceLevel(0, &targetsurf))) - { - if (SUCCEEDED(D3DDevice->GetRenderTarget(0, &OldRenderTarget))) - { - if (FAILED(D3DDevice->SetRenderTarget(0, targetsurf))) - { - // Setting the render target failed. - } - } - targetsurf->Release(); - } - } - - SetTexture(0, FBTexture); - SetPaletteTexture(PaletteTexture, 256, BorderColor); - D3DDevice->SetFVF (D3DFVF_FBVERTEX); - memset(Constant, 0, sizeof(Constant)); - SetAlphaBlend(D3DBLENDOP(0)); - EnableAlphaTest(FALSE); - if (IsBgra()) - SetPixelShader(Shaders[SHADER_NormalColor]); - else - SetPixelShader(Shaders[SHADER_NormalColorPal]); - if (copy3d) - { - FBVERTEX verts[4]; - D3DCOLOR color0, color1; - if (Accel2D) - { - auto map = swrenderer::CameraLight::Instance()->ShaderColormap(); - if (map == NULL) - { - color0 = 0; - color1 = 0xFFFFFFF; - } - else - { - color0 = D3DCOLOR_COLORVALUE(map->ColorizeStart[0]/2, map->ColorizeStart[1]/2, map->ColorizeStart[2]/2, 0); - color1 = D3DCOLOR_COLORVALUE(map->ColorizeEnd[0]/2, map->ColorizeEnd[1]/2, map->ColorizeEnd[2]/2, 1); - if (IsBgra()) - SetPixelShader(Shaders[SHADER_SpecialColormap]); - else - SetPixelShader(Shaders[SHADER_SpecialColormapPal]); - } - } - else - { - color0 = FlashColor0; - color1 = FlashColor1; - } - CalcFullscreenCoords(verts, Accel2D, false, color0, color1); - D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(FBVERTEX)); - } - if (IsBgra()) - SetPixelShader(Shaders[SHADER_NormalColor]); - else - SetPixelShader(Shaders[SHADER_NormalColorPal]); -} - -//========================================================================== -// -// D3DFB :: DrawLetterbox -// -// Draws the black bars at the top and bottom of the screen for letterboxed -// modes. -// -//========================================================================== - -void D3DFB::DrawLetterbox() -{ - if (LBOffsetI != 0) - { - D3DRECT rects[2] = { { 0, 0, Width, LBOffsetI }, { 0, Height + LBOffsetI, Width, TrueHeight } }; - D3DDevice->Clear (2, rects, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.f, 0); - } -} - -//========================================================================== -// -// D3DFB :: DoWindowedGamma -// -// Draws the render target texture to the real back buffer using a gamma- -// correcting pixel shader. -// -//========================================================================== - -void D3DFB::DoWindowedGamma() -{ - if (OldRenderTarget != NULL) - { - FBVERTEX verts[4]; - - CalcFullscreenCoords(verts, false, true, 0, 0xFFFFFFFF); - D3DDevice->SetRenderTarget(0, OldRenderTarget); - D3DDevice->SetFVF(D3DFVF_FBVERTEX); - SetTexture(0, TempRenderTexture); - SetPixelShader(Windowed && GammaShader ? GammaShader : Shaders[SHADER_NormalColor]); - if (SM14 && Windowed && GammaShader) - { - SetTexture(2, GammaTexture); - SetTexture(3, GammaTexture); - SetTexture(4, GammaTexture); - } - SetAlphaBlend(D3DBLENDOP(0)); - EnableAlphaTest(FALSE); - D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(FBVERTEX)); - OldRenderTarget->Release(); - OldRenderTarget = NULL; - if (SM14 && Windowed && GammaShader) - { -// SetTexture(0, GammaTexture); -// SetPixelShader(Shaders[SHADER_NormalColor]); -// D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(FBVERTEX)); - } - } -} - -//========================================================================== -// -// D3DFB :: UpdateGammaTexture -// -// Updates the gamma texture used by the PS14 shader. We only use the first -// half of the texture so that we needn't worry about imprecision causing -// it to grab from the border. -// -//========================================================================== - -void D3DFB::UpdateGammaTexture(float igamma) -{ - D3DLOCKED_RECT lockrect; - - if (GammaTexture != NULL && SUCCEEDED(GammaTexture->LockRect(0, &lockrect, NULL, 0))) - { - uint8_t *pix = (uint8_t *)lockrect.pBits; - for (int i = 0; i <= 128; ++i) - { - pix[i*4+2] = pix[i*4+1] = pix[i*4] = uint8_t(255.f * powf(i / 128.f, igamma)); - pix[i*4+3] = 255; - } - GammaTexture->UnlockRect(0); - } -} - -//========================================================================== -// -// D3DFB :: DoOffByOneCheck -// -// Pixel Shader 1.x does not have enough precision to properly map a "color" -// from the source texture to an index in the palette texture. The best we -// can do is use 255 pixels of the palette and get the 256th from the -// texture border color. This routine determines which pixel of the texture -// is skipped so that we don't use it for palette data. -// -//========================================================================== - -void D3DFB::DoOffByOneCheck () -{ - IDirect3DSurface9 *savedrendertarget; - IDirect3DSurface9 *testsurf, *readsurf; - D3DLOCKED_RECT lockrect; - RECT testrect = { 0, 0, 256, 1 }; - float texright = 256.f / float(FBWidth); - float texbot = 1.f / float(FBHeight); - FBVERTEX verts[4] = - { - { -0.5f, -0.5f, 0.5f, 1.f, D3DCOLOR_RGBA(0,0,0,0), D3DCOLOR_RGBA(255,255,255,255), 0.f, 0.f }, - { 255.5f, -0.5f, 0.5f, 1.f, D3DCOLOR_RGBA(0,0,0,0), D3DCOLOR_RGBA(255,255,255,255), texright, 0.f }, - { 255.5f, 0.5f, 0.5f, 1.f, D3DCOLOR_RGBA(0,0,0,0), D3DCOLOR_RGBA(255,255,255,255), texright, texbot }, - { -0.5f, 0.5f, 0.5f, 1.f, D3DCOLOR_RGBA(0,0,0,0), D3DCOLOR_RGBA(255,255,255,255), 0.f, texbot } - }; - int i, c; - - if (SkipAt >= 0) - { - return; - } - - // Create an easily recognizable R3G3B2 palette. - if (SUCCEEDED(PaletteTexture->LockRect(0, &lockrect, NULL, 0))) - { - uint8_t *pal = (uint8_t *)(lockrect.pBits); - for (i = 0; i < 256; ++i) - { - pal[i*4+0] = (i & 0x03) << 6; // blue - pal[i*4+1] = (i & 0x1C) << 3; // green - pal[i*4+2] = (i & 0xE0); // red; - pal[i*4+3] = 255; - } - PaletteTexture->UnlockRect (0); - } - else - { - return; - } - // Prepare a texture with values 0-256. - if (SUCCEEDED(FBTexture->LockRect(0, &lockrect, &testrect, 0))) - { - for (i = 0; i < 256; ++i) - { - ((uint8_t *)lockrect.pBits)[i] = i; - } - FBTexture->UnlockRect(0); - } - else - { - return; - } - // Create a render target that we can draw it to. - if (FAILED(D3DDevice->GetRenderTarget(0, &savedrendertarget))) - { - return; - } - if (FAILED(D3DDevice->CreateRenderTarget(256, 1, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, FALSE, &testsurf, NULL))) - { - return; - } - if (FAILED(D3DDevice->CreateOffscreenPlainSurface(256, 1, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &readsurf, NULL))) - { - testsurf->Release(); - return; - } - if (FAILED(D3DDevice->SetRenderTarget(0, testsurf))) - { - testsurf->Release(); - readsurf->Release(); - return; - } - // Write it to the render target using the pixel shader. - D3DDevice->BeginScene(); - D3DDevice->SetTexture(0, FBTexture); - D3DDevice->SetTexture(1, PaletteTexture); - D3DDevice->SetFVF(D3DFVF_FBVERTEX); - D3DDevice->SetPixelShader(Shaders[SHADER_NormalColorPal]); - SetConstant(PSCONST_PaletteMod, 1.f, 0.5f / 256.f, 0, 0); - D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(FBVERTEX)); - D3DDevice->EndScene(); - D3DDevice->SetRenderTarget(0, savedrendertarget); - savedrendertarget->Release(); - // Now read it back and see where it skips an entry - if (SUCCEEDED(D3DDevice->GetRenderTargetData(testsurf, readsurf)) && - SUCCEEDED(readsurf->LockRect(&lockrect, &testrect, D3DLOCK_READONLY))) - { - const uint8_t *pix = (const uint8_t *)lockrect.pBits; - for (i = 0; i < 256; ++i, pix += 4) - { - c = (pix[0] >> 6) | // blue - ((pix[1] >> 5) << 2) | // green - ((pix[2] >> 5) << 5); // red - if (c != i) - { - break; - } - } - } - readsurf->UnlockRect(); - readsurf->Release(); - testsurf->Release(); - SkipAt = i; -} - -void D3DFB::UploadPalette () -{ - D3DLOCKED_RECT lockrect; - - if (SkipAt < 0) - { - if (SM14) - { - DoOffByOneCheck(); - } - else - { - SkipAt = 256; - } - } - if (SUCCEEDED(PaletteTexture->LockRect(0, &lockrect, NULL, 0))) - { - uint8_t *pix = (uint8_t *)lockrect.pBits; - int i; - - for (i = 0; i < SkipAt; ++i, pix += 4) - { - pix[0] = SourcePalette[i].b; - pix[1] = SourcePalette[i].g; - pix[2] = SourcePalette[i].r; - pix[3] = (i == 0 ? 0 : 255); - // To let masked textures work, the first palette entry's alpha is 0. - } - pix += 4; - for (; i < 255; ++i, pix += 4) - { - pix[0] = SourcePalette[i].b; - pix[1] = SourcePalette[i].g; - pix[2] = SourcePalette[i].r; - pix[3] = 255; - } - PaletteTexture->UnlockRect(0); - BorderColor = D3DCOLOR_XRGB(SourcePalette[255].r, SourcePalette[255].g, SourcePalette[255].b); - } -} - -PalEntry *D3DFB::GetPalette () -{ - return SourcePalette; -} - -void D3DFB::UpdatePalette () -{ - NeedPalUpdate = true; -} - -bool D3DFB::SetGamma (float gamma) -{ - LOG1 ("SetGamma %g\n", gamma); - Gamma = gamma; - NeedGammaUpdate = true; - return true; -} - -bool D3DFB::SetFlash (PalEntry rgb, int amount) -{ - FlashColor = rgb; - FlashAmount = amount; - - // Fill in the constants for the pixel shader to do linear interpolation between the palette and the flash: - float r = rgb.r / 255.f, g = rgb.g / 255.f, b = rgb.b / 255.f, a = amount / 256.f; - FlashColor0 = D3DCOLOR_COLORVALUE(r * a, g * a, b * a, 0); - a = 1 - a; - FlashColor1 = D3DCOLOR_COLORVALUE(a, a, a, 1); - return true; -} - -void D3DFB::GetFlash (PalEntry &rgb, int &amount) -{ - rgb = FlashColor; - amount = FlashAmount; -} - -void D3DFB::GetFlashedPalette (PalEntry pal[256]) -{ - memcpy (pal, SourcePalette, 256*sizeof(PalEntry)); - if (FlashAmount) - { - DoBlending (pal, pal, 256, FlashColor.r, FlashColor.g, FlashColor.b, FlashAmount); - } -} - -void D3DFB::SetVSync (bool vsync) -{ - if (VSync != vsync) - { - VSync = vsync; - Reset(); - } -} - -void D3DFB::NewRefreshRate () -{ - if (!Windowed) - { - Reset(); - } -} - -void D3DFB::Blank () -{ -} - -void D3DFB::SetBlendingRect(int x1, int y1, int x2, int y2) -{ - BlendingRect.left = x1; - BlendingRect.top = y1; - BlendingRect.right = x2; - BlendingRect.bottom = y2; -} - -//========================================================================== -// -// D3DFB :: GetScreenshotBuffer -// -// Returns a pointer into a surface holding the current screen data. -// -//========================================================================== - -void D3DFB::GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type, float &gamma) -{ - D3DLOCKED_RECT lrect; - - if (!Accel2D) - { - Super::GetScreenshotBuffer(buffer, pitch, color_type, gamma); - return; - } - buffer = NULL; - if ((ScreenshotTexture = GetCurrentScreen()) != NULL) - { - if (FAILED(ScreenshotTexture->GetSurfaceLevel(0, &ScreenshotSurface))) - { - ScreenshotTexture->Release(); - ScreenshotTexture = NULL; - } - else if (FAILED(ScreenshotSurface->LockRect(&lrect, NULL, D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK))) - { - ScreenshotSurface->Release(); - ScreenshotSurface = NULL; - ScreenshotTexture->Release(); - ScreenshotTexture = NULL; - } - else - { - buffer = (const uint8_t *)lrect.pBits; - pitch = lrect.Pitch; - color_type = SS_BGRA; - gamma = Gamma; - } - } -} - -//========================================================================== -// -// D3DFB :: ReleaseScreenshotBuffer -// -//========================================================================== - -void D3DFB::ReleaseScreenshotBuffer() -{ - if (LockCount > 0) - { - Super::ReleaseScreenshotBuffer(); - } - if (ScreenshotSurface != NULL) - { - ScreenshotSurface->UnlockRect(); - ScreenshotSurface->Release(); - ScreenshotSurface = NULL; - } - SAFE_RELEASE( ScreenshotTexture ); -} - -//========================================================================== -// -// D3DFB :: GetCurrentScreen -// -// Returns a texture containing the pixels currently visible on-screen. -// -//========================================================================== - -IDirect3DTexture9 *D3DFB::GetCurrentScreen(D3DPOOL pool) -{ - IDirect3DTexture9 *tex; - IDirect3DSurface9 *surf; - D3DSURFACE_DESC desc; - HRESULT hr; - - assert(pool == D3DPOOL_SYSTEMMEM || pool == D3DPOOL_DEFAULT); - - if (FrontCopySurface == NULL || FAILED(FrontCopySurface->GetDesc(&desc))) - { - return NULL; - } - if (pool == D3DPOOL_SYSTEMMEM) - { - hr = D3DDevice->CreateTexture(desc.Width, desc.Height, 1, 0, desc.Format, D3DPOOL_SYSTEMMEM, &tex, NULL); - } - else - { - hr = D3DDevice->CreateTexture(FBWidth, FBHeight, 1, D3DUSAGE_RENDERTARGET, desc.Format, D3DPOOL_DEFAULT, &tex, NULL); - } - if (FAILED(hr)) - { - return NULL; - } - if (FAILED(tex->GetSurfaceLevel(0, &surf))) - { - tex->Release(); - return NULL; - } - if (pool == D3DPOOL_SYSTEMMEM) - { - // Video -> System memory : use GetRenderTargetData - hr = D3DDevice->GetRenderTargetData(FrontCopySurface, surf); - } - else - { - // Video -> Video memory : use StretchRect - RECT destrect = { 0, 0, Width, Height }; - hr = D3DDevice->StretchRect(FrontCopySurface, NULL, surf, &destrect, D3DTEXF_POINT); - } - surf->Release(); - if (FAILED(hr)) - { - tex->Release(); - return NULL; - } - return tex; -} - -/**************************************************************************/ -/* 2D Stuff */ -/**************************************************************************/ - -//========================================================================== -// -// D3DFB :: DrawPackedTextures -// -// DEBUG: Draws the texture atlases to the screen, starting with the -// 1-based packnum. Ignores atlases that are flagged for use by one -// texture only. -// -//========================================================================== - -void D3DFB::DrawPackedTextures(int packnum) -{ - D3DCOLOR empty_colors[8] = - { - 0x50FF0000, 0x5000FF00, 0x500000FF, 0x50FFFF00, - 0x50FF00FF, 0x5000FFFF, 0x50FF8000, 0x500080FF - }; - Atlas *pack; - int x = 8, y = 8; - - if (packnum <= 0) - { - return; - } - pack = Atlases; - // Find the first texture atlas that is an actual atlas. - while (pack != NULL && pack->OneUse) - { // Skip textures that aren't used as atlases - pack = pack->Next; - } - // Skip however many atlases we would have otherwise drawn - // until we've skipped of them. - while (pack != NULL && packnum != 1) - { - if (!pack->OneUse) - { // Skip textures that aren't used as atlases - packnum--; - } - pack = pack->Next; - } - // Draw atlases until we run out of room on the screen. - while (pack != NULL) - { - if (pack->OneUse) - { // Skip textures that aren't used as atlases - pack = pack->Next; - continue; - } - - AddColorOnlyRect(x-1, y-1-LBOffsetI, 258, 258, D3DCOLOR_XRGB(255,255,0)); - int back = 0; - for (PackedTexture *box = pack->UsedList; box != NULL; box = box->Next) - { - AddColorOnlyQuad( - x + box->Area.left * 256 / pack->Width, - y + box->Area.top * 256 / pack->Height, - (box->Area.right - box->Area.left) * 256 / pack->Width, - (box->Area.bottom - box->Area.top) * 256 / pack->Height, empty_colors[back]); - back = (back + 1) & 7; - } -// AddColorOnlyQuad(x, y-LBOffsetI, 256, 256, D3DCOLOR_ARGB(180,0,0,0)); - - CheckQuadBatch(); - - BufferedTris *quad = &QuadExtra[QuadBatchPos]; - FBVERTEX *vert = &VertexData[VertexPos]; - - quad->Group1 = 0; - if (pack->Format == D3DFMT_L8/* && !tex->IsGray*/) - { - quad->Flags = BQF_WrapUV | BQF_GamePalette/* | BQF_DisableAlphaTest*/; - quad->ShaderNum = BQS_PalTex; - } - else - { - quad->Flags = BQF_WrapUV/* | BQF_DisableAlphaTest*/; - quad->ShaderNum = BQS_Plain; - } - quad->Palette = NULL; - quad->Texture = pack->Tex; - quad->NumVerts = 4; - quad->NumTris = 2; - - float x0 = float(x) - 0.5f; - float y0 = float(y) - 0.5f; - float x1 = x0 + 256.f; - float y1 = y0 + 256.f; - - vert[0].x = x0; - vert[0].y = y0; - vert[0].z = 0; - vert[0].rhw = 1; - vert[0].color0 = 0; - vert[0].color1 = 0xFFFFFFFF; - vert[0].tu = 0; - vert[0].tv = 0; - - vert[1].x = x1; - vert[1].y = y0; - vert[1].z = 0; - vert[1].rhw = 1; - vert[1].color0 = 0; - vert[1].color1 = 0xFFFFFFFF; - vert[1].tu = 1; - vert[1].tv = 0; - - vert[2].x = x1; - vert[2].y = y1; - vert[2].z = 0; - vert[2].rhw = 1; - vert[2].color0 = 0; - vert[2].color1 = 0xFFFFFFFF; - vert[2].tu = 1; - vert[2].tv = 1; - - vert[3].x = x0; - vert[3].y = y1; - vert[3].z = 0; - vert[3].rhw = 1; - vert[3].color0 = 0; - vert[3].color1 = 0xFFFFFFFF; - vert[3].tu = 0; - vert[3].tv = 1; - - IndexData[IndexPos ] = VertexPos; - IndexData[IndexPos + 1] = VertexPos + 1; - IndexData[IndexPos + 2] = VertexPos + 2; - IndexData[IndexPos + 3] = VertexPos; - IndexData[IndexPos + 4] = VertexPos + 2; - IndexData[IndexPos + 5] = VertexPos + 3; - - QuadBatchPos++; - VertexPos += 4; - IndexPos += 6; - - x += 256 + 8; - if (x > Width - 256) - { - x = 8; - y += 256 + 8; - if (y > TrueHeight - 256) - { - return; - } - } - pack = pack->Next; - } -} - -//========================================================================== -// -// D3DFB :: AllocPackedTexture -// -// Finds space to pack an image inside a texture atlas and returns it. -// Large images and those that need to wrap always get their own textures. -// -//========================================================================== - -D3DFB::PackedTexture *D3DFB::AllocPackedTexture(int w, int h, bool wrapping, D3DFORMAT format) -{ - Atlas *pack; - Rect box; - bool padded; - - // The - 2 to account for padding - if (w > 256 - 2 || h > 256 - 2 || wrapping) - { // Create a new texture atlas. - pack = new Atlas(this, w, h, format); - pack->OneUse = true; - box = pack->Packer.Insert(w, h); - padded = false; - } - else - { // Try to find space in an existing texture atlas. - w += 2; // Add padding - h += 2; - for (pack = Atlases; pack != NULL; pack = pack->Next) - { - // Use the first atlas it fits in. - if (pack->Format == format) - { - box = pack->Packer.Insert(w, h); - if (box.width != 0) - { - break; - } - } - } - if (pack == NULL) - { // Create a new texture atlas. - pack = new Atlas(this, DEF_ATLAS_WIDTH, DEF_ATLAS_HEIGHT, format); - box = pack->Packer.Insert(w, h); - } - padded = true; - } - assert(box.width != 0 && box.height != 0); - return pack->AllocateImage(box, padded); -} - -//========================================================================== -// -// Atlas Constructor -// -//========================================================================== - -D3DFB::Atlas::Atlas(D3DFB *fb, int w, int h, D3DFORMAT format) - : Packer(w, h, true) -{ - Tex = NULL; - Format = format; - UsedList = NULL; - OneUse = false; - Width = 0; - Height = 0; - Next = NULL; - - // Attach to the end of the atlas list - Atlas **prev = &fb->Atlases; - while (*prev != NULL) - { - prev = &((*prev)->Next); - } - *prev = this; - -#if 1 - if (FAILED(fb->D3DDevice->CreateTexture(w, h, 1, 0, format, D3DPOOL_MANAGED, &Tex, NULL))) -#endif - { // Try again, using power-of-2 sizes - int i; - - for (i = 1; i < w; i <<= 1) {} w = i; - for (i = 1; i < h; i <<= 1) {} h = i; - if (FAILED(fb->D3DDevice->CreateTexture(w, h, 1, 0, format, D3DPOOL_MANAGED, &Tex, NULL))) - { - return; - } - } - Width = w; - Height = h; -} - -//========================================================================== -// -// Atlas Destructor -// -//========================================================================== - -D3DFB::Atlas::~Atlas() -{ - PackedTexture *box, *next; - - SAFE_RELEASE( Tex ); - for (box = UsedList; box != NULL; box = next) - { - next = box->Next; - delete box; - } -} - -//========================================================================== -// -// Atlas :: AllocateImage -// -// Moves the box from the empty list to the used list, sizing it to the -// requested dimensions and adding additional boxes to the empty list if -// needed. -// -// The passed box *MUST* be in this texture atlas's empty list. -// -//========================================================================== - -D3DFB::PackedTexture *D3DFB::Atlas::AllocateImage(const Rect &rect, bool padded) -{ - PackedTexture *box = new PackedTexture; - - box->Owner = this; - box->Area.left = rect.x; - box->Area.top = rect.y; - box->Area.right = rect.x + rect.width; - box->Area.bottom = rect.y + rect.height; - - box->Left = float(box->Area.left + padded) / Width; - box->Right = float(box->Area.right - padded) / Width; - box->Top = float(box->Area.top + padded) / Height; - box->Bottom = float(box->Area.bottom - padded) / Height; - - box->Padded = padded; - - // Add it to the used list. - box->Next = UsedList; - if (box->Next != NULL) - { - box->Next->Prev = &box->Next; - } - UsedList = box; - box->Prev = &UsedList; - - return box; -} - -//========================================================================== -// -// Atlas :: FreeBox -// -// Removes a box from the used list and deletes it. Space is returned to the -// waste list. Once all boxes for this atlas are freed, the entire bin -// packer is reinitialized for maximum efficiency. -// -//========================================================================== - -void D3DFB::Atlas::FreeBox(D3DFB::PackedTexture *box) -{ - *(box->Prev) = box->Next; - if (box->Next != NULL) - { - box->Next->Prev = box->Prev; - } - Rect waste; - waste.x = box->Area.left; - waste.y = box->Area.top; - waste.width = box->Area.right - box->Area.left; - waste.height = box->Area.bottom - box->Area.top; - box->Owner->Packer.AddWaste(waste); - delete box; - if (UsedList == NULL) - { - Packer.Init(Width, Height, true); - } -} - -//========================================================================== -// -// D3DTex Constructor -// -//========================================================================== - -D3DTex::D3DTex(FTexture *tex, FTextureFormat fmt, D3DFB *fb, bool wrapping) - : FNativeTexture(tex, fmt) -{ - // Attach to the texture list for the D3DFB - Next = fb->Textures; - if (Next != NULL) - { - Next->Prev = &Next; - } - Prev = &fb->Textures; - fb->Textures = this; - - Box = NULL; - IsGray = false; - - Create(fb, wrapping); -} - -//========================================================================== -// -// D3DTex Destructor -// -//========================================================================== - -D3DTex::~D3DTex() -{ - if (Box != NULL) - { - Box->Owner->FreeBox(Box); - Box = NULL; - } - // Detach from the texture list - *Prev = Next; - if (Next != NULL) - { - Next->Prev = Prev; - } -} - -//========================================================================== -// -// D3DTex :: CheckWrapping -// -// Returns true if the texture is compatible with the specified wrapping -// mode. -// -//========================================================================== - -bool D3DTex::CheckWrapping(bool wrapping) -{ - // If it doesn't need to wrap, then it works. - if (!wrapping) - { - return true; - } - // If it needs to wrap, then it can't be packed inside another texture. - return Box->Owner->OneUse; -} - -//========================================================================== -// -// D3DTex :: Create -// -// Creates an IDirect3DTexture9 for the texture and copies the image data -// to it. Note that unlike FTexture, this image is row-major. -// -//========================================================================== - -bool D3DTex::Create(D3DFB *fb, bool wrapping) -{ - assert(Box == NULL); - if (Box != NULL) - { - Box->Owner->FreeBox(Box); - } - - Box = fb->AllocPackedTexture(mGameTex->GetWidth(), mGameTex->GetHeight(), wrapping, GetTexFormat()); - - if (Box == NULL) - { - return false; - } - if (!Update()) - { - Box->Owner->FreeBox(Box); - Box = NULL; - return false; - } - return true; -} - -//========================================================================== -// -// D3DTex :: Update -// -// Copies image data from the underlying FTexture to the D3D texture. -// -//========================================================================== - -bool D3DTex::Update() -{ - D3DSURFACE_DESC desc; - D3DLOCKED_RECT lrect; - RECT rect; - uint8_t *dest; - - assert(Box != NULL); - assert(Box->Owner != NULL); - assert(Box->Owner->Tex != NULL); - assert(mGameTex != NULL); - - if (FAILED(Box->Owner->Tex->GetLevelDesc(0, &desc))) - { - return false; - } - rect = Box->Area; - if (FAILED(Box->Owner->Tex->LockRect(0, &lrect, &rect, 0))) - { - return false; - } - dest = (uint8_t *)lrect.pBits; - if (Box->Padded) - { - dest += lrect.Pitch + (desc.Format == D3DFMT_L8 ? 1 : 4); - } - mGameTex->FillBuffer(dest, lrect.Pitch, mGameTex->GetHeight(), mFormat); - if (Box->Padded) - { - // Clear top padding row. - dest = (uint8_t *)lrect.pBits; - int numbytes = mGameTex->GetWidth() + 2; - if (desc.Format != D3DFMT_L8) - { - numbytes <<= 2; - } - memset(dest, 0, numbytes); - dest += lrect.Pitch; - // Clear left and right padding columns. - if (desc.Format == D3DFMT_L8) - { - for (int y = Box->Area.bottom - Box->Area.top - 2; y > 0; --y) - { - dest[0] = 0; - dest[numbytes-1] = 0; - dest += lrect.Pitch; - } - } - else - { - for (int y = Box->Area.bottom - Box->Area.top - 2; y > 0; --y) - { - *(DWORD *)dest = 0; - *(DWORD *)(dest + numbytes - 4) = 0; - dest += lrect.Pitch; - } - } - // Clear bottom padding row. - memset(dest, 0, numbytes); - } - Box->Owner->Tex->UnlockRect(0); - return true; -} - -//========================================================================== -// -// D3DTex :: GetTexFormat -// -// Returns the texture format that would best fit this texture. -// -//========================================================================== - -D3DFORMAT D3DTex::GetTexFormat() -{ - IsGray = false; - - switch (mFormat) - { - case TEX_Pal: return D3DFMT_L8; - case TEX_Gray: IsGray = true; return D3DFMT_L8; - case TEX_RGB: return D3DFMT_A8R8G8B8; -#if 0 - case TEX_DXT1: return D3DFMT_DXT1; - case TEX_DXT2: return D3DFMT_DXT2; - case TEX_DXT3: return D3DFMT_DXT3; - case TEX_DXT4: return D3DFMT_DXT4; - case TEX_DXT5: return D3DFMT_DXT5; -#endif - default: I_FatalError ("GameTex->GetFormat() returned invalid format."); - } - return D3DFMT_L8; -} - -//========================================================================== -// -// D3DPal Constructor -// -//========================================================================== - -D3DPal::D3DPal(FRemapTable *remap, D3DFB *fb) - : Tex(NULL), Remap(remap) -{ - int count; - - // Attach to the palette list for the D3DFB - Next = fb->Palettes; - if (Next != NULL) - { - Next->Prev = &Next; - } - Prev = &fb->Palettes; - fb->Palettes = this; - - // Palette textures must be 256 entries for Shader Model 1.4 - if (fb->SM14) - { - count = 256; - // If the palette isn't big enough, then we don't need to - // worry about setting the gamma ramp. - DoColorSkip = (remap->NumEntries >= 256 - 8); - } - else - { - int pow2count; - - // Round up to the nearest power of 2. - for (pow2count = 1; pow2count < remap->NumEntries; pow2count <<= 1) - { } - count = pow2count; - DoColorSkip = false; - } - BorderColor = 0; - RoundedPaletteSize = count; - if (SUCCEEDED(fb->D3DDevice->CreateTexture(count, 1, 1, 0, - D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &Tex, NULL))) - { - if (!Update()) - { - Tex->Release(); - Tex = NULL; - } - } -} - -//========================================================================== -// -// D3DPal Destructor -// -//========================================================================== - -D3DPal::~D3DPal() -{ - SAFE_RELEASE( Tex ); - // Detach from the palette list - *Prev = Next; - if (Next != NULL) - { - Next->Prev = Prev; - } - // Remove link from the remap table - if (Remap != NULL) - { - Remap->Native = NULL; - } -} - -//========================================================================== -// -// D3DPal :: Update -// -// Copies the palette to the texture. -// -//========================================================================== - -bool D3DPal::Update() -{ - D3DLOCKED_RECT lrect; - D3DCOLOR *buff; - const PalEntry *pal; - int skipat, i; - - assert(Tex != NULL); - - if (FAILED(Tex->LockRect(0, &lrect, NULL, 0))) - { - return false; - } - buff = (D3DCOLOR *)lrect.pBits; - pal = Remap->Palette; - - // See explanation in UploadPalette() for skipat rationale. - skipat = MIN(Remap->NumEntries, DoColorSkip ? 256 - 8 : 256); - - for (i = 0; i < skipat; ++i) - { - buff[i] = D3DCOLOR_ARGB(pal[i].a, pal[i].r, pal[i].g, pal[i].b); - } - for (++i; i < Remap->NumEntries; ++i) - { - buff[i] = D3DCOLOR_ARGB(pal[i].a, pal[i-1].r, pal[i-1].g, pal[i-1].b); - } - BorderColor = D3DCOLOR_ARGB(pal[i].a, pal[i-1].r, pal[i-1].g, pal[i-1].b); - - Tex->UnlockRect(0); - return true; -} - -//========================================================================== -// -// D3DFB :: Begin2D -// -// Begins 2D mode drawing operations. In particular, DrawTexture is -// rerouted to use Direct3D instead of the software renderer. -// -//========================================================================== - -bool D3DFB::Begin2D(bool copy3d) -{ - Super::Begin2D(copy3d); - if (!Accel2D) - { - return false; - } - if (In2D) - { - return true; - } - In2D = 2 - copy3d; - Update(); - In2D = 3; - - return true; -} - -//========================================================================== -// -// D3DFB :: DrawBlendingRect -// -// Call after Begin2D to blend the 3D view. -// -//========================================================================== - -void D3DFB::DrawBlendingRect() -{ - if (!In2D || !Accel2D) - { - return; - } - Dim(FlashColor, FlashAmount / 256.f, viewwindowx, viewwindowy, viewwidth, viewheight); -} - -//========================================================================== -// -// D3DFB :: CreateTexture -// -// Returns a native texture that wraps a FTexture. -// -//========================================================================== - -FNativeTexture *D3DFB::CreateTexture(FTexture *gametex, FTextureFormat fmt, bool wrapping) -{ - D3DTex *tex = new D3DTex(gametex, fmt, this, wrapping); - if (tex->Box == NULL) - { - delete tex; - return NULL; - } - return tex; -} - -//========================================================================== -// -// D3DFB :: CreatePalette -// -// Returns a native texture that contains a palette. -// -//========================================================================== - -FNativePalette *D3DFB::CreatePalette(FRemapTable *remap) -{ - D3DPal *tex = new D3DPal(remap, this); - if (tex->Tex == NULL) - { - delete tex; - return NULL; - } - return tex; -} - -//========================================================================== -// -// D3DFB :: Clear -// -// Fills the specified region with a color. -// -//========================================================================== - -void D3DFB::DoClear (int left, int top, int right, int bottom, int palcolor, uint32_t color) -{ - if (In2D < 2) - { - Super::DoClear(left, top, right, bottom, palcolor, color); - return; - } - if (!InScene) - { - return; - } - if (palcolor >= 0 && color == 0) - { - color = GPalette.BaseColors[palcolor]; - } - else if (APART(color) < 255) - { - Dim(color, APART(color)/255.f, left, top, right - left, bottom - top); - return; - } - AddColorOnlyQuad(left, top, right - left, bottom - top, color | 0xFF000000); -} - -//========================================================================== -// -// D3DFB :: Dim -// -//========================================================================== - -void D3DFB::DoDim (PalEntry color, float amount, int x1, int y1, int w, int h) -{ - if (amount <= 0) - { - return; - } - if (In2D < 2) - { - Super::DoDim(color, amount, x1, y1, w, h); - return; - } - if (!InScene) - { - return; - } - if (amount > 1) - { - amount = 1; - } - AddColorOnlyQuad(x1, y1, w, h, color | (int(amount * 255) << 24)); -} - -//========================================================================== -// -// D3DFB :: BeginLineBatch -// -//========================================================================== - -void D3DFB::BeginLineBatch() -{ - if (In2D < 2 || !InScene || BatchType == BATCH_Lines) - { - return; - } - EndQuadBatch(); // Make sure all quads have been drawn first. - VertexBuffer->Lock(0, 0, (void **)&VertexData, D3DLOCK_DISCARD); - VertexPos = 0; - BatchType = BATCH_Lines; -} - -//========================================================================== -// -// D3DFB :: EndLineBatch -// -//========================================================================== - -void D3DFB::EndLineBatch() -{ - if (In2D < 2 || !InScene || BatchType != BATCH_Lines) - { - return; - } - VertexBuffer->Unlock(); - if (VertexPos > 0) - { - SetPixelShader(Shaders[SHADER_VertexColor]); - SetAlphaBlend(D3DBLENDOP_ADD, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA); - D3DDevice->SetStreamSource(0, VertexBuffer, 0, sizeof(FBVERTEX)); - D3DDevice->DrawPrimitive(D3DPT_LINELIST, 0, VertexPos / 2); - } - VertexPos = -1; - BatchType = BATCH_None; -} - -//========================================================================== -// -// D3DFB :: DrawLine -// -//========================================================================== - -void D3DFB::DrawLine(int x0, int y0, int x1, int y1, int palcolor, uint32_t color) -{ - if (In2D < 2) - { - Super::DrawLine(x0, y0, x1, y1, palcolor, color); - return; - } - if (!InScene) - { - return; - } - if (BatchType != BATCH_Lines) - { - BeginLineBatch(); - } - if (VertexPos == NUM_VERTS) - { // Flush the buffer and refill it. - EndLineBatch(); - BeginLineBatch(); - } - // Add the endpoints to the vertex buffer. - VertexData[VertexPos].x = float(x0); - VertexData[VertexPos].y = float(y0) + LBOffset; - VertexData[VertexPos].z = 0; - VertexData[VertexPos].rhw = 1; - VertexData[VertexPos].color0 = color; - VertexData[VertexPos].color1 = 0; - VertexData[VertexPos].tu = 0; - VertexData[VertexPos].tv = 0; - - VertexData[VertexPos+1].x = float(x1); - VertexData[VertexPos+1].y = float(y1) + LBOffset; - VertexData[VertexPos+1].z = 0; - VertexData[VertexPos+1].rhw = 1; - VertexData[VertexPos+1].color0 = color; - VertexData[VertexPos+1].color1 = 0; - VertexData[VertexPos+1].tu = 0; - VertexData[VertexPos+1].tv = 0; - - VertexPos += 2; -} - -//========================================================================== -// -// D3DFB :: DrawPixel -// -//========================================================================== - -void D3DFB::DrawPixel(int x, int y, int palcolor, uint32_t color) -{ - if (In2D < 2) - { - Super::DrawPixel(x, y, palcolor, color); - return; - } - if (!InScene) - { - return; - } - FBVERTEX pt = - { - float(x), float(y), 0, 1, color - }; - EndBatch(); // Draw out any batched operations. - SetPixelShader(Shaders[SHADER_VertexColor]); - SetAlphaBlend(D3DBLENDOP_ADD, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA); - D3DDevice->DrawPrimitiveUP(D3DPT_POINTLIST, 1, &pt, sizeof(FBVERTEX)); -} - -//========================================================================== -// -// D3DFB :: DrawTextureV -// -// If not in 2D mode, just call the normal software version. -// If in 2D mode, then use Direct3D calls to perform the drawing. -// -//========================================================================== - -void D3DFB::DrawTextureParms (FTexture *img, DrawParms &parms) -{ - if (In2D < 2) - { - Super::DrawTextureParms(img, parms); - return; - } - if (!InScene) - { - return; - } - - FTextureFormat fmt; - if (parms.style.Flags & STYLEF_RedIsAlpha) fmt = TEX_Gray; - else if (parms.remap != nullptr) fmt = TEX_Pal; - else fmt = img->GetFormat(); - - D3DTex *tex = static_cast(img->GetNative(fmt, false)); - - if (tex == NULL) - { - assert(tex != NULL); - return; - } - - CheckQuadBatch(); - - double xscale = parms.destwidth / parms.texwidth; - double yscale = parms.destheight / parms.texheight; - double x0 = parms.x - parms.left * xscale; - double y0 = parms.y - parms.top * yscale; - double x1 = x0 + parms.destwidth; - double y1 = y0 + parms.destheight; - float u0 = tex->Box->Left; - float v0 = tex->Box->Top; - float u1 = tex->Box->Right; - float v1 = tex->Box->Bottom; - double uscale = 1.f / tex->Box->Owner->Width; - bool scissoring = false; - FBVERTEX *vert; - float yoffs; - - if (parms.flipX) - { - swapvalues(u0, u1); - } - if (parms.windowleft > 0 || parms.windowright < parms.texwidth) - { - double wi = MIN(parms.windowright, parms.texwidth); - x0 += parms.windowleft * xscale; - u0 = float(u0 + parms.windowleft * uscale); - x1 -= (parms.texwidth - wi) * xscale; - u1 = float(u1 - (parms.texwidth - wi) * uscale); - } - -#if 0 - float vscale = 1.f / tex->Box->Owner->Height / yscale; - if (y0 < parms.uclip) - { - v0 += (float(parms.uclip) - y0) * vscale; - y0 = float(parms.uclip); - } - if (y1 > parms.dclip) - { - v1 -= (y1 - float(parms.dclip)) * vscale; - y1 = float(parms.dclip); - } - if (x0 < parms.lclip) - { - u0 += float(parms.lclip - x0) * uscale / xscale * 2; - x0 = float(parms.lclip); - } - if (x1 > parms.rclip) - { - u1 -= (x1 - parms.rclip) * uscale / xscale * 2; - x1 = float(parms.rclip); - } -#else - // Use a scissor test because the math above introduces some jitter - // that is noticeable at low resolutions. Unfortunately, this means this - // quad has to be in a batch by itself. - if (y0 < parms.uclip || y1 > parms.dclip || x0 < parms.lclip || x1 > parms.rclip) - { - scissoring = true; - if (QuadBatchPos > 0) - { - EndQuadBatch(); - BeginQuadBatch(); - } - RECT scissor = { - parms.lclip, parms.uclip + LBOffsetI, - parms.rclip, parms.dclip + LBOffsetI - }; - D3DDevice->SetScissorRect(&scissor); - D3DDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); - } -#endif - parms.bilinear = false; - - D3DCOLOR color0, color1; - BufferedTris *quad = &QuadExtra[QuadBatchPos]; - - if (!SetStyle(tex, parms, color0, color1, *quad)) - { - goto done; - } - - quad->Texture = tex->Box->Owner->Tex; - if (parms.bilinear) - { - quad->Flags |= BQF_Bilinear; - } - quad->NumTris = 2; - quad->NumVerts = 4; - - yoffs = GatheringWipeScreen ? 0.5f : 0.5f - LBOffset; - -#if 0 - // Coordinates are truncated to integers, because that's effectively - // what the software renderer does. The hardware will instead round - // to nearest, it seems. - x0 = floorf(x0) - 0.5f; - y0 = floorf(y0) - yoffs; - x1 = floorf(x1) - 0.5f; - y1 = floorf(y1) - yoffs; -#else - x0 = x0 - 0.5f; - y0 = y0 - yoffs; - x1 = x1 - 0.5f; - y1 = y1 - yoffs; -#endif - - vert = &VertexData[VertexPos]; - - { - PalEntry color = color1; - color = PalEntry((color.a * parms.color.a) / 255, (color.r * parms.color.r) / 255, (color.g * parms.color.g) / 255, (color.b * parms.color.b) / 255); - color1 = color; - } - - // Fill the vertex buffer. - vert[0].x = float(x0); - vert[0].y = float(y0); - vert[0].z = 0; - vert[0].rhw = 1; - vert[0].color0 = color0; - vert[0].color1 = color1; - vert[0].tu = u0; - vert[0].tv = v0; - - vert[1].x = float(x1); - vert[1].y = float(y0); - vert[1].z = 0; - vert[1].rhw = 1; - vert[1].color0 = color0; - vert[1].color1 = color1; - vert[1].tu = u1; - vert[1].tv = v0; - - vert[2].x = float(x1); - vert[2].y = float(y1); - vert[2].z = 0; - vert[2].rhw = 1; - vert[2].color0 = color0; - vert[2].color1 = color1; - vert[2].tu = u1; - vert[2].tv = v1; - - vert[3].x = float(x0); - vert[3].y = float(y1); - vert[3].z = 0; - vert[3].rhw = 1; - vert[3].color0 = color0; - vert[3].color1 = color1; - vert[3].tu = u0; - vert[3].tv = v1; - - // Fill the vertex index buffer. - IndexData[IndexPos ] = VertexPos; - IndexData[IndexPos + 1] = VertexPos + 1; - IndexData[IndexPos + 2] = VertexPos + 2; - IndexData[IndexPos + 3] = VertexPos; - IndexData[IndexPos + 4] = VertexPos + 2; - IndexData[IndexPos + 5] = VertexPos + 3; - - // Batch the quad. - QuadBatchPos++; - VertexPos += 4; - IndexPos += 6; -done: - if (scissoring) - { - EndQuadBatch(); - D3DDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); - } -} - -//========================================================================== -// -// D3DFB :: FlatFill -// -// Fills an area with a repeating copy of the texture. -// -//========================================================================== - -void D3DFB::FlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin) -{ - if (In2D < 2) - { - Super::FlatFill(left, top, right, bottom, src, local_origin); - return; - } - if (!InScene) - { - return; - } - - D3DTex *tex = static_cast(src->GetNative(src->GetFormat(), true)); - if (tex == NULL) - { - return; - } - float yoffs = GatheringWipeScreen ? 0.5f : 0.5f - LBOffset; - float x0 = float(left); - float y0 = float(top); - float x1 = float(right); - float y1 = float(bottom); - float itw = 1.f / float(src->GetWidth()); - float ith = 1.f / float(src->GetHeight()); - float xo = local_origin ? x0 : 0; - float yo = local_origin ? y0 : 0; - float u0 = (x0 - xo) * itw; - float v0 = (y0 - yo) * ith; - float u1 = (x1 - xo) * itw; - float v1 = (y1 - yo) * ith; - x0 -= 0.5f; - y0 -= yoffs; - x1 -= 0.5f; - y1 -= yoffs; - - CheckQuadBatch(); - - BufferedTris *quad = &QuadExtra[QuadBatchPos]; - FBVERTEX *vert = &VertexData[VertexPos]; - - quad->Group1 = 0; - if (tex->GetTexFormat() == D3DFMT_L8 && !tex->IsGray) - { - quad->Flags = BQF_WrapUV | BQF_GamePalette; // | BQF_DisableAlphaTest; - quad->ShaderNum = BQS_PalTex; - } - else - { - quad->Flags = BQF_WrapUV; // | BQF_DisableAlphaTest; - quad->ShaderNum = BQS_Plain; - } - quad->Palette = NULL; - quad->Texture = tex->Box->Owner->Tex; - quad->NumVerts = 4; - quad->NumTris = 2; - - vert[0].x = x0; - vert[0].y = y0; - vert[0].z = 0; - vert[0].rhw = 1; - vert[0].color0 = 0; - vert[0].color1 = 0xFFFFFFFF; - vert[0].tu = u0; - vert[0].tv = v0; - - vert[1].x = x1; - vert[1].y = y0; - vert[1].z = 0; - vert[1].rhw = 1; - vert[1].color0 = 0; - vert[1].color1 = 0xFFFFFFFF; - vert[1].tu = u1; - vert[1].tv = v0; - - vert[2].x = x1; - vert[2].y = y1; - vert[2].z = 0; - vert[2].rhw = 1; - vert[2].color0 = 0; - vert[2].color1 = 0xFFFFFFFF; - vert[2].tu = u1; - vert[2].tv = v1; - - vert[3].x = x0; - vert[3].y = y1; - vert[3].z = 0; - vert[3].rhw = 1; - vert[3].color0 = 0; - vert[3].color1 = 0xFFFFFFFF; - vert[3].tu = u0; - vert[3].tv = v1; - - IndexData[IndexPos ] = VertexPos; - IndexData[IndexPos + 1] = VertexPos + 1; - IndexData[IndexPos + 2] = VertexPos + 2; - IndexData[IndexPos + 3] = VertexPos; - IndexData[IndexPos + 4] = VertexPos + 2; - IndexData[IndexPos + 5] = VertexPos + 3; - - QuadBatchPos++; - VertexPos += 4; - IndexPos += 6; -} - -//========================================================================== -// -// D3DFB :: FillSimplePoly -// -// Here, "simple" means that a simple triangle fan can draw it. -// -// Bottomclip is ignored by this implementation, since the hardware renderer -// will unconditionally draw the status bar border every frame on top of the -// polygons, so there's no need to waste time setting up a special scissor -// rectangle here and needlessly forcing separate batches. -// -//========================================================================== - -void D3DFB::FillSimplePoly(FTexture *texture, FVector2 *points, int npoints, - double originx, double originy, double scalex, double scaley, - DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel, int bottomclip) -{ - // Use an equation similar to player sprites to determine shade - double fadelevel = clamp((swrenderer::LightVisibility::LightLevelToShade(lightlevel, true)/65536. - 12) / NUMCOLORMAPS, 0.0, 1.0); - - BufferedTris *quad; - FBVERTEX *verts; - D3DTex *tex; - float yoffs, uscale, vscale; - int i, ipos; - D3DCOLOR color0, color1; - float ox, oy; - float cosrot, sinrot; - bool dorotate = rotation != 0; - - if (npoints < 3) - { // This is no polygon. - return; - } - if (In2D < 2) - { - Super::FillSimplePoly(texture, points, npoints, originx, originy, scalex, scaley, rotation, colormap, flatcolor, lightlevel, bottomclip); - return; - } - if (!InScene) - { - return; - } - - tex = static_cast(texture->GetNative(texture->GetFormat(), true)); - if (tex == NULL) - { - return; - } - - cosrot = (float)cos(rotation.Radians()); - sinrot = (float)sin(rotation.Radians()); - - CheckQuadBatch(npoints - 2, npoints); - quad = &QuadExtra[QuadBatchPos]; - verts = &VertexData[VertexPos]; - - color0 = 0; - color1 = 0xFFFFFFFF; - - quad->Group1 = 0; - if (tex->GetTexFormat() == D3DFMT_L8 && !tex->IsGray) - { - quad->Flags = BQF_WrapUV | BQF_GamePalette | BQF_DisableAlphaTest; - quad->ShaderNum = BQS_PalTex; - if (colormap.Desaturation != 0) - { - quad->Flags |= BQF_Desaturated; - } - quad->ShaderNum = BQS_InGameColormap; - quad->Desat = colormap.Desaturation; - color0 = D3DCOLOR_ARGB(255, colormap.LightColor.r, colormap.LightColor.g, colormap.LightColor.b); - color1 = D3DCOLOR_ARGB(DWORD((1 - fadelevel) * 255), - DWORD(colormap.FadeColor.r * fadelevel), - DWORD(colormap.FadeColor.g * fadelevel), - DWORD(colormap.FadeColor.b * fadelevel)); - } - else - { - quad->Flags = BQF_WrapUV | BQF_DisableAlphaTest; - quad->ShaderNum = BQS_Plain; - } - quad->Palette = NULL; - quad->Texture = tex->Box->Owner->Tex; - quad->NumVerts = npoints; - quad->NumTris = npoints - 2; - - yoffs = GatheringWipeScreen ? 0 : LBOffset; - uscale = float(1.f / (texture->GetScaledWidth() * scalex)); - vscale = float(1.f / (texture->GetScaledHeight() * scaley)); - ox = float(originx); - oy = float(originy); - - for (i = 0; i < npoints; ++i) - { - verts[i].x = points[i].X; - verts[i].y = points[i].Y + yoffs; - verts[i].z = 0; - verts[i].rhw = 1; - verts[i].color0 = color0; - verts[i].color1 = color1; - float u = points[i].X - 0.5f - ox; - float v = points[i].Y - 0.5f - oy; - if (dorotate) - { - float t = u; - u = t * cosrot - v * sinrot; - v = v * cosrot + t * sinrot; - } - verts[i].tu = u * uscale; - verts[i].tv = v * vscale; - } - for (ipos = IndexPos, i = 2; i < npoints; ++i, ipos += 3) - { - IndexData[ipos ] = VertexPos; - IndexData[ipos + 1] = VertexPos + i - 1; - IndexData[ipos + 2] = VertexPos + i; - } - - QuadBatchPos++; - VertexPos += npoints; - IndexPos = ipos; -} - -//========================================================================== -// -// D3DFB :: AddColorOnlyQuad -// -// Adds a single-color, untextured quad to the batch. -// -//========================================================================== - -void D3DFB::AddColorOnlyQuad(int left, int top, int width, int height, D3DCOLOR color) -{ - BufferedTris *quad; - FBVERTEX *verts; - - CheckQuadBatch(); - quad = &QuadExtra[QuadBatchPos]; - verts = &VertexData[VertexPos]; - - float x = float(left) - 0.5f; - float y = float(top) - 0.5f + (GatheringWipeScreen ? 0 : LBOffset); - - quad->Group1 = 0; - quad->ShaderNum = BQS_ColorOnly; - if ((color & 0xFF000000) != 0xFF000000) - { - quad->BlendOp = D3DBLENDOP_ADD; - quad->SrcBlend = D3DBLEND_SRCALPHA; - quad->DestBlend = D3DBLEND_INVSRCALPHA; - } - quad->Palette = NULL; - quad->Texture = NULL; - quad->NumVerts = 4; - quad->NumTris = 2; - - verts[0].x = x; - verts[0].y = y; - verts[0].z = 0; - verts[0].rhw = 1; - verts[0].color0 = color; - verts[0].color1 = 0; - verts[0].tu = 0; - verts[0].tv = 0; - - verts[1].x = x + width; - verts[1].y = y; - verts[1].z = 0; - verts[1].rhw = 1; - verts[1].color0 = color; - verts[1].color1 = 0; - verts[1].tu = 0; - verts[1].tv = 0; - - verts[2].x = x + width; - verts[2].y = y + height; - verts[2].z = 0; - verts[2].rhw = 1; - verts[2].color0 = color; - verts[2].color1 = 0; - verts[2].tu = 0; - verts[2].tv = 0; - - verts[3].x = x; - verts[3].y = y + height; - verts[3].z = 0; - verts[3].rhw = 1; - verts[3].color0 = color; - verts[3].color1 = 0; - verts[3].tu = 0; - verts[3].tv = 0; - - IndexData[IndexPos ] = VertexPos; - IndexData[IndexPos + 1] = VertexPos + 1; - IndexData[IndexPos + 2] = VertexPos + 2; - IndexData[IndexPos + 3] = VertexPos; - IndexData[IndexPos + 4] = VertexPos + 2; - IndexData[IndexPos + 5] = VertexPos + 3; - - QuadBatchPos++; - VertexPos += 4; - IndexPos += 6; -} - -//========================================================================== -// -// D3DFB :: AddColorOnlyRect -// -// Like AddColorOnlyQuad, except it's hollow. -// -//========================================================================== - -void D3DFB::AddColorOnlyRect(int left, int top, int width, int height, D3DCOLOR color) -{ - AddColorOnlyQuad(left, top, width - 1, 1, color); // top - AddColorOnlyQuad(left + width - 1, top, 1, height - 1, color); // right - AddColorOnlyQuad(left + 1, top + height - 1, width - 1, 1, color); // bottom - AddColorOnlyQuad(left, top + 1, 1, height - 1, color); // left -} - -//========================================================================== -// -// D3DFB :: CheckQuadBatch -// -// Make sure there's enough room in the batch for one more set of triangles. -// -//========================================================================== - -void D3DFB::CheckQuadBatch(int numtris, int numverts) -{ - if (BatchType == BATCH_Lines) - { - EndLineBatch(); - } - else if (QuadBatchPos == MAX_QUAD_BATCH || - VertexPos + numverts > NUM_VERTS || - IndexPos + numtris * 3 > NUM_INDEXES) - { - EndQuadBatch(); - } - if (QuadBatchPos < 0) - { - BeginQuadBatch(); - } -} - -//========================================================================== -// -// D3DFB :: BeginQuadBatch -// -// Locks the vertex buffer for quads and sets the cursor to 0. -// -//========================================================================== - -void D3DFB::BeginQuadBatch() -{ - if (In2D < 2 || !InScene || QuadBatchPos >= 0) - { - return; - } - EndLineBatch(); // Make sure all lines have been drawn first. - VertexBuffer->Lock(0, 0, (void **)&VertexData, D3DLOCK_DISCARD); - IndexBuffer->Lock(0, 0, (void **)&IndexData, D3DLOCK_DISCARD); - VertexPos = 0; - IndexPos = 0; - QuadBatchPos = 0; - BatchType = BATCH_Quads; -} - -//========================================================================== -// -// D3DFB :: EndQuadBatch -// -// Draws all the quads that have been batched up. -// -//========================================================================== - -void D3DFB::EndQuadBatch() -{ - if (In2D < 2 || !InScene || BatchType != BATCH_Quads) - { - return; - } - BatchType = BATCH_None; - VertexBuffer->Unlock(); - IndexBuffer->Unlock(); - if (QuadBatchPos == 0) - { - QuadBatchPos = -1; - VertexPos = -1; - IndexPos = -1; - return; - } - D3DDevice->SetStreamSource(0, VertexBuffer, 0, sizeof(FBVERTEX)); - D3DDevice->SetIndices(IndexBuffer); - bool uv_wrapped = false; - bool uv_should_wrap; - int indexpos, vertpos; - - indexpos = vertpos = 0; - for (int i = 0; i < QuadBatchPos; ) - { - const BufferedTris *quad = &QuadExtra[i]; - int j; - - int startindex = indexpos; - int startvertex = vertpos; - - indexpos += quad->NumTris * 3; - vertpos += quad->NumVerts; - - // Quads with matching parameters should be done with a single - // DrawPrimitive call. - for (j = i + 1; j < QuadBatchPos; ++j) - { - const BufferedTris *q2 = &QuadExtra[j]; - if (quad->Texture != q2->Texture || - quad->Group1 != q2->Group1 || - quad->Palette != q2->Palette) - { - break; - } - if (quad->ShaderNum == BQS_InGameColormap && (quad->Flags & BQF_Desaturated) && quad->Desat != q2->Desat) - { - break; - } - indexpos += q2->NumTris * 3; - vertpos += q2->NumVerts; - } - - // Set the palette (if one) - if ((quad->Flags & BQF_Paletted) == BQF_GamePalette) - { - SetPaletteTexture(PaletteTexture, 256, BorderColor); - } - else if ((quad->Flags & BQF_Paletted) == BQF_CustomPalette) - { - assert(quad->Palette != NULL); - SetPaletteTexture(quad->Palette->Tex, quad->Palette->RoundedPaletteSize, quad->Palette->BorderColor); - } -#if 0 - // Set paletted bilinear filtering (IF IT WORKED RIGHT!) - if ((quad->Flags & (BQF_Paletted | BQF_Bilinear)) == (BQF_Paletted | BQF_Bilinear)) - { - SetPalTexBilinearConstants(quad->Texture); - } -#endif - - // Set the alpha blending - SetAlphaBlend(D3DBLENDOP(quad->BlendOp), D3DBLEND(quad->SrcBlend), D3DBLEND(quad->DestBlend)); - - // Set the alpha test - EnableAlphaTest(!(quad->Flags & BQF_DisableAlphaTest)); - - // Set the pixel shader - if (quad->ShaderNum == BQS_PalTex) - { - SetPixelShader(Shaders[(quad->Flags & BQF_InvertSource) ? - SHADER_NormalColorPalInv : SHADER_NormalColorPal]); - } - else if (quad->ShaderNum == BQS_Plain) - { - SetPixelShader(Shaders[(quad->Flags & BQF_InvertSource) ? - SHADER_NormalColorInv : SHADER_NormalColor]); - } - else if (quad->ShaderNum == BQS_RedToAlpha) - { - SetPixelShader(Shaders[(quad->Flags & BQF_InvertSource) ? - SHADER_RedToAlphaInv : SHADER_RedToAlpha]); - } - else if (quad->ShaderNum == BQS_ColorOnly) - { - SetPixelShader(Shaders[SHADER_VertexColor]); - } - else if (quad->ShaderNum == BQS_SpecialColormap) - { - int select; - - select = !!(quad->Flags & BQF_Paletted); - SetPixelShader(Shaders[SHADER_SpecialColormap + select]); - } - else if (quad->ShaderNum == BQS_InGameColormap) - { - int select; - - select = !!(quad->Flags & BQF_Desaturated); - select |= !!(quad->Flags & BQF_InvertSource) << 1; - select |= !!(quad->Flags & BQF_Paletted) << 2; - if (quad->Flags & BQF_Desaturated) - { - SetConstant(PSCONST_Desaturation, quad->Desat / 255.f, (255 - quad->Desat) / 255.f, 0, 0); - } - SetPixelShader(Shaders[SHADER_InGameColormap + select]); - } - - // Set the texture clamp addressing mode - uv_should_wrap = !!(quad->Flags & BQF_WrapUV); - if (uv_wrapped != uv_should_wrap) - { - DWORD mode = uv_should_wrap ? D3DTADDRESS_WRAP : D3DTADDRESS_BORDER; - uv_wrapped = uv_should_wrap; - D3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, mode); - D3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, mode); - } - - // Set the texture - if (quad->Texture != NULL) - { - SetTexture(0, quad->Texture); - } - - // Draw the quad - D3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, - startvertex, // MinIndex - vertpos - startvertex, // NumVertices - startindex, // StartIndex - (indexpos - startindex) / 3 // PrimitiveCount - /*4 * i, 4 * (j - i), 6 * i, 2 * (j - i)*/); - i = j; - } - if (uv_wrapped) - { - D3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER); - D3DDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER); - } - QuadBatchPos = -1; - VertexPos = -1; - IndexPos = -1; -} - -//========================================================================== -// -// D3DFB :: EndBatch -// -// Draws whichever type of primitive is currently being batched. -// -//========================================================================== - -void D3DFB::EndBatch() -{ - if (BatchType == BATCH_Quads) - { - EndQuadBatch(); - } - else if (BatchType == BATCH_Lines) - { - EndLineBatch(); - } -} - -//========================================================================== -// -// D3DFB :: SetStyle -// -// Patterned after R_SetPatchStyle. -// -//========================================================================== - -bool D3DFB::SetStyle(D3DTex *tex, DrawParms &parms, D3DCOLOR &color0, D3DCOLOR &color1, BufferedTris &quad) -{ - D3DFORMAT fmt = tex->GetTexFormat(); - FRenderStyle style = parms.style; - float alpha; - bool stencilling; - - if (style.Flags & STYLEF_TransSoulsAlpha) - { - alpha = transsouls; - } - else if (style.Flags & STYLEF_Alpha1) - { - alpha = 1; - } - else - { - alpha = clamp(parms.Alpha, 0.f, 1.f); - } - - style.CheckFuzz(); - if (style.BlendOp == STYLEOP_Shadow) - { - style = LegacyRenderStyles[STYLE_TranslucentStencil]; - alpha = 0.3f; - parms.fillcolor = 0; - } - - // FIXME: Fuzz effect is not written - if (style.BlendOp == STYLEOP_FuzzOrAdd || style.BlendOp == STYLEOP_Fuzz) - { - style.BlendOp = STYLEOP_Add; - } - else if (style.BlendOp == STYLEOP_FuzzOrSub) - { - style.BlendOp = STYLEOP_Sub; - } - else if (style.BlendOp == STYLEOP_FuzzOrRevSub) - { - style.BlendOp = STYLEOP_RevSub; - } - - stencilling = false; - quad.Palette = NULL; - quad.Flags = 0; - quad.Desat = 0; - - switch (style.BlendOp) - { - default: - case STYLEOP_Add: quad.BlendOp = D3DBLENDOP_ADD; break; - case STYLEOP_Sub: quad.BlendOp = D3DBLENDOP_SUBTRACT; break; - case STYLEOP_RevSub: quad.BlendOp = D3DBLENDOP_REVSUBTRACT; break; - case STYLEOP_None: return false; - } - quad.SrcBlend = GetStyleAlpha(style.SrcAlpha); - quad.DestBlend = GetStyleAlpha(style.DestAlpha); - - if (style.Flags & STYLEF_InvertOverlay) - { - // Only the overlay color is inverted, not the overlay alpha. - parms.colorOverlay = D3DCOLOR_ARGB(APART(parms.colorOverlay), - 255 - RPART(parms.colorOverlay), 255 - GPART(parms.colorOverlay), - 255 - BPART(parms.colorOverlay)); - } - - SetColorOverlay(parms.colorOverlay, alpha, color0, color1); - - if (style.Flags & STYLEF_ColorIsFixed) - { - if (style.Flags & STYLEF_InvertSource) - { // Since the source color is a constant, we can invert it now - // without spending time doing it in the shader. - parms.fillcolor = D3DCOLOR_XRGB(255 - RPART(parms.fillcolor), - 255 - GPART(parms.fillcolor), 255 - BPART(parms.fillcolor)); - } - // Set up the color mod to replace the color from the image data. - color0 = (color0 & D3DCOLOR_RGBA(0,0,0,255)) | (parms.fillcolor & D3DCOLOR_RGBA(255,255,255,0)); - color1 &= D3DCOLOR_RGBA(0,0,0,255); - - if (style.Flags & STYLEF_RedIsAlpha) - { - // Note that if the source texture is paletted, the palette is ignored. - quad.Flags = 0; - quad.ShaderNum = BQS_RedToAlpha; - } - else if (fmt == D3DFMT_L8) - { - quad.Flags = BQF_GamePalette; - quad.ShaderNum = BQS_PalTex; - } - else - { - quad.Flags = 0; - quad.ShaderNum = BQS_Plain; - } - } - else - { - if (style.Flags & STYLEF_RedIsAlpha) - { - quad.Flags = 0; - quad.ShaderNum = BQS_RedToAlpha; - } - else if (fmt == D3DFMT_L8) - { - if (parms.remap != NULL) - { - quad.Flags = BQF_CustomPalette; - quad.Palette = reinterpret_cast(parms.remap->GetNative()); - quad.ShaderNum = BQS_PalTex; - } - else if (tex->IsGray) - { - quad.Flags = 0; - quad.ShaderNum = BQS_Plain; - } - else - { - quad.Flags = BQF_GamePalette; - quad.ShaderNum = BQS_PalTex; - } - } - else - { - quad.Flags = 0; - quad.ShaderNum = BQS_Plain; - } - if (style.Flags & STYLEF_InvertSource) - { - quad.Flags |= BQF_InvertSource; - } - - if (parms.specialcolormap != NULL) - { // Emulate an invulnerability or similar colormap. - float *start, *end; - start = parms.specialcolormap->ColorizeStart; - end = parms.specialcolormap->ColorizeEnd; - if (quad.Flags & BQF_InvertSource) - { - quad.Flags &= ~BQF_InvertSource; - swapvalues(start, end); - } - quad.ShaderNum = BQS_SpecialColormap; - color0 = D3DCOLOR_RGBA(DWORD(start[0]/2*255), DWORD(start[1]/2*255), DWORD(start[2]/2*255), color0 >> 24); - color1 = D3DCOLOR_RGBA(DWORD(end[0]/2*255), DWORD(end[1]/2*255), DWORD(end[2]/2*255), color1 >> 24); - } - else if (parms.colormapstyle != NULL) - { // Emulate the fading from an in-game colormap (colorized, faded, and desaturated) - if (parms.colormapstyle->Desaturate != 0) - { - quad.Flags |= BQF_Desaturated; - } - quad.ShaderNum = BQS_InGameColormap; - quad.Desat = parms.colormapstyle->Desaturate; - color0 = D3DCOLOR_ARGB(color1 >> 24, - parms.colormapstyle->Color.r, - parms.colormapstyle->Color.g, - parms.colormapstyle->Color.b); - double fadelevel = parms.colormapstyle->FadeLevel; - color1 = D3DCOLOR_ARGB(DWORD((1 - fadelevel) * 255), - DWORD(parms.colormapstyle->Fade.r * fadelevel), - DWORD(parms.colormapstyle->Fade.g * fadelevel), - DWORD(parms.colormapstyle->Fade.b * fadelevel)); - } - } - - // For unmasked images, force the alpha from the image data to be ignored. - if (!parms.masked && quad.ShaderNum != BQS_InGameColormap) - { - color0 = (color0 & D3DCOLOR_RGBA(255, 255, 255, 0)) | D3DCOLOR_COLORVALUE(0, 0, 0, alpha); - color1 &= D3DCOLOR_RGBA(255, 255, 255, 0); - - // If our alpha is one and we are doing normal adding, then we can turn the blend off completely. - if (quad.BlendOp == D3DBLENDOP_ADD && - ((alpha == 1 && quad.SrcBlend == D3DBLEND_SRCALPHA) || quad.SrcBlend == D3DBLEND_ONE) && - ((alpha == 1 && quad.DestBlend == D3DBLEND_INVSRCALPHA) || quad.DestBlend == D3DBLEND_ZERO)) - { - quad.BlendOp = D3DBLENDOP(0); - } - quad.Flags |= BQF_DisableAlphaTest; - } - return true; -} - -D3DBLEND D3DFB::GetStyleAlpha(int type) -{ - switch (type) - { - case STYLEALPHA_Zero: return D3DBLEND_ZERO; - case STYLEALPHA_One: return D3DBLEND_ONE; - case STYLEALPHA_Src: return D3DBLEND_SRCALPHA; - case STYLEALPHA_InvSrc: return D3DBLEND_INVSRCALPHA; - default: return D3DBLEND_ZERO; - } -} - - -void D3DFB::SetColorOverlay(DWORD color, float alpha, D3DCOLOR &color0, D3DCOLOR &color1) -{ - if (APART(color) != 0) - { - int a = APART(color) * 256 / 255; - color0 = D3DCOLOR_RGBA( - (RPART(color) * a) >> 8, - (GPART(color) * a) >> 8, - (BPART(color) * a) >> 8, - 0); - a = 256 - a; - color1 = D3DCOLOR_RGBA(a, a, a, int(alpha * 255)); - } - else - { - color0 = 0; - color1 = D3DCOLOR_COLORVALUE(1, 1, 1, alpha); - } -} - -void D3DFB::EnableAlphaTest(BOOL enabled) -{ - if (enabled != AlphaTestEnabled) - { - AlphaTestEnabled = enabled; - D3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, enabled); - } -} - -void D3DFB::SetAlphaBlend(D3DBLENDOP op, D3DBLEND srcblend, D3DBLEND destblend) -{ - if (op == 0) - { // Disable alpha blend - if (AlphaBlendEnabled) - { - AlphaBlendEnabled = FALSE; - D3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - } - } - else - { // Enable alpha blend - assert(srcblend != 0); - assert(destblend != 0); - - if (!AlphaBlendEnabled) - { - AlphaBlendEnabled = TRUE; - D3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - } - if (AlphaBlendOp != op) - { - AlphaBlendOp = op; - D3DDevice->SetRenderState(D3DRS_BLENDOP, op); - } - if (AlphaSrcBlend != srcblend) - { - AlphaSrcBlend = srcblend; - D3DDevice->SetRenderState(D3DRS_SRCBLEND, srcblend); - } - if (AlphaDestBlend != destblend) - { - AlphaDestBlend = destblend; - D3DDevice->SetRenderState(D3DRS_DESTBLEND, destblend); - } - } -} - -void D3DFB::SetConstant(int cnum, float r, float g, float b, float a) -{ - if (Constant[cnum][0] != r || - Constant[cnum][1] != g || - Constant[cnum][2] != b || - Constant[cnum][3] != a) - { - Constant[cnum][0] = r; - Constant[cnum][1] = g; - Constant[cnum][2] = b; - Constant[cnum][3] = a; - D3DDevice->SetPixelShaderConstantF(cnum, Constant[cnum], 1); - } -} - -void D3DFB::SetPixelShader(IDirect3DPixelShader9 *shader) -{ - if (CurPixelShader != shader) - { - CurPixelShader = shader; - D3DDevice->SetPixelShader(shader); - } -} - -void D3DFB::SetTexture(int tnum, IDirect3DTexture9 *texture) -{ - assert(unsigned(tnum) < countof(Texture)); - if (Texture[tnum] != texture) - { - Texture[tnum] = texture; - D3DDevice->SetTexture(tnum, texture); - } -} - -void D3DFB::SetPaletteTexture(IDirect3DTexture9 *texture, int count, D3DCOLOR border_color) -{ - if (SM14) - { - // Shader Model 1.4 only uses 256-color palettes. - SetConstant(PSCONST_PaletteMod, 1.f, 0.5f / 256.f, 0, 0); - if (border_color != 0 && CurBorderColor != border_color) - { - CurBorderColor = border_color; - D3DDevice->SetSamplerState(1, D3DSAMP_BORDERCOLOR, border_color); - } - } - else - { - // The pixel shader receives color indexes in the range [0.0,1.0]. - // The palette texture is also addressed in the range [0.0,1.0], - // HOWEVER the coordinate 1.0 is the right edge of the texture and - // not actually the texture itself. We need to scale and shift - // the palette indexes so they lie exactly in the center of each - // texel. For a normal palette with 256 entries, that means the - // range we use should be [0.5,255.5], adjusted so the coordinate - // is still within [0.0,1.0]. - // - // The constant register c2 is used to hold the multiplier in the - // x part and the adder in the y part. - float fcount = 1 / float(count); - SetConstant(PSCONST_PaletteMod, 255 * fcount, 0.5f * fcount, 0, 0); - } - SetTexture(1, texture); -} - -void D3DFB::SetPalTexBilinearConstants(Atlas *tex) -{ -#if 0 - float con[8]; - - // Don't bother doing anything if the constants won't be used. - if (PalTexShader == PalTexBilinearShader) - { - return; - } - - con[0] = float(tex->Width); - con[1] = float(tex->Height); - con[2] = 0; - con[3] = 1 / con[0]; - con[4] = 0; - con[5] = 1 / con[1]; - con[6] = con[5]; - con[7] = con[3]; - - D3DDevice->SetPixelShaderConstantF(3, con, 2); -#endif -} diff --git a/src/win32/fb_d3d9_wipe.cpp b/src/win32/fb_d3d9_wipe.cpp deleted file mode 100644 index 62533899ac..0000000000 --- a/src/win32/fb_d3d9_wipe.cpp +++ /dev/null @@ -1,658 +0,0 @@ -/* -** fb_d3d9_wipe.cpp -** Implements the different screen wipes using Direct3D calls. -** -**--------------------------------------------------------------------------- -** Copyright 1998-2008 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -// HEADER FILES ------------------------------------------------------------ - -#ifdef _DEBUG -#define D3D_DEBUG_INFO -#endif -#define DIRECT3D_VERSION 0x0900 -#define WIN32_LEAN_AND_MEAN - -#include -#include -#include - -#include "doomtype.h" -#include "f_wipe.h" -#include "win32iface.h" -#include "win32swiface.h" -#include "templates.h" -#include "m_random.h" - -// MACROS ------------------------------------------------------------------ - -// TYPES ------------------------------------------------------------------- - -class D3DFB::Wiper_Crossfade : public D3DFB::Wiper -{ -public: - Wiper_Crossfade(); - bool Run(int ticks, D3DFB *fb); - -private: - int Clock; -}; - -class D3DFB::Wiper_Melt : public D3DFB::Wiper -{ -public: - Wiper_Melt(); - bool Run(int ticks, D3DFB *fb); - -private: - // Match the strip sizes that oldschool Doom used. - static const int WIDTH = 160, HEIGHT = 200; - int y[WIDTH]; -}; - -class D3DFB::Wiper_Burn : public D3DFB::Wiper -{ -public: - Wiper_Burn(D3DFB *fb); - ~Wiper_Burn(); - bool Run(int ticks, D3DFB *fb); - -private: - static const int WIDTH = 64, HEIGHT = 64; - uint8_t BurnArray[WIDTH * (HEIGHT + 5)]; - IDirect3DTexture9 *BurnTexture; - int Density; - int BurnTime; - - struct BURNVERTEX - { - FLOAT x, y, z, rhw; - FLOAT tu0, tv0; - FLOAT tu1, tv1; - }; -#define D3DFVF_BURNVERTEX (D3DFVF_XYZRHW|D3DFVF_TEX2) -}; - -// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- - -// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- - -// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- - -// EXTERNAL DATA DECLARATIONS ---------------------------------------------- - -// PRIVATE DATA DEFINITIONS ------------------------------------------------ - -// PUBLIC DATA DEFINITIONS ------------------------------------------------- - -// CODE -------------------------------------------------------------------- - -//========================================================================== -// -// D3DFB :: WipeStartScreen -// -// Called before the current screen has started rendering. This needs to -// save what was drawn the previous frame so that it can be animated into -// what gets drawn this frame. -// -// In fullscreen mode, we use GetFrontBufferData() to grab the data that -// is visible on screen right now. -// -// In windowed mode, we can't do that because we'll get the whole desktop. -// Instead, we can conveniently use the TempRenderTexture, which is normally -// used for gamma-correcting copying the image to the back buffer. -// -//========================================================================== - -bool D3DFB::WipeStartScreen(int type) -{ - IDirect3DSurface9 *tsurf; - D3DSURFACE_DESC desc; - - if (!Accel2D) - { - return Super::WipeStartScreen(type); - } - - switch (type) - { - case wipe_Melt: - ScreenWipe = new Wiper_Melt; - break; - - case wipe_Burn: - ScreenWipe = new Wiper_Burn(this); - break; - - case wipe_Fade: - ScreenWipe = new Wiper_Crossfade; - break; - - default: - return false; - } - - InitialWipeScreen = GetCurrentScreen(D3DPOOL_DEFAULT); - - // Create another texture to copy the final wipe screen to so - // we can still gamma correct the wipe. Since this is just for - // gamma correction, it's okay to fail (though not desirable.) - if (PixelDoubling || Windowed) - { - if (SUCCEEDED(TempRenderTexture->GetSurfaceLevel(0, &tsurf))) - { - if (FAILED(tsurf->GetDesc(&desc)) || - FAILED(D3DDevice->CreateTexture(desc.Width, desc.Height, - 1, D3DUSAGE_RENDERTARGET, desc.Format, D3DPOOL_DEFAULT, - &FinalWipeScreen, NULL))) - { - (FinalWipeScreen = TempRenderTexture)->AddRef(); - } - tsurf->Release(); - } - } - else - { - (FinalWipeScreen = TempRenderTexture)->AddRef(); - } - - // Make even fullscreen model render to the TempRenderTexture, so - // we can have a copy of the new screen readily available. - GatheringWipeScreen = true; - return true; -} - -//========================================================================== -// -// D3DFB :: WipeEndScreen -// -// The screen we want to animate to has just been drawn. This function is -// called in place of Update(), so it has not been Presented yet. -// -//========================================================================== - -void D3DFB::WipeEndScreen() -{ - if (!Accel2D) - { - Super::WipeEndScreen(); - return; - } - - // Don't do anything if there is no starting point. - if (InitialWipeScreen == NULL) - { - return; - } - - // If the whole screen was drawn without 2D accel, get it in to - // video memory now. - if (!In2D) - { - Begin2D(true); - } - - EndBatch(); // Make sure all batched primitives have been drawn. - - // Don't do anything if there is no ending point. - if (OldRenderTarget == NULL) - { - return; - } - - // If these are different, reverse their roles so we don't need to - // waste time copying from TempRenderTexture to FinalWipeScreen. - if (FinalWipeScreen != TempRenderTexture) - { - swapvalues(RenderTexture[CurrRenderTexture], FinalWipeScreen); - TempRenderTexture = RenderTexture[CurrRenderTexture]; - } - - // At this point, InitialWipeScreen holds the screen we are wiping from. - // FinalWipeScreen holds the screen we are wiping to, which may be the - // same texture as TempRenderTexture. -} - -//========================================================================== -// -// D3DFB :: WipeDo -// -// Perform the actual wipe animation. The number of tics since the last -// time this function was called is passed in. Returns true when the wipe -// is over. The first time this function has been called, the screen is -// still locked from before and EndScene() still has not been called. -// Successive times need to call BeginScene(). -// -//========================================================================== - -bool D3DFB::WipeDo(int ticks) -{ - if (!Accel2D) - { - return Super::WipeDo(ticks); - } - - // Sanity checks. - if (InitialWipeScreen == NULL || FinalWipeScreen == NULL) - { - return true; - } - if (GatheringWipeScreen) - { // This is the first time we've been called for this wipe. - GatheringWipeScreen = false; - - if (OldRenderTarget == NULL) - { - return true; - } - D3DDevice->SetRenderTarget(0, OldRenderTarget); - } - else - { // This is the second or later time we've been called for this wipe. - D3DDevice->BeginScene(); - InScene = true; - } - SAFE_RELEASE( OldRenderTarget ); - if (TempRenderTexture != NULL && TempRenderTexture != FinalWipeScreen) - { - IDirect3DSurface9 *targetsurf; - if (SUCCEEDED(TempRenderTexture->GetSurfaceLevel(0, &targetsurf))) - { - if (SUCCEEDED(D3DDevice->GetRenderTarget(0, &OldRenderTarget))) - { - if (FAILED(D3DDevice->SetRenderTarget(0, targetsurf))) - { - // Setting the render target failed. - } - } - targetsurf->Release(); - } - } - In2D = 3; - - EnableAlphaTest(FALSE); - bool done = ScreenWipe->Run(ticks, this); - DrawLetterbox(); - return done; -} - -//========================================================================== -// -// D3DFB :: WipeCleanup -// -// Release any resources that were specifically created for the wipe. -// -//========================================================================== - -void D3DFB::WipeCleanup() -{ - if (ScreenWipe != NULL) - { - delete ScreenWipe; - ScreenWipe = NULL; - } - SAFE_RELEASE( InitialWipeScreen ); - SAFE_RELEASE( FinalWipeScreen ); - GatheringWipeScreen = false; - if (!Accel2D) - { - Super::WipeCleanup(); - return; - } -} - -//========================================================================== -// -// D3DFB :: Wiper Constructor -// -//========================================================================== - -D3DFB::Wiper::~Wiper() -{ -} - -//========================================================================== -// -// D3DFB :: Wiper :: DrawScreen -// -// Draw either the initial or target screen completely to the screen. -// -//========================================================================== - -void D3DFB::Wiper::DrawScreen(D3DFB *fb, IDirect3DTexture9 *tex, - D3DBLENDOP blendop, D3DCOLOR color0, D3DCOLOR color1) -{ - FBVERTEX verts[4]; - - fb->CalcFullscreenCoords(verts, false, false, color0, color1); - fb->D3DDevice->SetFVF(D3DFVF_FBVERTEX); - fb->SetTexture(0, tex); - fb->SetAlphaBlend(blendop, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA); - fb->SetPixelShader(fb->Shaders[SHADER_NormalColor]); - fb->D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(FBVERTEX)); -} - -// WIPE: CROSSFADE --------------------------------------------------------- - -//========================================================================== -// -// D3DFB :: Wiper_Crossfade Constructor -// -//========================================================================== - -D3DFB::Wiper_Crossfade::Wiper_Crossfade() -: Clock(0) -{ -} - -//========================================================================== -// -// D3DFB :: Wiper_Crossfade :: Run -// -// Fades the old screen into the new one over 32 ticks. -// -//========================================================================== - -bool D3DFB::Wiper_Crossfade::Run(int ticks, D3DFB *fb) -{ - Clock += ticks; - - // Put the initial screen back to the buffer. - DrawScreen(fb, fb->InitialWipeScreen); - - // Draw the new screen on top of it. - DrawScreen(fb, fb->FinalWipeScreen, D3DBLENDOP_ADD, - D3DCOLOR_COLORVALUE(0,0,0,Clock / 32.f), D3DCOLOR_RGBA(255,255,255,0)); - - return Clock >= 32; -} - -// WIPE: MELT -------------------------------------------------------------- - -//========================================================================== -// -// D3DFB :: Wiper_Melt Constructor -// -//========================================================================== - -D3DFB::Wiper_Melt::Wiper_Melt() -{ - int i, r; - - // setup initial column positions - // (y<0 => not ready to scroll yet) - y[0] = -(M_Random() & 15); - for (i = 1; i < WIDTH; ++i) - { - r = (M_Random()%3) - 1; - y[i] = clamp(y[i-1] + r, -15, 0); - } -} - -//========================================================================== -// -// D3DFB :: Wiper_Melt :: Run -// -// Fades the old screen into the new one over 32 ticks. -// -//========================================================================== - -bool D3DFB::Wiper_Melt::Run(int ticks, D3DFB *fb) -{ - // Draw the new screen on the bottom. - DrawScreen(fb, fb->FinalWipeScreen); - - int i, dy; - int fbwidth = fb->Width; - int fbheight = fb->Height; - bool done = true; - - // Copy the old screen in vertical strips on top of the new one. - while (ticks--) - { - done = true; - for (i = 0; i < WIDTH; i++) - { - if (y[i] < 0) - { - y[i]++; - done = false; - } - else if (y[i] < HEIGHT) - { - dy = (y[i] < 16) ? y[i]+1 : 8; - y[i] = MIN(y[i] + dy, HEIGHT); - done = false; - } - if (ticks == 0) - { // Only draw for the final tick. - RECT rect; - POINT dpt; - - dpt.x = i * fbwidth / WIDTH; - dpt.y = MAX(0, y[i] * fbheight / HEIGHT); - rect.left = dpt.x; - rect.top = 0; - rect.right = (i + 1) * fbwidth / WIDTH; - rect.bottom = fbheight - dpt.y; - if (rect.bottom > rect.top) - { - fb->CheckQuadBatch(); - - BufferedTris *quad = &fb->QuadExtra[fb->QuadBatchPos]; - FBVERTEX *vert = &fb->VertexData[fb->VertexPos]; - uint16_t *index = &fb->IndexData[fb->IndexPos]; - - quad->Group1 = 0; - quad->Flags = BQF_DisableAlphaTest; - quad->ShaderNum = BQS_Plain; - quad->Palette = NULL; - quad->Texture = fb->InitialWipeScreen; - quad->NumVerts = 4; - quad->NumTris = 2; - - // Fill the vertex buffer. - float u0 = rect.left / float(fb->FBWidth); - float v0 = 0; - float u1 = rect.right / float(fb->FBWidth); - float v1 = (rect.bottom - rect.top) / float(fb->FBHeight); - - float x0 = float(rect.left) - 0.5f; - float x1 = float(rect.right) - 0.5f; - float y0 = float(dpt.y + fb->LBOffsetI) - 0.5f; - float y1 = float(fbheight + fb->LBOffsetI) - 0.5f; - - vert[0].x = x0; - vert[0].y = y0; - vert[0].z = 0; - vert[0].rhw = 1; - vert[0].color0 = 0; - vert[0].color1 = 0xFFFFFFF; - vert[0].tu = u0; - vert[0].tv = v0; - - vert[1].x = x1; - vert[1].y = y0; - vert[1].z = 0; - vert[1].rhw = 1; - vert[1].color0 = 0; - vert[1].color1 = 0xFFFFFFF; - vert[1].tu = u1; - vert[1].tv = v0; - - vert[2].x = x1; - vert[2].y = y1; - vert[2].z = 0; - vert[2].rhw = 1; - vert[2].color0 = 0; - vert[2].color1 = 0xFFFFFFF; - vert[2].tu = u1; - vert[2].tv = v1; - - vert[3].x = x0; - vert[3].y = y1; - vert[3].z = 0; - vert[3].rhw = 1; - vert[3].color0 = 0; - vert[3].color1 = 0xFFFFFFF; - vert[3].tu = u0; - vert[3].tv = v1; - - // Fill the vertex index buffer. - index[0] = fb->VertexPos; - index[1] = fb->VertexPos + 1; - index[2] = fb->VertexPos + 2; - index[3] = fb->VertexPos; - index[4] = fb->VertexPos + 2; - index[5] = fb->VertexPos + 3; - - // Batch the quad. - fb->QuadBatchPos++; - fb->VertexPos += 4; - fb->IndexPos += 6; - } - } - } - } - fb->EndQuadBatch(); - return done; -} - -// WIPE: BURN -------------------------------------------------------------- - -//========================================================================== -// -// D3DFB :: Wiper_Burn Constructor -// -//========================================================================== - -D3DFB::Wiper_Burn::Wiper_Burn(D3DFB *fb) -{ - Density = 4; - BurnTime = 0; - memset(BurnArray, 0, sizeof(BurnArray)); - if (fb->Shaders[SHADER_BurnWipe] == NULL || FAILED(fb->D3DDevice->CreateTexture(WIDTH, HEIGHT, 1, - D3DUSAGE_DYNAMIC, D3DFMT_L8, D3DPOOL_DEFAULT, &BurnTexture, NULL))) - { - BurnTexture = NULL; - } -} - -//========================================================================== -// -// D3DFB :: Wiper_Burn Destructor -// -//========================================================================== - -D3DFB::Wiper_Burn::~Wiper_Burn() -{ - SAFE_RELEASE( BurnTexture ); -} - -//========================================================================== -// -// D3DFB :: Wiper_Burn :: Run -// -//========================================================================== - -bool D3DFB::Wiper_Burn::Run(int ticks, D3DFB *fb) -{ - bool done; - - BurnTime += ticks; - ticks *= 2; - - // Make the fire burn - done = false; - while (!done && ticks--) - { - Density = wipe_CalcBurn(BurnArray, WIDTH, HEIGHT, Density); - done = (Density < 0); - } - - // Update the burn texture with the new burn data - D3DLOCKED_RECT lrect; - if (SUCCEEDED(BurnTexture->LockRect(0, &lrect, NULL, D3DLOCK_DISCARD))) - { - const uint8_t *src = BurnArray; - uint8_t *dest = (uint8_t *)lrect.pBits; - for (int y = HEIGHT; y != 0; --y) - { - for (int x = WIDTH; x != 0; --x) - { - *dest++ = *src++; - } - dest += lrect.Pitch - WIDTH; - } - BurnTexture->UnlockRect(0); - } - - // Put the initial screen back to the buffer. - DrawScreen(fb, fb->InitialWipeScreen); - - // Burn the new screen on top of it. - float top = fb->LBOffset - 0.5f; - float right = float(fb->Width) - 0.5f; - float bot = float(fb->Height) + top; - float texright = float(fb->Width) / float(fb->FBWidth); - float texbot = float(fb->Height) / float(fb->FBHeight); - - BURNVERTEX verts[4] = - { - { -0.5f, top, 0.5f, 1.f, 0.f, 0.f, 0, 0 }, - { right, top, 0.5f, 1.f, texright, 0.f, 1, 0 }, - { right, bot, 0.5f, 1.f, texright, texbot, 1, 1 }, - { -0.5f, bot, 0.5f, 1.f, 0.f, texbot, 0, 1 } - }; - - fb->D3DDevice->SetFVF(D3DFVF_BURNVERTEX); - fb->SetTexture(0, fb->FinalWipeScreen); - fb->SetTexture(1, BurnTexture); - fb->SetAlphaBlend(D3DBLENDOP_ADD, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA); - fb->SetPixelShader(fb->Shaders[SHADER_BurnWipe]); - fb->D3DDevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - if (fb->SM14) - { - fb->D3DDevice->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); - fb->D3DDevice->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); - } - fb->D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(BURNVERTEX)); - fb->D3DDevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_POINT); - if (fb->SM14) - { - fb->D3DDevice->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER); - fb->D3DDevice->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER); - } - fb->D3DDevice->SetFVF(D3DFVF_FBVERTEX); - - // The fire may not always stabilize, so the wipe is forced to end - // after an arbitrary maximum time. - return done || (BurnTime > 40); -} diff --git a/src/win32/fb_ddraw.cpp b/src/win32/fb_ddraw.cpp deleted file mode 100644 index 813509bc06..0000000000 --- a/src/win32/fb_ddraw.cpp +++ /dev/null @@ -1,1321 +0,0 @@ -/* -** fb_ddraw.cpp -** Code to let ZDoom use DirectDraw 3 -** -**--------------------------------------------------------------------------- -** Copyright 1998-2008 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -// HEADER FILES ------------------------------------------------------------ - -#define DIRECTDRAW_VERSION 0x0300 -#define WIN32_LEAN_AND_MEAN - -#include -#include -#include - -#include "doomtype.h" - -#include "c_dispatch.h" -#include "templates.h" -#include "i_system.h" -#include "i_video.h" -#include "v_video.h" -#include "v_pfx.h" -#include "stats.h" -#include "doomerrors.h" - -#include "win32iface.h" -#include "win32swiface.h" -#include "v_palette.h" - -// MACROS ------------------------------------------------------------------ - -// TYPES ------------------------------------------------------------------- - -// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- - -// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- - -void DoBlending (const PalEntry *from, PalEntry *to, int count, int r, int g, int b, int a); - -// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- - -// EXTERNAL DATA DECLARATIONS ---------------------------------------------- - -extern HWND Window; -extern IVideo *Video; -extern BOOL AppActive; -extern int SessionState; -extern bool VidResizing; - -EXTERN_CVAR (Bool, fullscreen) -EXTERN_CVAR (Float, Gamma) -EXTERN_CVAR (Int, vid_refreshrate) - -extern IDirectDraw2 *DDraw; - -// PRIVATE DATA DEFINITIONS ------------------------------------------------ - -// PUBLIC DATA DEFINITIONS ------------------------------------------------- - -CVAR (Bool, vid_palettehack, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -CVAR (Bool, vid_noblitter, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -CVAR (Int, vid_displaybits, 8, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -CUSTOM_CVAR (Float, rgamma, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -{ - if (screen != NULL) - { - screen->SetGamma (Gamma); - } -} -CUSTOM_CVAR (Float, ggamma, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -{ - if (screen != NULL) - { - screen->SetGamma (Gamma); - } -} -CUSTOM_CVAR (Float, bgamma, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -{ - if (screen != NULL) - { - screen->SetGamma (Gamma); - } -} - -cycle_t BlitCycles; - -// CODE -------------------------------------------------------------------- - -DDrawFB::DDrawFB (int width, int height, bool fullscreen) - : BaseWinFB (width, height, false) -{ - int i; - - LastHR = 0; - - Palette = NULL; - PrimarySurf = NULL; - BackSurf = NULL; - BackSurf2 = NULL; - BlitSurf = NULL; - Clipper = NULL; - GDIPalette = NULL; - ClipSize = 0; - BufferCount = 1; - Gamma = 1.0; - BufferPitch = Pitch; - FlipFlags = vid_vsync ? DDFLIP_WAIT : DDFLIP_WAIT|DDFLIP_NOVSYNC; - PixelDoubling = 0; - - NeedGammaUpdate = false; - NeedPalUpdate = false; - NeedResRecreate = false; - PaletteChangeExpected = false; - MustBuffer = false; - BufferingNow = false; - WasBuffering = false; - Write8bit = false; - UpdatePending = false; - UseBlitter = false; - - FlashAmount = 0; - - if (MemBuffer == NULL) - { - return; - } - - for (i = 0; i < 256; i++) - { - PalEntries[i].peRed = GPalette.BaseColors[i].r; - PalEntries[i].peGreen = GPalette.BaseColors[i].g; - PalEntries[i].peBlue = GPalette.BaseColors[i].b; - GammaTable[0][i] = GammaTable[1][i] = GammaTable[2][i] = (uint8_t)i; - } - memcpy (SourcePalette, GPalette.BaseColors, sizeof(PalEntry)*256); - - MustBuffer = false; - - Windowed = !(static_cast(Video)->GoFullscreen (fullscreen)); - - if (vid_noblitter) - { - LOG ("Blitter forced off\n"); - } - else - { - DDCAPS hwcaps = { sizeof(DDCAPS) }; - HRESULT hr = DDraw->GetCaps (&hwcaps, NULL); - if (SUCCEEDED(hr)) - { - LOG2 ("dwCaps = %08lx, dwSVBCaps = %08lx\n", hwcaps.dwCaps, hwcaps.dwSVBCaps); - if (hwcaps.dwCaps & DDCAPS_BLT) - { - LOG ("Driver supports blits\n"); - if (hwcaps.dwSVBCaps & DDCAPS_CANBLTSYSMEM) - { - LOG ("Driver can blit from system memory\n"); - if (hwcaps.dwCaps & DDCAPS_BLTQUEUE) - { - LOG ("Driver supports asynchronous blits\n"); - UseBlitter = true; - } - else - { - LOG ("Driver does not support asynchronous blits\n"); - } - } - else - { - LOG ("Driver cannot blit from system memory\n"); - } - } - else - { - LOG ("Driver does not support blits\n"); - } - } - } - - if (!CreateResources ()) - { - SAFE_RELEASE( PrimarySurf ); - } -} - -DDrawFB::~DDrawFB () -{ - I_SaveWindowedPos (); - ReleaseResources (); -} - -bool DDrawFB::CreateResources () -{ - DDSURFACEDESC ddsd = { sizeof(ddsd), }; - HRESULT hr; - int bits; - - BufferCount = 1; - - if (!Windowed) - { - // Remove the window border in fullscreen mode - SetWindowLong (Window, GWL_STYLE, WS_POPUP|WS_VISIBLE|WS_SYSMENU); - - TrueHeight = Height; - for (Win32Video::ModeInfo *mode = static_cast(Video)->m_Modes; mode != NULL; mode = mode->next) - { - if (mode->width == Width && mode->height == Height) - { - TrueHeight = mode->realheight; - PixelDoubling = mode->doubling; - break; - } - } - hr = DDraw->SetDisplayMode (Width << PixelDoubling, TrueHeight << PixelDoubling, bits = vid_displaybits, vid_refreshrate, 0); - if (FAILED(hr)) - { - hr = DDraw->SetDisplayMode (Width << PixelDoubling, TrueHeight << PixelDoubling, bits = vid_displaybits, 0, 0); - bits = 32; - while (FAILED(hr) && bits >= 8) - { - hr = DDraw->SetDisplayMode (Width << PixelDoubling, Height << PixelDoubling, bits, vid_refreshrate, 0); - if (FAILED(hr)) - { - hr = DDraw->SetDisplayMode (Width << PixelDoubling, Height << PixelDoubling, bits, 0, 0); - } - bits -= 8; - } - if (FAILED(hr)) - { - LastHR = hr; - return false; - } - } - LOG3 ("Mode set to %d x %d x %d\n", Width, Height, bits); - - if (!CreateSurfacesComplex ()) - return false; - - if (UseBlitter) - { - UseBlitter = CreateBlitterSource (); - } - } - else - { - MustBuffer = true; - - LOG ("Running in a window\n"); - TrueHeight = Height; - - // Create the primary surface - ddsd.dwFlags = DDSD_CAPS; - ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; -// PixelDoubling = 1; - do - { - hr = DDraw->CreateSurface (&ddsd, &PrimarySurf, NULL); - LOG1 ("Create primary: %08lx\n", hr); - } while (0); - if (FAILED(hr)) - { - LastHR = hr; - return false; - } - - MaybeCreatePalette (); - - // Resize the window to match desired dimensions - RECT rect = { 0, 0, Width << PixelDoubling, Height << PixelDoubling }; - AdjustWindowRectEx(&rect, WS_VISIBLE|WS_OVERLAPPEDWINDOW, FALSE, WS_EX_APPWINDOW); - int sizew = rect.right - rect.left; - int sizeh = rect.bottom - rect.top; - LOG2 ("Resize window to %dx%d\n", sizew, sizeh); - VidResizing = true; - // Make sure the window has a border in windowed mode - SetWindowLong (Window, GWL_STYLE, WS_VISIBLE|WS_OVERLAPPEDWINDOW); - if (!SetWindowPos (Window, NULL, 0, 0, sizew, sizeh, - SWP_DRAWFRAME | SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOZORDER)) - { - LOG1 ("SetWindowPos failed because %08lx\n", GetLastError()); - } - I_RestoreWindowedPos (); - VidResizing = false; - - // Create the clipper - hr = DDraw->CreateClipper (0, &Clipper, NULL); - LOG1 ("Create clipper: %08lx\n", hr); - if (FAILED(hr)) - { - LastHR = hr; - return false; - } - // Associate the clipper with the window - Clipper->SetHWnd (0, Window); - PrimarySurf->SetClipper (Clipper); - LOG1 ("Clipper @ %p set\n", Clipper); - - // Create the backbuffer - ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS; - ddsd.dwWidth = Width << PixelDoubling; - ddsd.dwHeight = Height << PixelDoubling; - ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | (UseBlitter ? DDSCAPS_SYSTEMMEMORY : 0); - - hr = DDraw->CreateSurface (&ddsd, &BackSurf, NULL); - LOG1 ("Create backbuffer: %08lx\n", hr); - if (FAILED(hr)) - { - LastHR = hr; - return false; - } - LockingSurf = BackSurf; - LOG1 ("LockingSurf and BackSurf @ %p\n", BackSurf); - LOG ("Created backbuf\n"); - } - SetGamma (Gamma); - SetFlash (Flash, FlashAmount); - return true; -} - -bool DDrawFB::CreateSurfacesAttached () -{ - DDSURFACEDESC ddsd = { sizeof(ddsd), }; - HRESULT hr; - - LOG ("creating surfaces using AddAttachedSurface\n"); - - ddsd.dwFlags = DDSD_CAPS; - ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY; - hr = DDraw->CreateSurface (&ddsd, &PrimarySurf, NULL); - if (FAILED(hr)) - { - LastHR = hr; - return false; - } - - LOG1 ("Primary surface @ %p\n", PrimarySurf); - - // Under NT 4 and with bad DDraw drivers under 9x (and maybe Win2k?) - // if the palette is not attached to the primary surface before any - // back buffers are added to it, colors 0 and 255 will remain black - // and white respectively. - MaybeCreatePalette (); - - // Try for triple buffering. Unbuffered output is only allowed if - // we manage to get triple buffering. Even with double buffering, - // framerate can slow significantly compared to triple buffering, - // so we force buffering in that case, which effectively emulates - // triple buffering (after a fashion). - if (!AddBackBuf (&BackSurf, 1) || !AddBackBuf (&BackSurf2, 2)) - { -// MustBuffer = true; - } - if (BackSurf != NULL) - { - DDSCAPS caps = { DDSCAPS_BACKBUFFER, }; - hr = PrimarySurf->GetAttachedSurface (&caps, &LockingSurf); - if (FAILED (hr)) - { - LOG1 ("Could not get attached surface: %08lx\n", hr); - if (BackSurf2 != NULL) - { - PrimarySurf->DeleteAttachedSurface (0, BackSurf2); - BackSurf2->Release (); - BackSurf2 = NULL; - } - PrimarySurf->DeleteAttachedSurface (0, BackSurf); - BackSurf->Release (); - BackSurf = NULL; -// MustBuffer = true; - LockingSurf = PrimarySurf; - } - else - { - BufferCount = (BackSurf2 != NULL) ? 3 : 2; - LOG ("Got attached surface\n"); - } - } - else - { - LOG ("No flip chain\n"); - LockingSurf = PrimarySurf; - } - return true; -} - -bool DDrawFB::AddBackBuf (LPDIRECTDRAWSURFACE *surface, int num) -{ - DDSURFACEDESC ddsd = { sizeof(ddsd), }; - HRESULT hr; - - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.dwWidth = Width; - ddsd.dwHeight = Height; - ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; - hr = DDraw->CreateSurface (&ddsd, surface, NULL); - if (FAILED(hr)) - { - LOG2 ("could not create back buf %d: %08lx\n", num, hr); - return false; - } - else - { - LOG2 ("BackBuf %d created @ %p\n", num, *surface); - hr = PrimarySurf->AddAttachedSurface (*surface); - if (FAILED(hr)) - { - LOG2 ("could not add back buf %d: %08lx\n", num, hr); - (*surface)->Release (); - *surface = NULL; - return false; - } - else - { - LOG1 ("Attachment of back buf %d succeeded\n", num); - } - } - return true; -} - -bool DDrawFB::CreateSurfacesComplex () -{ - DDSURFACEDESC ddsd = { sizeof(ddsd), }; - HRESULT hr; - int tries = 2; - - LOG ("creating surfaces using a complex primary\n"); - - // Try for triple buffering first. - // If that fails, try for double buffering. - // If that fails, settle for single buffering. - // If that fails, then give up. - // - // However, if using the blitter, then do not triple buffer the - // primary surface, because that is effectively like quadruple - // buffering and player response starts feeling too sluggish. - ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; - ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY - | DDSCAPS_FLIP | DDSCAPS_COMPLEX; - do - { - LOG1 ("Try #%d\n", tries); - ddsd.dwBackBufferCount = UseBlitter ? 1 : 2; - hr = DDraw->CreateSurface (&ddsd, &PrimarySurf, NULL); - if (FAILED(hr)) - { - if (hr == DDERR_NOEXCLUSIVEMODE) - { - LOG ("Exclusive mode was lost, so restoring it now.\n"); - hr = DDraw->SetCooperativeLevel (Window, DDSCL_ALLOWMODEX | DDSCL_ALLOWREBOOT | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); - LOG1 ("SetCooperativeLevel result: %08lx\n", hr); - hr = DDraw->SetDisplayMode (Width, Height, 8, 0, 0); - //hr = DDraw->RestoreDisplayMode (); - LOG1 ("SetDisplayMode result: %08lx\n", hr); - ++tries; - hr = E_FAIL; - continue; - } - - LOG1 ("Could not create with 2 backbuffers: %lx\n", hr); - ddsd.dwBackBufferCount = 1; - hr = DDraw->CreateSurface (&ddsd, &PrimarySurf, NULL); - if (FAILED(hr)) - { - LOG1 ("Could not create with 1 backbuffer: %lx\n", hr); - ddsd.ddsCaps.dwCaps &= ~DDSCAPS_FLIP | DDSCAPS_COMPLEX; - ddsd.dwBackBufferCount = 0; - hr = DDraw->CreateSurface (&ddsd, &PrimarySurf, NULL); - if (FAILED (hr)) - { - LOG1 ("Could not create with 0 backbuffers: %lx\n", hr); - if (tries == 2) - { - LOG ("Retrying without DDSCAPS_VIDEOMEMORY\n"); - ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE - | DDSCAPS_FLIP | DDSCAPS_COMPLEX; - } - } - } - } - } while (FAILED(hr) && --tries); - - if (FAILED(hr)) - { - LastHR = hr; - return false; - } - - LOG1 ("Complex surface chain @ %p\n", PrimarySurf); - if (PrimarySurf == NULL) - { - LOG ("It's NULL but it didn't fail?!?\n"); - LastHR = E_FAIL; - return false; - } - - if (ddsd.dwBackBufferCount == 0) - { - LOG ("No flip chain\n"); -// MustBuffer = true; - LockingSurf = PrimarySurf; - } - else - { - DDSCAPS caps = { DDSCAPS_BACKBUFFER, }; - hr = PrimarySurf->GetAttachedSurface (&caps, &LockingSurf); - if (FAILED (hr)) - { - LOG1 ("Could not get attached surface: %08lx\n", hr); -// MustBuffer = true; - LockingSurf = PrimarySurf; - } - else - { - BufferCount = ddsd.dwBackBufferCount + 1; - LOG1 ("Got attached surface. %d buffers\n", BufferCount); - } - } - - MaybeCreatePalette (); - return true; -} - -bool DDrawFB::CreateBlitterSource () -{ - DDSURFACEDESC ddsd = { sizeof(ddsd), }; - HRESULT hr; - - LOG ("Creating surface for blitter source\n"); - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_BACKBUFFERCOUNT; - ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY - | DDSCAPS_FLIP | DDSCAPS_COMPLEX; - ddsd.dwBackBufferCount = 2; - ddsd.dwWidth = (Width==1024?1024+16:Width); - ddsd.dwHeight = Height; - hr = DDraw->CreateSurface (&ddsd, &BlitSurf, NULL); - if (FAILED(hr)) - { - LOG1 ("Trying to create blitter source with only one surface (%08lx)\n", hr); - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; - hr = DDraw->CreateSurface (&ddsd, &BlitSurf, NULL); - if (FAILED(hr)) - { - LOG1 ("Could not create blitter source: %08lx\n", hr); - MustBuffer = true; - return false; - } - BufferCount = MAX (BufferCount, 1); - } - else - { - BufferCount = MAX (BufferCount, 2); - } - LOG1 ("Blitter source created successfully @ %p\n", BlitSurf); - return true; -} - -void DDrawFB::MaybeCreatePalette () -{ - DDPIXELFORMAT fmt = { sizeof(fmt), }; - HRESULT hr; - int i; - - UsePfx = false; - - // If the surface needs a palette, try to create one. If the palette - // cannot be created, the result is ugly but non-fatal. - hr = PrimarySurf->GetPixelFormat (&fmt); - if (SUCCEEDED (hr) && (fmt.dwFlags & DDPF_PALETTEINDEXED8)) - { - LOG ("Surface is paletted\n"); - GPfx.SetFormat (fmt.dwRGBBitCount, - fmt.dwRBitMask, fmt.dwGBitMask, fmt.dwBBitMask); - - if (Windowed) - { - struct { LOGPALETTE head; PALETTEENTRY filler[255]; } pal; - - LOG ("Writing in a window\n"); - Write8bit = true; - pal.head.palVersion = 0x300; - pal.head.palNumEntries = 256; - memcpy (pal.head.palPalEntry, PalEntries, 256*sizeof(PalEntries[0])); - for (i = 0; i < 256; i++) - { - pal.head.palPalEntry[i].peFlags = 0; - } - GDIPalette = ::CreatePalette (&pal.head); - LOG ("Created GDI palette\n"); - if (GDIPalette != NULL) - { - HDC dc = GetDC (Window); - SelectPalette (dc, GDIPalette, FALSE); - RealizePalette (dc); - ReleaseDC (Window, dc); - RebuildColorTable (); - } - } - else - { - hr = DDraw->CreatePalette (DDPCAPS_8BIT|DDPCAPS_ALLOW256, PalEntries, &Palette, NULL); - if (FAILED(hr)) - { - LOG ("Could not create palette\n"); - Palette = NULL; // NULL it just to be safe - } - else - { - hr = PrimarySurf->SetPalette (Palette); - if (FAILED(hr)) - { - LOG ("Could not attach palette to surface\n"); - Palette->Release (); - Palette = NULL; - } - else - { - // The palette was supposed to have been initialized with - // the correct colors, but some drivers don't do that. - // (On the other hand, the docs for the SetPalette method - // don't state that the surface will be set to the - // palette's colors when it gets set, so this might be - // legal behavior. Wish I knew...) - NeedPalUpdate = true; - } - } - if (PixelDoubling) - { - UsePfx = true; - GPfx.SetFormat (-8, 0, 0, 0); - } - } - } - else - { - LOG ("Surface is direct color\n"); - UsePfx = true; - GPfx.SetFormat (fmt.dwRGBBitCount, - fmt.dwRBitMask, fmt.dwGBitMask, fmt.dwBBitMask); - GPfx.SetPalette (GPalette.BaseColors); - } -} - -void DDrawFB::ReleaseResources () -{ - if (LockCount) - { - LockCount = 1; - Unlock (); - } - - SAFE_RELEASE( Clipper ); - SAFE_RELEASE( PrimarySurf ); - SAFE_RELEASE( BackSurf ); - SAFE_RELEASE( BackSurf2 ); - SAFE_RELEASE( BlitSurf ); - SAFE_RELEASE( Palette ); - if (GDIPalette != NULL) - { - HDC dc = GetDC (Window); - SelectPalette (dc, (HPALETTE)GetStockObject (DEFAULT_PALETTE), TRUE); - DeleteObject (GDIPalette); - ReleaseDC (Window, dc); - GDIPalette = NULL; - } - LockingSurf = NULL; -} - -int DDrawFB::GetPageCount () -{ - return MustBuffer ? 1 : BufferCount+1; -} - -void DDrawFB::PaletteChanged () -{ - // Somebody else changed the palette. If we are running fullscreen, - // they are obviously jerks, and we need to restore our own palette. - if (!Windowed) - { - if (!PaletteChangeExpected && Palette != NULL) - { - // It is not enough to set NeedPalUpdate to true. Some palette - // entries might now be reserved for system usage, and nothing - // we do will change them. The only way I have found to fix this - // is to recreate all our surfaces and the palette from scratch. - - // IMPORTANT: Do not recreate the resources here. The screen might - // be locked for a drawing operation. Do it later the next time - // somebody tries to lock it. - NeedResRecreate = true; - } - PaletteChangeExpected = false; - } - else - { - QueryNewPalette (); - } -} - -int DDrawFB::QueryNewPalette () -{ - LOG ("QueryNewPalette\n"); - if (GDIPalette == NULL && Windowed) - { - if (Write8bit) - { - RebuildColorTable (); - } - return 0; - } - - HDC dc = GetDC (Window); - HPALETTE oldPal = SelectPalette (dc, GDIPalette, FALSE); - int i = RealizePalette (dc); - SelectPalette (dc, oldPal, TRUE); - RealizePalette (dc); - ReleaseDC (Window, dc); - if (i != 0) - { - RebuildColorTable (); - } - return i; -} - -void DDrawFB::RebuildColorTable () -{ - int i; - - if (Write8bit) - { - PALETTEENTRY syspal[256]; - HDC dc = GetDC (Window); - - GetSystemPaletteEntries (dc, 0, 256, syspal); - - for (i = 0; i < 256; i++) - { - swapvalues (syspal[i].peRed, syspal[i].peBlue); - } - for (i = 0; i < 256; i++) - { - GPfxPal.Pal8[i] = (uint8_t)BestColor ((uint32_t *)syspal, PalEntries[i].peRed, - PalEntries[i].peGreen, PalEntries[i].peBlue); - } - } -} - -bool DDrawFB::Is8BitMode() -{ - if (Windowed) - { - return Write8bit; - } - DDPIXELFORMAT fmt = { sizeof(fmt), }; - HRESULT hr; - - hr = PrimarySurf->GetPixelFormat(&fmt); - if (SUCCEEDED(hr)) - { - return !!(fmt.dwFlags & DDPF_PALETTEINDEXED8); - } - // Can't get the primary surface's pixel format, so assume - // vid_displaybits is accurate. - return vid_displaybits == 8; -} - -bool DDrawFB::IsValid () -{ - return PrimarySurf != NULL; -} - -HRESULT DDrawFB::GetHR () -{ - return LastHR; -} - -bool DDrawFB::Lock (bool useSimpleCanvas) -{ - static int lock_num; - bool wasLost; - -// LOG2 (" Lock (%d) <%d>\n", buffered, LockCount); - - LOG3("Lock %5x <%d> %d\n", (AppActive << 16) | (SessionState << 12) | (MustBuffer << 8) | - (useSimpleCanvas << 4) | (int)UseBlitter, LockCount, lock_num++); - - if (LockCount++ > 0) - { - return false; - } - - wasLost = false; - - if (NeedResRecreate && LockCount == 1) - { - LOG("Recreating resources\n"); - NeedResRecreate = false; - ReleaseResources (); - CreateResources (); - // ReleaseResources sets LockCount to 0. - LockCount = 1; - } - - if (!AppActive || SessionState || MustBuffer || useSimpleCanvas || !UseBlitter) - { - Buffer = MemBuffer; - Pitch = BufferPitch; - BufferingNow = true; - } - else - { - HRESULT hr GCCNOWARN = BlitSurf->Flip (NULL, DDFLIP_WAIT); - hr; - LOG1 ("Blit flip = %08lx\n", hr); - LockSurfRes res = LockSurf (NULL, BlitSurf); - - if (res == NoGood) - { // We must have a surface locked before returning, - // but we could not lock the hardware surface, so buffer - // for this frame. - Buffer = MemBuffer; - Pitch = BufferPitch; - BufferingNow = true; - } - else - { - wasLost = (res == GoodWasLost); - } - } - - wasLost = wasLost || (BufferingNow != WasBuffering); - WasBuffering = BufferingNow; - return wasLost; -} - -void DDrawFB::Unlock () -{ - LOG1 ("Unlock <%d>\n", LockCount); - - if (LockCount == 0) - { - LOG("Unlock called when already unlocked\n"); - return; - } - - if (UpdatePending && LockCount == 1) - { - Update (); - } - else if (--LockCount == 0) - { - if (!BufferingNow) - { - if (BlitSurf == NULL) - { - LockingSurf->Unlock (NULL); - } - else - { - BlitSurf->Unlock (NULL); - } - } - Buffer = NULL; - } -} - -DDrawFB::LockSurfRes DDrawFB::LockSurf (LPRECT lockrect, LPDIRECTDRAWSURFACE toLock) -{ - HRESULT hr; - DDSURFACEDESC desc = { sizeof(desc), }; - bool wasLost = false; - bool lockingLocker = false; - - if (toLock == NULL) - { - lockingLocker = true; - if (LockingSurf == NULL) - { - LOG("LockingSurf lost\n"); - if (!CreateResources ()) - { - if (LastHR != DDERR_UNSUPPORTEDMODE) - { - I_FatalError ("Could not rebuild framebuffer: %08lx", LastHR); - } - else - { - LOG ("Display is in unsupported mode right now.\n"); - return NoGood; - } - } - } - toLock = LockingSurf; - } - - hr = toLock->Lock (lockrect, &desc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL); - LOG3 ("LockSurf %p (%d): %08lx\n", toLock, lockingLocker, hr); - - if (hr == DDERR_SURFACELOST) - { - wasLost = true; - if (FAILED (AttemptRestore ())) - { - return NoGood; - } - if (BlitSurf && FAILED(BlitSurf->IsLost ())) - { - LOG ("Restore blitter surface\n"); - hr = BlitSurf->Restore (); - if (FAILED (hr)) - { - LOG1 ("Could not restore blitter surface: %08lx", hr); - BlitSurf->Release (); - if (BlitSurf == toLock) - { - BlitSurf = NULL; - return NoGood; - } - BlitSurf = NULL; - } - } - if (lockingLocker) - { - toLock = LockingSurf; - } - LOG ("Trying to lock again\n"); - hr = toLock->Lock (lockrect, &desc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL); - if (hr == DDERR_SURFACELOST && Windowed) - { // If this is NT, the user probably opened the Windows NT Security dialog. - // If this is not NT, trying to recreate everything from scratch won't hurt. - ReleaseResources (); - if (!CreateResources ()) - { - if (LastHR != DDERR_UNSUPPORTEDMODE) - { - I_FatalError ("Could not rebuild framebuffer: %08lx", LastHR); - } - else - { - LOG ("Display is in unsupported mode right now.\n"); - return NoGood; - } - } - if (lockingLocker) - { - toLock = LockingSurf; - } - hr = toLock->Lock (lockrect, &desc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL); - } - } - if (FAILED (hr)) - { // Still could not restore the surface, so don't draw anything - //I_FatalError ("Could not lock framebuffer: %08lx", hr); - LOG1 ("Final result after restoration attempts: %08lx\n", hr); - return NoGood; - } - Buffer = (uint8_t *)desc.lpSurface; - Pitch = desc.lPitch; - BufferingNow = false; - return wasLost ? GoodWasLost : Good; -} - -HRESULT DDrawFB::AttemptRestore () -{ - LOG ("Restore primary\n"); - HRESULT hr = PrimarySurf->Restore (); - if (hr == DDERR_WRONGMODE && Windowed) - { // The user changed the screen mode - LOG ("DDERR_WRONGMODE and windowed, so recreating all resources\n"); - ReleaseResources (); - if (!CreateResources ()) - { - LOG1 ("Could not recreate framebuffer: %08lx", LastHR); - return LastHR; - } - } - else if (FAILED (hr)) - { - LOG1 ("Could not restore primary surface: %08lx", hr); - return hr; - } - if (BackSurf && FAILED(BackSurf->IsLost ())) - { - LOG ("Restore backbuffer\n"); - hr = BackSurf->Restore (); - if (FAILED (hr)) - { - I_FatalError ("Could not restore backbuffer: %08lx", hr); - } - } - if (BackSurf2 && FAILED(BackSurf2->IsLost ())) - { - LOG ("Restore backbuffer 2\n"); - hr = BackSurf2->Restore (); - if (FAILED (hr)) - { - I_FatalError ("Could not restore backbuffer 2: %08lx", hr); - } - } - return 0; -} - -void DDrawFB::Update () -{ - bool pchanged = false; - int i; - - LOG3 ("Update <%d,%c:%d>\n", LockCount, AppActive?'Y':'N', SessionState); - - if (LockCount != 1) - { - //I_FatalError ("Framebuffer must have exactly 1 lock to be updated"); - if (LockCount > 0) - { - UpdatePending = true; - --LockCount; - } - return; - } - - DrawRateStuff (); - - if (NeedGammaUpdate) - { - NeedGammaUpdate = false; - CalcGamma (Windowed || rgamma == 0.f ? Gamma : Gamma * rgamma, GammaTable[0]); - CalcGamma (Windowed || ggamma == 0.f ? Gamma : Gamma * ggamma, GammaTable[1]); - CalcGamma (Windowed || bgamma == 0.f ? Gamma : Gamma * bgamma, GammaTable[2]); - NeedPalUpdate = true; - } - - if (NeedPalUpdate || vid_palettehack) - { - NeedPalUpdate = false; - if (Palette != NULL || GDIPalette != NULL) - { - for (i = 0; i < 256; i++) - { - PalEntries[i].peRed = GammaTable[0][SourcePalette[i].r]; - PalEntries[i].peGreen = GammaTable[1][SourcePalette[i].g]; - PalEntries[i].peBlue = GammaTable[2][SourcePalette[i].b]; - } - if (FlashAmount) - { - DoBlending ((PalEntry *)PalEntries, (PalEntry *)PalEntries, - 256, GammaTable[2][Flash.b], GammaTable[1][Flash.g], GammaTable[0][Flash.r], - FlashAmount); - } - if (Palette != NULL) - { - pchanged = true; - } - else - { - /* Argh! Too slow! - SetPaletteEntries (GDIPalette, 0, 256, PalEntries); - HDC dc = GetDC (Window); - SelectPalette (dc, GDIPalette, FALSE); - RealizePalette (dc); - ReleaseDC (Window, dc); - */ - RebuildColorTable (); - } - } - else - { - for (i = 0; i < 256; i++) - { - ((PalEntry *)PalEntries)[i].r = GammaTable[0][SourcePalette[i].r]; - ((PalEntry *)PalEntries)[i].g = GammaTable[1][SourcePalette[i].g]; - ((PalEntry *)PalEntries)[i].b = GammaTable[2][SourcePalette[i].b]; - } - if (FlashAmount) - { - DoBlending ((PalEntry *)PalEntries, (PalEntry *)PalEntries, - 256, GammaTable[0][Flash.r], GammaTable[1][Flash.g], GammaTable[2][Flash.b], - FlashAmount); - } - GPfx.SetPalette ((PalEntry *)PalEntries); - } - } - - BlitCycles.Reset(); - BlitCycles.Clock(); - - if (BufferingNow) - { - LockCount = 0; - if ((Windowed || AppActive) && !SessionState && !PaintToWindow()) - { - if (LockSurf (NULL, NULL) != NoGood) - { - uint8_t *writept = Buffer + (TrueHeight - Height)/2*Pitch; - LOG3 ("Copy %dx%d (%d)\n", Width, Height, BufferPitch); - if (UsePfx) - { - GPfx.Convert (MemBuffer, BufferPitch, - writept, Pitch, Width << PixelDoubling, Height << PixelDoubling, - FRACUNIT >> PixelDoubling, FRACUNIT >> PixelDoubling, 0, 0); - } - else - { - CopyFromBuff (MemBuffer, BufferPitch, Width, Height, writept); - } - if (TrueHeight != Height) - { - // Letterbox time! Draw black top and bottom borders. - int topborder = (TrueHeight - Height) / 2; - int botborder = TrueHeight - topborder - Height; - memset (Buffer, 0, Pitch*topborder); - memset (writept + Height*Pitch, 0, Pitch*botborder); - } - LockingSurf->Unlock (NULL); - } - } - } - else - { - if (BlitSurf != NULL) - { - HRESULT hr; - BlitSurf->Unlock (NULL); - RECT srcRect = { 0, 0, Width, Height }; - hr = LockingSurf->BltFast (0, 0, BlitSurf, &srcRect, DDBLTFAST_NOCOLORKEY|DDBLTFAST_WAIT); - if (FAILED (hr)) - { - LOG1 ("Could not blit: %08lx\n", hr); - if (hr == DDERR_SURFACELOST) - { - if (SUCCEEDED (AttemptRestore ())) - { - hr = LockingSurf->BltFast (0, 0, BlitSurf, &srcRect, DDBLTFAST_NOCOLORKEY|DDBLTFAST_WAIT); - if (FAILED (hr)) - { - LOG1 ("Blit retry also failed: %08lx\n", hr); - } - } - } - } - else - { - LOG ("Blit ok\n"); - } - } - else - { - LockingSurf->Unlock (NULL); - } - } - - BlitCycles.Unclock(); - LOG1 ("cycles = %.1f ms\n", BlitCycles.TimeMS()); - - Buffer = NULL; - LockCount = 0; - UpdatePending = false; - - I_FPSLimit(); - if (!Windowed && AppActive && !SessionState /*&& !UseBlitter && !MustBuffer*/) - { - HRESULT hr = PrimarySurf->Flip (NULL, FlipFlags); - LOG1 ("Flip = %08lx\n", hr); - if (hr == DDERR_INVALIDPARAMS) - { - if (FlipFlags & DDFLIP_NOVSYNC) - { - FlipFlags &= ~DDFLIP_NOVSYNC; - Printf ("Can't disable vsync\n"); - PrimarySurf->Flip (NULL, FlipFlags); - } - } - } - - if (pchanged && AppActive && !SessionState) - { - PaletteChangeExpected = true; - Palette->SetEntries (0, 0, 256, PalEntries); - } -} - -bool DDrawFB::PaintToWindow () -{ - if (Windowed && LockCount == 0) - { - HRESULT hr; - RECT rect; - GetClientRect (Window, &rect); - if (rect.right != 0 && rect.bottom != 0) - { - // Use blit to copy/stretch to window's client rect - ClientToScreen (Window, (POINT*)&rect.left); - ClientToScreen (Window, (POINT*)&rect.right); - LOG ("Paint to window\n"); - if (LockSurf (NULL, NULL) != NoGood) - { - GPfx.Convert (MemBuffer, BufferPitch, - Buffer, Pitch, Width << PixelDoubling, Height << PixelDoubling, - FRACUNIT >> PixelDoubling, FRACUNIT >> PixelDoubling, 0, 0); - LockingSurf->Unlock (NULL); - if (FAILED (hr = PrimarySurf->Blt (&rect, BackSurf, NULL, DDBLT_WAIT|DDBLT_ASYNC, NULL))) - { - if (hr == DDERR_SURFACELOST) - { - PrimarySurf->Restore (); - } - PrimarySurf->Blt (&rect, BackSurf, NULL, DDBLT_WAIT, NULL); - } - } - Buffer = NULL; - LOG ("Did paint to window\n"); - } - return true; - } - return false; -} - -PalEntry *DDrawFB::GetPalette () -{ - return SourcePalette; -} - -void DDrawFB::UpdatePalette () -{ - NeedPalUpdate = true; -} - -bool DDrawFB::SetGamma (float gamma) -{ - LOG1 ("SetGamma %g\n", gamma); - Gamma = gamma; - NeedGammaUpdate = true; - return true; -} - -bool DDrawFB::SetFlash (PalEntry rgb, int amount) -{ - Flash = rgb; - FlashAmount = amount; - NeedPalUpdate = true; - return true; -} - -void DDrawFB::GetFlash (PalEntry &rgb, int &amount) -{ - rgb = Flash; - amount = FlashAmount; -} - -// Q: Should I gamma adjust the returned palette? -// A: No. PNG screenshots save the gamma value, so there is no need. -void DDrawFB::GetFlashedPalette (PalEntry pal[256]) -{ - memcpy (pal, SourcePalette, 256*sizeof(PalEntry)); - if (FlashAmount) - { - DoBlending (pal, pal, 256, Flash.r, Flash.g, Flash.b, FlashAmount); - } -} - -void DDrawFB::SetVSync (bool vsync) -{ - LOG1 ("vid_vsync set to %d\n", vsync); - FlipFlags = vsync ? DDFLIP_WAIT : DDFLIP_WAIT|DDFLIP_NOVSYNC; -} - -void DDrawFB::NewRefreshRate() -{ - if (!Windowed) - { - NeedResRecreate = true; - } -} - -void DDrawFB::Blank () -{ - if (IsFullscreen ()) - { - DDBLTFX blitFX = { sizeof(blitFX) }; - - blitFX.dwFillColor = 0; - DDraw->FlipToGDISurface (); - PrimarySurf->Blt (NULL, NULL, NULL, DDBLT_COLORFILL, &blitFX); - } -} - -ADD_STAT (blit) -{ - FString out; - out.Format ("blit=%04.1f ms", BlitCycles.TimeMS()); - return out; -} diff --git a/src/win32/gl_sysfb.h b/src/win32/gl_sysfb.h new file mode 100644 index 0000000000..52054615f8 --- /dev/null +++ b/src/win32/gl_sysfb.h @@ -0,0 +1,50 @@ +#ifndef __WIN32_GL_SYSFB_H__ +#define __WIN32_GL_SYSFB_H__ + +#include "v_video.h" + +class SystemFrameBuffer : public DFrameBuffer +{ + typedef DFrameBuffer Super; + +public: + SystemFrameBuffer() {} + // Actually, hMonitor is a HMONITOR, but it's passed as a void * as there + // look to be some cross-platform bits in the way. + SystemFrameBuffer(void *hMonitor, int width, int height, int bits, int refreshHz, bool fullscreen, bool bgra); + virtual ~SystemFrameBuffer(); + + void SetVSync (bool vsync); + void SwapBuffers(); + void NewRefreshRate (); + + int GetClientWidth(); + int GetClientHeight(); + + int GetTrueHeight(); + + + bool IsFullscreen(); + + void InitializeState(); + +protected: + + bool CanUpdate(); + void ResetGammaTable(); + void SetGammaTable(uint16_t * tbl); + + float m_Gamma, m_Brightness, m_Contrast; + uint16_t m_origGamma[768]; + bool m_supportsGamma; + bool m_Fullscreen, m_Bgra; + int m_Width, m_Height, m_Bits, m_RefreshHz; + char m_displayDeviceNameBuffer[32/*CCHDEVICENAME*/]; // do not use windows.h constants here! + char *m_displayDeviceName; + int SwapInterval; + + friend class Win32GLVideo; + +}; + +#endif // __WIN32_GL_SYSFB_H__ diff --git a/src/win32/hardware.cpp b/src/win32/hardware.cpp index a8ecfccae9..4c7f437796 100644 --- a/src/win32/hardware.cpp +++ b/src/win32/hardware.cpp @@ -36,7 +36,6 @@ #include #include "hardware.h" -#include "win32iface.h" #include "i_video.h" #include "i_system.h" #include "c_console.h" @@ -50,9 +49,7 @@ EXTERN_CVAR (Bool, ticker) EXTERN_CVAR (Bool, fullscreen) -EXTERN_CVAR (Bool, swtruecolor) EXTERN_CVAR (Float, vid_winscale) -EXTERN_CVAR (Bool, vid_forceddraw) EXTERN_CVAR (Bool, win_borderless) CVAR(Int, win_x, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) @@ -67,10 +64,8 @@ IVideo *Video; // do not include GL headers here, only declare the necessary functions. IVideo *gl_CreateVideo(); -FRenderer *gl_CreateInterface(); void I_RestartRenderer(); -int currentrenderer = -1; int currentcanvas = -1; int currentgpuswitch = -1; bool changerenderer; @@ -100,38 +95,6 @@ CUSTOM_CVAR(Int, vid_gpuswitch, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINI } } -// Software OpenGL canvas -CUSTOM_CVAR(Bool, vid_glswfb, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) -{ - if ((self ? 1 : 0) != currentcanvas) - Printf("You must restart " GAMENAME " for this change to take effect.\n"); -} - -// [ZDoomGL] -CUSTOM_CVAR (Int, vid_renderer, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) -{ - // 0: Software renderer - // 1: OpenGL renderer - - if (self != currentrenderer) - { - switch (self) - { - case 0: - Printf("Switching to software renderer...\n"); - break; - case 1: - Printf("Switching to OpenGL renderer...\n"); - break; - default: - Printf("Unknown renderer (%d). Falling back to software renderer...\n", *vid_renderer); - self = 0; // make sure to actually switch to the software renderer - break; - } - //changerenderer = true; - Printf("You must restart " GAMENAME " to switch the renderer\n"); - } -} CCMD (vid_restart) { @@ -179,13 +142,7 @@ void I_InitGraphics () val.Bool = !!Args->CheckParm ("-devparm"); ticker.SetGenericRepDefault (val, CVAR_Bool); - if (currentcanvas == 0) // Software Canvas: 0 = D3D or DirectDraw, 1 = OpenGL - if (currentrenderer == 1) - Video = gl_CreateVideo(); - else - Video = new Win32Video(0); - else - Video = gl_CreateVideo(); + Video = gl_CreateVideo(); if (Video == NULL) I_FatalError ("Failed to initialize display"); @@ -195,33 +152,6 @@ void I_InitGraphics () Video->SetWindowedScale (vid_winscale); } -static void I_DeleteRenderer() -{ - if (Renderer != NULL) delete Renderer; -} - -void I_CreateRenderer() -{ - currentrenderer = vid_renderer; - currentcanvas = vid_glswfb; - if (currentrenderer == 1) - Printf("Renderer: OpenGL\n"); - else if (currentcanvas == 1) - Printf("Renderer: Software on OpenGL\n"); - else if (currentcanvas == 0 && vid_forceddraw == false) - Printf("Renderer: Software on Direct3D\n"); - else if (currentcanvas == 0) - Printf("Renderer: Software on DirectDraw\n"); - else - Printf("Renderer: Unknown\n"); - if (Renderer == NULL) - { - if (currentrenderer==1) Renderer = gl_CreateInterface(); - else Renderer = new FSoftwareRenderer; - atterm(I_DeleteRenderer); - } -} - /** Remaining code is common to Win32 and Linux **/ // VIDEO WRAPPERS --------------------------------------------------------- @@ -248,7 +178,7 @@ DFrameBuffer *I_SetMode (int &width, int &height, DFrameBuffer *old) } break; } - DFrameBuffer *res = Video->CreateFrameBuffer (width, height, swtruecolor, fs, old); + DFrameBuffer *res = Video->CreateFrameBuffer (width, height, false, fs, old); //* Right now, CreateFrameBuffer cannot return NULL if (res == NULL) @@ -427,19 +357,6 @@ void I_RestoreWindowedPos () extern int NewWidth, NewHeight, NewBits, DisplayBits; -CUSTOM_CVAR(Bool, swtruecolor, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL) -{ - // Strictly speaking this doesn't require a mode switch, but it is the easiest - // way to force a CreateFramebuffer call without a lot of refactoring. - if (currentrenderer == 0) - { - NewWidth = screen->VideoWidth; - NewHeight = screen->VideoHeight; - NewBits = DisplayBits; - setmodeneeded = true; - } -} - CUSTOM_CVAR(Bool, win_borderless, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) { // Just reinit the window. Saves a lot of trouble. diff --git a/src/win32/hardware.h b/src/win32/hardware.h index d996bf3944..a4885964b8 100644 --- a/src/win32/hardware.h +++ b/src/win32/hardware.h @@ -57,7 +57,6 @@ class IVideo void I_InitGraphics (); void I_ShutdownGraphics (); -void I_CreateRenderer(); void I_SaveWindowedPos (); void I_RestoreWindowedPos (); diff --git a/src/win32/i_dijoy.cpp b/src/win32/i_dijoy.cpp index 199a4fa568..3dc978c4a9 100644 --- a/src/win32/i_dijoy.cpp +++ b/src/win32/i_dijoy.cpp @@ -52,7 +52,7 @@ #include "c_dispatch.h" #include "doomdef.h" #include "doomstat.h" -#include "win32iface.h" +#include "hardware.h" #include "templates.h" #include "gameconfigfile.h" #include "cmdlib.h" diff --git a/src/win32/i_input.cpp b/src/win32/i_input.cpp index 84ab3ff84e..e6653f5126 100644 --- a/src/win32/i_input.cpp +++ b/src/win32/i_input.cpp @@ -94,7 +94,7 @@ #include "s_sound.h" #include "m_misc.h" #include "gameconfigfile.h" -#include "win32iface.h" +#include "hardware.h" #include "templates.h" #include "cmdlib.h" #include "d_event.h" @@ -456,10 +456,6 @@ LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) break; case WM_PAINT: - if (screen != NULL && 0) - { - static_cast (screen)->PaintToWindow (); - } return DefWindowProc (hWnd, message, wParam, lParam); case WM_SETTINGCHANGE: @@ -616,22 +612,6 @@ LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) } break; - case WM_PALETTECHANGED: - if ((HWND)wParam == Window) - break; - if (screen != NULL) - { - screen->PaletteChanged (); - } - return DefWindowProc (hWnd, message, wParam, lParam); - - case WM_QUERYNEWPALETTE: - if (screen != NULL) - { - return screen->QueryNewPalette (); - } - return DefWindowProc (hWnd, message, wParam, lParam); - case WM_ERASEBKGND: return true; diff --git a/src/win32/i_keyboard.cpp b/src/win32/i_keyboard.cpp index 04dd5a1cc7..056f802934 100644 --- a/src/win32/i_keyboard.cpp +++ b/src/win32/i_keyboard.cpp @@ -46,7 +46,7 @@ #include "c_cvars.h" #include "doomdef.h" #include "doomstat.h" -#include "win32iface.h" +#include "hardware.h" #include "rawinput.h" // MACROS ------------------------------------------------------------------ diff --git a/src/win32/i_main.cpp b/src/win32/i_main.cpp index 019b01e7e8..90e437a146 100644 --- a/src/win32/i_main.cpp +++ b/src/win32/i_main.cpp @@ -1351,7 +1351,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE nothing, LPSTR cmdline, int n _CrtSetDbgFlag (_CrtSetDbgFlag(0) | _CRTDBG_LEAK_CHECK_DF); // Use this to break at a specific allocation number. - //_crtBreakAlloc = 53039; + //_crtBreakAlloc = 177312; #endif DoMain (hInstance); diff --git a/src/win32/i_mouse.cpp b/src/win32/i_mouse.cpp index f091f5e8c9..a6d606f8da 100644 --- a/src/win32/i_mouse.cpp +++ b/src/win32/i_mouse.cpp @@ -46,7 +46,7 @@ #include "c_cvars.h" #include "doomdef.h" #include "doomstat.h" -#include "win32iface.h" +#include "hardware.h" #include "rawinput.h" #include "menu/menu.h" #include "events.h" diff --git a/src/win32/i_rawps2.cpp b/src/win32/i_rawps2.cpp index 9ae44161e8..efd9cd2216 100644 --- a/src/win32/i_rawps2.cpp +++ b/src/win32/i_rawps2.cpp @@ -47,7 +47,7 @@ #include "c_dispatch.h" #include "doomdef.h" #include "doomstat.h" -#include "win32iface.h" +#include "hardware.h" #include "templates.h" #include "gameconfigfile.h" #include "cmdlib.h" diff --git a/src/win32/i_system.cpp b/src/win32/i_system.cpp index 75c63025ea..7b79ad26ff 100644 --- a/src/win32/i_system.cpp +++ b/src/win32/i_system.cpp @@ -129,7 +129,6 @@ static void DestroyCustomCursor(); EXTERN_CVAR(String, language); EXTERN_CVAR (Bool, queryiwad); // Used on welcome/IWAD screen. -EXTERN_CVAR (Int, vid_renderer) EXTERN_CVAR (Bool, fullscreen) EXTERN_CVAR (Bool, disableautoload) EXTERN_CVAR (Bool, autoloadlights) @@ -824,7 +823,7 @@ BOOL CALLBACK IWADBoxCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lPa char szString[256]; // Check the current video settings. - SendDlgItemMessage( hDlg, vid_renderer ? IDC_WELCOME_OPENGL : IDC_WELCOME_SOFTWARE, BM_SETCHECK, BST_CHECKED, 0 ); + //SendDlgItemMessage( hDlg, vid_renderer ? IDC_WELCOME_OPENGL : IDC_WELCOME_SOFTWARE, BM_SETCHECK, BST_CHECKED, 0 ); SendDlgItemMessage( hDlg, IDC_WELCOME_FULLSCREEN, BM_SETCHECK, fullscreen ? BST_CHECKED : BST_UNCHECKED, 0 ); // [SP] This is our's @@ -870,7 +869,6 @@ BOOL CALLBACK IWADBoxCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lPa { SetQueryIWad(hDlg); // [SP] Upstreamed from Zandronum - vid_renderer = SendDlgItemMessage( hDlg, IDC_WELCOME_OPENGL, BM_GETCHECK, 0, 0 ) == BST_CHECKED; fullscreen = SendDlgItemMessage( hDlg, IDC_WELCOME_FULLSCREEN, BM_GETCHECK, 0, 0 ) == BST_CHECKED; // [SP] This is our's. @@ -933,8 +931,7 @@ bool I_SetCursor(FTexture *cursorpic) { HCURSOR cursor; - if (cursorpic != NULL && cursorpic->UseType != ETextureType::Null && - (screen == NULL || !screen->Is8BitMode())) + if (cursorpic != NULL && cursorpic->UseType != ETextureType::Null) { // Must be no larger than 32x32. if (cursorpic->GetWidth() > 32 || cursorpic->GetHeight() > 32) @@ -1042,7 +1039,7 @@ static HCURSOR CreateCompatibleCursor(FTexture *cursorpic) DeleteDC(xor_mask_dc); // Create the cursor from the bitmaps. - return CreateBitmapCursor(cursorpic->LeftOffset, cursorpic->TopOffset, and_mask, xor_mask); + return CreateBitmapCursor(cursorpic->GetLeftOffset(0), cursorpic->GetTopOffset(0), and_mask, xor_mask); } //========================================================================== @@ -1126,7 +1123,7 @@ static HCURSOR CreateAlphaCursor(FTexture *cursorpic) } } - return CreateBitmapCursor(cursorpic->LeftOffset * scale, cursorpic->TopOffset * scale, mono, color); + return CreateBitmapCursor(cursorpic->GetLeftOffset(0) * scale, cursorpic->GetTopOffset(0) * scale, mono, color); } //========================================================================== diff --git a/src/win32/i_xinput.cpp b/src/win32/i_xinput.cpp index 5c5e25aed9..c7c104d941 100644 --- a/src/win32/i_xinput.cpp +++ b/src/win32/i_xinput.cpp @@ -50,7 +50,7 @@ #include "c_dispatch.h" #include "doomdef.h" #include "doomstat.h" -#include "win32iface.h" +#include "hardware.h" #include "templates.h" #include "gameconfigfile.h" #include "cmdlib.h" diff --git a/src/win32/win32gliface.cpp b/src/win32/win32gliface.cpp index 3726050e01..b66b5ecc35 100644 --- a/src/win32/win32gliface.cpp +++ b/src/win32/win32gliface.cpp @@ -32,21 +32,17 @@ ** */ -//#include "gl/system/gl_system.h" - #define WIN32_LEAN_AND_MEAN #include #include #include "wglext.h" -#include "win32iface.h" -#include "win32gliface.h" -//#include "gl/gl_intern.h" +#include "gl_sysfb.h" +#include "hardware.h" #include "x86.h" #include "templates.h" #include "version.h" #include "c_console.h" -#include "hardware.h" #include "v_video.h" #include "i_input.h" #include "i_system.h" @@ -54,21 +50,18 @@ #include "v_text.h" #include "m_argv.h" #include "doomerrors.h" -//#include "gl_defs.h" #include "gl/renderer/gl_renderer.h" #include "gl/system/gl_framebuffer.h" -#include "gl/system/gl_swframebuffer.h" extern HWND Window; extern BOOL AppActive; extern "C" { - _declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; + __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; } -void gl_CalculateCPUSpeed(); extern int NewWidth, NewHeight, NewBits, DisplayBits; // these get used before GLEW is initialized so we have to use separate pointers with different names @@ -86,6 +79,9 @@ CUSTOM_CVAR(Bool, gl_debug, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINI EXTERN_CVAR(Bool, vr_enable_quadbuffered) EXTERN_CVAR(Int, vid_refreshrate) +EXTERN_CVAR(Int, vid_defwidth) +EXTERN_CVAR(Int, vid_defheight) +EXTERN_CVAR(Int, vid_adapter) //========================================================================== @@ -166,9 +162,6 @@ public: Win32GLVideo::Win32GLVideo(int parm) : m_Modes(NULL), m_IsFullscreen(false) { - #ifdef _WIN32 - gl_CalculateCPUSpeed(); - #endif I_SetWndProc(); m_DisplayWidth = vid_defwidth; m_DisplayHeight = vid_defheight; @@ -459,7 +452,7 @@ bool Win32GLVideo::GoFullscreen(bool yes) DFrameBuffer *Win32GLVideo::CreateFrameBuffer(int width, int height, bool bgra, bool fs, DFrameBuffer *old) { - Win32GLFrameBuffer *fb; + SystemFrameBuffer *fb; if (fs) { @@ -488,7 +481,7 @@ DFrameBuffer *Win32GLVideo::CreateFrameBuffer(int width, int height, bool bgra, if (old != NULL) { // Reuse the old framebuffer if its attributes are the same - fb = static_cast (old); + fb = static_cast (old); if (fb->m_Width == m_DisplayWidth && fb->m_Height == m_DisplayHeight && fb->m_Bits == m_DisplayBits && @@ -501,10 +494,7 @@ DFrameBuffer *Win32GLVideo::CreateFrameBuffer(int width, int height, bool bgra, //old->GetFlash(flashColor, flashAmount); delete old; } - if (vid_renderer == 1) - fb = new OpenGLFrameBuffer(m_hMonitor, m_DisplayWidth, m_DisplayHeight, m_DisplayBits, m_DisplayHz, fs); - else - fb = new OpenGLSWFrameBuffer(m_hMonitor, m_DisplayWidth, m_DisplayHeight, m_DisplayBits, m_DisplayHz, fs, bgra); + fb = new OpenGLFrameBuffer(m_hMonitor, m_DisplayWidth, m_DisplayHeight, m_DisplayBits, m_DisplayHz, fs); return fb; } @@ -985,7 +975,7 @@ bool Win32GLVideo::SetFullscreen(const char *devicename, int w, int h, int bits, // //========================================================================== -Win32GLFrameBuffer::Win32GLFrameBuffer(void *hMonitor, int width, int height, int bits, int refreshHz, bool fullscreen, bool bgra) : BaseWinFB(width, height, bgra) +SystemFrameBuffer::SystemFrameBuffer(void *hMonitor, int width, int height, int bits, int refreshHz, bool fullscreen, bool bgra) : DFrameBuffer(width, height, bgra) { m_Width = width; m_Height = height; @@ -993,7 +983,6 @@ Win32GLFrameBuffer::Win32GLFrameBuffer(void *hMonitor, int width, int height, in m_RefreshHz = refreshHz; m_Fullscreen = fullscreen; m_Bgra = bgra; - m_Lock=0; RECT r; LONG style, exStyle; @@ -1056,7 +1045,7 @@ Win32GLFrameBuffer::Win32GLFrameBuffer(void *hMonitor, int width, int height, in if (!static_cast(Video)->InitHardware(Window, 0)) { - vid_renderer = 0; + I_FatalError("Unable to initialize OpenGL"); return; } HDC hDC = GetDC(Window); @@ -1095,7 +1084,7 @@ Win32GLFrameBuffer::Win32GLFrameBuffer(void *hMonitor, int width, int height, in // //========================================================================== -Win32GLFrameBuffer::~Win32GLFrameBuffer() +SystemFrameBuffer::~SystemFrameBuffer() { ResetGammaTable(); I_SaveWindowedPos(); @@ -1118,7 +1107,7 @@ Win32GLFrameBuffer::~Win32GLFrameBuffer() // //========================================================================== -void Win32GLFrameBuffer::InitializeState() +void SystemFrameBuffer::InitializeState() { } @@ -1128,7 +1117,7 @@ void Win32GLFrameBuffer::InitializeState() // //========================================================================== -bool Win32GLFrameBuffer::CanUpdate() +bool SystemFrameBuffer::CanUpdate() { if (!AppActive && IsFullscreen()) return false; return true; @@ -1140,7 +1129,7 @@ bool Win32GLFrameBuffer::CanUpdate() // //========================================================================== -void Win32GLFrameBuffer::ResetGammaTable() +void SystemFrameBuffer::ResetGammaTable() { if (m_supportsGamma) { @@ -1150,7 +1139,7 @@ void Win32GLFrameBuffer::ResetGammaTable() } } -void Win32GLFrameBuffer::SetGammaTable(uint16_t *tbl) +void SystemFrameBuffer::SetGammaTable(uint16_t *tbl) { if (m_supportsGamma) { @@ -1166,83 +1155,23 @@ void Win32GLFrameBuffer::SetGammaTable(uint16_t *tbl) // //========================================================================== -bool Win32GLFrameBuffer::Lock(bool buffered) -{ - m_Lock++; - Buffer = MemBuffer; - return true; -} - -bool Win32GLFrameBuffer::Lock () -{ - return Lock(false); -} - -void Win32GLFrameBuffer::Unlock () -{ - m_Lock--; -} - -bool Win32GLFrameBuffer::IsLocked () -{ - return m_Lock > 0; -} - -//========================================================================== -// -// -// -//========================================================================== - -bool Win32GLFrameBuffer::IsFullscreen() +bool SystemFrameBuffer::IsFullscreen() { return m_Fullscreen; } -void Win32GLFrameBuffer::PaletteChanged() -{ -} - -int Win32GLFrameBuffer::QueryNewPalette() -{ - return 0; -} - -HRESULT Win32GLFrameBuffer::GetHR() -{ - return 0; -} - -void Win32GLFrameBuffer::Blank () -{ -} - -bool Win32GLFrameBuffer::PaintToWindow () -{ - return false; -} - -bool Win32GLFrameBuffer::CreateResources () -{ - return false; -} - -void Win32GLFrameBuffer::ReleaseResources () -{ -} - //========================================================================== // // // //========================================================================== -void Win32GLFrameBuffer::SetVSync (bool vsync) +void SystemFrameBuffer::SetVSync (bool vsync) { if (myWglSwapIntervalExtProc != NULL) myWglSwapIntervalExtProc(vsync ? SwapInterval : 0); } -void Win32GLFrameBuffer::SwapBuffers() +void SystemFrameBuffer::SwapBuffers() { // Limiting the frame rate is as simple as waiting for the timer to signal this event. I_FPSLimit(); @@ -1255,7 +1184,7 @@ void Win32GLFrameBuffer::SwapBuffers() // //========================================================================== -void Win32GLFrameBuffer::NewRefreshRate () +void SystemFrameBuffer::NewRefreshRate () { if (m_Fullscreen) { @@ -1266,21 +1195,21 @@ void Win32GLFrameBuffer::NewRefreshRate () } } -int Win32GLFrameBuffer::GetClientWidth() +int SystemFrameBuffer::GetClientWidth() { RECT rect = { 0 }; GetClientRect(Window, &rect); return rect.right - rect.left; } -int Win32GLFrameBuffer::GetClientHeight() +int SystemFrameBuffer::GetClientHeight() { RECT rect = { 0 }; GetClientRect(Window, &rect); return rect.bottom - rect.top; } -int Win32GLFrameBuffer::GetTrueHeight() +int SystemFrameBuffer::GetTrueHeight() { return static_cast(Video)->GetTrueHeight(); } @@ -1288,4 +1217,4 @@ int Win32GLFrameBuffer::GetTrueHeight() IVideo *gl_CreateVideo() { return new Win32GLVideo(0); -} \ No newline at end of file +} diff --git a/src/win32/win32gliface.h b/src/win32/win32gliface.h deleted file mode 100644 index 09e9e56420..0000000000 --- a/src/win32/win32gliface.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef __WIN32GLIFACE_H__ -#define __WIN32GLIFACE_H__ - -#include "hardware.h" -#include "win32iface.h" -#include "v_video.h" -#include "tarray.h" - -extern IVideo *Video; - - - -EXTERN_CVAR (Float, dimamount) -EXTERN_CVAR (Color, dimcolor) - -EXTERN_CVAR(Int, vid_defwidth); -EXTERN_CVAR(Int, vid_defheight); -EXTERN_CVAR(Int, vid_renderer); -EXTERN_CVAR(Int, vid_adapter); - -extern IVideo *Video; - -struct FRenderer; -FRenderer *gl_CreateInterface(); - - - -class Win32GLFrameBuffer : public BaseWinFB -{ - typedef BaseWinFB Super; - -public: - Win32GLFrameBuffer() {} - // Actually, hMonitor is a HMONITOR, but it's passed as a void * as there - // look to be some cross-platform bits in the way. - Win32GLFrameBuffer(void *hMonitor, int width, int height, int bits, int refreshHz, bool fullscreen, bool bgra); - virtual ~Win32GLFrameBuffer(); - - - // unused but must be defined - virtual void Blank (); - virtual bool PaintToWindow (); - virtual long/*HRESULT*/ GetHR(); // windows.h pollution prevention. - - virtual bool CreateResources (); - virtual void ReleaseResources (); - - void SetVSync (bool vsync); - void SwapBuffers(); - void NewRefreshRate (); - - int GetClientWidth(); - int GetClientHeight(); - - int GetTrueHeight(); - - bool Lock(bool buffered); - bool Lock (); - void Unlock(); - bool IsLocked (); - - - bool IsFullscreen(); - void PaletteChanged(); - int QueryNewPalette(); - - void InitializeState(); - -protected: - - bool CanUpdate(); - void ResetGammaTable(); - void SetGammaTable(uint16_t * tbl); - - float m_Gamma, m_Brightness, m_Contrast; - uint16_t m_origGamma[768]; - bool m_supportsGamma; - bool m_Fullscreen, m_Bgra; - int m_Width, m_Height, m_Bits, m_RefreshHz; - int m_Lock; - char m_displayDeviceNameBuffer[32/*CCHDEVICENAME*/]; // do not use windows.h constants here! - char *m_displayDeviceName; - int SwapInterval; - - friend class Win32GLVideo; - -}; - -#endif //__WIN32GLIFACE_H__ diff --git a/src/win32/win32iface.h b/src/win32/win32iface.h deleted file mode 100644 index 7ea1901352..0000000000 --- a/src/win32/win32iface.h +++ /dev/null @@ -1,129 +0,0 @@ -/* -** win32iface.h -** -**--------------------------------------------------------------------------- -** Copyright 1998-2008 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -#ifndef __WIN32IFACE_H -#define __WIN32IFACE_H - -#include "hardware.h" - - -EXTERN_CVAR (Bool, vid_vsync) - -class D3DTex; -class D3DPal; -struct FSoftwareRenderer; - -class Win32Video : public IVideo -{ - public: - Win32Video (int parm); - ~Win32Video (); - - bool InitD3D9(); - void InitDDraw(); - - EDisplayType GetDisplayType () { return DISPLAY_Both; } - void SetWindowedScale (float scale); - - DFrameBuffer *CreateFrameBuffer (int width, int height, bool bgra, bool fs, DFrameBuffer *old); - - void StartModeIterator (int bits, bool fs); - bool NextMode (int *width, int *height, bool *letterbox); - - bool GoFullscreen (bool yes); - void BlankForGDI (); - - void DumpAdapters (); - void AddMode(int x, int y, int bits, int baseHeight, int doubling); - - private: - struct ModeInfo - { - ModeInfo (int inX, int inY, int inBits, int inRealY, int inDoubling) - : next (NULL), - width (inX), - height (inY), - bits (inBits), - realheight (inRealY), - doubling (inDoubling) - {} - - ModeInfo *next; - int width, height, bits; - int realheight; - int doubling; - } *m_Modes; - - ModeInfo *m_IteratorMode; - int m_IteratorBits; - bool m_IteratorFS; - bool m_IsFullscreen; - unsigned int m_Adapter; - - void FreeModes (); - - void AddD3DModes (unsigned adapter); - void AddLowResModes (); - void AddLetterboxModes (); - void ScaleModes (int doubling); - - friend class DDrawFB; - friend class D3DFB; -}; - -class BaseWinFB : public DFrameBuffer -{ - typedef DFrameBuffer Super; -public: - BaseWinFB(int width, int height, bool bgra) : DFrameBuffer(width, height, bgra), Windowed(true) {} - - bool IsFullscreen () { return !Windowed; } - virtual void Blank () = 0; - virtual bool PaintToWindow () = 0; - virtual long/*HRESULT*/ GetHR () = 0; // HRESULT is a long in Windows but this header should not be polluted with windows.h just for this single definition - virtual void ScaleCoordsFromWindow(int16_t &x, int16_t &y); - -protected: - virtual bool CreateResources () = 0; - virtual void ReleaseResources () = 0; - virtual int GetTrueHeight() { return GetHeight(); } - - bool Windowed; - - friend class Win32Video; - - BaseWinFB() {} -}; - - -#endif // __WIN32IFACE_H diff --git a/src/win32/win32swiface.h b/src/win32/win32swiface.h deleted file mode 100644 index 110469777c..0000000000 --- a/src/win32/win32swiface.h +++ /dev/null @@ -1,402 +0,0 @@ -#pragma once - -#ifndef DIRECTDRAW_VERSION -#define DIRECTDRAW_VERSION 0x0300 -#endif -#ifndef DIRECT3D_VERSION -#define DIRECT3D_VERSION 0x0900 -#endif - -#define WIN32_LEAN_AND_MEAN -#include -#include -#include - -#define SAFE_RELEASE(x) { if (x != NULL) { x->Release(); x = NULL; } } - -extern HANDLE FPSLimitEvent; - -class DDrawFB : public BaseWinFB -{ - typedef BaseWinFB Super; -public: - DDrawFB (int width, int height, bool fullscreen); - ~DDrawFB (); - - bool IsValid (); - bool Lock (bool buffer); - void Unlock (); - void ForceBuffering (bool force); - void Update (); - PalEntry *GetPalette (); - void GetFlashedPalette (PalEntry pal[256]); - void UpdatePalette (); - bool SetGamma (float gamma); - bool SetFlash (PalEntry rgb, int amount); - void GetFlash (PalEntry &rgb, int &amount); - int GetPageCount (); - int QueryNewPalette (); - void PaletteChanged (); - void SetVSync (bool vsync); - void NewRefreshRate(); - HRESULT GetHR (); - bool Is8BitMode(); - virtual int GetTrueHeight() { return TrueHeight; } - - void Blank (); - bool PaintToWindow (); - -private: - enum LockSurfRes { NoGood, Good, GoodWasLost }; - - bool CreateResources (); - void ReleaseResources (); - bool CreateSurfacesAttached (); - bool CreateSurfacesComplex (); - bool CreateBlitterSource (); - LockSurfRes LockSurf (LPRECT lockrect, LPDIRECTDRAWSURFACE surf); - void RebuildColorTable (); - void MaybeCreatePalette (); - bool AddBackBuf (LPDIRECTDRAWSURFACE *surface, int num); - HRESULT AttemptRestore (); - - HRESULT LastHR; - uint8_t GammaTable[3][256]; - PalEntry SourcePalette[256]; - PALETTEENTRY PalEntries[256]; - DWORD FlipFlags; - - LPDIRECTDRAWPALETTE Palette; - LPDIRECTDRAWSURFACE PrimarySurf; - LPDIRECTDRAWSURFACE BackSurf; - LPDIRECTDRAWSURFACE BackSurf2; - LPDIRECTDRAWSURFACE BlitSurf; - LPDIRECTDRAWSURFACE LockingSurf; - LPDIRECTDRAWCLIPPER Clipper; - HPALETTE GDIPalette; - DWORD ClipSize; - PalEntry Flash; - int FlashAmount; - int BufferCount; - int BufferPitch; - int TrueHeight; - int PixelDoubling; - float Gamma; - - bool NeedGammaUpdate; - bool NeedPalUpdate; - bool NeedResRecreate; - bool PaletteChangeExpected; - bool MustBuffer; // The screen is not 8-bit, or there is no backbuffer - bool BufferingNow; // Most recent Lock was buffered - bool WasBuffering; // Second most recent Lock was buffered - bool Write8bit; - bool UpdatePending; // On final unlock, call Update() - bool UseBlitter; // Use blitter to copy from sys mem to video mem - bool UsePfx; - - DDrawFB() {} -}; - -class D3DFB : public BaseWinFB -{ - typedef BaseWinFB Super; -public: - D3DFB (UINT adapter, int width, int height, bool bgra, bool fullscreen); - ~D3DFB (); - - bool IsValid (); - bool Lock (bool buffered); - void Unlock (); - void Update (); - void Flip (); - PalEntry *GetPalette (); - void GetFlashedPalette (PalEntry palette[256]); - void UpdatePalette (); - bool SetGamma (float gamma); - bool SetFlash (PalEntry rgb, int amount); - void GetFlash (PalEntry &rgb, int &amount); - int GetPageCount (); - bool IsFullscreen (); - void PaletteChanged (); - int QueryNewPalette (); - void Blank (); - bool PaintToWindow (); - void SetVSync (bool vsync); - void NewRefreshRate(); - void GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type, float &gamma) override; - void ReleaseScreenshotBuffer(); - void SetBlendingRect (int x1, int y1, int x2, int y2); - bool Begin2D (bool copy3d); - void DrawBlendingRect (); - FNativeTexture *CreateTexture (FTexture *gametex, FTextureFormat fmt, bool wrapping); - FNativePalette *CreatePalette (FRemapTable *remap); - void DrawTextureParms (FTexture *img, DrawParms &parms); - void DoClear (int left, int top, int right, int bottom, int palcolor, uint32_t color); - void DoDim (PalEntry color, float amount, int x1, int y1, int w, int h); - void FlatFill (int left, int top, int right, int bottom, FTexture *src, bool local_origin); - void DrawLine(int x0, int y0, int x1, int y1, int palColor, uint32_t realcolor); - void DrawPixel(int x, int y, int palcolor, uint32_t rgbcolor); - void FillSimplePoly(FTexture *tex, FVector2 *points, int npoints, - double originx, double originy, double scalex, double scaley, - DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel, int bottomclip) override; - bool WipeStartScreen(int type); - void WipeEndScreen(); - bool WipeDo(int ticks); - void WipeCleanup(); - HRESULT GetHR (); - bool Is8BitMode() { return false; } - virtual int GetTrueHeight() { return TrueHeight; } - virtual bool LegacyHardware() const { return SM14; } - -private: - friend class D3DTex; - friend class D3DPal; - - struct PackedTexture; - struct Atlas; - - struct FBVERTEX - { - FLOAT x, y, z, rhw; - D3DCOLOR color0, color1; - FLOAT tu, tv; - }; -#define D3DFVF_FBVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1) - - struct BufferedTris - { - union - { - struct - { - uint8_t Flags; - uint8_t ShaderNum:4; - uint8_t BlendOp:4; - uint8_t SrcBlend, DestBlend; - }; - DWORD Group1; - }; - uint8_t Desat; - D3DPal *Palette; - IDirect3DTexture9 *Texture; - int NumVerts; // Number of _unique_ vertices used by this set. - int NumTris; // Number of triangles used by this set. - }; - - enum - { - PSCONST_Desaturation = 1, - PSCONST_PaletteMod = 2, - PSCONST_Weights = 6, - PSCONST_Gamma = 7, - }; - enum - { - SHADER_NormalColor, - SHADER_NormalColorPal, - SHADER_NormalColorInv, - SHADER_NormalColorPalInv, - - SHADER_RedToAlpha, - SHADER_RedToAlphaInv, - - SHADER_VertexColor, - - SHADER_SpecialColormap, - SHADER_SpecialColormapPal, - - SHADER_InGameColormap, - SHADER_InGameColormapDesat, - SHADER_InGameColormapInv, - SHADER_InGameColormapInvDesat, - SHADER_InGameColormapPal, - SHADER_InGameColormapPalDesat, - SHADER_InGameColormapPalInv, - SHADER_InGameColormapPalInvDesat, - - SHADER_BurnWipe, - SHADER_GammaCorrection, - - NUM_SHADERS - }; - static const char *const ShaderNames[NUM_SHADERS]; - - void SetInitialState(); - bool CreateResources(); - void ReleaseResources(); - bool LoadShaders(); - void CreateBlockSurfaces(); - bool CreateFBTexture(); - bool CreatePaletteTexture(); - bool CreateGammaTexture(); - bool CreateVertexes(); - void DoOffByOneCheck(); - void UploadPalette(); - void UpdateGammaTexture(float igamma); - void FillPresentParameters (D3DPRESENT_PARAMETERS *pp, bool fullscreen, bool vsync); - void CalcFullscreenCoords (FBVERTEX verts[4], bool viewarea_only, bool can_double, D3DCOLOR color0, D3DCOLOR color1) const; - bool Reset(); - IDirect3DTexture9 *GetCurrentScreen(D3DPOOL pool=D3DPOOL_SYSTEMMEM); - void ReleaseDefaultPoolItems(); - void KillNativePals(); - void KillNativeTexs(); - PackedTexture *AllocPackedTexture(int width, int height, bool wrapping, D3DFORMAT format); - void DrawPackedTextures(int packnum); - void DrawLetterbox(); - void Draw3DPart(bool copy3d); - bool SetStyle(D3DTex *tex, DrawParms &parms, D3DCOLOR &color0, D3DCOLOR &color1, BufferedTris &quad); - static D3DBLEND GetStyleAlpha(int type); - static void SetColorOverlay(DWORD color, float alpha, D3DCOLOR &color0, D3DCOLOR &color1); - void DoWindowedGamma(); - void AddColorOnlyQuad(int left, int top, int width, int height, D3DCOLOR color); - void AddColorOnlyRect(int left, int top, int width, int height, D3DCOLOR color); - void CheckQuadBatch(int numtris=2, int numverts=4); - void BeginQuadBatch(); - void EndQuadBatch(); - void BeginLineBatch(); - void EndLineBatch(); - void EndBatch(); - void CopyNextFrontBuffer(); - - D3DCAPS9 DeviceCaps; - - // State - void EnableAlphaTest(BOOL enabled); - void SetAlphaBlend(D3DBLENDOP op, D3DBLEND srcblend=D3DBLEND(0), D3DBLEND destblend=D3DBLEND(0)); - void SetConstant(int cnum, float r, float g, float b, float a); - void SetPixelShader(IDirect3DPixelShader9 *shader); - void SetTexture(int tnum, IDirect3DTexture9 *texture); - void SetPaletteTexture(IDirect3DTexture9 *texture, int count, D3DCOLOR border_color); - void SetPalTexBilinearConstants(Atlas *texture); - - BOOL AlphaTestEnabled; - BOOL AlphaBlendEnabled; - D3DBLENDOP AlphaBlendOp; - D3DBLEND AlphaSrcBlend; - D3DBLEND AlphaDestBlend; - float Constant[3][4]; - D3DCOLOR CurBorderColor; - IDirect3DPixelShader9 *CurPixelShader; - IDirect3DTexture9 *Texture[5]; - - PalEntry SourcePalette[256]; - D3DCOLOR BorderColor; - D3DCOLOR FlashColor0, FlashColor1; - PalEntry FlashColor; - int FlashAmount; - int TrueHeight; - int PixelDoubling; - int SkipAt; - int LBOffsetI; - int RenderTextureToggle; - int CurrRenderTexture; - float LBOffset; - float Gamma; - bool UpdatePending; - bool NeedPalUpdate; - bool NeedGammaUpdate; - int FBWidth, FBHeight; - D3DFORMAT FBFormat; - bool VSync; - RECT BlendingRect; - int In2D; - bool InScene; - bool SM14; - bool GatheringWipeScreen; - bool AALines; - uint8_t BlockNum; - D3DPal *Palettes; - D3DTex *Textures; - Atlas *Atlases; - HRESULT LastHR; - - UINT Adapter; - IDirect3DDevice9 *D3DDevice; - IDirect3DTexture9 *FBTexture; - IDirect3DTexture9 *TempRenderTexture, *RenderTexture[2]; - IDirect3DTexture9 *PaletteTexture; - IDirect3DTexture9 *GammaTexture; - IDirect3DTexture9 *ScreenshotTexture; - IDirect3DSurface9 *ScreenshotSurface; - IDirect3DSurface9 *FrontCopySurface; - - IDirect3DVertexBuffer9 *VertexBuffer; - FBVERTEX *VertexData; - IDirect3DIndexBuffer9 *IndexBuffer; - uint16_t *IndexData; - BufferedTris *QuadExtra; - int VertexPos; - int IndexPos; - int QuadBatchPos; - enum { BATCH_None, BATCH_Quads, BATCH_Lines } BatchType; - - IDirect3DPixelShader9 *Shaders[NUM_SHADERS]; - IDirect3DPixelShader9 *GammaShader; - - IDirect3DSurface9 *BlockSurface[2]; - IDirect3DSurface9 *OldRenderTarget; - IDirect3DTexture9 *InitialWipeScreen, *FinalWipeScreen; - - D3DFB() {} - - class Wiper - { - public: - virtual ~Wiper(); - virtual bool Run(int ticks, D3DFB *fb) = 0; - - void DrawScreen(D3DFB *fb, IDirect3DTexture9 *tex, - D3DBLENDOP blendop=D3DBLENDOP(0), D3DCOLOR color0=0, D3DCOLOR color1=0xFFFFFFF); - }; - - class Wiper_Melt; friend class Wiper_Melt; - class Wiper_Burn; friend class Wiper_Burn; - class Wiper_Crossfade; friend class Wiper_Crossfade; - - Wiper *ScreenWipe; -}; - -// Flags for a buffered quad -enum -{ - BQF_GamePalette = 1, - BQF_CustomPalette = 7, - BQF_Paletted = 7, - BQF_Bilinear = 8, - BQF_WrapUV = 16, - BQF_InvertSource = 32, - BQF_DisableAlphaTest= 64, - BQF_Desaturated = 128, -}; - -// Shaders for a buffered quad -enum -{ - BQS_PalTex, - BQS_Plain, - BQS_RedToAlpha, - BQS_ColorOnly, - BQS_SpecialColormap, - BQS_InGameColormap, -}; - -#if _DEBUG && 0 -#define STARTLOG -#define STOPLOG -#define LOG(x) { OutputDebugString(x); } -#define LOG1(x,y) { char poo[1024]; mysnprintf(poo, countof(poo), x, y); OutputDebugString(poo); } -#define LOG2(x,y,z) { char poo[1024]; mysnprintf(poo, countof(poo), x, y, z); OutputDebugString(poo); } -#define LOG3(x,y,z,zz) { char poo[1024]; mysnprintf(poo, countof(poo), x, y, z, zz); OutputDebugString(poo); } -#define LOG4(x,y,z,a,b) { char poo[1024]; mysnprintf(poo, countof(poo), x, y, z, a, b); OutputDebugString(poo); } -#define LOG5(x,y,z,a,b,c) { char poo[1024]; mysnprintf(poo, countof(poo), x, y, z, a, b, c); OutputDebugString(poo); } -#else -#define STARTLOG -#define STOPLOG -#define LOG(x) -#define LOG1(x,y) -#define LOG2(x,y,z) -#define LOG3(x,y,z,zz) -#define LOG4(x,y,z,a,b) -#define LOG5(x,y,z,a,b,c) -#endif diff --git a/src/win32/win32video.cpp b/src/win32/win32video.cpp index 3ef45e6de2..6a314621a3 100644 --- a/src/win32/win32video.cpp +++ b/src/win32/win32video.cpp @@ -68,11 +68,8 @@ #include "m_argv.h" #include "r_defs.h" #include "v_text.h" -#include "swrenderer/r_swrenderer.h" #include "version.h" -#include "win32iface.h" -#include "win32swiface.h" #include "optwin32.h" @@ -80,693 +77,26 @@ // TYPES ------------------------------------------------------------------- -typedef IDirect3D9 *(WINAPI *DIRECT3DCREATE9FUNC)(UINT SDKVersion); -typedef HRESULT (WINAPI *DIRECTDRAWCREATEFUNC)(GUID FAR *lpGUID, LPDIRECTDRAW FAR *lplpDD, IUnknown FAR *pUnkOuter); - // PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- -void DoBlending (const PalEntry *from, PalEntry *to, int count, int r, int g, int b, int a); - // PRIVATE FUNCTION PROTOTYPES --------------------------------------------- static void StopFPSLimit(); // EXTERNAL DATA DECLARATIONS ---------------------------------------------- -extern HWND Window; -extern IVideo *Video; -extern BOOL AppActive; -extern int SessionState; -extern bool FullscreenReset; -extern bool VidResizing; - -EXTERN_CVAR (Bool, fullscreen) -EXTERN_CVAR (Float, Gamma) -EXTERN_CVAR (Bool, cl_capfps) +EXTERN_CVAR(Int, vid_maxfps) // PRIVATE DATA DEFINITIONS ------------------------------------------------ -static HMODULE D3D9_dll; -static HMODULE DDraw_dll; static UINT FPSLimitTimer; // PUBLIC DATA DEFINITIONS ------------------------------------------------- -IDirectDraw2 *DDraw; -IDirect3D9 *D3D; -IDirect3DDevice9 *D3Device; HANDLE FPSLimitEvent; -CVAR (Bool, vid_forceddraw, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR (Int, vid_adapter, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -CUSTOM_CVAR (Int, vid_maxfps, 200, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) -{ - if (vid_maxfps < TICRATE && vid_maxfps != 0) - { - vid_maxfps = TICRATE; - } - else if (vid_maxfps > 1000) - { - vid_maxfps = 1000; - } - else if (cl_capfps == 0) - { - I_SetFPSLimit(vid_maxfps); - } -} -#if VID_FILE_DEBUG -FILE *dbg; -#endif - -// CODE -------------------------------------------------------------------- - -Win32Video::Win32Video (int parm) -: m_Modes (NULL), - m_IsFullscreen (false), - m_Adapter (D3DADAPTER_DEFAULT) -{ - I_SetWndProc(); - if (!InitD3D9()) - { - InitDDraw(); - } -} - -Win32Video::~Win32Video () -{ - FreeModes (); - - if (DDraw != NULL) - { - if (m_IsFullscreen) - { - DDraw->SetCooperativeLevel (NULL, DDSCL_NORMAL); - } - DDraw->Release(); - DDraw = NULL; - } - if (D3D != NULL) - { - D3D->Release(); - D3D = NULL; - } - - STOPLOG; -} - -bool Win32Video::InitD3D9 () -{ - DIRECT3DCREATE9FUNC direct3d_create_9; - - if (vid_forceddraw) - { - return false; - } - - // Load the Direct3D 9 library. - if ((D3D9_dll = LoadLibraryA ("d3d9.dll")) == NULL) - { - Printf("Unable to load d3d9.dll! Falling back to DirectDraw...\n"); - return false; - } - - // Obtain an IDirect3D interface. - if ((direct3d_create_9 = (DIRECT3DCREATE9FUNC)GetProcAddress (D3D9_dll, "Direct3DCreate9")) == NULL) - { - goto closelib; - } - if ((D3D = direct3d_create_9 (D3D_SDK_VERSION)) == NULL) - { - goto closelib; - } - - // Select adapter. - m_Adapter = (vid_adapter < 1 || (UINT)vid_adapter > D3D->GetAdapterCount()) - ? D3DADAPTER_DEFAULT : (UINT)vid_adapter - 1u; - - // Check that we have at least PS 1.4 available. - D3DCAPS9 devcaps; - if (FAILED(D3D->GetDeviceCaps (m_Adapter, D3DDEVTYPE_HAL, &devcaps))) - { - goto d3drelease; - } - if ((devcaps.PixelShaderVersion & 0xFFFF) < 0x104) - { - goto d3drelease; - } - if (!(devcaps.Caps2 & D3DCAPS2_DYNAMICTEXTURES)) - { - goto d3drelease; - } - - // Enumerate available display modes. - FreeModes (); - AddD3DModes (m_Adapter); - AddD3DModes (m_Adapter); - if (Args->CheckParm ("-2")) - { // Force all modes to be pixel-doubled. - ScaleModes (1); - } - else if (Args->CheckParm ("-4")) - { // Force all modes to be pixel-quadrupled. - ScaleModes (2); - } - else - { - AddLowResModes (); - } - AddLetterboxModes (); - if (m_Modes == NULL) - { // Too bad. We didn't find any modes for D3D9. We probably won't find any - // for DDraw either... - goto d3drelease; - } - return true; - -d3drelease: - D3D->Release(); - D3D = NULL; -closelib: - FreeLibrary (D3D9_dll); - Printf("Direct3D acceleration failed! Falling back to DirectDraw...\n"); - return false; -} - -static HRESULT WINAPI EnumDDModesCB(LPDDSURFACEDESC desc, void *data) -{ - ((Win32Video *)data)->AddMode(desc->dwWidth, desc->dwHeight, 8, desc->dwHeight, 0); - return DDENUMRET_OK; -} - -void Win32Video::InitDDraw () -{ - DIRECTDRAWCREATEFUNC directdraw_create; - LPDIRECTDRAW ddraw1; - STARTLOG; - - HRESULT dderr; - - // Load the DirectDraw library. - if ((DDraw_dll = LoadLibraryA ("ddraw.dll")) == NULL) - { - I_FatalError ("Could not load ddraw.dll"); - } - - // Obtain an IDirectDraw interface. - if ((directdraw_create = (DIRECTDRAWCREATEFUNC)GetProcAddress (DDraw_dll, "DirectDrawCreate")) == NULL) - { - I_FatalError ("The system file ddraw.dll is missing the DirectDrawCreate export"); - } - - dderr = directdraw_create (NULL, &ddraw1, NULL); - - if (FAILED(dderr)) - I_FatalError ("Could not create DirectDraw object: %08lx", dderr); - - static const GUID IDIRECTDRAW2_GUID = { 0xB3A6F3E0, 0x2B43, 0x11CF, 0xA2, 0xDE, 0x00, 0xAA, 0x00, 0xB9, 0x33, 0x56 }; - - dderr = ddraw1->QueryInterface (IDIRECTDRAW2_GUID, (LPVOID*)&DDraw); - if (FAILED(dderr)) - { - ddraw1->Release (); - DDraw = NULL; - I_FatalError ("Could not initialize IDirectDraw2 interface: %08lx", dderr); - } - - // Okay, we have the IDirectDraw2 interface now, so we can release the - // really old-fashioned IDirectDraw one. - ddraw1->Release (); - - DDraw->SetCooperativeLevel (Window, DDSCL_NORMAL); - FreeModes (); - dderr = DDraw->EnumDisplayModes (0, NULL, this, EnumDDModesCB); - if (FAILED(dderr)) - { - DDraw->Release (); - DDraw = NULL; - I_FatalError ("Could not enumerate display modes: %08lx", dderr); - } - if (m_Modes == NULL) - { - DDraw->Release (); - DDraw = NULL; - I_FatalError ("DirectDraw returned no display modes.\n\n" - "If you started " GAMENAME " from a fullscreen DOS box, run it from " - "a DOS window instead. If that does not work, you may need to reboot."); - } - if (Args->CheckParm ("-2")) - { // Force all modes to be pixel-doubled. - ScaleModes(1); - } - else if (Args->CheckParm ("-4")) - { // Force all modes to be pixel-quadrupled. - ScaleModes(2); - } - else - { - AddLowResModes (); - } - AddLetterboxModes (); -} - -// Returns true if fullscreen, false otherwise -bool Win32Video::GoFullscreen (bool yes) -{ - static const char *const yestypes[2] = { "windowed", "fullscreen" }; - HRESULT hr[2]; - int count; - - // FIXME: Do this right for D3D. - if (D3D != NULL) - { - return yes; - } - - if (m_IsFullscreen == yes) - return yes; - - for (count = 0; count < 2; ++count) - { - LOG1 ("fullscreen: %d\n", yes); - hr[count] = DDraw->SetCooperativeLevel (Window, !yes ? DDSCL_NORMAL : - DDSCL_ALLOWMODEX | DDSCL_ALLOWREBOOT | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); - if (SUCCEEDED(hr[count])) - { - if (count != 0) - { -// Ack! Cannot print because the screen does not exist right now. -// Printf ("Setting %s mode failed. Error %08lx\n", -// yestypes[!yes], hr[0]); - } - m_IsFullscreen = yes; - return yes; - } - yes = !yes; - } - - I_FatalError ("Could not set %s mode: %08lx\n" - "Could not set %s mode: %08lx\n", - yestypes[yes], hr[0], yestypes[!yes], hr[1]); - - // Appease the compiler, even though we never return if we get here. - return false; -} - -// Flips to the GDI surface and clears it -void Win32Video::BlankForGDI () -{ - static_cast (screen)->Blank (); -} - -//========================================================================== -// -// Win32Video :: DumpAdapters -// -// Dumps the list of display adapters to the console. Only meaningful for -// Direct3D. -// -//========================================================================== - -void Win32Video::DumpAdapters() -{ - using OptWin32::GetMonitorInfoA; - - if (D3D == NULL) - { - Printf("Multi-monitor support requires Direct3D.\n"); - return; - } - - UINT num_adapters = D3D->GetAdapterCount(); - - for (UINT i = 0; i < num_adapters; ++i) - { - D3DADAPTER_IDENTIFIER9 ai; - char moreinfo[64] = ""; - - if (FAILED(D3D->GetAdapterIdentifier(i, 0, &ai))) - { - continue; - } - // Strip trailing whitespace from adapter description. - for (char *p = ai.Description + strlen(ai.Description) - 1; - p >= ai.Description && isspace(*p); - --p) - { - *p = '\0'; - } - HMONITOR hm = D3D->GetAdapterMonitor(i); - MONITORINFOEX mi; - mi.cbSize = sizeof(mi); - - assert(GetMonitorInfo); // Missing in NT4, but so is D3D - if (GetMonitorInfo(hm, &mi)) - { - mysnprintf(moreinfo, countof(moreinfo), " [%ldx%ld @ (%ld,%ld)]%s", - mi.rcMonitor.right - mi.rcMonitor.left, - mi.rcMonitor.bottom - mi.rcMonitor.top, - mi.rcMonitor.left, mi.rcMonitor.top, - mi.dwFlags & MONITORINFOF_PRIMARY ? " (Primary)" : ""); - } - Printf("%s%u. %s%s\n", - i == m_Adapter ? TEXTCOLOR_BOLD : "", - i + 1, ai.Description, moreinfo); - } -} - -// Mode enumeration -------------------------------------------------------- - -void Win32Video::AddD3DModes (unsigned adapter) -{ - for (D3DFORMAT format : { D3DFMT_X8R8G8B8, D3DFMT_R5G6B5}) - { - UINT modecount, i; - D3DDISPLAYMODE mode; - - modecount = D3D->GetAdapterModeCount(adapter, format); - for (i = 0; i < modecount; ++i) - { - if (D3D_OK == D3D->EnumAdapterModes(adapter, format, i, &mode)) - { - AddMode(mode.Width, mode.Height, 8, mode.Height, 0); - } - } - } -} - -//========================================================================== -// -// Win32Video :: AddLowResModes -// -// Recent NVidia drivers no longer support resolutions below 640x480, even -// if you try to add them as a custom resolution. With D3DFB, pixel doubling -// is quite easy to do and hardware-accelerated. If you have 1280x800, then -// you can have 320x200, but don't be surprised if it shows up as widescreen -// on a widescreen monitor, since that's what it is. -// -//========================================================================== - -void Win32Video::AddLowResModes() -{ - ModeInfo *mode, *nextmode; - - for (mode = m_Modes; mode != NULL; mode = nextmode) - { - nextmode = mode->next; - if (mode->realheight == mode->height && - mode->doubling == 0 && - mode->height >= 200*2 && - mode->height <= 480*2 && - mode->width >= 320*2 && - mode->width <= 640*2) - { - AddMode (mode->width / 2, mode->height / 2, mode->bits, mode->height / 2, 1); - } - } - for (mode = m_Modes; mode != NULL; mode = nextmode) - { - nextmode = mode->next; - if (mode->realheight == mode->height && - mode->doubling == 0 && - mode->height >= 200*4 && - mode->height <= 480*4 && - mode->width >= 320*4 && - mode->width <= 640*4) - { - AddMode (mode->width / 4, mode->height / 4, mode->bits, mode->height / 4, 2); - } - } -} - -// Add 16:9 and 16:10 resolutions you can use in a window or letterboxed -void Win32Video::AddLetterboxModes () -{ - ModeInfo *mode, *nextmode; - - for (mode = m_Modes; mode != NULL; mode = nextmode) - { - nextmode = mode->next; - if (mode->realheight == mode->height && mode->height * 4/3 == mode->width) - { - if (mode->width >= 360) - { - AddMode (mode->width, mode->width * 9/16, mode->bits, mode->height, mode->doubling); - } - if (mode->width > 640) - { - AddMode (mode->width, mode->width * 10/16, mode->bits, mode->height, mode->doubling); - } - } - } -} - -void Win32Video::AddMode (int x, int y, int bits, int y2, int doubling) -{ - // Reject modes that do not meet certain criteria. - if ((x & 1) != 0 || - y > MAXHEIGHT || - x > MAXWIDTH || - y < 200 || - x < 320) - { - return; - } - - ModeInfo **probep = &m_Modes; - ModeInfo *probe = m_Modes; - - // This mode may have been already added to the list because it is - // enumerated multiple times at different refresh rates. If it's - // not present, add it to the right spot in the list; otherwise, do nothing. - // Modes are sorted first by width, then by height, then by depth. In each - // case the order is ascending. - for (; probe != 0; probep = &probe->next, probe = probe->next) - { - if (probe->width > x) break; - if (probe->width < x) continue; - // Width is equal - if (probe->height > y) break; - if (probe->height < y) continue; - // Height is equal - if (probe->bits > bits) break; - if (probe->bits < bits) continue; - // Bits is equal - return; - } - - *probep = new ModeInfo (x, y, bits, y2, doubling); - (*probep)->next = probe; -} - -void Win32Video::FreeModes () -{ - ModeInfo *mode = m_Modes; - - while (mode) - { - ModeInfo *tempmode = mode; - mode = mode->next; - delete tempmode; - } - m_Modes = NULL; -} - -// For every mode, set its scaling factor. Modes that end up with too -// small a display area are discarded. - -void Win32Video::ScaleModes (int doubling) -{ - ModeInfo *mode, **prev; - - prev = &m_Modes; - mode = m_Modes; - - while (mode != NULL) - { - assert(mode->doubling == 0); - mode->width >>= doubling; - mode->height >>= doubling; - mode->realheight >>= doubling; - mode->doubling = doubling; - if ((mode->width & 7) != 0 || mode->width < 320 || mode->height < 200) - { // Mode became too small. Delete it. - *prev = mode->next; - delete mode; - } - else - { - prev = &mode->next; - } - mode = *prev; - } -} - -void Win32Video::StartModeIterator (int bits, bool fs) -{ - m_IteratorMode = m_Modes; - m_IteratorBits = bits; - m_IteratorFS = fs; -} - -bool Win32Video::NextMode (int *width, int *height, bool *letterbox) -{ - if (m_IteratorMode) - { - while (m_IteratorMode && m_IteratorMode->bits != m_IteratorBits) - { - m_IteratorMode = m_IteratorMode->next; - } - - if (m_IteratorMode) - { - *width = m_IteratorMode->width; - *height = m_IteratorMode->height; - if (letterbox != NULL) *letterbox = m_IteratorMode->realheight != m_IteratorMode->height; - m_IteratorMode = m_IteratorMode->next; - return true; - } - } - return false; -} - -DFrameBuffer *Win32Video::CreateFrameBuffer (int width, int height, bool bgra, bool fullscreen, DFrameBuffer *old) -{ - static int retry = 0; - static int owidth, oheight; - - BaseWinFB *fb; - PalEntry flashColor; - int flashAmount; - - if (fullscreen) - { - I_ClosestResolution(&width, &height, D3D ? 32 : 8); - } - - LOG4 ("CreateFB %d %d %d %p\n", width, height, fullscreen, old); - - if (old != NULL) - { // Reuse the old framebuffer if its attributes are the same - BaseWinFB *fb = static_cast (old); - if (fb->Width == width && - fb->Height == height && - fb->Windowed == !fullscreen && - fb->Bgra == bgra) - { - return old; - } - old->GetFlash (flashColor, flashAmount); - if (old == screen) screen = nullptr; - delete old; - } - else - { - flashColor = 0; - flashAmount = 0; - } - - if (D3D != NULL) - { - fb = new D3DFB (m_Adapter, width, height, bgra, fullscreen); - } - else - { - fb = new DDrawFB (width, height, fullscreen); - } - - LOG1 ("New fb created @ %p\n", fb); - - // If we could not create the framebuffer, try again with slightly - // different parameters in this order: - // 1. Try with the closest size - // 2. Try in the opposite screen mode with the original size - // 3. Try in the opposite screen mode with the closest size - // This is a somewhat confusing mass of recursion here. - - while (fb == NULL || !fb->IsValid ()) - { - static HRESULT hr; - - if (fb != NULL) - { - if (retry == 0) - { - hr = fb->GetHR (); - } - delete fb; - - LOG1 ("fb is bad: %08lx\n", hr); - } - else - { - LOG ("Could not create fb at all\n"); - } - screen = NULL; - - LOG1 ("Retry number %d\n", retry); - - switch (retry) - { - case 0: - owidth = width; - oheight = height; - case 2: - // Try a different resolution. Hopefully that will work. - I_ClosestResolution (&width, &height, 8); - LOG2 ("Retry with size %d,%d\n", width, height); - break; - - case 1: - // Try changing fullscreen mode. Maybe that will work. - width = owidth; - height = oheight; - fullscreen = !fullscreen; - LOG1 ("Retry with fullscreen %d\n", fullscreen); - break; - - default: - // I give up! - LOG3 ("Could not create new screen (%d x %d): %08lx", owidth, oheight, hr); - I_FatalError ("Could not create new screen (%d x %d): %08lx", owidth, oheight, hr); - } - - ++retry; - fb = static_cast(CreateFrameBuffer (width, height, bgra, fullscreen, NULL)); - } - retry = 0; - - fb->SetFlash (flashColor, flashAmount); - return fb; -} - -void Win32Video::SetWindowedScale (float scale) -{ - // FIXME -} - -//========================================================================== -// -// BaseWinFB :: ScaleCoordsFromWindow -// -// Given coordinates in window space, return coordinates in what the game -// thinks screen space is. -// -//========================================================================== - -void BaseWinFB::ScaleCoordsFromWindow(int16_t &x, int16_t &y) -{ - RECT rect; - - int TrueHeight = GetTrueHeight(); - if (GetClientRect(Window, &rect)) - { - x = int16_t(x * Width / (rect.right - rect.left)); - y = int16_t(y * TrueHeight / (rect.bottom - rect.top)); - } - // Subtract letterboxing borders - y -= (TrueHeight - Height) / 2; -} //========================================================================== // @@ -846,4 +176,5 @@ void I_FPSLimit() { WaitForSingleObject(FPSLimitEvent, 1000); } -} \ No newline at end of file +} + diff --git a/src/win32/zdoom.rc b/src/win32/zdoom.rc index 3450c2a809..9208e54e57 100644 --- a/src/win32/zdoom.rc +++ b/src/win32/zdoom.rc @@ -8,8 +8,8 @@ // Generated from the TEXTINCLUDE 2 resource. // #include "afxres.h" -#include "../version.h" -#include "../gitinfo.h" +#include "../version.h" +#include "../gitinfo.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS @@ -234,9 +234,7 @@ FONT 8, "MS Shell Dlg" CONTROL "Select which game file (IWAD) to run.", IDC_STATIC, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 12, 44, 190, 8 CONTROL "", IDC_IWADLIST, LISTBOX, LBS_NOTIFY | LBS_NOINTEGRALHEIGHT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | WS_TABSTOP, 12, 56, 200, 87 CONTROL "Video settings", IDC_STATIC, BUTTON, BS_GROUPBOX | WS_CHILD | WS_VISIBLE, 8, 155, 109, 52 - CONTROL "Hardware (OpenGL)", IDC_WELCOME_OPENGL, BUTTON, BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE, 12, 170, 93, 10 - CONTROL "Software (Doom)", IDC_WELCOME_SOFTWARE, BUTTON, BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE, 12, 180, 93, 10 - CONTROL "Fullscreen", IDC_WELCOME_FULLSCREEN, BUTTON, BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 12, 190, 48, 10 + CONTROL "Fullscreen", IDC_WELCOME_FULLSCREEN, BUTTON, BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 12, 170, 48, 10 CONTROL "Resource settings", IDC_STATIC, BUTTON, BS_GROUPBOX | WS_CHILD | WS_VISIBLE, 123, 155, 95, 52 CONTROL "Disable autoload", IDC_WELCOME_NOAUTOLOAD, BUTTON, BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 130, 170, 65, 10 CONTROL "Load lights", IDC_WELCOME_LIGHTS, BUTTON, BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 130, 180, 51, 10 diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index 6730028771..f5ea9710d2 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -1,35 +1,3 @@ -6DC9F6CCEAE7A91AEC48EBE506F22BC4 // void.wad MAP01 -{ - // Slightly squash the pillars in the starting room with "stimpacks" - // floating on them so that they can be obtained. - setsectoroffset 62 floor -8 - setwallyscale 286 front bot 1.090909 - setwallyscale 287 front bot 1.090909 - setwallyscale 288 front bot 1.090909 - setwallyscale 289 front bot 1.090909 - - setsectoroffset 63 floor -8 - setwallyscale 290 front bot 1.090909 - setwallyscale 291 front bot 1.090909 - setwallyscale 292 front bot 1.090909 - setwallyscale 293 front bot 1.090909 - - setsectoroffset 118 floor -8 - setwallyscale 710 front bot 1.090909 - setwallyscale 711 front bot 1.090909 - setwallyscale 712 front bot 1.090909 - setwallyscale 713 front bot 1.090909 - - setsectoroffset 119 floor -8 - setwallyscale 714 front bot 1.090909 - setwallyscale 715 front bot 1.090909 - setwallyscale 716 front bot 1.090909 - setwallyscale 717 front bot 1.090909 - - setslopeoverflow - polyobj -} - B2D8DA03489D1C67F60DC87FBC4EA338 // map01 - Massmouth 2 801304DA3784308D333951B5E0CF8E9E // map02 6EA4D5CAEA16857B2A882467E1633BC2 // map03 @@ -52,15 +20,6 @@ A80E7EE40E0D0C76A6FBD242BE29FE27 // map15 resetplayerspeed } -5C594C67CF7721005DE71429F9811370 // Eternal Doom map03 -{ - // fix broken staircase. The compatibility option is not sufficient - // to reliably handle this so clear the tags from the unwanted sectors. - setsectortag 212 0 - setsectortag 213 0 - setsectortag 214 0 -} - 6DA6FCBA8089161BDEC6A1D3F6C8D60F // Eternal Doom MAP25 { stairs @@ -77,7 +36,6 @@ A80E7EE40E0D0C76A6FBD242BE29FE27 // map15 useblocking } -// mostly cosmetic (except AV MAP07 and MM2 MAP25) 0EECBF37B328C9CAAF20DED4949A4157 // Sudtic e2m6 4ACE0644883BDA0CBA254FA02C9ACF83 // Teutic e3m4 9F2BE080A33F775294BD78822456924E // Nukemine e1m4 @@ -87,6 +45,7 @@ CD31793D3A4B00231B124C0C23649644 // Strain map02 F84AB4557464A383E93F37CD3A82AC48 // MM2 map03 1497894956B3C8EBE8A240B7FDD99C6A // MM2 map25 941E4CB56EE4184E0B1ED43486AB0BBF // AV map07 +6D4156EE0D12B77AD143A37C4D3DCF98 // dmonfear.wad map22 { shorttex } @@ -97,11 +56,6 @@ F84AB4557464A383E93F37CD3A82AC48 // MM2 map03 trace } -9D50EBE17CEC78938C7A668DB0768611 // Strain map07: Make the exit accessible -{ - clearlineflags 1021 1 -} - 71C2E6D9CFA3D8750C6A9599FB2453BD // Hacx map03: There are some switches behind 96368EB950E33AF62EA6423434E3CEF7 // HacX map17: shootable covers in these levels BA530202AF0BA0C6CBAE6A0C7076FB72 // Requiem map04 @@ -180,11 +134,6 @@ CA267398C9B3A8F79349D3394F8B2106 // map20 spritesort } -DCE862393CAAA6FF1294FB7056B53057 // UAC Ultra map07: Contains a scroller depending on Boom side effects -{ - setlinespecial 391 Sector_CopyScroller 99 6 0 0 0 -} - 1D9E43988940CCD3555724E15DD8B1AB // Happy Time Circus map01 has bad teleporters 040F83028FFA74456E335ED300BE2C33 // MAP17 (TownInfection.wad) 156FA31F5FF72A87BF345B68029D3051 // MAP02 (nprject5.wad) @@ -201,19 +150,6 @@ AF40D0E49BD1B76D4B1AADD8212ADC46 // MAP01 (the wad that shall not be named =P) badangles } -E2B5D1400279335811C1C1C0B437D9C8 // Deathknights of the Dark Citadel, map54 -{ - // This map has two gear boxes which are flagged for player cross - // activation instead of the proper player uses activation. - setactivation 963 2 - setactivation 943 2 -} - -3F249EDD62A3A08F53A6C53CB4C7ABE5 // Artica 3 map01 -{ - clearlinespecial 66 -} - 8FA29398776146189396AA1AC6BB9E13 // Roger Ritenour's Phobos map03 { floormove @@ -225,188 +161,20 @@ E2B5D1400279335811C1C1C0B437D9C8 // Deathknights of the Dark Citadel, map54 limitpain } -// Daedalus: Fix SPAC_Push lines that aren't on lines you can actually push -3ABB618A475BCBC531B457BAA6E4E70A // map04 -{ - // forcefields - // the lines we're setting are already set for repeatable SPAC_Push - clearlinespecial 90 - setlinespecial 3749 ACS_Execute 23 0 1 0 0 - clearlinespecial 94 - setlinespecial 3766 ACS_Execute 23 0 2 0 0 - clearlinespecial 92 - setlinespecial 3777 ACS_Execute 23 0 3 0 0 - clearlinespecial 98 - setlinespecial 3784 ACS_Execute 23 0 4 0 0 -} -795FDE3CC1C97140F326D0152B3FCE2A // map24 -{ - // doors - clearlinespecial 1512 - setlinespecial 1505 Door_Raise 213 50 100 0 0 - setlineflags 1505 0x200 // repeatable - setactivation 1505 16 // SPAC_Push - clearlinespecial 1514 - setlinespecial 1508 Door_Raise 213 50 100 0 0 - setlineflags 1508 0x200 - setactivation 1508 16 - - clearlinespecial 1525 - setlinespecial 1522 Door_Raise 214 50 100 0 0 - setlineflags 1522 0x200 - setactivation 1522 16 - clearlinespecial 1530 - setlinespecial 1527 Door_Raise 214 50 100 0 0 - setlineflags 1527 0x200 - setactivation 1527 16 - - clearlinespecial 5277 - setlinespecial 5209 Door_Raise 24 20 255 0 0 - setlineflags 5209 0x200 - setactivation 5209 16 - clearlinespecial 5714 - setlinespecial 5267 Door_Raise 24 20 255 0 0 - setlineflags 5267 0x200 - setactivation 5267 16 - - clearlinespecial 5715 - setlinespecial 5229 Door_Raise 24 20 255 0 0 - setlineflags 5229 0x200 - setactivation 5229 16 - clearlinespecial 5345 - setlinespecial 5232 Door_Raise 24 20 255 0 0 - setlineflags 5232 0x200 - setactivation 5232 16 - - // consoles? - clearlinespecial 3639 - setlinespecial 3633 ACS_Execute 14 0 0 0 0 - setlinespecial 3635 ACS_Execute 14 0 0 0 0 - setlineflags 3633 0x200 - setlineflags 3635 0x200 - setactivation 3633 16 - setactivation 3635 16 - - clearlinespecial 3647 - setlinespecial 3644 ACS_Execute 14 0 0 0 0 - setlinespecial 3641 ACS_Execute 14 0 0 0 0 - setlineflags 3644 0x200 - setlineflags 3641 0x200 - setactivation 3644 16 - setactivation 3641 16 - - clearlinespecial 3659 - clearlinespecial 3657 - setlinespecial 3653 ACS_Execute 13 0 0 0 0 - setlinespecial 3655 ACS_Execute 13 0 0 0 0 - setlinespecial 3651 ACS_Execute 13 0 0 0 0 - setlinespecial 3654 ACS_Execute 13 0 0 0 0 - setlineflags 3653 0x200 - setlineflags 3655 0x200 - setlineflags 3651 0x200 - setlineflags 3654 0x200 - setactivation 3653 16 - setactivation 3655 16 - setactivation 3651 16 - setactivation 3654 16 -} - -// Community Chest 3 -F481922F4881F74760F3C0437FD5EDD0 // map03 -{ - // I have no idea how this conveyor belt setup manages to work under Boom. - // Set the sector the voodoo doll ends up standing on when sectors tagged - // 1 are raised so that the voodoo doll will be carried. - setlinespecial 3559 Sector_CopyScroller 17 6 0 0 0 -} - 7C1913DEE396BA26CFF22A0E9369B7D2 // Nuke Mine, e1m2 { pointonline } -5B862477519B21B30059A466F2FF6460 // Khorus, map08 -{ - // This map uses a voodoo conveyor with slanted walls to shunt the - // voodoo doll into side areas. For some reason, this voodoo doll - // is unable to slide on them, because the slide calculation gets - // them slightly inside the walls and thinks they are stuck. I could - // not reproduce this with the real player, which is what has me - // stumped. So, help them out be attaching some ThrustThing specials - // to the walls. - setlinespecial 443 ThrustThing 96 4 0 0 0 - setlineflags 443 0x200 // repeatable - setactivation 443 16 // SPAC_Push - setlinespecial 455 ThrustThing 96 4 0 0 0 - setlineflags 455 0x200 // repeatable - setactivation 455 16 // SPAC_Push -} - 8B2AC8D4DB4A49A5DCCBB067E04434D6 // The Hell Factory Hub One, map04 65A1EB4C87386F290816660A52932FF1 // Master Levels, garrison.wad 3DEE4EFEFAF3260C800A30734F54CE75 // Hellbound, map14 5FAA25F5A6AAB3409CAE0AF87F910341 // DOOM.wad e1m6 +94893A0DC429A22ADC4B3A73DA537E16 // DOOM2.WAD map25 { rebuildnodes } -3D1E36E50F5A8D289E15433941605224 // Master Levels, catwalk.wad -{ - // make it impossible to open door to 1-way bridge before getting red key - setsectortag 35 0 // existing tag must be cleared before new one can be set - setsectortag 35 15 - setactivation 605 1 // SPAC_PCross - setactivation 606 1 - setactivation 607 1 - setactivation 608 1 - setlinespecial 605 Door_Open 15 64 0 0 0 // fast, stay open - setlinespecial 606 Door_Open 15 64 0 0 0 - setlinespecial 607 Door_Open 15 64 0 0 0 - setlinespecial 608 Door_Open 15 64 0 0 0 -} - -3B9CAA02952F405269353FAAD8F8EC33 // Master Levels, nessus.wad -{ - // move secret sector from too-thin doorframe to BFG closet - setsectorspecial 211 0 - setsectorspecial 212 1024 - // lower floor a bit so secret sector can be entered fully - setsectoroffset 212 floor -16 - // make secret door stay open so you can't get locked in closet - setlinespecial 1008 Door_Open 0 64 0 0 0 -} - -7ED9800213C00D6E7FB98652AB48B3DE // Ultimate Simplicity, map04 -{ - // Add missing map spots on easy and medium skills - // Demons will teleport into starting room making 100% kills possible - setthingskills 31 31 - setthingskills 32 31 -} - -1891E029994B023910CFE0B3209C3CDB // Ultimate Simplicity, map07 -{ - // It is possible to get stuck on skill 0 or 1 when no shots have been fired - // after sector 17 became accessible and before entering famous mancubus room. - // Monsters from the mentioned sector won't be alerted and so - // they won't teleport into the battle. ACS will wait forever for their deaths. - setlinespecial 397 NoiseAlert 0 0 0 0 0 - setlinespecial 411 NoiseAlert 0 0 0 0 0 -} - -F0E6F30F57B0425F17E43600AA813E80 // Ultimate Simplicity, map11 -{ - // If door (sector #309) is closed it cannot be open again - // from one side potentially blocking level progression - clearlinespecial 2445 -} - -952CC8D03572E17BA550B01B366EFBB9 // Cheogsh map01 -{ - // make the blue key spawn above the 3D floor - setthingz 918 296 -} - 64B6CE3CB7349B6F6B1A885C449ACB96 // Super Sonic Doom, map31 { // During the end-of-level tally, both PROP_FROZEN and PROP_TOTALLYFROZEN @@ -415,80 +183,15 @@ F0E6F30F57B0425F17E43600AA813E80 // Ultimate Simplicity, map11 linkfrozenprops } -D62DCA9EC226DE49108D5DD9271F7631 // Cheogsh 2 map04 -{ - // Stuff in megasphere cage is positioned too low - setthingz 1640 528 - setthingz 1641 528 - setthingz 1642 528 - setthingz 1643 528 - setthingz 1644 528 - setthingz 1645 528 - setthingz 1646 528 - setthingz 1647 528 - setthingz 1648 528 - setthingz 1649 528 -} - E89CCC7E155F1032F693359CC219BE6C // hexen.wad map30 B9DFF13207EACAC675C71D82624D0007 // XtheaterIII map01 6941BDC2F80C0FEBE34EFA23D5FB72B7 // sonic.wad map10 +3ABB618A475BCBC531B457BAA6E4E70A // Daedalus map04 +795FDE3CC1C97140F326D0152B3FCE2A // Daedalus map24 { DisablePushWindowCheck } -DFC18B92BF3E8142B8684ECD8BD2EF06 // TNT: Evilution map15 -{ - // raise up sector with its counterpart so 100% kills becomes possible - setsectortag 330 11 -} - -2C4A3356C5EB3526D2C72A4AA4B18A36 // TNT: Evilution map29 -{ - // remove mancubus who always gets stuck in teleport tunnel, preventing - // 100% kills on HMP - setthingflags 405 0 -} - -A53AE580A4AF2B5D0B0893F86914781E // TNT: Evilution map31 -{ - setthingflags 470 2016 -} - -D99AD22FF21A41B4EECDB3A7C803D75E // TNT: Evilution map32 -{ - // door can close permanently; make switch that opens it repeatable - setlineflags 872 0x200 - // switch should only open way to red key, don't lower bars yet, - // instead make line just before red key open bars - setsectortag 197 0 - setsectortag 197 8 - setlinespecial 1279 Floor_LowerToLowest 8 32 0 0 0 - setactivation 1240 1 // SPAC_PCross - setlinespecial 1240 Floor_LowerToLowest 38 32 0 0 0 -} - -279BB50468FE9F5B36C6D821E4902369 // Plutonia Experiment map30 -{ - // flag items in deathmatch-only area correctly so that 100% items - // are possible in solo - setthingflags 250 17 - setthingflags 251 17 - setthingflags 252 17 - setthingflags 253 17 - setthingflags 254 17 - setthingflags 206 17 -} - -4CB7AAC5C43CF32BDF05FD36481C1D9F // Plutonia: Revisited map27 -{ - setlinespecial 1214 Plat_DownWaitUpStayLip 20 64 150 0 0 - setlinespecial 1215 Plat_DownWaitUpStayLip 20 64 150 0 0 - setlinespecial 1216 Plat_DownWaitUpStayLip 20 64 150 0 0 - setlinespecial 1217 Plat_DownWaitUpStayLip 20 64 150 0 0 - setlinespecial 1227 Plat_DownWaitUpStayLip 20 64 150 0 0 -} - D0139194F7817BF06F3988DFC47DB38D // Whispers of Satan map29 { nopassover @@ -514,254 +217,19 @@ C98F79709BD7E0E4C19026AB9575EC6F // cc-cod.zip:codlev.wad map07 noslopeid } +3FFAF2F624C1B4BB6F581DCF7B99CBA7 // hexen.wad MAP36 +7DC65D5029DD834481CD716B3D71388A // hexdd.wad MAP47 05AA32F1D2220A462DCDA245ED22B94B // sonic.wad map09 { polyobj } - D7F6E9F08C39A17026349A04F8C0B0BE // Return to Hadron, e1m9 19D03FFC875589E21EDBB7AB74EF4AEF // Return to Hadron, e1m9, 2016.01.03 update { pointonline } -5B26545FF21B051CA06D389CE535684C // doom.wad e1m4 -{ - // missing textures - setwalltexture 693 back top BROWN1 - // fix HOM errors with sectors too low - setsectoroffset 9 floor 8 - setsectoroffset 105 floor 8 - setsectoroffset 132 floor 8 - setsectoroffset 137 floor 8 -} -A24FE135D5B6FD427FE27BEF89717A65 // doom.wad e2m2 -{ - // missing textures - setwalltexture 947 back top BROWN1 - setwalltexture 1596 back top WOOD1 -} -1BC04D646B32D3A3E411DAF3C1A38FF8 // doom.wad e2m4 -{ - // missing textures - setwalltexture 551 back top PIPE4 - setwalltexture 865 back bot STEP5 - setwalltexture 1062 front top GSTVINE1 - setwalltexture 1071 front top MARBLE1 -} -99C580AD8FABE923CAB485CB7F3C5E5D // doom.wad e2m5 -{ - // missing textures - setwalltexture 590 back top GRAYBIG - setwalltexture 590 front bot BROWN1 -} -3838AB29292587A7EE3CA71E7040868D // doom.wad e2m6 -{ - // missing texture - setwalltexture 1091 back top compspan -} -8590F489879870C098CD7029C3187159 // doom.wad e2m7 -{ - // missing texture - setwalltexture 1286 front bot SHAWN2 -} -8A6399FAAA2E68649D4E4B16642074BE // doom.wad e2m9 -{ - // missing textures - setwalltexture 121 back top SW1LION - setwalltexture 123 back top GSTONE1 - setwalltexture 140 back top GSTONE1 -} -2B65CB046EA40D2E44576949381769CA // Commercial Doom e3m4 -{ - // This line is erroneously specified as Door_Raise that monsters - // can operate. If they do, they block you off from half the map. Change - // this into a one-shot Door_Open so that it won't close. - setlinespecial 1069 Door_Open 0 16 0 0 0 - clearlineflags 1069 0x200 -} -5AC51CA9F1B57D4538049422A5E37291 // doom.wad e3m7 -{ - // missing texture - setwalltexture 971 back top SP_HOT1 -} -DA0C8281AC70EEC31127C228BCD7FE2C // doom.wad e4m1 -{ - // missing texture - setwalltexture 470 front top GSTONE1 -} -F6EE16F770AD309D608EA0B1F1E249FC // Ultimate Doom, e4m3 -{ - // Remove unreachable secrets - setsectorspecial 124 0 - setsectorspecial 125 0 - // clear staircase to secret area - setsectorspecial 127 0 - setsectorspecial 128 0 - setsectorspecial 129 0 - setsectorspecial 130 0 - setsectorspecial 131 0 - setsectorspecial 132 0 - setsectorspecial 133 0 - setsectorspecial 134 0 - setsectorspecial 136 0 - setsectorspecial 137 0 - setsectorspecial 138 0 - setsectorspecial 147 0 - setsectorspecial 148 0 - setsectorspecial 149 0 - setsectorspecial 150 0 - setsectorspecial 151 0 - setsectorspecial 152 0 - setsectorspecial 155 0 -} -AAECADD4D97970AFF702D86FAFAC7D17 // doom.wad e4m4 -{ - // missing textures - setwalltexture 427 back top BROWNHUG - setwalltexture 558 back top BROWNHUG - setwalltexture 567 front top BROWNHUG - setwalltexture 572 front top BROWNHUG -} -94D4C869A0C02EF4F7375022B36AAE45 // Ultimate Doom, e4m7 -{ - // Remove unreachable secrets - setsectorspecial 263 0 - setsectorspecial 264 0 -} - - -AB24AE6E2CB13CBDD04600A4D37F9189 // doom2.wad map02 -1EC0AF1E3985650F0C9000319C599D0C // doom2bfg.wad map02 -{ - // missing textures - setwalltexture 327 front bot STONE4 - setwalltexture 328 front bot STONE4 - setwalltexture 338 front bot STONE4 - setwalltexture 339 front bot STONE4 -} -CEC791136A83EEC4B91D39718BDF9D82 // doom2.wad map04 -{ - // missing textures - setwalltexture 456 back top SUPPORT3 - setwalltexture 108 front top STONE - setwalltexture 109 front top STONE - setwalltexture 110 front top STONE - setwalltexture 111 front top STONE - setwalltexture 127 front top STONE - setwalltexture 128 front top STONE - // remove erroneous blue keycard pickup ambush sector tags (nearby viewing windows, and the lights) - setsectortag 19 0 - setsectortag 20 0 - setsectortag 23 0 - setsectortag 28 0 - setsectortag 33 0 - setsectortag 34 0 - setsectortag 83 0 - setsectortag 85 0 -} -9E061AD7FBCD7FAD968C976CB4AA3B9D // doom2.wad map05 -{ - // fix bug with opening westmost door in door hallway - incorrect sector tagging - see doomwiki.org for more info - setsectortag 4 0 - setsectortag 153 0 -} -66C46385EB1A23D60839D1532522076B // doom2.wad map08 -{ - // missing texture - setwalltexture 101 back top BRICK7 -} -5BDA34DA60C0530794CC1EA2DA017976 // doom2.wad map14 -{ - // missing textures - setwalltexture 1259 back top BSTONE2 - setwalltexture 1305 back top BSTONE2 -} -1A540BA717BF9EC85F8522594C352F2A // Doom II, map15 -{ - setsectorspecial 147 0 -} -0D491365C1B88B7D1B603890100DD03E // doom2.wad map18 -{ - // missing textures - setwalltexture 451 front mid metal - setwalltexture 459 front mid metal -} -B5506B1E8F2FC272AD0C77B9E0DF5491 // doom2.wad map19 -{ - // missing textures - setwalltexture 355 back top STONE2 - setwalltexture 736 front top SLADWALL -} -EBDAC00E9D25D884B2C8F4B1F0390539 // doom2.wad map21 -{ - // push ceiling down in glitchy sectors above the stair switches - setsectoroffset 50 ceil -56 - setsectoroffset 54 ceil -56 -} -94893A0DC429A22ADC4B3A73DA537E16 // DOOM2.WAD map25 -{ - rebuildnodes -} -110F84DE041052B59307FAF0293E6BC0 // Doom II, map27 -{ - setsectorspecial 93 0 - setwalltexture 582 back top ZIMMER3 -} -20251EDA21B2F2ECF6FF5B8BBC00B26C // Doom II, MAP29 -{ - // Missing textures on teleporters - setwalltexture 405 back bot SUPPORT3 - setwalltexture 406 back bot SUPPORT3 - setwalltexture 407 back bot SUPPORT3 - setwalltexture 408 back bot SUPPORT3 - setwalltexture 516 back bot SUPPORT3 - setwalltexture 517 back bot SUPPORT3 - setwalltexture 518 back bot SUPPORT3 - setwalltexture 519 back bot SUPPORT3 - setwalltexture 524 back bot SUPPORT3 - setwalltexture 525 back bot SUPPORT3 - setwalltexture 526 back bot SUPPORT3 - setwalltexture 527 back bot SUPPORT3 - setwalltexture 1146 back bot SUPPORT3 - setwalltexture 1147 back bot SUPPORT3 - setwalltexture 1148 back bot SUPPORT3 - setwalltexture 1149 back bot SUPPORT3 - setwalltexture 1138 back bot SUPPORT3 - setwalltexture 1139 back bot SUPPORT3 - setwalltexture 1140 back bot SUPPORT3 - setwalltexture 1141 back bot SUPPORT3 -} -ABC4EB5A1535ECCD0061AD14F3547908 // Plutonia Experiment, map26 -{ - setsectorspecial 156 0 -} - -FF635FB9A2F076566299910F8C78F707 // nerve.wad, level04 -{ - setsectorspecial 868 0 -} - -B68EB7CFB4CC481796E2919B9C16DFBD // Moc11.wad e1m6 -{ - setvertex 1650 -3072 2671 - setvertex 1642 -2944 2671 -} - -712BB4CFBD0753178CA0C6814BE4C288 // map12 BTSX_E1 - patch some rendering glitches that are problematic to detect -{ - setsectortag 545 32000 - setsectortag 1618 32000 - setlinespecial 2853 Sector_Set3DFloor 32000 4 0 0 0 - setsectortag 439 32001 - setsectortag 458 32001 - setlinespecial 2182 Sector_Set3DFloor 32001 4 0 0 0 - setsectortag 454 32002 - setsectortag 910 32002 - setlinespecial 2410 Sector_Set3DFloor 32002 4 1 0 0 -} - 1ED329858AB154C55878DA1C11A4F100 // unloved.pk3:unlovedmaps.wad map01 FA23E72FA955E66EC68609F72C0BA71E // unloved.pk3:unlovedmaps.wad map02 41BEC1F643CFEEC997AF98276A05EC88 // unloved.pk3:unlovedmaps.wad map03 @@ -776,109 +244,8 @@ DC96228097DD004C40CCB1DB14A91EAA // unloved.pk3:unlovedmaps.wad map05 clipmidtex } - -// Cosmetic fixes for Heretic: Shadow of the Serpent Riders -D94587625BA779644D58151A87897CF1 // e1m2 -{ - // Missing textures - setwalltexture 477 back top MOSSRCK1 - setwalltexture 478 back top MOSSRCK1 - setwalltexture 479 back top MOSSRCK1 - setwalltexture 1057 front top MOSSRCK1 -} -ADD0FAC41AFB0B3C9B9F3C0006F93805 // e1m3 -{ - // Broken door between the hallway that leads to a Torch - // and the passage that has a Bag of Holding at its end - setsectoroffset 86 floor -128 - setsectoroffset 86 ceil -128 -} -916318D8B06DAC2D83424B23E4B66531 // e1m4 -{ - // Wrong sector offsets - setsectoroffset 0 ceil 8 - setsectoroffset 1 ceil 8 - setsectoroffset 2 ceil 8 - setsectoroffset 3 ceil 8 - setsectoroffset 4 ceil 8 - setsectoroffset 6 ceil 8 - setsectoroffset 6 floor 8 - setsectoroffset 17 ceil 8 - // Yellow key door - setsectoroffset 284 floor -8 - setsectoroffset 284 ceil -8 - // Missing textures - setwalltexture 490 back bot GRSTNPB - setwalltexture 722 front bot WOODWL - setwalltexture 911 front bot WOODWL - setwalltexture 1296 front bot WOODWL -} -397A0E17A39542E4E8294E156FAB0502 // e2m2 -{ - // Missing green door statues on easy and hard difficulties - setthingskills 17 31 - setthingskills 18 31 -} -CA3773ED313E8899311F3DD0CA195A68 // e3m6 -{ - // Quartz flask outside of map - setthingskills 373 0 - // Missing wall torch on hard difficulty - setthingskills 448 31 - // Missing textures - setwalltexture 343 front top MOSSRCK1 - setwalltexture 370 front top MOSSRCK1 -} -5E3FCFDE78310BB89F92B1626A47D0AD // heretic.wad E4M7 -{ - // Missing textures - setwalltexture 1274 front top CSTLRCK - setwalltexture 1277 back top CSTLRCK - setwalltexture 1278 front top CSTLRCK -} - -39C594CAC07EE51C80F757DA465FCC94 // strife1.wad map10 -{ - // fix the shooting range by matching sector 138 and 145 properties together - setsectoroffset 145 floor -32 - setsectoroffset 145 ceil 40 - setsectortexture 145 floor F_CONCRP - setsectorlight 138 192 - setwalltexture 3431 back top BRKGRY01 -} - -3FFAF2F624C1B4BB6F581DCF7B99CBA7 // hexen.wad MAP36 -7DC65D5029DD834481CD716B3D71388A // hexdd.wad MAP47 +6DC9F6CCEAE7A91AEC48EBE506F22BC4 // void.wad MAP01 { + setslopeoverflow polyobj } - -3D8ED20BF5CAAE6D6AE0E10999C75084 // hgarden.pk3 map01 -{ - // spawn trees on top of arches - setthingz 399 168 - setthingz 400 168 - setthingz 401 168 - setthingz 402 168 - setthingz 403 168 - setthingz 404 168 -} - -6D4156EE0D12B77AD143A37C4D3DCF98 // dmonfear.wad map22 -{ - shorttex -} - -FCCA97FC851F6473EAA069F74247B317 // pg-raw.wad map31 -{ - setlinesectorref 331 front 74 - setlinesectorref 326 front 74 - setlinesectorref 497 front 74 - setlinesectorref 474 front 74 - setlinesectorref 471 front 74 - setlinesectorref 327 front 74 - setlinesectorref 328 front 74 - setlinesectorref 329 front 74 - setsectortag 74 4 - setlinespecial 357 Transfer_Heights 4 2 0 0 0 -} diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index d7da664e1d..348faac9c7 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -2211,6 +2211,7 @@ RNDMNU_CANVAS = "Software Canvas"; // Video Options VIDMNU_TITLE = "VIDEO MODE"; +VIDMNU_RENDERMODE = "Render Mode"; VIDMNU_FULLSCREEN = "Fullscreen"; VIDMNU_HIDPI = "Retina/HiDPI support"; VIDMNU_BRDLSS = "Borderless Windowed Mode"; @@ -2398,6 +2399,9 @@ OPTVAL_SDL = "SDL"; OPTVAL_COCOA = "Cocoa"; OPTVAL_HWPOLY = "OpenGL-Accelerated"; OPTVAL_SWDOOM = "Doom Software Renderer"; +OPTVAL_SWDOOMTC = "True Color SW Renderer"; +OPTVAL_SWPOLY = "Softpoly Renderer"; +OPTVAL_SWPOLYTC = "True Color Softpoly"; OPTVAL_DEDICATED = "High-Performance"; OPTVAL_INTEGRATED = "Power-Saving"; OPTVAL_VANILLA = "Vanilla"; diff --git a/wadsrc/static/mapinfo/common.txt b/wadsrc/static/mapinfo/common.txt index b79ecd5f4f..d3764371ee 100644 --- a/wadsrc/static/mapinfo/common.txt +++ b/wadsrc/static/mapinfo/common.txt @@ -400,7 +400,7 @@ Intermission Inter_Underwater { Image { - Background = "E2END", 0, "E2PAL" + Background = "E2END", 0 } GotoTitle { diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index a93a752bf4..85c77e35d5 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -352,7 +352,6 @@ OptionMenu "OptionsMenu" protected Submenu "$OPTMNU_SOUND", "SoundOptions" Submenu "$OPTMNU_DISPLAY", "VideoOptions" Submenu "$OPTMNU_VIDEO", "VideoModeMenu" - Submenu "$OPTMNU_CHANGERENDER", "RendererMenu" StaticText " " SafeCommand "$OPTMNU_DEFAULTS", "reset2defaults" SafeCommand "$OPTMNU_RESETTOSAVED", "reset2saved" @@ -710,7 +709,6 @@ OptionMenu "TrueColorOptions" protected { Title "$TCMNU_TITLE" StaticText " " - //Option "$TCMNU_TRUECOLOR", "swtruecolor", "OnOff" Option "$TCMNU_MINFILTER", "r_minfilter", "OnOff" Option "$TCMNU_MAGFILTER", "r_magfilter", "OnOff" Option "$TCMNU_MIPMAP", "r_mipmap", "OnOff" @@ -1844,54 +1842,13 @@ OptionMenu ModReplayerOptions protected * *=======================================*/ -OptionValue "PolyDoom" +OptionValue "RenderMode" { 0, "$OPTVAL_SWDOOM" - 1, "$OPTVAL_HWPOLY" -} - -OptionValue "D3DGL" -{ - 0, "$OPTVAL_GL" - 1, "$OPTVAL_D3D" -} - -OptionValue "GLD3D" -{ - 0, "$OPTVAL_D3D" - 1, "$OPTVAL_GL" -} - -OptionValue "GLSDL" -{ - 0, "$OPTVAL_SDL" - 1, "$OPTVAL_GL" -} - -OptionValue "GLCOCOA" -{ - 0, "$OPTVAL_COCOA" - 1, "$OPTVAL_GL" -} - -OptionMenu RendererMenu protected -{ - Title "$RNDMNU_TITLE" - Option "$RNDMNU_RENDERER", "vid_renderer", "PolyDoom" - Option "$RNDMNU_TRUECOLOR", "swtruecolor", "OnOff" - Option "$RNDMNU_POLY", "r_polyrenderer", "OnOff" - IfOption(Windows) - { - Option "$RNDMNU_CANVAS", "vid_glswfb", "GLD3D" - } - IfOption(unix) - { - Option "$RNDMNU_CANVAS", "vid_glswfb", "GLSDL" - } - IfOption(Mac) - { - Option "$RNDMNU_CANVAS", "vid_glswfb", "GLCOCOA" - } + 1, "$OPTVAL_SWDOOMTC" + 2, "$OPTVAL_SWPOLY" + 3, "$OPTVAL_SWPOLYTC" + 4, "$OPTVAL_HWPOLY" } /*======================================= @@ -1938,6 +1895,7 @@ OptionMenu VideoModeMenu protected { Title "$VIDMNU_TITLE" + Option "$VIDMNU_RENDERMODE", "vid_rendermode", "RenderMode" Option "$VIDMNU_FULLSCREEN", "fullscreen", "YesNo" IfOption(Mac) diff --git a/wadsrc/static/shaders/d3d/build.bat b/wadsrc/static/shaders/d3d/build.bat deleted file mode 100644 index 4f81b24e70..0000000000 --- a/wadsrc/static/shaders/d3d/build.bat +++ /dev/null @@ -1,10 +0,0 @@ -cd sm14 -call build.bat - -cd ..\sm20 -call build.bat - -cd ..\sm30 -call build.bat - -cd .. diff --git a/wadsrc/static/shaders/d3d/shaders.ps b/wadsrc/static/shaders/d3d/shaders.ps deleted file mode 100644 index b2a69f8b5d..0000000000 --- a/wadsrc/static/shaders/d3d/shaders.ps +++ /dev/null @@ -1,136 +0,0 @@ -sampler2D Image : register(s0); -sampler1D Palette : register(s1); -#if PS14 -sampler1D Gamma1 : register(s2); -sampler1D Gamma2 : register(s3); -sampler1D Gamma3 : register(s4); -#endif - -float4 Desaturation : register(c1); // { Desat, 1 - Desat } -float4 PaletteMod : register(c2); -float4 Weights : register(c6); // RGB->Gray weighting { 77/256.0, 143/256.0, 37/256.0, 1 } -float4 Gamma : register(c7); - -float4 TextureLookup(float2 tex_coord) -{ -#if PALTEX - float index = tex2D(Image, tex_coord).x; - index = index * PaletteMod.x + PaletteMod.y; - return tex1D(Palette, index); -#else - return tex2D(Image, tex_coord); -#endif -} - -float4 Invert(float4 rgb) -{ -#if INVERT - rgb.rgb = Weights.www - rgb.xyz; -#endif - return rgb; -} - -float Grayscale(float4 rgb) -{ - return dot(rgb.rgb, Weights.rgb); -} - -float4 SampleTexture(float2 tex_coord) -{ - return Invert(TextureLookup(tex_coord)); -} - -// Normal color calculation for most drawing modes. - -float4 NormalColor(float2 tex_coord : TEXCOORD0, float4 Flash : COLOR0, float4 InvFlash : COLOR1) : COLOR -{ - return Flash + SampleTexture(tex_coord) * InvFlash; -} - -// Copy the red channel to the alpha channel. Pays no attention to palettes. - -float4 RedToAlpha(float2 tex_coord : TEXCOORD0, float4 Flash : COLOR0, float4 InvFlash : COLOR1) : COLOR -{ - float4 color = Invert(tex2D(Image, tex_coord)); - color.a = color.r; - return Flash + color * InvFlash; -} - -// Just return the value of c0. - -float4 VertexColor(float4 color : COLOR0) : COLOR -{ - return color; -} - -// Emulate one of the special colormaps. (Invulnerability, gold, etc.) - -float4 SpecialColormap(float2 tex_coord : TEXCOORD0, float4 start : COLOR0, float4 end : COLOR1) : COLOR -{ - float4 color = SampleTexture(tex_coord); - float4 range = end - start; - // We can't store values greater than 1.0 in a color register, so we multiply - // the final result by 2 and expect the caller to divide the start and end by 2. - color.rgb = 2 * (start + Grayscale(color) * range).rgb; - // Duplicate alpha semantics of NormalColor. - color.a = start.a + color.a * end.a; - return color; -} - -// In-game colormap effect: fade to a particular color and multiply by another, with -// optional desaturation of the original color. Desaturation is stored in c1. -// Fade level is packed int fade.a. Fade.rgb has been premultiplied by alpha. -// Overall alpha is in color.a. -float4 InGameColormap(float2 tex_coord : TEXCOORD0, float4 color : COLOR0, float4 fade : COLOR1) : COLOR -{ - float4 rgb = SampleTexture(tex_coord); - - // Desaturate -#if DESAT - float3 intensity; - intensity.rgb = Grayscale(rgb) * Desaturation.x; - rgb.rgb = intensity.rgb + rgb.rgb * Desaturation.y; -#endif - - // Fade - rgb.rgb = rgb.rgb * fade.aaa + fade.rgb; - - // Shade and Alpha - rgb = rgb * color; - - return rgb; -} - -// Windowed gamma correction. - -float4 GammaCorrection(float2 tex_coord : TEXCOORD0) : COLOR -{ - float4 color = tex2D(Image, tex_coord); -#if !PS14 - color.rgb = pow(color.rgb, Gamma.rgb); -#else - // On PS14 targets, we can only sample once from each sampler - // per stage. Fortunately, we have 16 samplers to play with, - // so we can just set three of them to the gamma texture and - // use one for each component. Unfortunately, all these - // texture lookups are probably not as efficient as the pow() - // solution that later targets make possible. - color.r = tex1D(Gamma1, color.r * Gamma.w).r; - color.g = tex1D(Gamma2, color.g * Gamma.w).g; - color.b = tex1D(Gamma3, color.b * Gamma.w).b; -#endif - return color; -} - -// The burn wipe effect. - -sampler2D NewScreen : register(s0); -sampler2D Burn : register(s1); - -float4 BurnWipe(float2 coord[2] : TEXCOORD0) : COLOR -{ - float4 color = tex2D(NewScreen, coord[0]); - float4 alpha = tex2D(Burn, coord[1]); - color.a = alpha.r * 2; - return color; -} diff --git a/wadsrc/static/shaders/d3d/sm14/BurnWipe.pso b/wadsrc/static/shaders/d3d/sm14/BurnWipe.pso deleted file mode 100644 index 566e518b0d..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm14/BurnWipe.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm14/GammaCorrection.pso b/wadsrc/static/shaders/d3d/sm14/GammaCorrection.pso deleted file mode 100644 index 8abf541bc1..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm14/GammaCorrection.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm14/InGameColormap.pso b/wadsrc/static/shaders/d3d/sm14/InGameColormap.pso deleted file mode 100644 index 18a7471962..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm14/InGameColormap.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm14/InGameColormapDesat.pso b/wadsrc/static/shaders/d3d/sm14/InGameColormapDesat.pso deleted file mode 100644 index 9eedbdadc5..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm14/InGameColormapDesat.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm14/InGameColormapInv.pso b/wadsrc/static/shaders/d3d/sm14/InGameColormapInv.pso deleted file mode 100644 index 4122e261aa..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm14/InGameColormapInv.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm14/InGameColormapInvDesat.pso b/wadsrc/static/shaders/d3d/sm14/InGameColormapInvDesat.pso deleted file mode 100644 index 4b2b2268a4..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm14/InGameColormapInvDesat.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm14/InGameColormapPal.pso b/wadsrc/static/shaders/d3d/sm14/InGameColormapPal.pso deleted file mode 100644 index d8294f6630..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm14/InGameColormapPal.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm14/InGameColormapPalDesat.pso b/wadsrc/static/shaders/d3d/sm14/InGameColormapPalDesat.pso deleted file mode 100644 index daec85c3a7..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm14/InGameColormapPalDesat.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm14/InGameColormapPalInv.pso b/wadsrc/static/shaders/d3d/sm14/InGameColormapPalInv.pso deleted file mode 100644 index e94efa48aa..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm14/InGameColormapPalInv.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm14/InGameColormapPalInvDesat.pso b/wadsrc/static/shaders/d3d/sm14/InGameColormapPalInvDesat.pso deleted file mode 100644 index c75fd148d3..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm14/InGameColormapPalInvDesat.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm14/NormalColor.pso b/wadsrc/static/shaders/d3d/sm14/NormalColor.pso deleted file mode 100644 index 0ab04a2699..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm14/NormalColor.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm14/NormalColorInv.pso b/wadsrc/static/shaders/d3d/sm14/NormalColorInv.pso deleted file mode 100644 index bb0869f1d7..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm14/NormalColorInv.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm14/NormalColorPal.pso b/wadsrc/static/shaders/d3d/sm14/NormalColorPal.pso deleted file mode 100644 index 7dc9146896..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm14/NormalColorPal.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm14/NormalColorPalInv.pso b/wadsrc/static/shaders/d3d/sm14/NormalColorPalInv.pso deleted file mode 100644 index adfd1ab82c..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm14/NormalColorPalInv.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm14/RedToAlpha.pso b/wadsrc/static/shaders/d3d/sm14/RedToAlpha.pso deleted file mode 100644 index 07e43e9f22..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm14/RedToAlpha.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm14/RedToAlphaInv.pso b/wadsrc/static/shaders/d3d/sm14/RedToAlphaInv.pso deleted file mode 100644 index 5f87a11cde..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm14/RedToAlphaInv.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm14/SpecialColormap.pso b/wadsrc/static/shaders/d3d/sm14/SpecialColormap.pso deleted file mode 100644 index 8dc3111b2a..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm14/SpecialColormap.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm14/SpecialColormapPal.pso b/wadsrc/static/shaders/d3d/sm14/SpecialColormapPal.pso deleted file mode 100644 index 4b5cf3f9f7..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm14/SpecialColormapPal.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm14/VertexColor.pso b/wadsrc/static/shaders/d3d/sm14/VertexColor.pso deleted file mode 100644 index 7cc88be7e5..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm14/VertexColor.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm14/build.bat b/wadsrc/static/shaders/d3d/sm14/build.bat deleted file mode 100644 index f8b515a154..0000000000 --- a/wadsrc/static/shaders/d3d/sm14/build.bat +++ /dev/null @@ -1,25 +0,0 @@ -fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /ENormalColor -DPALTEX=0 -DINVERT=0 /FoNormalColor.pso -fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /ENormalColor -DPALTEX=0 -DINVERT=1 /FoNormalColorInv.pso -fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /ENormalColor -DPALTEX=1 -DINVERT=0 /FoNormalColorPal.pso -fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /ENormalColor -DPALTEX=1 -DINVERT=1 /FoNormalColorPalInv.pso - -fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /ERedToAlpha -DINVERT=0 /FoRedToAlpha.pso -fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /ERedToAlpha -DINVERT=1 /FoRedToAlphaInv.pso - -fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /EVertexColor /FoVertexColor.pso - -fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /ESpecialColormap -DPALTEX=0 -DINVERT=0 /FoSpecialColormap.pso -fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /ESpecialColormap -DPALTEX=1 -DINVERT=0 /FoSpecialColormapPal.pso - -fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /EInGameColormap -DPALTEX=0 -DINVERT=0 -DDESAT=0 /FoInGameColormap.pso -fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /EInGameColormap -DPALTEX=0 -DINVERT=0 -DDESAT=1 /FoInGameColormapDesat.pso -fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /EInGameColormap -DPALTEX=0 -DINVERT=1 -DDESAT=0 /FoInGameColormapInv.pso -fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /EInGameColormap -DPALTEX=0 -DINVERT=1 -DDESAT=1 /FoInGameColormapInvDesat.pso -fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /EInGameColormap -DPALTEX=1 -DINVERT=0 -DDESAT=0 /FoInGameColormapPal.pso -fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /EInGameColormap -DPALTEX=1 -DINVERT=0 -DDESAT=1 /FoInGameColormapPalDesat.pso -fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /EInGameColormap -DPALTEX=1 -DINVERT=1 -DDESAT=0 /FoInGameColormapPalInv.pso -fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /EInGameColormap -DPALTEX=1 -DINVERT=1 -DDESAT=1 /FoInGameColormapPalInvDesat.pso - -fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /EBurnWipe /FoBurnWipe.pso - -fxc ..\shaders.ps /Tps_1_4 /LD -DPS14=1 /EGammaCorrection /FoGammaCorrection.pso diff --git a/wadsrc/static/shaders/d3d/sm20/BurnWipe.pso b/wadsrc/static/shaders/d3d/sm20/BurnWipe.pso deleted file mode 100644 index b1daa59be6..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/BurnWipe.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/GammaCorrection.pso b/wadsrc/static/shaders/d3d/sm20/GammaCorrection.pso deleted file mode 100644 index 92251eb02f..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/GammaCorrection.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/InGameColormap.pso b/wadsrc/static/shaders/d3d/sm20/InGameColormap.pso deleted file mode 100644 index 7ef9f5322c..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/InGameColormap.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/InGameColormapDesat.pso b/wadsrc/static/shaders/d3d/sm20/InGameColormapDesat.pso deleted file mode 100644 index 2a87e6e96b..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/InGameColormapDesat.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/InGameColormapInv.pso b/wadsrc/static/shaders/d3d/sm20/InGameColormapInv.pso deleted file mode 100644 index 98ff0cc387..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/InGameColormapInv.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/InGameColormapInvDesat.pso b/wadsrc/static/shaders/d3d/sm20/InGameColormapInvDesat.pso deleted file mode 100644 index 3605fb6ba5..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/InGameColormapInvDesat.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/InGameColormapPal.pso b/wadsrc/static/shaders/d3d/sm20/InGameColormapPal.pso deleted file mode 100644 index bccbbc0046..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/InGameColormapPal.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/InGameColormapPalDesat.pso b/wadsrc/static/shaders/d3d/sm20/InGameColormapPalDesat.pso deleted file mode 100644 index 3f08538b12..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/InGameColormapPalDesat.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/InGameColormapPalInv.pso b/wadsrc/static/shaders/d3d/sm20/InGameColormapPalInv.pso deleted file mode 100644 index 14c602bc42..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/InGameColormapPalInv.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/InGameColormapPalInvDesat.pso b/wadsrc/static/shaders/d3d/sm20/InGameColormapPalInvDesat.pso deleted file mode 100644 index ac3e5dc67b..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/InGameColormapPalInvDesat.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/NormalColor.pso b/wadsrc/static/shaders/d3d/sm20/NormalColor.pso deleted file mode 100644 index 530002972c..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/NormalColor.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/NormalColorInv.pso b/wadsrc/static/shaders/d3d/sm20/NormalColorInv.pso deleted file mode 100644 index da470159a0..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/NormalColorInv.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/NormalColorPal.pso b/wadsrc/static/shaders/d3d/sm20/NormalColorPal.pso deleted file mode 100644 index 57b34eb352..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/NormalColorPal.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/NormalColorPalInv.pso b/wadsrc/static/shaders/d3d/sm20/NormalColorPalInv.pso deleted file mode 100644 index 2c490574c0..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/NormalColorPalInv.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/RedToAlpha.pso b/wadsrc/static/shaders/d3d/sm20/RedToAlpha.pso deleted file mode 100644 index 10fa58af8b..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/RedToAlpha.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/RedToAlphaInv.pso b/wadsrc/static/shaders/d3d/sm20/RedToAlphaInv.pso deleted file mode 100644 index 792ffbf35d..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/RedToAlphaInv.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/SpecialColormap.pso b/wadsrc/static/shaders/d3d/sm20/SpecialColormap.pso deleted file mode 100644 index 24ebb375ae..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/SpecialColormap.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/SpecialColormapPal.pso b/wadsrc/static/shaders/d3d/sm20/SpecialColormapPal.pso deleted file mode 100644 index b706962aa1..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/SpecialColormapPal.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/VertexColor.pso b/wadsrc/static/shaders/d3d/sm20/VertexColor.pso deleted file mode 100644 index bd62a1d299..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm20/VertexColor.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm20/build.bat b/wadsrc/static/shaders/d3d/sm20/build.bat deleted file mode 100644 index 4783370739..0000000000 --- a/wadsrc/static/shaders/d3d/sm20/build.bat +++ /dev/null @@ -1,25 +0,0 @@ -fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=0 /FoNormalColor.pso -fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=1 /FoNormalColorInv.pso -fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=0 /FoNormalColorPal.pso -fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=1 /FoNormalColorPalInv.pso - -fxc ..\shaders.ps /Tps_2_0 /O3 /ERedToAlpha -DINVERT=0 /FoRedToAlpha.pso -fxc ..\shaders.ps /Tps_2_0 /O3 /ERedToAlpha -DINVERT=1 /FoRedToAlphaInv.pso - -fxc ..\shaders.ps /Tps_2_0 /O3 /EVertexColor /FoVertexColor.pso - -fxc ..\shaders.ps /Tps_2_0 /O3 /ESpecialColormap -DPALTEX=0 -DINVERT=0 /FoSpecialColormap.pso -fxc ..\shaders.ps /Tps_2_0 /O3 /ESpecialColormap -DPALTEX=1 -DINVERT=0 /FoSpecialColormapPal.pso - -fxc ..\shaders.ps /Tps_2_0 /O3 /EInGameColormap -DPALTEX=0 -DINVERT=0 -DDESAT=0 /FoInGameColormap.pso -fxc ..\shaders.ps /Tps_2_0 /O3 /EInGameColormap -DPALTEX=0 -DINVERT=0 -DDESAT=1 /FoInGameColormapDesat.pso -fxc ..\shaders.ps /Tps_2_0 /O3 /EInGameColormap -DPALTEX=0 -DINVERT=1 -DDESAT=0 /FoInGameColormapInv.pso -fxc ..\shaders.ps /Tps_2_0 /O3 /EInGameColormap -DPALTEX=0 -DINVERT=1 -DDESAT=1 /FoInGameColormapInvDesat.pso -fxc ..\shaders.ps /Tps_2_0 /O3 /EInGameColormap -DPALTEX=1 -DINVERT=0 -DDESAT=0 /FoInGameColormapPal.pso -fxc ..\shaders.ps /Tps_2_0 /O3 /EInGameColormap -DPALTEX=1 -DINVERT=0 -DDESAT=1 /FoInGameColormapPalDesat.pso -fxc ..\shaders.ps /Tps_2_0 /O3 /EInGameColormap -DPALTEX=1 -DINVERT=1 -DDESAT=0 /FoInGameColormapPalInv.pso -fxc ..\shaders.ps /Tps_2_0 /O3 /EInGameColormap -DPALTEX=1 -DINVERT=1 -DDESAT=1 /FoInGameColormapPalInvDesat.pso - -fxc ..\shaders.ps /Tps_2_0 /O3 /EBurnWipe /FoBurnWipe.pso - -fxc ..\shaders.ps /Tps_2_0 /O3 /EGammaCorrection /FoGammaCorrection.pso diff --git a/wadsrc/static/shaders/d3d/sm30/BurnWipe.pso b/wadsrc/static/shaders/d3d/sm30/BurnWipe.pso deleted file mode 100644 index 50e942ab30..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/BurnWipe.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/GammaCorrection.pso b/wadsrc/static/shaders/d3d/sm30/GammaCorrection.pso deleted file mode 100644 index 662f59f373..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/GammaCorrection.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/InGameColormap.pso b/wadsrc/static/shaders/d3d/sm30/InGameColormap.pso deleted file mode 100644 index 82f702f841..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/InGameColormap.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/InGameColormapDesat.pso b/wadsrc/static/shaders/d3d/sm30/InGameColormapDesat.pso deleted file mode 100644 index 44d67d57bc..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/InGameColormapDesat.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/InGameColormapInv.pso b/wadsrc/static/shaders/d3d/sm30/InGameColormapInv.pso deleted file mode 100644 index 78d4abc9d7..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/InGameColormapInv.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/InGameColormapInvDesat.pso b/wadsrc/static/shaders/d3d/sm30/InGameColormapInvDesat.pso deleted file mode 100644 index 2da2e7b20e..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/InGameColormapInvDesat.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/InGameColormapPal.pso b/wadsrc/static/shaders/d3d/sm30/InGameColormapPal.pso deleted file mode 100644 index 8de88be2a5..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/InGameColormapPal.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/InGameColormapPalDesat.pso b/wadsrc/static/shaders/d3d/sm30/InGameColormapPalDesat.pso deleted file mode 100644 index ad57fb5768..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/InGameColormapPalDesat.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/InGameColormapPalInv.pso b/wadsrc/static/shaders/d3d/sm30/InGameColormapPalInv.pso deleted file mode 100644 index b44f9161cb..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/InGameColormapPalInv.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/InGameColormapPalInvDesat.pso b/wadsrc/static/shaders/d3d/sm30/InGameColormapPalInvDesat.pso deleted file mode 100644 index 1513123170..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/InGameColormapPalInvDesat.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/NormalColor.pso b/wadsrc/static/shaders/d3d/sm30/NormalColor.pso deleted file mode 100644 index ef03e98856..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/NormalColor.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/NormalColorInv.pso b/wadsrc/static/shaders/d3d/sm30/NormalColorInv.pso deleted file mode 100644 index 7215d533d9..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/NormalColorInv.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/NormalColorPal.pso b/wadsrc/static/shaders/d3d/sm30/NormalColorPal.pso deleted file mode 100644 index 5b9e9bc8a9..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/NormalColorPal.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/NormalColorPalInv.pso b/wadsrc/static/shaders/d3d/sm30/NormalColorPalInv.pso deleted file mode 100644 index 6db8949643..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/NormalColorPalInv.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/RedToAlpha.pso b/wadsrc/static/shaders/d3d/sm30/RedToAlpha.pso deleted file mode 100644 index e8bff75b3f..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/RedToAlpha.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/RedToAlphaInv.pso b/wadsrc/static/shaders/d3d/sm30/RedToAlphaInv.pso deleted file mode 100644 index 85f3d1417d..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/RedToAlphaInv.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/SpecialColormap.pso b/wadsrc/static/shaders/d3d/sm30/SpecialColormap.pso deleted file mode 100644 index 5da15158e9..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/SpecialColormap.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/SpecialColormapPal.pso b/wadsrc/static/shaders/d3d/sm30/SpecialColormapPal.pso deleted file mode 100644 index baa84e7971..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/SpecialColormapPal.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/VertexColor.pso b/wadsrc/static/shaders/d3d/sm30/VertexColor.pso deleted file mode 100644 index 46d2bc3d45..0000000000 Binary files a/wadsrc/static/shaders/d3d/sm30/VertexColor.pso and /dev/null differ diff --git a/wadsrc/static/shaders/d3d/sm30/build.bat b/wadsrc/static/shaders/d3d/sm30/build.bat deleted file mode 100644 index 8129659ab3..0000000000 --- a/wadsrc/static/shaders/d3d/sm30/build.bat +++ /dev/null @@ -1,25 +0,0 @@ -fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=0 /FoNormalColor.pso -fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=1 /FoNormalColorInv.pso -fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=0 /FoNormalColorPal.pso -fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=1 /FoNormalColorPalInv.pso - -fxc ..\shaders.ps /Tps_3_0 /O3 /ERedToAlpha -DINVERT=0 /FoRedToAlpha.pso -fxc ..\shaders.ps /Tps_3_0 /O3 /ERedToAlpha -DINVERT=1 /FoRedToAlphaInv.pso - -fxc ..\shaders.ps /Tps_3_0 /O3 /EVertexColor /FoVertexColor.pso - -fxc ..\shaders.ps /Tps_3_0 /O3 /ESpecialColormap -DPALTEX=0 -DINVERT=0 /FoSpecialColormap.pso -fxc ..\shaders.ps /Tps_3_0 /O3 /ESpecialColormap -DPALTEX=1 -DINVERT=0 /FoSpecialColormapPal.pso - -fxc ..\shaders.ps /Tps_3_0 /O3 /EInGameColormap -DPALTEX=0 -DINVERT=0 -DDESAT=0 /FoInGameColormap.pso -fxc ..\shaders.ps /Tps_3_0 /O3 /EInGameColormap -DPALTEX=0 -DINVERT=0 -DDESAT=1 /FoInGameColormapDesat.pso -fxc ..\shaders.ps /Tps_3_0 /O3 /EInGameColormap -DPALTEX=0 -DINVERT=1 -DDESAT=0 /FoInGameColormapInv.pso -fxc ..\shaders.ps /Tps_3_0 /O3 /EInGameColormap -DPALTEX=0 -DINVERT=1 -DDESAT=1 /FoInGameColormapInvDesat.pso -fxc ..\shaders.ps /Tps_3_0 /O3 /EInGameColormap -DPALTEX=1 -DINVERT=0 -DDESAT=0 /FoInGameColormapPal.pso -fxc ..\shaders.ps /Tps_3_0 /O3 /EInGameColormap -DPALTEX=1 -DINVERT=0 -DDESAT=1 /FoInGameColormapPalDesat.pso -fxc ..\shaders.ps /Tps_3_0 /O3 /EInGameColormap -DPALTEX=1 -DINVERT=1 -DDESAT=0 /FoInGameColormapPalInv.pso -fxc ..\shaders.ps /Tps_3_0 /O3 /EInGameColormap -DPALTEX=1 -DINVERT=1 -DDESAT=1 /FoInGameColormapPalInvDesat.pso - -fxc ..\shaders.ps /Tps_3_0 /O3 /EBurnWipe /FoBurnWipe.pso - -fxc ..\shaders.ps /Tps_3_0 /O3 /EGammaCorrection /FoGammaCorrection.pso diff --git a/wadsrc/static/shaders/glsl/func_paletted.fp b/wadsrc/static/shaders/glsl/func_paletted.fp new file mode 100644 index 0000000000..fbcd992340 --- /dev/null +++ b/wadsrc/static/shaders/glsl/func_paletted.fp @@ -0,0 +1,10 @@ + +vec4 ProcessTexel() +{ + float index = getTexel(vTexCoord.st).r; + index = ((index * 255.0) + 0.5) / 256.0; + vec4 tex = texture(texture2, vec2(index, 0.5)); + tex.a = 1.0; + return tex; +} + diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index 2ff3ef483e..a90141d0df 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -17,6 +17,17 @@ vec4 ProcessTexel(); vec4 ProcessLight(vec4 color); vec3 ProcessMaterial(vec3 material, vec3 color); +//=========================================================================== +// +// Color to grayscale +// +//=========================================================================== + +float grayscale(vec4 color) +{ + return dot(color.rgb, vec3(0.4, 0.56, 0.14)); +} + //=========================================================================== // // Desaturate a color @@ -27,7 +38,7 @@ vec4 desaturate(vec4 texel) { if (uDesaturationFactor > 0.0) { - float gray = (texel.r * 0.3 + texel.g * 0.56 + texel.b * 0.14); + float gray = grayscale(texel); return mix (texel, vec4(gray,gray,gray,texel.a), uDesaturationFactor); } else @@ -64,7 +75,7 @@ vec4 getTexel(vec2 st) break; case 4: // TM_REDTOALPHA - float gray = (texel.r * 0.3 + texel.g * 0.56 + texel.b * 0.14); + float gray = grayscale(texel); texel = vec4(1.0, 1.0, 1.0, gray*texel.a); break; @@ -74,6 +85,10 @@ vec4 getTexel(vec2 st) texel.a = 0.0; } break; + + case 6: // TM_OPAQUEINVERSE + texel = vec4(1.0-texel.r, 1.0-texel.b, 1.0-texel.g, 1.0); + break; } if (uObjectColor2.a == 0.0) texel *= uObjectColor; else texel *= mix(uObjectColor, uObjectColor2, glowdist.z); @@ -415,7 +430,7 @@ void main() switch (uFixedColormap) { - case 0: + case 0: // in-game rendering. { float fogdist = 0.0; float fogfactor = 0.0; @@ -451,21 +466,21 @@ void main() break; } - case 1: + case 1: // special colormap { - float gray = (frag.r * 0.3 + frag.g * 0.56 + frag.b * 0.14); + float gray = grayscale(frag); vec4 cm = uFixedColormapStart + gray * uFixedColormapRange; frag = vec4(clamp(cm.rgb, 0.0, 1.0), frag.a*vColor.a); break; } - case 2: + case 2: // fullscreen tint. { frag = vColor * frag * uFixedColormapStart; break; } - case 3: + case 3: // fog layer { float fogdist; float fogfactor; @@ -486,6 +501,14 @@ void main() frag = vec4(uFogColor.rgb, (1.0 - fogfactor) * frag.a * 0.75 * vColor.a); break; } + + case 4: // simple 2D (reuses a uniform for the special colormap for the color overlay.) + { + frag = frag * vColor; + frag.rgb = frag.rgb + uFixedColormapStart.rgb; + break; + } + } FragColor = frag; #ifdef GBUFFER_PASS diff --git a/wadsrc/static/shaders/glsl/swshader.fp b/wadsrc/static/shaders/glsl/swshader.fp index e33389f29b..79432b2083 100644 --- a/wadsrc/static/shaders/glsl/swshader.fp +++ b/wadsrc/static/shaders/glsl/swshader.fp @@ -1,148 +1,31 @@ - -precision mediump float; - -in vec4 PixelColor0; -in vec4 PixelColor1; -in vec4 PixelTexCoord0; - +in vec4 vTexCoord; out vec4 FragColor; -uniform sampler2D Image; -uniform sampler2D Palette; -uniform sampler2D NewScreen; -uniform sampler2D Burn; - -uniform vec4 Desaturation; // { Desat, 1 - Desat } -uniform vec4 PaletteMod; -uniform vec4 Weights; // RGB->Gray weighting { 77/256.0, 143/256.0, 37/256.0, 1 } -uniform vec4 Gamma; - vec4 TextureLookup(vec2 tex_coord) { -#if defined(PALTEX) - float index = texture(Image, tex_coord).x; - index = index * PaletteMod.x + PaletteMod.y; - return texture(Palette, vec2(index, 0.5)); -#else - return texture(Image, tex_coord); -#endif -} - -vec4 Invert(vec4 rgb) -{ -#if defined(INVERT) - rgb.rgb = Weights.www - rgb.xyz; -#endif - return rgb; -} - -float Grayscale(vec4 rgb) -{ - return dot(rgb.rgb, Weights.rgb); -} - -vec4 SampleTexture(vec2 tex_coord) -{ - return Invert(TextureLookup(tex_coord)); -} - -// Normal color calculation for most drawing modes. - -vec4 NormalColor(vec2 tex_coord, vec4 Flash, vec4 InvFlash) -{ - return Flash + SampleTexture(tex_coord) * InvFlash; -} - -// Copy the red channel to the alpha channel. Pays no attention to palettes. - -vec4 RedToAlpha(vec2 tex_coord, vec4 Flash, vec4 InvFlash) -{ - vec4 color = Invert(texture(Image, tex_coord)); - color.a = color.r; - return Flash + color * InvFlash; -} - -// Just return the value of c0. - -vec4 VertexColor(vec4 color) -{ - return color; -} - -// Emulate one of the special colormaps. (Invulnerability, gold, etc.) - -vec4 SpecialColormap(vec2 tex_coord, vec4 start, vec4 end) -{ - vec4 color = SampleTexture(tex_coord); - vec4 range = end - start; - // We can't store values greater than 1.0 in a color register, so we multiply - // the final result by 2 and expect the caller to divide the start and end by 2. - color.rgb = 2.0 * (start + Grayscale(color) * range).rgb; - // Duplicate alpha semantics of NormalColor. - color.a = start.a + color.a * end.a; - return color; -} - -// In-game colormap effect: fade to a particular color and multiply by another, with -// optional desaturation of the original color. Desaturation is stored in c1. -// Fade level is packed int fade.a. Fade.rgb has been premultiplied by alpha. -// Overall alpha is in color.a. -vec4 InGameColormap(vec2 tex_coord, vec4 color, vec4 fade) -{ - vec4 rgb = SampleTexture(tex_coord); - - // Desaturate -#if defined(DESAT) - vec3 intensity; - intensity.rgb = vec3(Grayscale(rgb) * Desaturation.x); - rgb.rgb = intensity.rgb + rgb.rgb * Desaturation.y; -#endif - - // Fade - rgb.rgb = rgb.rgb * fade.aaa + fade.rgb; - - // Shade and Alpha - rgb = rgb * color; - - return rgb; -} - -// Windowed gamma correction. - -vec4 GammaCorrection(vec2 tex_coord) -{ - vec4 color = texture(Image, tex_coord); - color.rgb = pow(color.rgb, Gamma.rgb); - return color; -} - -// The burn wipe effect. - -vec4 BurnWipe(vec4 coord) -{ - vec4 color = texture(NewScreen, coord.xy); - vec4 alpha = texture(Burn, coord.zw); - color.a = alpha.r * 2.0; - return color; + if (uTextureMode == 1) + { + float index = texture(tex, tex_coord).x; + index = index * 256.0 + 0.5; // We only have 256 color palettes here. + return texture(texture2, vec2(index, 0.5)); + } + else + { + return texture(tex, tex_coord); + } } void main() { -#if defined(ENORMALCOLOR) - FragColor = NormalColor(PixelTexCoord0.xy, PixelColor0, PixelColor1); -#elif defined(EREDTOALPHA) - FragColor = RedToAlpha(PixelTexCoord0.xy, PixelColor0, PixelColor1); -#elif defined(EVERTEXCOLOR) - FragColor = VertexColor(PixelColor0); -#elif defined(ESPECIALCOLORMAP) - FragColor = SpecialColormap(PixelTexCoord0.xy, PixelColor0, PixelColor1); -#elif defined(EINGAMECOLORMAP) - FragColor = InGameColormap(PixelTexCoord0.xy, PixelColor0, PixelColor1); -#elif defined(EBURNWIPE) - FragColor = BurnWipe(PixelTexCoord0); -#elif defined(EGAMMACORRECTION) - FragColor = GammaCorrection(PixelTexCoord0.xy); -#else - #error Entry point define is missing -#endif + if (uFixedColormap == 0) + { + FragColor = TextureLookup(vTexCoord.xy); + } + else + { + vec4 frag = TextureLookup(vTexCoord.xy); + float gray = dot(frag.rgb, vec3(0.4, 0.56, 0.14)); + vec4 cm = uFixedColormapStart + gray * uFixedColormapRange; + FragColor = vec4(clamp(cm.rgb, 0.0, 1.0), 1.0); + } } diff --git a/wadsrc/static/shaders/glsl/swshader.vp b/wadsrc/static/shaders/glsl/swshader.vp deleted file mode 100644 index a317025aaf..0000000000 --- a/wadsrc/static/shaders/glsl/swshader.vp +++ /dev/null @@ -1,22 +0,0 @@ - -in vec4 AttrPosition; -in vec4 AttrColor0; -in vec4 AttrColor1; -in vec4 AttrTexCoord0; - -out vec4 PixelColor0; -out vec4 PixelColor1; -out vec4 PixelTexCoord0; - -uniform vec4 ScreenSize; - -void main() -{ - gl_Position = vec4(AttrPosition.xy / ScreenSize.xy * 2.0 - 1.0, 1.0, 1.0); -#if defined(EGAMMACORRECTION) - gl_Position.y = -gl_Position.y; -#endif - PixelColor0 = AttrColor0.bgra; - PixelColor1 = AttrColor1.bgra; - PixelTexCoord0 = AttrTexCoord0; -} diff --git a/wadsrc/static/shaders/swgl/swshadergl2.fp b/wadsrc/static/shaders/swgl/swshadergl2.fp new file mode 100644 index 0000000000..a65538fb5d --- /dev/null +++ b/wadsrc/static/shaders/swgl/swshadergl2.fp @@ -0,0 +1,32 @@ +uniform sampler2D tex; +uniform sampler2D palette; +uniform vec4 uColor1; +uniform vec4 uColor2; + +vec4 TextureLookup(vec2 tex_coord) +{ +#ifdef PAL_TEX + float index = texture2D(tex, tex_coord).x; + index = ((index * 255.0) + 0.5) / 256.0; + return texture2D(palette, vec2(index, 0.5)); +#else + return texture2D(tex, tex_coord); +#endif +} + +float grayscale(vec4 rgb) +{ + return dot(rgb.rgb, vec3(0.4, 0.56, 0.14)); +} + +void main() +{ +#ifndef SPECIALCM + gl_FragColor = TextureLookup(gl_TexCoord[0].xy); +#else + vec4 frag = TextureLookup(gl_TexCoord[0].xy); + float gray = grayscale(frag); + vec4 cm = uColor1 + gray * uColor2; + gl_FragColor = vec4(clamp(cm.rgb, 0.0, 1.0), 1.0); +#endif +} diff --git a/wadsrc/static/shaders/swgl/swshadergl2.vp b/wadsrc/static/shaders/swgl/swshadergl2.vp new file mode 100644 index 0000000000..97d05c35f8 --- /dev/null +++ b/wadsrc/static/shaders/swgl/swshadergl2.vp @@ -0,0 +1,6 @@ + +void main() +{ + gl_TexCoord[0] = gl_MultiTexCoord0; + gl_Position = ftransform(); +} diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index 755e427dda..31531ed281 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -7,6 +7,7 @@ version "3.3" #include "zscript/actor.txt" #include "zscript/actor_checks.txt" #include "zscript/events.txt" +#include "zscript/level_compatibility.txt" #include "zscript/menu/menuitembase.txt" #include "zscript/menu/menu.txt" diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 52020816de..6faba67059 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -138,7 +138,7 @@ enum DrawTextureTags DTA_ColorOverlay, // DWORD: ARGB to overlay on top of image; limited to black for software DTA_Internal1, DTA_Internal2, - DTA_Internal3, + DTA_Desaturate, // explicit desaturation factor (does not do anything in Legacy OpenGL) DTA_Fullscreen, // Draw image fullscreen (same as DTA_VirtualWidth/Height with graphics size.) // floating point duplicates of some of the above: @@ -155,6 +155,14 @@ enum DrawTextureTags DTA_TextLen, // stop after this many characters, even if \0 not hit DTA_CellX, // horizontal size of character cell DTA_CellY, // vertical size of character cell + + DTA_Color, + DTA_FlipY, // bool: flip image vertically + DTA_SrcX, // specify a source rectangle (this supersedes the poorly implemented DTA_WindowLeft/Right + DTA_SrcY, + DTA_SrcWidth, + DTA_SrcHeight + }; struct Screen native diff --git a/wadsrc/static/zscript/constants.txt b/wadsrc/static/zscript/constants.txt index ef20e23107..fea498deb2 100644 --- a/wadsrc/static/zscript/constants.txt +++ b/wadsrc/static/zscript/constants.txt @@ -1223,3 +1223,21 @@ enum ActorRenderFeatureFlag RFF_VOXELS = 1<<12, // renderer is capable of voxels }; +// Special activation types +enum SPAC +{ + SPAC_Cross = 1<<0, // when player crosses line + SPAC_Use = 1<<1, // when player uses line + SPAC_MCross = 1<<2, // when monster crosses line + SPAC_Impact = 1<<3, // when projectile hits line + SPAC_Push = 1<<4, // when player pushes line + SPAC_PCross = 1<<5, // when projectile crosses line + SPAC_UseThrough = 1<<6, // when player uses line (doesn't block) + // SPAC_PTOUCH is mapped to SPAC_PCross|SPAC_Impact + SPAC_AnyCross = 1<<7, // when anything without the MF2_TELEPORT flag crosses the line + SPAC_MUse = 1<<8, // monsters can use + SPAC_MPush = 1<<9, // monsters can push + SPAC_UseBack = 1<<10, // Can be used from the backside + + SPAC_PlayerActivate = (SPAC_Cross|SPAC_Use|SPAC_Impact|SPAC_Push|SPAC_AnyCross|SPAC_UseThrough|SPAC_UseBack), +}; diff --git a/wadsrc/static/zscript/level_compatibility.txt b/wadsrc/static/zscript/level_compatibility.txt new file mode 100644 index 0000000000..c2d1834e2e --- /dev/null +++ b/wadsrc/static/zscript/level_compatibility.txt @@ -0,0 +1,740 @@ + +class LevelCompatibility play +{ + private static void Apply(Name checksum) + { + switch (checksum) + { + case 'AB24AE6E2CB13CBDD04600A4D37F9189': // doom2.wad map02 + case '1EC0AF1E3985650F0C9000319C599D0C': // doom2bfg.wad map02 + { + // Missing textures + TextureID stone4 = TexMan.CheckForTexture("STONE4", TexMan.Type_Wall); + SetWallTextureID(327, Line.front, Side.bottom, stone4); + SetWallTextureID(328, Line.front, Side.bottom, stone4); + SetWallTextureID(338, Line.front, Side.bottom, stone4); + SetWallTextureID(339, Line.front, Side.bottom, stone4); + break; + } + + case '66C46385EB1A23D60839D1532522076B': // doom2.wad map08 + { + // Missing texture + SetWallTexture(101, Line.back, Side.top, "BRICK7"); + break; + } + + case 'E2B5D1400279335811C1C1C0B437D9C8': // Deathknights of the Dark Citadel, map54 + { + // This map has two gear boxes which are flagged for player cross + // activation instead of the proper player uses activation. + SetLineActivation(943, SPAC_Use); + SetLineActivation(963, SPAC_Use); + break; + } + + case '3F249EDD62A3A08F53A6C53CB4C7ABE5': // Artica 3 map01 + { + ClearLineSpecial(66); + break; + } + + case 'F481922F4881F74760F3C0437FD5EDD0': // Community Chest 3 map03 + { + // I have no idea how this conveyor belt setup manages to work under Boom. + // Set the sector the voodoo doll ends up standing on when sectors tagged + // 1 are raised so that the voodoo doll will be carried. + SetLineSpecial(3559, Sector_CopyScroller, 17, 6); + break; + } + + case '5B862477519B21B30059A466F2FF6460': // Khorus, map08 + { + // This map uses a voodoo conveyor with slanted walls to shunt the + // voodoo doll into side areas. For some reason, this voodoo doll + // is unable to slide on them, because the slide calculation gets + // them slightly inside the walls and thinks they are stuck. I could + // not reproduce this with the real player, which is what has me + // stumped. So, help them out be attaching some ThrustThing specials + // to the walls. + SetLineSpecial(443, ThrustThing, 96, 4); + SetLineFlags(443, Line.ML_REPEAT_SPECIAL); + SetLineActivation(443, SPAC_Push); + SetLineSpecial(455, ThrustThing, 96, 4); + SetLineFlags(455, Line.ML_REPEAT_SPECIAL); + SetLineActivation(455, SPAC_Push); + break; + } + + case '3D1E36E50F5A8D289E15433941605224': // Master Levels, catwalk.wad + { + // make it impossible to open door to 1-way bridge before getting red key + ClearSectorTags(35); + AddSectorTag(35, 15); + for(int i=605; i<609;i++) + { + SetLineActivation(i, SPAC_PCross); + SetLineSpecial(i, Door_Open, 15, 64); + } + break; + } + + case '3B9CAA02952F405269353FAAD8F8EC33': // Master Levels, nessus.wad + { + // move secret sector from too-thin doorframe to BFG closet + SetSectorSpecial(211, 0); + SetSectorSpecial(212, 1024); + // lower floor a bit so secret sector can be entered fully + OffsetSectorPlane(212, Sector.floor, -16); + // make secret door stay open so you can't get locked in closet + SetLineSpecial(1008, Door_Open, 0, 64); + break; + } + + case '7ED9800213C00D6E7FB98652AB48B3DE': // Ultimate Simplicity, map04 + { + // Add missing map spots on easy and medium skills + // Demons will teleport into starting room making 100% kills possible + SetThingSkills(31, 31); + SetThingSkills(32, 31); + break; + } + + case '1891E029994B023910CFE0B3209C3CDB': // Ultimate Simplicity, map07 + { + // It is possible to get stuck on skill 0 or 1 when no shots have been fired + // after sector 17 became accessible and before entering famous mancubus room. + // Monsters from the mentioned sector won't be alerted and so + // they won't teleport into the battle. ACS will wait forever for their deaths. + SetLineSpecial(397, NoiseAlert); + SetLineSpecial(411, NoiseAlert); + break; + } + + case 'F0E6F30F57B0425F17E43600AA813E80': // Ultimate Simplicity, map11 + { + // If door (sector #309) is closed it cannot be open again + // from one side potentially blocking level progression + ClearLineSpecial(2445); + break; + } + + case '952CC8D03572E17BA550B01B366EFBB9': // Cheogsh map01 + { + // make the blue key spawn above the 3D floor + SetThingZ(918, 296); + break; + } + + case 'D62DCA9EC226DE49108D5DD9271F7631': // Cheogsh 2 map04 + { + // Stuff in megasphere cage is positioned too low + for(int i=1640; i<=1649; i++) + { + SetThingZ(i, 528); + } + break; + } + + case 'DFC18B92BF3E8142B8684ECD8BD2EF06': // TNT: Evilution map15 + { + // raise up sector with its counterpart so 100% kills becomes possible + AddSectorTag(330, 11); + break; + } + + case '2C4A3356C5EB3526D2C72A4AA4B18A36': // TNT: Evilution map29 + { + // remove mancubus who always gets stuck in teleport tunnel, preventing + // 100% kills on HMP + SetThingFlags(405, 0); + break; + } + + case 'A53AE580A4AF2B5D0B0893F86914781E': // TNT: Evilution map31 + { + // The famous missing yellow key... + SetThingFlags(470, 2016); + break; + } + + case 'D99AD22FF21A41B4EECDB3A7C803D75E': // TNT: Evilution map32 + { + // door can close permanently; make switch that opens it repeatable + SetLineFlags(872, Line.ML_REPEAT_SPECIAL); + // switch should only open way to red key, don't lower bars yet, + // instead make line just before red key open bars + ClearSectorTags(197); + AddSectorTag(197, 8); + SetLineSpecial(1279, Floor_LowerToLowest, 8, 32); + SetLineActivation(1240, SPAC_PCross); + SetLineSpecial(1240, Floor_LowerToLowest, 38, 32); + break; + } + + case '279BB50468FE9F5B36C6D821E4902369': // Plutonia Experiment map30 + { + // flag items in deathmatch-only area correctly so that 100% items + // are possible in solo + SetThingFlags(250, 17); + SetThingFlags(251, 17); + SetThingFlags(252, 17); + SetThingFlags(253, 17); + SetThingFlags(254, 17); + SetThingFlags(206, 17); + break; + } + + case '4CB7AAC5C43CF32BDF05FD36481C1D9F': // Plutonia: Revisited map27 + { + SetLineSpecial(1214, Plat_DownWaitUpStayLip, 20, 64, 150); + SetLineSpecial(1215, Plat_DownWaitUpStayLip, 20, 64, 150); + SetLineSpecial(1216, Plat_DownWaitUpStayLip, 20, 64, 150); + SetLineSpecial(1217, Plat_DownWaitUpStayLip, 20, 64, 150); + SetLineSpecial(1227, Plat_DownWaitUpStayLip, 20, 64, 150); + break; + } + + case '5B26545FF21B051CA06D389CE535684C': // doom.wad e1m4 + { + // missing textures + SetWallTexture(693, Line.back, Side.top, "BROWN1"); + // fix HOM errors with sectors too low + OffsetSectorPlane(9, Sector.floor, 8); + OffsetSectorPlane(105, Sector.floor, 8); + OffsetSectorPlane(132, Sector.floor, 8); + OffsetSectorPlane(137, Sector.floor, 8); + break; + } + case 'A24FE135D5B6FD427FE27BEF89717A65': // doom.wad e2m2 + { + // missing textures + SetWallTexture(947, Line.back, Side.top, "BROWN1"); + SetWallTexture(1596, Line.back, Side.top, "WOOD1"); + break; + } + case '1BC04D646B32D3A3E411DAF3C1A38FF8': // doom.wad e2m4 + { + // missing textures + SetWallTexture(551, Line.back, Side.top, "PIPE4"); + SetWallTexture(865, Line.back, Side.bottom, "STEP5"); + SetWallTexture(1062, Line.front, Side.top, "GSTVINE1"); + SetWallTexture(1071, Line.front, Side.top, "MARBLE1"); + break; + } + case '99C580AD8FABE923CAB485CB7F3C5E5D': // doom.wad e2m5 + { + // missing textures + SetWallTexture(590, Line.back, Side.top, "GRAYBIG"); + SetWallTexture(590, Line.front, Side.bottom, "BROWN1"); + break; + } + case '3838AB29292587A7EE3CA71E7040868D': // doom.wad e2m6 + { + // missing texture + SetWallTexture(1091, Line.back, Side.top, "compspan"); + break; + } + case '8590F489879870C098CD7029C3187159': // doom.wad e2m7 + { + // missing texture + SetWallTexture(1286, Line.front, Side.bottom, "SHAWN2"); + break; + } + case '8A6399FAAA2E68649D4E4B16642074BE': // doom.wad e2m9 + { + // missing textures + SetWallTexture(121, Line.back, Side.top, "SW1LION"); + SetWallTexture(123, Line.back, Side.top, "GSTONE1"); + SetWallTexture(140, Line.back, Side.top, "GSTONE1"); + break; + } + case '2B65CB046EA40D2E44576949381769CA': // Commercial Doom e3m4 + { + // This line is erroneously specified as Door_Raise that monsters + // can operate. If they do, they block you off from half the map. Change + // this into a one-shot Door_Open so that it won't close. + SetLineSpecial(1069, Door_Open, 0, 16); + SetLineFlags(1069, 0, Line.ML_REPEAT_SPECIAL); + break; + } + case '5AC51CA9F1B57D4538049422A5E37291': // doom.wad e3m7 + { + // missing texture + SetWallTexture(971, Line.back, Side.top, "SP_HOT1"); + break; + } + case 'DA0C8281AC70EEC31127C228BCD7FE2C': // doom.wad e4m1 + { + // missing texture + SetWallTexture(470, Line.front, Side.top, "GSTONE1"); + break; + } + case 'F6EE16F770AD309D608EA0B1F1E249FC': // Ultimate Doom, e4m3 + { + // Remove unreachable secrets + SetSectorSpecial(124, 0); + SetSectorSpecial(125, 0); + // clear staircase to secret area + SetSectorSpecial(127, 0); + SetSectorSpecial(128, 0); + SetSectorSpecial(129, 0); + SetSectorSpecial(130, 0); + SetSectorSpecial(131, 0); + SetSectorSpecial(132, 0); + SetSectorSpecial(133, 0); + SetSectorSpecial(134, 0); + SetSectorSpecial(136, 0); + SetSectorSpecial(137, 0); + SetSectorSpecial(138, 0); + SetSectorSpecial(147, 0); + SetSectorSpecial(148, 0); + SetSectorSpecial(149, 0); + SetSectorSpecial(150, 0); + SetSectorSpecial(151, 0); + SetSectorSpecial(152, 0); + SetSectorSpecial(155, 0); + break; + } + case 'AAECADD4D97970AFF702D86FAFAC7D17': // doom.wad e4m4 + { + // missing textures + TextureID brownhug = TexMan.CheckForTexture("BROWNHUG", TexMan.Type_Wall); + SetWallTextureID(427, Line.back, Side.top, BROWNHUG); + SetWallTextureID(558, Line.back, Side.top, BROWNHUG); + SetWallTextureID(567, Line.front, Side.top, BROWNHUG); + SetWallTextureID(572, Line.front, Side.top, BROWNHUG); + break; + } + case '94D4C869A0C02EF4F7375022B36AAE45': // Ultimate Doom, e4m7 + { + // Remove unreachable secrets + SetSectorSpecial(263, 0); + SetSectorSpecial(264, 0); + break; + } + + case 'CEC791136A83EEC4B91D39718BDF9D82': // doom2.wad map04 + { + // missing textures + SetWallTexture(456, Line.back, Side.top, "SUPPORT3"); + TextureID stone = TexMan.CheckForTexture("STONE", TexMan.Type_Wall); + SetWallTextureID(108, Line.front, Side.top, STONE); + SetWallTextureID(109, Line.front, Side.top, STONE); + SetWallTextureID(110, Line.front, Side.top, STONE); + SetWallTextureID(111, Line.front, Side.top, STONE); + SetWallTextureID(127, Line.front, Side.top, STONE); + SetWallTextureID(128, Line.front, Side.top, STONE); + // remove erroneous blue keycard pickup ambush sector tags (nearby viewing windows, and the lights) + ClearSectorTags(19); + ClearSectorTags(20); + ClearSectorTags(23); + ClearSectorTags(28); + ClearSectorTags(33); + ClearSectorTags(34); + ClearSectorTags(83); + ClearSectorTags(85); + break; + } + case '9E061AD7FBCD7FAD968C976CB4AA3B9D': // doom2.wad map05 + { + // fix bug with opening westmost door in door hallway - incorrect sector tagging - see doomwiki.org for more info + ClearSectorTags(4); + ClearSectorTags(153); + break; + } + case '5BDA34DA60C0530794CC1EA2DA017976': // doom2.wad map14 + { + // missing textures + SetWallTexture(1259, Line.back, Side.top, "BSTONE2"); + SetWallTexture(1305, Line.back, Side.top, "BSTONE2"); + } + case '1A540BA717BF9EC85F8522594C352F2A': // Doom II, map15 + { + SetSectorSpecial(147, 0); + break; + } + case '0D491365C1B88B7D1B603890100DD03E': // doom2.wad map18 + { + // missing textures + SetWallTexture(451, Line.front, Side.mid, "metal"); + SetWallTexture(459, Line.front, Side.mid, "metal"); + break; + } + case 'B5506B1E8F2FC272AD0C77B9E0DF5491': // doom2.wad map19 + { + // missing textures + SetWallTexture(355, Line.back, Side.top, "STONE2"); + SetWallTexture(736, Line.front, Side.top, "SLADWALL"); + break; + } + case 'EBDAC00E9D25D884B2C8F4B1F0390539': // doom2.wad map21 + { + // push ceiling down in glitchy sectors above the stair switches + OffsetSectorPlane(50, Sector.ceiling, -56); + OffsetSectorPlane(54, Sector.ceiling, -56); + break; + } + case '110F84DE041052B59307FAF0293E6BC0': // Doom II, map27 + { + SetSectorSpecial(93, 0); + SetWallTexture(582, Line.back, Side.top, "ZIMMER3"); + break; + } + case '20251EDA21B2F2ECF6FF5B8BBC00B26C': // Doom II, MAP29 + { + // Missing textures on teleporters + TextureID support3 = TexMan.CheckForTexture("SUPPORT3", TexMan.Type_Wall); + for(int i=0;i<4;i++) + { + SetWallTextureID(405+i, Line.back, Side.bottom, SUPPORT3); + SetWallTextureID(516+i, Line.back, Side.bottom, SUPPORT3); + SetWallTextureID(524+1, Line.back, Side.bottom, SUPPORT3); + SetWallTextureID(1146+i, Line.back, Side.bottom, SUPPORT3); + SetWallTextureID(1138+i, Line.back, Side.bottom, SUPPORT3); + } + break; + } + case 'ABC4EB5A1535ECCD0061AD14F3547908': // Plutonia Experiment, map26 + { + SetSectorSpecial(156, 0); + break; + } + + case 'FF635FB9A2F076566299910F8C78F707': // nerve.wad, level04 + { + SetSectorSpecial(868, 0); + break; + } + + case 'D94587625BA779644D58151A87897CF1': // heretic.wad e1m2 + { + // Missing textures + TextureID mossrck1 = TexMan.CheckForTexture("MOSSRCK1", TexMan.Type_Wall); + SetWallTextureID( 477, Line.back, Side.top, mossrck1); + SetWallTextureID( 478, Line.back, Side.top, mossrck1); + SetWallTextureID( 479, Line.back, Side.top, mossrck1); + SetWallTextureID(1057, Line.front, Side.top, mossrck1); + break; + } + case 'ADD0FAC41AFB0B3C9B9F3C0006F93805': // heretic.wad e1m3 + { + // Broken door between the hallway that leads to a Torch + // and the passage that has a Bag of Holding at its end + OffsetSectorPlane(86, Sector.floor, -128); + OffsetSectorPlane(86, Sector.ceiling, -128); + break; + } + case '916318D8B06DAC2D83424B23E4B66531': // heretic.wad e1m4 + { + // Wrong sector offsets + OffsetSectorPlane( 0, Sector.ceiling, 8); + OffsetSectorPlane( 1, Sector.ceiling, 8); + OffsetSectorPlane( 2, Sector.ceiling, 8); + OffsetSectorPlane( 3, Sector.ceiling, 8); + OffsetSectorPlane( 4, Sector.ceiling, 8); + OffsetSectorPlane( 6, Sector.ceiling, 8); + OffsetSectorPlane( 6, Sector.floor, 8); + OffsetSectorPlane(17, Sector.ceiling, 8); + // Yellow key door + OffsetSectorPlane(284, Sector.floor, -8); + OffsetSectorPlane(284, Sector.ceiling, -8); + // Missing textures + SetWallTexture(490, Line.back, Side.bottom, "GRSTNPB"); + TextureID woodwl = TexMan.CheckForTexture("WOODWL", TexMan.Type_Wall); + SetWallTextureID( 722, Line.front, Side.bottom, woodwl); + SetWallTextureID( 911, Line.front, Side.bottom, woodwl); + SetWallTextureID(1296, Line.front, Side.bottom, woodwl); + break; + } + case '397A0E17A39542E4E8294E156FAB0502': // heretic.wad e2m2 + { + // Missing green door statues on easy and hard difficulties + SetThingSkills(17, 31); + SetThingSkills(18, 31); + break; + } + case 'CA3773ED313E8899311F3DD0CA195A68': // heretic.wad e3m6 + { + // Quartz flask outside of map + SetThingSkills(373, 0); + // Missing wall torch on hard difficulty + SetThingSkills(448, 31); + // Missing textures + TextureID mossrck1 = TexMan.CheckForTexture("MOSSRCK1", TexMan.Type_Wall); + SetWallTextureID(343, Line.front, Side.top, mossrck1); + SetWallTextureID(370, Line.front, Side.top, mossrck1); + break; + } + case '5E3FCFDE78310BB89F92B1626A47D0AD': // heretic.wad E4M7 + { + // Missing textures + TextureID cstlrck = TexMan.CheckForTexture("CSTLRCK", TexMan.Type_Wall); + SetWallTextureID(1274, Line.front, Side.top, cstlrck); + SetWallTextureID(1277, Line.back, Side.top, cstlrck); + SetWallTextureID(1278, Line.front, Side.top, cstlrck); + break; + } + + case '39C594CAC07EE51C80F757DA465FCC94': // strife1.wad map10 + { + // fix the shooting range by matching sector 138 and 145 properties together + OffsetSectorPlane(145, Sector.floor, -32); + OffsetSectorPlane(145, Sector.ceiling, 40); + SetSectorTexture(145, Sector.floor, "F_CONCRP"); + SetSectorLight(138, 192); + SetWallTexture(3431, Line.back, Side.top, "BRKGRY01"); + break; + } + + case 'DB31D71B11E3E4393B9C0CCB44A8639F': // rop_2015.wad e1m5 + { + // Lower floor a bit so secret switch becomes accessible + OffsetSectorPlane(527, Sector.floor, -32); + break; + } + + case 'CC3911090452D7C39EC8B3D97CEFDD6F': // jenesis.wad map16 + { + // Missing texture with hardware renderer because of wrongly lowered sector + ClearSectorTags(483); + break; + } + + case 'B68EB7CFB4CC481796E2919B9C16DFBD': // Moc11.wad e1m6 + { + SetVertex(1650, -3072, 2671); + SetVertex(1642, -2944, 2671); + break; + } + + case '5C594C67CF7721005DE71429F9811370': // Eternal Doom map03 + { + // fix broken staircase. The compatibility option is not sufficient + // to reliably handle this so clear the tags from the unwanted sectors. + ClearSectorTags(212); + ClearSectorTags(213); + ClearSectorTags(214); + break; + } + + case 'DCE862393CAAA6FF1294FB7056B53057': // UAC Ultra map07 + { + // Contains a scroller depending on Boom side effects + SetLineSpecial(391, Sector_CopyScroller, 99, 6); + break; + } + + case '9D50EBE17CEC78938C7A668DB0768611': // Strain map07 + { + // Make the exit accessible + SetLineFlags(1021, 0, Line.ML_BLOCKING); + break; + } + + case '3D8ED20BF5CAAE6D6AE0E10999C75084': // hgarden.pk3 map01 + { + // spawn trees on top of arches + SetThingZ(399, 168); + SetThingZ(400, 168); + SetThingZ(401, 168); + SetThingZ(402, 168); + SetThingZ(403, 168); + SetThingZ(404, 168); + break; + } + + case '6DC9F6CCEAE7A91AEC48EBE506F22BC4': // void.wad MAP01 + { + // Slightly squash the pillars in the starting room with "stimpacks" + // floating on them so that they can be obtained. + OffsetSectorPlane( 62, Sector.floor, -8); + OffsetSectorPlane( 63, Sector.floor, -8); + OffsetSectorPlane(118, Sector.floor, -8); + OffsetSectorPlane(119, Sector.floor, -8); + for (int i = 0; i < 8; ++i) + { + SetWallYScale(286 + i, Line.front, Side.bottom, 1.090909); + SetWallYScale(710 + i, Line.front, Side.bottom, 1.090909); + } + break; + } + + case 'FCCA97FC851F6473EAA069F74247B317': // pg-raw.wad map31 + { + SetLineSectorRef(331, Line.front, 74); + SetLineSectorRef(326, Line.front, 74); + SetLineSectorRef(497, Line.front, 74); + SetLineSectorRef(474, Line.front, 74); + SetLineSectorRef(471, Line.front, 74); + SetLineSectorRef(327, Line.front, 74); + SetLineSectorRef(328, Line.front, 74); + SetLineSectorRef(329, Line.front, 74); + AddSectorTag(74, 4); + SetLineSpecial(357, Transfer_Heights, 6); + break; + } + + case '712BB4CFBD0753178CA0C6814BE4C288': // beta version of map12 BTSX_E1 - patch some rendering glitches that are problematic to detect + { + AddSectorTag(545, 32000); + AddSectorTag(1618, 32000); + SetLineSpecial(2853, Sector_Set3DFloor, 32000, 4); + AddSectorTag(439, 32001); + AddSectorTag(458, 32001); + SetLineSpecial(2182, Sector_Set3DFloor, 32001, 4); + AddSectorTag(454, 32002); + AddSectorTag(910, 32002); + SetLineSpecial(2410, Sector_Set3DFloor, 32002, 4, 1); + break; + } + + case '5A24FC83A3F9A2D6D54AF04E2E96684F': // AV.WAD MAP01 + { + SetLineSectorRef(225, Line.back, 36); + SetLineSectorRef(222, Line.back, 36); + SetLineSectorRef(231, Line.back, 36); + + SetLineSectorRef(223, Line.back, 36); + SetLineSectorRef(224, Line.back, 36); + SetLineSectorRef(227, Line.back, 36); + + SetLineSectorRef(229, Line.back, 39); + SetLineSectorRef(233, Line.back, 39); + + TextureID nukage = TexMan.CheckForTexture("NUKAGE1", TexMan.Type_Flat); + SetWallTextureID(222, Line.front, Side.bottom, nukage); + SetWallTextureID(223, Line.front, Side.bottom, nukage); + SetWallTextureID(224, Line.front, Side.bottom, nukage); + SetWallTextureID(225, Line.front, Side.bottom, nukage); + SetWallTextureID(227, Line.front, Side.bottom, nukage); + SetWallTextureID(231, Line.front, Side.bottom, nukage); + SetWallTextureID(229, Line.front, Side.bottom, nukage); + SetWallTextureID(233, Line.front, Side.bottom, nukage); + + for(int i = 0; i < 8; i++) + { + SetLineSectorRef(i+234, Line.back, 37); + SetLineSectorRef(i+243, Line.back, 37); + SetWallTextureID(i+234, Line.back, Side.bottom, nukage); + SetWallTextureID(i+243, Line.back, Side.bottom, nukage); + } + + SetLineSpecial(336, Transfer_Heights, 32000, 6); + AddSectorTag(40, 32000); + AddSectorTag(38, 32000); + AddSectorTag(37, 32000); + AddSectorTag(34, 32000); + break; + } + + case '32FADD80710CAFCC2B09B4610C3340B3': // ksutra.wad map01 + { + // This rebuilds the ending pit with a 3D floor. + for(int i = Line.front; i <= Line.back; i++) + { + SetLineSectorRef(509, i, 129); + SetLineSectorRef(510, i, 129); + SetLineSectorRef(522, i, 129); + SetLineSectorRef(526, i, 129); + SetLineSectorRef(527, i, 129); + for(int j = 538; j <= 544; j++) + { + SetLineSectorRef(j, i, 129); + } + for(int j = 547; j <= 552; j++) + { + SetLineSectorRef(j, i, 129); + } + } + AddSectorTag(129, 32000); + SetSectorLight(129, 160); + for(int i = 148; i <= 151; i++) + { + AddSectorTag(i, 32000); + SetSectorLight(i, 160); + } + SetSectorTexture(126, Sector.Ceiling, "GRASS1"); + OffsetSectorPlane(126, Sector.Floor, 72); + OffsetSectorPlane(126, Sector.Ceiling, 128); + SetLineSpecial(524, Sector_Set3DFloor, 32000, 1, 0, 255); + SetWallTexture(524, Line.Front, Side.Mid, "ASHWALL3"); + SetWallTexture(537, Line.Front, Side.Bottom, "ASHWALL3"); + SetWallTexture(536, Line.Front, Side.Bottom, "ASHWALL3"); + SetWallTexture(546, Line.Front, Side.Bottom, "ASHWALL3"); + SetWallTexture(449, Line.Front, Side.Mid, "-"); + break; + } + + } + } + + private static native void ClearSectorTags(int sector); + private static native void AddSectorTag(int sector, int tag); + private static native void OffsetSectorPlane(int sector, int plane, double offset); + private static native void SetThingSkills(int thing, int skills); + private static native void SetThingZ(int thing, double z); + private static native void SetThingFlags(int thing, int flags); + private static native void SetVertex(uint vertex, double x, double y); + private static native void SetLineSectorRef(uint line, uint side, uint sector); + + private static void SetWallTexture(int line, int side, int texpart, String texture) + { + SetWallTextureID(line, side, texpart, TexMan.CheckForTexture(texture, TexMan.Type_Wall)); + } + + private static void SetWallTextureID(int line, int side, int texpart, TextureID texture) + { + level.Lines[line].sidedef[side].SetTexture(texpart, texture); + } + + private static void SetLineFlags(int line, int setflags, int clearflags = 0) + { + level.Lines[line].flags = (level.Lines[line].flags & ~clearflags) | setflags; + } + + private static void SetLineActivation(int line, int acttype) + { + level.Lines[line].activation = acttype; + } + + private static void ClearLineSpecial(int line) + { + level.Lines[line].special = 0; + } + + private static void SetLineSpecial(int line, int special, int arg1 = 0, int arg2 = 0, int arg3 = 0, int arg4 = 0, int arg5 = 0) + { + level.Lines[line].special = special; + level.Lines[line].args[0] = arg1; + level.Lines[line].args[1] = arg2; + level.Lines[line].args[2] = arg3; + level.Lines[line].args[3] = arg4; + level.Lines[line].args[4] = arg5; + } + + private static void SetSectorSpecial(int sectornum, int special) + { + level.sectors[sectornum].special = special; + } + + private static void SetSectorTextureID(int sectornum, int plane, TextureID texture) + { + level.sectors[sectornum].SetTexture(plane, texture); + } + + private static void SetSectorTexture(int sectornum, int plane, String texture) + { + SetSectorTextureID(sectornum, plane, TexMan.CheckForTexture(texture, TexMan.Type_Flat)); + } + + private static void SetSectorLight(int sectornum, int newval) + { + level.sectors[sectornum].SetLightLevel(newval); + } + + private static void SetWallYScale(int line, int side, int texpart, double scale) + { + level.lines[line].sidedef[side].SetTextureYScale(texpart, scale); + } +} diff --git a/wadsrc/static/zscript/mapdata.txt b/wadsrc/static/zscript/mapdata.txt index e219e835a7..fb62faff72 100644 --- a/wadsrc/static/zscript/mapdata.txt +++ b/wadsrc/static/zscript/mapdata.txt @@ -102,6 +102,12 @@ struct Side native play struct Line native play { + enum ESide + { + front=0, + back=1 + } + enum ELineFlags { ML_BLOCKING =0x00000001, // solid, is an obstacle @@ -156,6 +162,8 @@ struct Line native play native Line getPortalDestination(); native int getPortalAlignment(); native int Index(); + native bool Activate(Actor activator, int side, int type); + native bool RemoteActivate(Actor activator, int side, int type, Vector3 pos); int GetUDMFInt(Name nm) { diff --git a/wadsrc/static/zscript/menu/loadsavemenu.txt b/wadsrc/static/zscript/menu/loadsavemenu.txt index 279024a58a..eb27b6f6ec 100644 --- a/wadsrc/static/zscript/menu/loadsavemenu.txt +++ b/wadsrc/static/zscript/menu/loadsavemenu.txt @@ -132,7 +132,8 @@ class LoadSaveMenu : ListMenu commentLeft = savepicLeft; commentTop = savepicTop + savepicHeight + 16; commentWidth = savepicWidth; - commentHeight = (51+(screen.GetHeight()>200?10:0))*CleanYfac; + //commentHeight = (51+(screen.GetHeight()>200?10:0))*CleanYfac; + commentHeight = listboxHeight - savepicHeight - 16; commentRight = commentLeft + commentWidth; commentBottom = commentTop + commentHeight; }