mirror of
https://github.com/ZDoom/Raze.git
synced 2025-02-16 16:51:08 +00:00
Merge branch 'master' into whaven
This commit is contained in:
commit
4030a18245
594 changed files with 43640 additions and 29703 deletions
126
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
126
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
|
@ -0,0 +1,126 @@
|
|||
name: Bug Report
|
||||
description: File a Bug report
|
||||
title: '[BUG] '
|
||||
labels: bug
|
||||
#assignees: 'anonymous@temp'
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
## Please fill out forms as cleanly as possible.
|
||||
#### Make sure that you have
|
||||
* properly edited & filled in the title of this bug report
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Raze version
|
||||
description: |
|
||||
What version are you using?
|
||||
Run `raze --version` or check in the console in game.
|
||||
Make sure to update to latest [release](https://github.com/coelckers/Raze/releases) version and test again before continuing.
|
||||
placeholder: "ex: Raze 1.0.0, Git version, Branch, other"
|
||||
validations:
|
||||
required: false
|
||||
- type: dropdown
|
||||
id: gameid
|
||||
attributes:
|
||||
label: Which game are you running with Raze?
|
||||
multiple: false
|
||||
options:
|
||||
- Blood
|
||||
- Duke Nukem 3D
|
||||
- Exhumed/Powerslave
|
||||
- NAM
|
||||
- Redneck Rampage
|
||||
- Shadow Warrior
|
||||
- WW2 GI
|
||||
- Other
|
||||
validations:
|
||||
required: false
|
||||
- type: dropdown
|
||||
id: OS
|
||||
attributes:
|
||||
label: What Operating System are you using?
|
||||
multiple: false
|
||||
options:
|
||||
- Windows 11
|
||||
- Windows 10
|
||||
- Windows 8
|
||||
- Windows 7
|
||||
- Windows Other
|
||||
- Mac OS
|
||||
- Linux x86
|
||||
- Linux x86_64
|
||||
- Linux ARM (Raspberry Pi)
|
||||
- Other
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: other
|
||||
attributes:
|
||||
label: If Other OS, please describe
|
||||
description: Other details
|
||||
placeholder: "Windows, Mac OSX version, Debian, Ubuntu, Arch, etc."
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: hardware
|
||||
attributes:
|
||||
label: Relevant hardware info
|
||||
description: Hardware
|
||||
placeholder: "CPU, GPU, device brand/model: e.g. Intel, AMD, Nvidia, etc"
|
||||
validations:
|
||||
required: false
|
||||
- type: checkboxes
|
||||
id: checked
|
||||
attributes:
|
||||
label: Have you checked that no other similar issue already exists?
|
||||
description: Searched issues before creating report?
|
||||
options:
|
||||
- label: I have searched and not found similar issues.
|
||||
required: true
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: A clear and concise description of what the bug is.
|
||||
description: Describe what happens, what software were you running? _Include screenshot if possible_
|
||||
placeholder: "How & When does this occur?"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: steps
|
||||
attributes:
|
||||
label: Steps to reproduce the behaviour.
|
||||
description: How can we reproduce this?
|
||||
placeholder: "Explain how to reproduce"
|
||||
value: |
|
||||
Explain how to reproduce
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: config_file
|
||||
attributes:
|
||||
label: Your configuration
|
||||
description: |
|
||||
Share the config file(s) you've been using to run the program. (`raze.ini`)
|
||||
Please avoid pasting the full config, _use attachments or links_
|
||||
placeholder: "example: cl_autorun=true"
|
||||
render: ini # syntax highlighting
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: log
|
||||
attributes:
|
||||
label: Provide a Log
|
||||
description: Please avoid pasting the full log, _use attachments or links_
|
||||
placeholder: "Copy & paste error log section or provide link"
|
||||
validations:
|
||||
required: false
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
* Make sure you have properly filled in the title of this bug report
|
101
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
101
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
|
@ -0,0 +1,101 @@
|
|||
name: Feature Request
|
||||
description: Suggest an idea (a new feature or other improvement) for this project
|
||||
title: '[Feature] '
|
||||
labels: enhancement
|
||||
#assignees: 'anonymous@temp'
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
## Please fill out forms as cleanly as possible.
|
||||
#### Make sure that you have
|
||||
* properly edited & filled in the title of this bug report
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Raze version
|
||||
description: |
|
||||
What version are you using?
|
||||
Run `raze --version` or check in the console in game.
|
||||
Make sure to update to latest [release](https://github.com/coelckers/Raze/releases) version and test again before continuing.
|
||||
placeholder: "ex: Raze 1.0.0, Git version, Branch, other"
|
||||
validations:
|
||||
required: false
|
||||
- type: dropdown
|
||||
id: gameid
|
||||
attributes:
|
||||
label: Which game are you running with Raze?
|
||||
multiple: false
|
||||
options:
|
||||
- Blood
|
||||
- Duke Nukem 3D
|
||||
- Exhumed/Powerslave
|
||||
- NAM
|
||||
- Redneck Rampage
|
||||
- Shadow Warrior
|
||||
- WW2 GI
|
||||
- Other
|
||||
validations:
|
||||
required: false
|
||||
- type: dropdown
|
||||
id: OS
|
||||
attributes:
|
||||
label: What Operating System are you using?
|
||||
multiple: false
|
||||
options:
|
||||
- Windows 11
|
||||
- Windows 10
|
||||
- Windows 8
|
||||
- Windows 7
|
||||
- Windows Other
|
||||
- Mac OS
|
||||
- Linux x86
|
||||
- Linux x86_64
|
||||
- Linux ARM (Raspberry Pi)
|
||||
- Other
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: other
|
||||
attributes:
|
||||
label: If Other OS, please describe
|
||||
description: Other details
|
||||
placeholder: "Windows, Mac OSX version, Debian, Ubuntu, Arch, etc."
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: related
|
||||
attributes:
|
||||
label: Is your feature request related to a problem? Please describe.
|
||||
description: Related
|
||||
placeholder: "Ex. I'm always frustrated when"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: solution
|
||||
attributes:
|
||||
label: Describe the solution you'd like
|
||||
placeholder: "Ex. How can we make it better?"
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: alternative
|
||||
attributes:
|
||||
label: Describe alternatives you've considered
|
||||
description: A clear and concise description of any alternative solutions or features you've considered.
|
||||
placeholder: "Similar idea or software"
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: additional
|
||||
attributes:
|
||||
label: Add any other context or screenshots about the feature request here.
|
||||
description: Screenshots or Links?
|
||||
placeholder: "Ex. Screenshot or Link"
|
||||
validations:
|
||||
required: false
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
* Make sure you have properly filled in the title of this feature request
|
12
.github/workflows/continuous_integration.yml
vendored
12
.github/workflows/continuous_integration.yml
vendored
|
@ -24,13 +24,13 @@ jobs:
|
|||
}
|
||||
- {
|
||||
name: "macOS",
|
||||
os: macos-10.15,
|
||||
os: macos-11,
|
||||
deps_cmdline: "brew install libvpx",
|
||||
build_type: "Release"
|
||||
}
|
||||
- {
|
||||
name: "macOS",
|
||||
os: macos-10.15,
|
||||
os: macos-11,
|
||||
extra_options: "-DDYN_FLUIDSYNTH=OFF -DDYN_OPENAL=OFF -DDYN_SNDFILE=OFF -DDYN_MPG123=OFF",
|
||||
deps_cmdline: "brew install libvpx fluidsynth mpg123 libsndfile",
|
||||
build_type: "Debug"
|
||||
|
@ -54,14 +54,14 @@ jobs:
|
|||
os: ubuntu-20.04,
|
||||
extra_options: "-DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 \
|
||||
-DDYN_FLUIDSYNTH=OFF -DDYN_OPENAL=OFF -DDYN_SNDFILE=OFF -DDYN_MPG123=OFF",
|
||||
deps_cmdline: "sudo apt update && sudo apt remove gcc-11 libgcc-11-dev g++-11 libstdc++-11-dev && sudo apt install clang-6.0 libstdc++-9-dev libsdl2-dev libvpx-dev libopenal-dev libfluidsynth-dev libmpg123-dev libsndfile1-dev",
|
||||
deps_cmdline: "sudo apt update && sudo apt install clang-6.0 libsdl2-dev libvpx-dev libopenal-dev libfluidsynth-dev libmpg123-dev libsndfile1-dev",
|
||||
build_type: "Debug"
|
||||
}
|
||||
- {
|
||||
name: "Linux Clang 11",
|
||||
name: "Linux Clang 12",
|
||||
os: ubuntu-20.04,
|
||||
extra_options: "-DCMAKE_C_COMPILER=clang-11 -DCMAKE_CXX_COMPILER=clang++-11",
|
||||
deps_cmdline: "sudo apt update && sudo apt install clang-11 libsdl2-dev libvpx-dev",
|
||||
extra_options: "-DCMAKE_C_COMPILER=clang-12 -DCMAKE_CXX_COMPILER=clang++-12",
|
||||
deps_cmdline: "sudo apt update && sudo apt install clang-12 libsdl2-dev libvpx-dev",
|
||||
build_type: "Release"
|
||||
}
|
||||
|
||||
|
|
|
@ -191,6 +191,7 @@ if( ${TARGET_ARCHITECTURE} MATCHES "x86_64" )
|
|||
endif()
|
||||
|
||||
option (HAVE_VULKAN "Enable Vulkan support" ON)
|
||||
option (HAVE_GLES2 "Enable GLES2 support" ON)
|
||||
|
||||
# no, we're not using external asmjit for now, we made too many modifications to our's.
|
||||
# if the asmjit author uses our changes then we'll update this.
|
||||
|
@ -207,10 +208,14 @@ if( MSVC )
|
|||
# String pooling
|
||||
# Function-level linking
|
||||
# Disable run-time type information
|
||||
set( ALL_C_FLAGS "/GF /Gy /permissive-" )
|
||||
|
||||
if ( HAVE_VULKAN )
|
||||
set( ALL_C_FLAGS "/GF /Gy /permissive- /DHAVE_VULKAN" )
|
||||
else()
|
||||
set( ALL_C_FLAGS "/GF /Gy /permissive-" )
|
||||
set( ALL_C_FLAGS "${ALL_C_FLAGS} /DHAVE_VULKAN" )
|
||||
endif()
|
||||
|
||||
if ( HAVE_GLES2 )
|
||||
set( ALL_C_FLAGS "${ALL_C_FLAGS} /DHAVE_GLES2" )
|
||||
endif()
|
||||
|
||||
# Use SSE 2 as minimum always as the true color drawers needs it for __vectorcall
|
||||
|
@ -253,12 +258,15 @@ if( MSVC )
|
|||
string(REPLACE " /GR" " " CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} )
|
||||
else()
|
||||
set( REL_LINKER_FLAGS "" )
|
||||
set( ALL_C_FLAGS "-ffp-contract=off -DUSE_OPENGL=1 -DNOASM=1" )
|
||||
|
||||
if ( HAVE_VULKAN )
|
||||
set( ALL_C_FLAGS "-ffp-contract=off -DHAVE_VULKAN" )
|
||||
else()
|
||||
set( ALL_C_FLAGS "-ffp-contract=off" )
|
||||
set( ALL_C_FLAGS "${ALL_C_FLAGS} -DHAVE_VULKAN" )
|
||||
endif()
|
||||
|
||||
if ( HAVE_GLES2 )
|
||||
set( ALL_C_FLAGS "${ALL_C_FLAGS} -DHAVE_GLES2" )
|
||||
endif()
|
||||
set( ALL_C_FLAGS "${ALL_C_FLAGS} -DUSE_OPENGL=1 -DNOASM=1" )
|
||||
|
||||
if ( UNIX )
|
||||
include(CheckSymbolExists)
|
||||
|
|
|
@ -1019,6 +1019,26 @@ set (VULKAN_SOURCES
|
|||
common/rendering/vulkan/thirdparty/vk_mem_alloc/vk_mem_alloc.cpp
|
||||
)
|
||||
|
||||
if (HAVE_GLES2)
|
||||
set (GLES_SOURCES
|
||||
common/rendering/gles/gles_system.cpp
|
||||
common/rendering/gles/gles_renderer.cpp
|
||||
common/rendering/gles/gles_framebuffer.cpp
|
||||
common/rendering/gles/gles_renderstate.cpp
|
||||
common/rendering/gles/gles_renderbuffers.cpp
|
||||
common/rendering/gles/gles_postprocess.cpp
|
||||
common/rendering/gles/gles_postprocessstate.cpp
|
||||
common/rendering/gles/gles_buffers.cpp
|
||||
common/rendering/gles/gles_hwtexture.cpp
|
||||
common/rendering/gles/gles_shader.cpp
|
||||
common/rendering/gles/gles_shaderprogram.cpp
|
||||
common/rendering/gles/gles_samplers.cpp
|
||||
common/rendering/gles/glad/src/glad.c
|
||||
)
|
||||
|
||||
set (FASTMATH_SOURCES ${FASTMATH_SOURCES} ${GLES_SOURCES})
|
||||
endif()
|
||||
|
||||
if (HAVE_VULKAN)
|
||||
set (FASTMATH_SOURCES ${FASTMATH_SOURCES} ${VULKAN_SOURCES})
|
||||
endif()
|
||||
|
@ -1433,6 +1453,9 @@ include_directories(
|
|||
common/rendering/hwrenderer/data
|
||||
common/rendering/gl_load
|
||||
common/rendering/gl
|
||||
common/rendering/gles
|
||||
common/rendering/gles/glad/include
|
||||
common/rendering/gles/Mali_OpenGL_ES_Emulator/include
|
||||
common/rendering/vulkan/thirdparty
|
||||
common/rendering/polyrenderer/backend
|
||||
common/rendering/polyrenderer/drawers
|
||||
|
@ -1600,6 +1623,7 @@ source_group("Common\\Rendering\\Hardware Renderer\\Data" REGULAR_EXPRESSION "^$
|
|||
source_group("Common\\Rendering\\Hardware Renderer\\Postprocessing" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/rendering/hwrenderer/postprocessing/.+")
|
||||
source_group("Common\\Rendering\\OpenGL Loader" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/rendering/gl_load/.+")
|
||||
source_group("Common\\Rendering\\OpenGL Backend" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/rendering/gl/.+")
|
||||
source_group("Common\\Rendering\\GLES Backend" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/rendering/gles/.+")
|
||||
source_group("Common\\Rendering\\Vulkan Renderer\\System" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/rendering/vulkan/system/.+")
|
||||
source_group("Common\\Rendering\\Vulkan Renderer\\Renderer" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/rendering/vulkan/renderer/.+")
|
||||
source_group("Common\\Rendering\\Vulkan Renderer\\Shaders" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/common/rendering/vulkan/shaders/.+")
|
||||
|
|
|
@ -51,13 +51,13 @@ enum
|
|||
MAXSTATUS = 1024,
|
||||
// Maximum number of component tiles in a multi-psky:
|
||||
MAXPSKYTILES = 16,
|
||||
MAXSPRITESONSCREEN = 2560,
|
||||
MAXSPRITESONSCREEN = MAXSPRITES >> 2,
|
||||
MAXUNIQHUDID = 256, //Extra slots so HUD models can store animation state without messing game sprites
|
||||
|
||||
TSPR_TEMP = 99,
|
||||
|
||||
CLIPMASK0 = (IntToFixed(1)+1),
|
||||
CLIPMASK1 = (IntToFixed(256)+64),
|
||||
CLIPMASK0 = (1 << 16) + 1,
|
||||
CLIPMASK1 = (256 << 16) + 64
|
||||
};
|
||||
|
||||
|
||||
|
@ -409,15 +409,11 @@ inline int sectoradjacent(int sect1, int sect2) { return findwallbetweensectors(
|
|||
int32_t getsectordist(vec2_t const in, int const sectnum, vec2_t * const out = nullptr);
|
||||
extern const int16_t *chsecptr_onextwall;
|
||||
|
||||
#if !KRANDDEBUG
|
||||
inline int32_t krand(void)
|
||||
{
|
||||
randomseed = (randomseed * 1664525ul) + 221297ul;
|
||||
randomseed = (randomseed * 27584621) + 1;
|
||||
return ((uint32_t) randomseed)>>16;
|
||||
}
|
||||
#else
|
||||
int32_t krand(void);
|
||||
#endif
|
||||
|
||||
inline int32_t ksqrt(uint64_t num)
|
||||
{
|
||||
|
@ -532,10 +528,6 @@ inline int32_t setsprite(int16_t spritenum, int x, int y, int z)
|
|||
return setsprite(spritenum, &v);
|
||||
}
|
||||
|
||||
inline void setspritepos(int spnum, int x, int y, int z)
|
||||
{
|
||||
sprite[spnum].pos = { x,y,z };
|
||||
}
|
||||
int32_t setspritez(int16_t spritenum, const vec3_t *) ATTRIBUTE((nonnull(2)));
|
||||
|
||||
int32_t spriteheightofsptr(uspriteptr_t spr, int32_t *height, int32_t alsotileyofs);
|
||||
|
|
|
@ -185,10 +185,13 @@ enum
|
|||
CSTAT_SPRITE_RESERVED5 = 1u<<14u, // used by Duke 3D (Polymer), Shadow Warrior, Blood
|
||||
|
||||
CSTAT_SPRITE_INVISIBLE = 1u<<15u,
|
||||
};
|
||||
|
||||
// Raze extensions, using the higher bits to avoid conflitcs with the reserved and undocumented bits above.
|
||||
CSTAT_SPRITE_MDLROTATE = 1u<<16u, // Only for tsprites: rotate if this is a model or voxel.
|
||||
CSTAT_SPRITE_NOFIND = 1u<<17u, // Invisible to neartag and hitscan
|
||||
enum
|
||||
{
|
||||
CSTAT2_SPRITE_MDLROTATE = 1, // Only for tsprites: rotate if this is a model or voxel.
|
||||
CSTAT2_SPRITE_NOFIND = 2, // Invisible to neartag and hitscan
|
||||
CSTAT2_SPRITE_MAPPED = 4, // sprite was mapped for automap
|
||||
|
||||
};
|
||||
enum
|
||||
|
@ -245,7 +248,7 @@ struct spritetype
|
|||
};
|
||||
vec3_t opos;
|
||||
};
|
||||
uint32_t cstat;
|
||||
uint16_t cstat;
|
||||
int16_t picnum;
|
||||
int8_t shade;
|
||||
uint8_t pal, clipdist, blend;
|
||||
|
@ -270,6 +273,7 @@ struct spritetype
|
|||
int16_t detail;
|
||||
int time;
|
||||
int16_t wall;
|
||||
uint16_t cstat2;
|
||||
int8_t wdist;
|
||||
|
||||
|
||||
|
|
|
@ -480,7 +480,7 @@ int32_t clipmove(vec3_t * const pos, int16_t * const sectnum, int32_t xvect, int
|
|||
int const initialsectnum = *sectnum;
|
||||
|
||||
int32_t const dawalclipmask = (cliptype & 65535); // CLIPMASK0 = 0x00010001
|
||||
int32_t const dasprclipmask = FixedToInt(cliptype); // CLIPMASK1 = 0x01000040
|
||||
int32_t const dasprclipmask = (cliptype >> 16); // CLIPMASK1 = 0x01000040
|
||||
|
||||
vec2_t const move = { xvect, yvect };
|
||||
vec2_t goal = { pos->x + (xvect >> 14), pos->y + (yvect >> 14) };
|
||||
|
@ -857,7 +857,7 @@ int pushmove(vec3_t *const vect, int16_t *const sectnum,
|
|||
int bad;
|
||||
|
||||
const int32_t dawalclipmask = (cliptype&65535);
|
||||
// const int32_t dasprclipmask = FixedToInt(cliptype);
|
||||
// const int32_t dasprclipmask = (cliptype >> 16);
|
||||
|
||||
if (*sectnum < 0)
|
||||
return -1;
|
||||
|
@ -983,7 +983,7 @@ void getzrange(const vec3_t *pos, int16_t sectnum,
|
|||
const int32_t xmax = pos->x+extradist, ymax = pos->y+extradist;
|
||||
|
||||
const int32_t dawalclipmask = (cliptype&65535);
|
||||
const int32_t dasprclipmask = FixedToInt(cliptype);
|
||||
const int32_t dasprclipmask = (cliptype >> 16);
|
||||
|
||||
vec2_t closest = pos->vec2;
|
||||
if (enginecompatibility_mode == ENGINECOMPATIBILITY_NONE)
|
||||
|
@ -1048,7 +1048,7 @@ void getzrange(const vec3_t *pos, int16_t sectnum,
|
|||
if (da.x >= da.y)
|
||||
continue;
|
||||
//It actually got here, through all the continue's!!!
|
||||
int32_t daz, daz2;
|
||||
int32_t daz = 0, daz2 = 0;
|
||||
closest = pos->vec2;
|
||||
if (enginecompatibility_mode == ENGINECOMPATIBILITY_NONE)
|
||||
getsectordist(closest, k, &closest);
|
||||
|
@ -1081,7 +1081,7 @@ void getzrange(const vec3_t *pos, int16_t sectnum,
|
|||
const int32_t cstat = sprite[j].cstat;
|
||||
int32_t daz, daz2;
|
||||
|
||||
if (cstat & CSTAT_SPRITE_NOFIND) continue;
|
||||
if (sprite[j].cstat2 & CSTAT2_SPRITE_NOFIND) continue;
|
||||
if (cstat&dasprclipmask)
|
||||
{
|
||||
int32_t clipyou = 0;
|
||||
|
@ -1298,7 +1298,7 @@ int32_t hitscan(const vec3_t *sv, int16_t sectnum, int32_t vx, int32_t vy, int32
|
|||
// tmp: { (int32_t)curidx, (spritetype *)curspr, (!=0 if outer sector) }
|
||||
intptr_t *tmpptr=NULL;
|
||||
const int32_t dawalclipmask = (cliptype&65535);
|
||||
const int32_t dasprclipmask = FixedToInt(cliptype);
|
||||
const int32_t dasprclipmask = (cliptype >> 16);
|
||||
|
||||
hit->sect = -1; hit->wall = -1; hit->sprite = -1;
|
||||
if (sectnum < 0)
|
||||
|
@ -1417,7 +1417,7 @@ int32_t hitscan(const vec3_t *sv, int16_t sectnum, int32_t vx, int32_t vy, int32
|
|||
auto const spr = (uspriteptr_t)&sprite[z];
|
||||
uint32_t const cstat = spr->cstat;
|
||||
|
||||
if (cstat & CSTAT_SPRITE_NOFIND)
|
||||
if (spr->cstat2 & CSTAT2_SPRITE_NOFIND)
|
||||
continue;
|
||||
|
||||
#ifdef USE_OPENGL
|
||||
|
|
|
@ -505,7 +505,7 @@ int32_t lintersect(const int32_t originX, const int32_t originY, const int32_t o
|
|||
//
|
||||
// rintersect (internal)
|
||||
//
|
||||
// returns: -1 if didn't intersect, coefficient IntToFixed(x3--x4 fraction) else
|
||||
// returns: -1 if didn't intersect, coefficient (x3--x4 fraction)<<16 else
|
||||
int32_t rintersect_old(int32_t x1, int32_t y1, int32_t z1,
|
||||
int32_t vx, int32_t vy, int32_t vz,
|
||||
int32_t x3, int32_t y3, int32_t x4, int32_t y4,
|
||||
|
@ -880,7 +880,7 @@ int32_t setsprite(int16_t spritenum, const vec3_t *newpos)
|
|||
{
|
||||
int16_t tempsectnum = sprite[spritenum].sectnum;
|
||||
|
||||
if ((void const *) newpos != (void *) &sprite[spritenum])
|
||||
if (newpos != &sprite[spritenum].pos)
|
||||
sprite[spritenum].pos = *newpos;
|
||||
|
||||
updatesector(newpos->x,newpos->y,&tempsectnum);
|
||||
|
@ -1152,7 +1152,7 @@ void neartag(int32_t xs, int32_t ys, int32_t zs, int16_t sectnum, int16_t ange,
|
|||
{
|
||||
auto const spr = (uspriteptr_t)&sprite[z];
|
||||
|
||||
if (spr->cstat & CSTAT_SPRITE_NOFIND)
|
||||
if (spr->cstat2 & CSTAT2_SPRITE_NOFIND)
|
||||
continue;
|
||||
if (blacklist_sprite_func && blacklist_sprite_func(z))
|
||||
continue;
|
||||
|
|
|
@ -1957,7 +1957,7 @@ void polymost_scansector(int32_t sectnum)
|
|||
|
||||
int const nextsectnum = wal->nextsector; //Scan close sectors
|
||||
|
||||
if (nextsectnum >= 0 && !(wal->cstat&32) && sectorbordercnt < countof(sectorborder))
|
||||
if (nextsectnum >= 0 && !(wal->cstat&32) && sectorbordercnt < (int)countof(sectorborder))
|
||||
if (gotsector[nextsectnum] == 0)
|
||||
{
|
||||
double const d = fp1.X* fp2.Y - fp2.X * fp1.Y;
|
||||
|
@ -2699,10 +2699,6 @@ static int32_t polymost_lintersect(int32_t x1, int32_t y1, int32_t x2, int32_t y
|
|||
#define TSPR_OFFSET_FACTOR .0002f
|
||||
#define TSPR_OFFSET(tspr) (TSPR_OFFSET_FACTOR + ((tspr->owner != -1 ? tspr->owner & 63 : 0) * TSPR_OFFSET_FACTOR))
|
||||
|
||||
#define TSPR_OFFSET_FACTOR2 .000008f
|
||||
#define TSPR_OFFSET2(tspr) ((TSPR_OFFSET_FACTOR + ((tspr->owner != -1 ? tspr->owner & 63 : 1) * TSPR_OFFSET_FACTOR)) * (float)sepdist(globalposx - tspr->x, globalposy - tspr->y, globalposz - tspr->z) * 0.025f)
|
||||
|
||||
|
||||
void polymost_drawsprite(int32_t snum)
|
||||
{
|
||||
auto const tspr = tspriteptr[snum];
|
||||
|
@ -2814,8 +2810,6 @@ void polymost_drawsprite(int32_t snum)
|
|||
int const ang = (getangle(tspr->x - globalposx, tspr->y - globalposy) + 1024) & 2047;
|
||||
|
||||
float foffs = TSPR_OFFSET(tspr);
|
||||
float foffs2 = TSPR_OFFSET(tspr);
|
||||
if (fabs(foffs2) < fabs(foffs)) foffs = foffs2;
|
||||
|
||||
vec2f_t const offs = { float(bcosf(ang, -6) * foffs), float(bsinf(ang, -6) * foffs) };
|
||||
|
||||
|
@ -2903,6 +2897,7 @@ void polymost_drawsprite(int32_t snum)
|
|||
|
||||
vec2_16_t tempsiz = { (int16_t)tsiz.x, (int16_t)tsiz.y };
|
||||
pow2xsplit = 0;
|
||||
if (globalshade > 63) globalshade = 63; // debug
|
||||
polymost_drawpoly(pxy, 4, method, tempsiz);
|
||||
|
||||
drawpoly_srepeat = 0;
|
||||
|
@ -3258,8 +3253,8 @@ void polymost_drawsprite(int32_t snum)
|
|||
break;
|
||||
}
|
||||
|
||||
if (automapping == 1 && (unsigned)spritenum < MAXSPRITES)
|
||||
show2dsprite.Set(spritenum);
|
||||
if ((unsigned)spritenum < MAXSPRITES)
|
||||
sprite[spritenum].cstat2 |= CSTAT2_SPRITE_MAPPED;
|
||||
|
||||
_drawsprite_return:
|
||||
;
|
||||
|
@ -3813,7 +3808,7 @@ int32_t polymost_voxdraw(voxmodel_t* m, tspriteptr_t const tspr, bool rotate)
|
|||
if ((tspr->cstat & 48) == 32)
|
||||
return 0;
|
||||
|
||||
if ((tspr->cstat & CSTAT_SPRITE_MDLROTATE) || rotate)
|
||||
if ((tspr->cstat2 & CSTAT2_SPRITE_MDLROTATE) || rotate)
|
||||
{
|
||||
int myclock = (PlayClock << 3) + MulScale(4 << 3, pm_smoothratio, 16);
|
||||
tspr->ang = (tspr->ang + myclock) & 2047; // will be applied in md3_vox_calcmat_common.
|
||||
|
|
|
@ -124,7 +124,7 @@ static void Shape2D_Clear(DShape2D* self, int which)
|
|||
if (which & C_Verts) self->mVertices.Clear();
|
||||
if (which & C_Coords) self->mCoords.Clear();
|
||||
if (which & C_Indices) self->mIndices.Clear();
|
||||
self->needsVertexUpload = true;
|
||||
self->bufferInfo->needsVertexUpload = true;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, Clear, Shape2D_Clear)
|
||||
|
@ -138,7 +138,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, Clear, Shape2D_Clear)
|
|||
static void Shape2D_PushVertex(DShape2D* self, double x, double y)
|
||||
{
|
||||
self->mVertices.Push(DVector2(x, y));
|
||||
self->needsVertexUpload = true;
|
||||
self->bufferInfo->needsVertexUpload = true;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, PushVertex, Shape2D_PushVertex)
|
||||
|
@ -153,7 +153,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, PushVertex, Shape2D_PushVertex)
|
|||
static void Shape2D_PushCoord(DShape2D* self, double u, double v)
|
||||
{
|
||||
self->mCoords.Push(DVector2(u, v));
|
||||
self->needsVertexUpload = true;
|
||||
self->bufferInfo->needsVertexUpload = true;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, PushCoord, Shape2D_PushCoord)
|
||||
|
@ -170,7 +170,7 @@ static void Shape2D_PushTriangle(DShape2D* self, int a, int b, int c)
|
|||
self->mIndices.Push(a);
|
||||
self->mIndices.Push(b);
|
||||
self->mIndices.Push(c);
|
||||
self->needsVertexUpload = true;
|
||||
self->bufferInfo->needsVertexUpload = true;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, PushTriangle, Shape2D_PushTriangle)
|
||||
|
@ -528,8 +528,15 @@ void F2DDrawer::AddTexture(FGameTexture* img, DrawParms& parms)
|
|||
offset = osave;
|
||||
}
|
||||
|
||||
DShape2D::~DShape2D() {
|
||||
delete lastParms;
|
||||
static TArray<RefCountedPtr<DShape2DBufferInfo>> buffersToDestroy;
|
||||
|
||||
void DShape2D::OnDestroy() {
|
||||
if (lastParms) delete lastParms;
|
||||
lastParms = nullptr;
|
||||
mIndices.Reset();
|
||||
mVertices.Reset();
|
||||
mCoords.Reset();
|
||||
buffersToDestroy.Push(std::move(bufferInfo));
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -562,11 +569,11 @@ void F2DDrawer::AddShape(FGameTexture* img, DShape2D* shape, DrawParms& parms)
|
|||
shape->lastParms = new DrawParms(parms);
|
||||
}
|
||||
else if (shape->lastParms->vertexColorChange(parms)) {
|
||||
shape->needsVertexUpload = true;
|
||||
if (!shape->uploadedOnce) {
|
||||
shape->bufIndex = -1;
|
||||
shape->buffers.Clear();
|
||||
shape->lastCommand = -1;
|
||||
shape->bufferInfo->needsVertexUpload = true;
|
||||
if (!shape->bufferInfo->uploadedOnce) {
|
||||
shape->bufferInfo->bufIndex = -1;
|
||||
shape->bufferInfo->buffers.Clear();
|
||||
shape->bufferInfo->lastCommand = -1;
|
||||
}
|
||||
delete shape->lastParms;
|
||||
shape->lastParms = new DrawParms(parms);
|
||||
|
@ -578,7 +585,7 @@ void F2DDrawer::AddShape(FGameTexture* img, DShape2D* shape, DrawParms& parms)
|
|||
auto osave = offset;
|
||||
if (parms.nooffset) offset = { 0,0 };
|
||||
|
||||
if (shape->needsVertexUpload)
|
||||
if (shape->bufferInfo->needsVertexUpload)
|
||||
{
|
||||
shape->minx = 16383;
|
||||
shape->miny = 16383;
|
||||
|
@ -617,15 +624,15 @@ void F2DDrawer::AddShape(FGameTexture* img, DShape2D* shape, DrawParms& parms)
|
|||
dg.transform = shape->transform;
|
||||
dg.transform.Cells[0][2] += offset.X;
|
||||
dg.transform.Cells[1][2] += offset.Y;
|
||||
dg.shape2D = shape;
|
||||
dg.shape2DBufInfo = shape->bufferInfo;
|
||||
dg.shape2DIndexCount = shape->mIndices.Size();
|
||||
if (shape->needsVertexUpload)
|
||||
if (shape->bufferInfo->needsVertexUpload)
|
||||
{
|
||||
shape->bufIndex += 1;
|
||||
shape->bufferInfo->bufIndex += 1;
|
||||
|
||||
shape->buffers.Reserve(1);
|
||||
shape->bufferInfo->buffers.Reserve(1);
|
||||
|
||||
auto buf = &shape->buffers[shape->bufIndex];
|
||||
auto buf = &shape->bufferInfo->buffers[shape->bufferInfo->bufIndex];
|
||||
|
||||
auto verts = TArray<TwoDVertex>(dg.mVertCount, true);
|
||||
for ( int i=0; i<dg.mVertCount; i++ )
|
||||
|
@ -644,12 +651,12 @@ void F2DDrawer::AddShape(FGameTexture* img, DShape2D* shape, DrawParms& parms)
|
|||
}
|
||||
|
||||
buf->UploadData(&verts[0], dg.mVertCount, &shape->mIndices[0], shape->mIndices.Size());
|
||||
shape->needsVertexUpload = false;
|
||||
shape->uploadedOnce = true;
|
||||
shape->bufferInfo->needsVertexUpload = false;
|
||||
shape->bufferInfo->uploadedOnce = true;
|
||||
}
|
||||
dg.shape2DBufIndex = shape->bufIndex;
|
||||
shape->lastCommand += 1;
|
||||
dg.shape2DCommandCounter = shape->lastCommand;
|
||||
dg.shape2DBufIndex = shape->bufferInfo->bufIndex;
|
||||
shape->bufferInfo->lastCommand += 1;
|
||||
dg.shape2DCommandCounter = shape->bufferInfo->lastCommand;
|
||||
AddCommand(&dg);
|
||||
offset = osave;
|
||||
}
|
||||
|
@ -1077,6 +1084,17 @@ void F2DDrawer::Clear()
|
|||
screenFade = 1.f;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void F2DDrawer::OnFrameDone()
|
||||
{
|
||||
buffersToDestroy.Clear();
|
||||
}
|
||||
|
||||
F2DVertexBuffer::F2DVertexBuffer()
|
||||
{
|
||||
mVertexBuffer = screen->CreateVertexBuffer();
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "textures.h"
|
||||
#include "renderstyle.h"
|
||||
#include "dobject.h"
|
||||
#include "refcounted.h"
|
||||
|
||||
struct DrawParms;
|
||||
struct FColormap;
|
||||
|
@ -49,6 +50,7 @@ struct F2DPolygons
|
|||
};
|
||||
|
||||
class DShape2D;
|
||||
struct DShape2DBufferInfo;
|
||||
|
||||
class F2DDrawer
|
||||
{
|
||||
|
@ -123,7 +125,7 @@ public:
|
|||
bool useTransform;
|
||||
DMatrix3x3 transform;
|
||||
|
||||
DShape2D* shape2D;
|
||||
RefCountedPtr<DShape2DBufferInfo> shape2DBufInfo;
|
||||
int shape2DBufIndex;
|
||||
int shape2DIndexCount;
|
||||
int shape2DCommandCounter;
|
||||
|
@ -136,7 +138,7 @@ public:
|
|||
// If these fields match, two draw commands can be batched.
|
||||
bool isCompatible(const RenderCommand &other) const
|
||||
{
|
||||
if (shape2D != nullptr || other.shape2D != nullptr) return false;
|
||||
if (shape2DBufInfo != nullptr || other.shape2DBufInfo != nullptr) return false;
|
||||
return mTexture == other.mTexture &&
|
||||
mType == other.mType &&
|
||||
mTranslationId == other.mTranslationId &&
|
||||
|
@ -214,6 +216,7 @@ public:
|
|||
void Begin(int w, int h) { isIn2D = true; Width = w; Height = h; }
|
||||
void End() { isIn2D = false; }
|
||||
bool HasBegun2D() { return isIn2D; }
|
||||
void OnFrameDone();
|
||||
|
||||
void ClearClipRect() { clipleft = cliptop = 0; clipwidth = clipheight = -1; }
|
||||
void SetClipRect(int x, int y, int w, int h);
|
||||
|
@ -240,12 +243,22 @@ public:
|
|||
bool mIsFirstPass = true;
|
||||
};
|
||||
|
||||
struct DShape2DBufferInfo : RefCountedBase
|
||||
{
|
||||
TArray<F2DVertexBuffer> buffers;
|
||||
bool needsVertexUpload = true;
|
||||
int bufIndex = -1;
|
||||
int lastCommand = -1;
|
||||
bool uploadedOnce = false;
|
||||
};
|
||||
|
||||
class DShape2D : public DObject
|
||||
{
|
||||
|
||||
DECLARE_CLASS(DShape2D,DObject)
|
||||
public:
|
||||
DShape2D()
|
||||
: bufferInfo(new DShape2DBufferInfo)
|
||||
{
|
||||
transform.Identity();
|
||||
}
|
||||
|
@ -261,15 +274,11 @@ public:
|
|||
|
||||
DMatrix3x3 transform;
|
||||
|
||||
TArray<F2DVertexBuffer> buffers;
|
||||
bool needsVertexUpload = true;
|
||||
int bufIndex = -1;
|
||||
int lastCommand = -1;
|
||||
RefCountedPtr<DShape2DBufferInfo> bufferInfo;
|
||||
|
||||
bool uploadedOnce = false;
|
||||
DrawParms* lastParms;
|
||||
|
||||
~DShape2D();
|
||||
void OnDestroy() override;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -618,17 +618,20 @@ static void CheckReplayGain(const char *musicname, EMidiDevice playertype, const
|
|||
ZMusic_Close(handle);
|
||||
|
||||
GainAnalyzer analyzer;
|
||||
analyzer.InitGainAnalysis(fmt.mSampleRate);
|
||||
int result = analyzer.AnalyzeSamples(lbuffer.Data(), rbuffer.Size() == 0 ? nullptr : rbuffer.Data(), lbuffer.Size(), rbuffer.Size() == 0? 1: 2);
|
||||
int result = analyzer.InitGainAnalysis(fmt.mSampleRate);
|
||||
if (result == GAIN_ANALYSIS_OK)
|
||||
{
|
||||
auto gain = analyzer.GetTitleGain();
|
||||
Printf("Calculated replay gain for %s at %f dB\n", hash.GetChars(), gain);
|
||||
result = analyzer.AnalyzeSamples(lbuffer.Data(), rbuffer.Size() == 0 ? nullptr : rbuffer.Data(), lbuffer.Size(), rbuffer.Size() == 0 ? 1 : 2);
|
||||
if (result == GAIN_ANALYSIS_OK)
|
||||
{
|
||||
auto gain = analyzer.GetTitleGain();
|
||||
Printf("Calculated replay gain for %s at %f dB\n", hash.GetChars(), gain);
|
||||
|
||||
gainMap.Insert(hash, gain);
|
||||
mus_playing.replayGain = gain;
|
||||
mus_playing.replayGainFactor = dBToAmplitude(mus_playing.replayGain + mus_gainoffset);
|
||||
SaveGains();
|
||||
gainMap.Insert(hash, gain);
|
||||
mus_playing.replayGain = gain;
|
||||
mus_playing.replayGainFactor = dBToAmplitude(mus_playing.replayGain + mus_gainoffset);
|
||||
SaveGains();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -856,7 +859,7 @@ void S_StopMusic (bool force)
|
|||
|
||||
CCMD (changemus)
|
||||
{
|
||||
if (!nomusic)
|
||||
if (MusicEnabled())
|
||||
{
|
||||
if (argv.argc() > 1)
|
||||
{
|
||||
|
|
|
@ -367,7 +367,7 @@ SoundHandle SoundRenderer::LoadSoundVoc(uint8_t *sfxdata, int length)
|
|||
i += 4;
|
||||
if (i + blocksize > length)
|
||||
{
|
||||
okay = false;
|
||||
//okay = false;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -450,7 +450,7 @@ SoundHandle SoundRenderer::LoadSoundVoc(uint8_t *sfxdata, int length)
|
|||
}
|
||||
|
||||
// Second pass to write the data
|
||||
if (okay)
|
||||
if (okay && len > 0)
|
||||
{
|
||||
data = new uint8_t[len];
|
||||
i = 26;
|
||||
|
|
|
@ -291,7 +291,7 @@ void FCommandBuffer::AddString(FString clip)
|
|||
if (clip.IsNotEmpty())
|
||||
{
|
||||
// Only paste the first line.
|
||||
long brk = clip.IndexOfAny("\r\n\b");
|
||||
auto brk = clip.IndexOfAny("\r\n\b");
|
||||
std::u32string build;
|
||||
if (brk >= 0)
|
||||
{
|
||||
|
|
|
@ -839,11 +839,11 @@ int FColorCVar::ToInt2 (UCVarValue value, ECVarType type)
|
|||
|
||||
if (string.IsNotEmpty())
|
||||
{
|
||||
ret = V_GetColorFromString (NULL, string);
|
||||
ret = V_GetColorFromString (string);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = V_GetColorFromString (NULL, value.String);
|
||||
ret = V_GetColorFromString (value.String);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -533,7 +533,7 @@ FString BuildString (int argc, FString *argv)
|
|||
else if (strchr(argv[arg], '"'))
|
||||
{ // If it contains one or more quotes, we need to escape them.
|
||||
buf << '"';
|
||||
long substr_start = 0, quotepos;
|
||||
ptrdiff_t substr_start = 0, quotepos;
|
||||
while ((quotepos = argv[arg].IndexOf('"', substr_start)) >= 0)
|
||||
{
|
||||
if (substr_start < quotepos)
|
||||
|
|
|
@ -123,12 +123,9 @@ public:
|
|||
frametime = currentclock;
|
||||
|
||||
int delay = 20;
|
||||
if (frameTicks)
|
||||
{
|
||||
if (curframe == 1) delay = frameTicks[0];
|
||||
else if (curframe < numframes - 2) delay = frameTicks[1];
|
||||
else delay = frameTicks[2];
|
||||
}
|
||||
if (curframe == 1) delay = frameTicks[0];
|
||||
else if (curframe < numframes - 2) delay = frameTicks[1];
|
||||
else delay = frameTicks[2];
|
||||
nextframetime += delay;
|
||||
|
||||
bool nostopsound = (flags & NOSOUNDCUTOFF);
|
||||
|
@ -532,7 +529,7 @@ public:
|
|||
SmkPlayer* pId = (SmkPlayer*)userdata;
|
||||
memcpy(buff, &pId->adata.samples[pId->adata.nRead], len);
|
||||
pId->adata.nRead += len / 2;
|
||||
if (pId->adata.nRead >= countof(pId->adata.samples)) pId->adata.nRead = 0;
|
||||
if (pId->adata.nRead >= (int)countof(pId->adata.samples)) pId->adata.nRead = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -541,7 +538,7 @@ public:
|
|||
for (unsigned i = 0; i < count; i++)
|
||||
{
|
||||
adata.samples[adata.nWrite] = (audioBuffer[i] - 128) << 8;
|
||||
if (++adata.nWrite >= countof(adata.samples)) adata.nWrite = 0;
|
||||
if (++adata.nWrite >= (int)countof(adata.samples)) adata.nWrite = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -551,7 +548,7 @@ public:
|
|||
for (unsigned i = 0; i < count/2; i++)
|
||||
{
|
||||
adata.samples[adata.nWrite] = *ptr++;
|
||||
if (++adata.nWrite >= countof(adata.samples)) adata.nWrite = 0;
|
||||
if (++adata.nWrite >= (int)countof(adata.samples)) adata.nWrite = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -789,7 +786,7 @@ DEFINE_ACTION_FUNCTION(_MoviePlayer, Create)
|
|||
auto movie = OpenMovie(filename, *sndinf, frametime == -1? nullptr : frametimes, flags, error);
|
||||
if (!movie)
|
||||
{
|
||||
Printf(TEXTCOLOR_YELLOW, "%s", error.GetChars());
|
||||
Printf(TEXTCOLOR_YELLOW "%s", error.GetChars());
|
||||
}
|
||||
ACTION_RETURN_POINTER(movie);
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ static bool StreamCallbackFunc(SoundStream* stream, void* buff, int len, void* u
|
|||
InterplayDecoder* pId = (InterplayDecoder*)userdata;
|
||||
memcpy(buff, &pId->audio.samples[pId->audio.nRead], len);
|
||||
pId->audio.nRead += len / 2;
|
||||
if (pId->audio.nRead >= countof(pId->audio.samples)) pId->audio.nRead = 0;
|
||||
if (pId->audio.nRead >= (int)countof(pId->audio.samples)) pId->audio.nRead = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -364,7 +364,7 @@ bool InterplayDecoder::RunFrame(uint64_t clock)
|
|||
}
|
||||
|
||||
audio.samples[audio.nWrite++] = predictor[ch];
|
||||
if (audio.nWrite >= countof(audio.samples)) audio.nWrite = 0;
|
||||
if (audio.nWrite >= (int)countof(audio.samples)) audio.nWrite = 0;
|
||||
}
|
||||
|
||||
int ch = 0;
|
||||
|
@ -374,7 +374,7 @@ bool InterplayDecoder::RunFrame(uint64_t clock)
|
|||
predictor[ch] = clamp(predictor[ch], -32768, 32768);
|
||||
|
||||
audio.samples[audio.nWrite++] = predictor[ch];
|
||||
if (audio.nWrite >= countof(audio.samples)) audio.nWrite = 0;
|
||||
if (audio.nWrite >= (int)countof(audio.samples)) audio.nWrite = 0;
|
||||
|
||||
// toggle channel
|
||||
ch ^= audio.nChannels - 1;
|
||||
|
@ -442,7 +442,7 @@ bool InterplayDecoder::RunFrame(uint64_t clock)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (opcodeSize != decodeMap.nSize) {
|
||||
if (opcodeSize != (int)decodeMap.nSize) {
|
||||
delete[] decodeMap.pData;
|
||||
decodeMap.pData = new uint8_t[opcodeSize];
|
||||
decodeMap.nSize = opcodeSize;
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include "s_music.h"
|
||||
#include "m_argv.h"
|
||||
#include "i_interface.h"
|
||||
#include "gamecontrol.h"
|
||||
|
||||
CVAR(Bool, inter_subtitles, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
||||
|
||||
|
|
|
@ -495,6 +495,7 @@ xx(Blockeverything)
|
|||
xx(Zoneboundary)
|
||||
xx(Jumpover)
|
||||
xx(Blockfloaters)
|
||||
xx(Blocklandmonsters)
|
||||
xx(Clipmidtex)
|
||||
xx(Wrapmidtex)
|
||||
xx(Midtex3d)
|
||||
|
@ -1109,3 +1110,5 @@ xy(menu_advance, "menu/advance")
|
|||
xx(zoomsize)
|
||||
xx(ScreenJobRunner)
|
||||
xx(RazeStatusBar)
|
||||
xx(RipSound)
|
||||
xx(Archvile)
|
||||
|
|
|
@ -51,7 +51,7 @@ extern uint8_t IcePalette[16][3];
|
|||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
void PaletteContainer::Init(int numslots) // This cannot be a constructor!!!
|
||||
void PaletteContainer::Init(int numslots, const uint8_t* indexmap) // This cannot be a constructor!!!
|
||||
{
|
||||
if (numslots < 1) numslots = 1;
|
||||
Clear();
|
||||
|
@ -63,6 +63,7 @@ void PaletteContainer::Init(int numslots) // This cannot be a constructor!!!
|
|||
TranslationTables.Resize(numslots);
|
||||
StoreTranslation(0, &remap); // make sure that translation ID 0 is the identity.
|
||||
ColorMatcher.SetPalette(BaseColors);
|
||||
ColorMatcher.SetIndexMap(indexmap);
|
||||
}
|
||||
|
||||
void PaletteContainer::SetPalette(const uint8_t* colors, int transparent_index)
|
||||
|
|
|
@ -116,7 +116,7 @@ private:
|
|||
FMemArena remapArena;
|
||||
TArray<TAutoGrowArray<FRemapTablePtr, FRemapTable*>> TranslationTables;
|
||||
public:
|
||||
void Init(int numslots); // This cannot be a constructor!!!
|
||||
void Init(int numslots, const uint8_t *indexmap); // This cannot be a constructor!!!
|
||||
void SetPalette(const uint8_t* colors, int transparent_index = -1);
|
||||
void Clear();
|
||||
int DetermineTranslucency(FileReader& file);
|
||||
|
|
|
@ -1051,8 +1051,8 @@ FSerializer &Serialize(FSerializer &arc, const char *key, double &value, double
|
|||
auto val = arc.r->FindKey(key);
|
||||
if (val != nullptr)
|
||||
{
|
||||
assert(val->IsDouble());
|
||||
if (val->IsDouble())
|
||||
assert(val->IsNumber());
|
||||
if (val->IsNumber())
|
||||
{
|
||||
value = val->GetDouble();
|
||||
}
|
||||
|
|
|
@ -238,7 +238,7 @@ FSerializer &SerializePointer(FSerializer &arc, const char *key, T *&value, T **
|
|||
vv = value - base;
|
||||
if (vv < 0 || vv >= count)
|
||||
{
|
||||
Printf("Trying to serialize out-of-bounds array value with key '%s', index = %lli, size = %lli\n", key, vv, count);
|
||||
Printf("Trying to serialize out-of-bounds array value with key '%s', index = %" PRId64 ", size = %" PRId64 "\n", key, vv, count);
|
||||
vv = -1;
|
||||
}
|
||||
}
|
||||
|
@ -247,7 +247,7 @@ FSerializer &SerializePointer(FSerializer &arc, const char *key, T *&value, T **
|
|||
value = nullptr;
|
||||
else if (vv < 0 || vv >= count)
|
||||
{
|
||||
Printf("Trying to serialize out-of-bounds array value with key '%s', index = %lli, size = %lli\n", key, vv, count);
|
||||
Printf("Trying to serialize out-of-bounds array value with key '%s', index = %" PRId64 ", size = %" PRId64 "\n", key, vv, count);
|
||||
value = nullptr;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -435,7 +435,7 @@ void FStringTable::InsertString(int lumpnum, int langid, FName label, const FStr
|
|||
{
|
||||
const char *strlangid = (const char *)&langid;
|
||||
TableElement te = { fileSystem.GetFileContainer(lumpnum), { string, string, string, string } };
|
||||
long index;
|
||||
ptrdiff_t index;
|
||||
while ((index = te.strings[0].IndexOf("@[")) >= 0)
|
||||
{
|
||||
auto endindex = te.strings[0].IndexOf(']', index);
|
||||
|
|
|
@ -208,8 +208,9 @@ bool FZipFile::Open(bool quiet, LumpFilterInfo* filter)
|
|||
char *dirptr = (char*)directory;
|
||||
FZipLump *lump_p = Lumps;
|
||||
|
||||
FString name0;
|
||||
FString name0, name1;
|
||||
bool foundspeciallump = false;
|
||||
bool foundprefix = false;
|
||||
|
||||
// Check if all files have the same prefix so that this can be stripped out.
|
||||
// This will only be done if there is either a MAPINFO, ZMAPINFO or GAMEINFO lump in the subdirectory, denoting a ZDoom mod.
|
||||
|
@ -233,32 +234,42 @@ bool FZipFile::Open(bool quiet, LumpFilterInfo* filter)
|
|||
}
|
||||
|
||||
name.ToLower();
|
||||
if (name.IndexOf("filter/") == 0)
|
||||
continue; // 'filter' is a reserved name of the file system.
|
||||
if (name.IndexOf("__macosx") == 0)
|
||||
continue; // skip Apple garbage. At this stage only the root folder matters,
|
||||
if (i == 0)
|
||||
continue; // skip Apple garbage. At this stage only the root folder matters.
|
||||
if (!foundprefix)
|
||||
{
|
||||
// check for special names, if one of these gets found this must be treated as a normal zip.
|
||||
bool isspecial = name.IndexOf("/") < 0 || (filter && filter->reservedFolders.Find(name) < filter->reservedFolders.Size());
|
||||
if (isspecial) break;
|
||||
name0 = name.Left(name.LastIndexOf("/")+1);
|
||||
name1 = name.Left(name.IndexOf("/") + 1);
|
||||
foundprefix = true;
|
||||
}
|
||||
else
|
||||
|
||||
if (name.IndexOf(name0) != 0)
|
||||
{
|
||||
if (name.IndexOf(name0) != 0)
|
||||
if (name1.IsNotEmpty())
|
||||
{
|
||||
name0 = "";
|
||||
break;
|
||||
name0 = name1;
|
||||
if (name.IndexOf(name0) != 0)
|
||||
{
|
||||
name0 = "";
|
||||
}
|
||||
}
|
||||
else if (!foundspeciallump && filter)
|
||||
{
|
||||
// at least one of the more common definition lumps must be present.
|
||||
for (auto &p : filter->requiredPrefixes)
|
||||
{
|
||||
if (name.IndexOf(name0 + p) == 0 || name.LastIndexOf(p) == name.Len() - strlen(p))
|
||||
{
|
||||
foundspeciallump = true;
|
||||
break;
|
||||
}
|
||||
if (name0.IsEmpty())
|
||||
break;
|
||||
}
|
||||
if (!foundspeciallump && filter)
|
||||
{
|
||||
// at least one of the more common definition lumps must be present.
|
||||
for (auto &p : filter->requiredPrefixes)
|
||||
{
|
||||
if (name.IndexOf(name0 + p) == 0 || name.LastIndexOf(p) == ptrdiff_t(name.Len() - strlen(p)))
|
||||
{
|
||||
foundspeciallump = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -113,7 +113,20 @@ struct FileSystem::LumpRecord
|
|||
if (Namespace == ns_hidden) shortName.qword = 0;
|
||||
else
|
||||
{
|
||||
long slash = longName.LastIndexOf('/');
|
||||
ptrdiff_t encodedResID = longName.LastIndexOf(".{");
|
||||
if (resourceId == -1 && encodedResID >= 0)
|
||||
{
|
||||
const char* p = longName.GetChars() + encodedResID;
|
||||
char* q;
|
||||
int id = (int)strtoull(p+2, &q, 10); // only decimal numbers allowed here.
|
||||
if (q[0] == '}' && (q[1] == '.' || q[1] == 0))
|
||||
{
|
||||
FString toDelete(p, q - p + 1);
|
||||
longName.Substitute(toDelete, "");
|
||||
resourceId = id;
|
||||
}
|
||||
}
|
||||
ptrdiff_t slash = longName.LastIndexOf('/');
|
||||
FString base = (slash >= 0) ? longName.Mid(slash + 1) : longName;
|
||||
auto dot = base.LastIndexOf('.');
|
||||
if (dot >= 0) base.Truncate(dot);
|
||||
|
@ -899,6 +912,12 @@ LumpShortName& FileSystem::GetShortName(int i)
|
|||
return FileInfo[i].shortName;
|
||||
}
|
||||
|
||||
FString& FileSystem::GetLongName(int i)
|
||||
{
|
||||
if ((unsigned)i >= NumEntries) I_Error("GetLongName: Invalid index");
|
||||
return FileInfo[i].longName;
|
||||
}
|
||||
|
||||
void FileSystem::RenameFile(int num, const char* newfn)
|
||||
{
|
||||
if ((unsigned)num >= NumEntries) I_Error("RenameFile: Invalid index");
|
||||
|
@ -1533,7 +1552,7 @@ bool FileSystem::CreatePathlessCopy(const char *name, int id, int /*flags*/)
|
|||
if (lump < 0) return false; // Does not exist.
|
||||
|
||||
auto oldlump = FileInfo[lump];
|
||||
int slash = oldlump.longName.LastIndexOf('/');
|
||||
ptrdiff_t slash = oldlump.longName.LastIndexOf('/');
|
||||
|
||||
if (slash == -1)
|
||||
{
|
||||
|
|
|
@ -117,6 +117,7 @@ public:
|
|||
}
|
||||
|
||||
LumpShortName& GetShortName(int i); // may only be called before the hash chains are set up.
|
||||
FString& GetLongName(int i); // may only be called before the hash chains are set up.
|
||||
void RenameFile(int num, const char* fn);
|
||||
bool CreatePathlessCopy(const char* name, int id, int flags);
|
||||
|
||||
|
|
|
@ -349,8 +349,8 @@ void FResourceFile::PostProcessArchive(void *lumps, size_t lumpsize, LumpFilterI
|
|||
uint32_t max = NumLumps;
|
||||
max -= FilterLumpsByGameType(filter, lumps, lumpsize, max);
|
||||
|
||||
long len;
|
||||
int lastpos = -1;
|
||||
ptrdiff_t len;
|
||||
ptrdiff_t lastpos = -1;
|
||||
FString file;
|
||||
FString LumpFilter = filter->dotFilter;
|
||||
while ((len = LumpFilter.IndexOf('.', lastpos+1)) > 0)
|
||||
|
|
|
@ -437,7 +437,7 @@ void FFont::ReadSheetFont(TArray<FolderEntry> &folderdata, int width, int height
|
|||
Chars[i].OriginalPic->CopySize(*lump, true);
|
||||
if (Chars[i].OriginalPic != *lump) TexMan.AddGameTexture(Chars[i].OriginalPic);
|
||||
}
|
||||
Chars[i].XMove = width;
|
||||
Chars[i].XMove = int(width / Scale.X);
|
||||
}
|
||||
|
||||
if (map1252)
|
||||
|
@ -570,6 +570,32 @@ void RecordTextureColors (FImageSource *pic, uint32_t *usedcolors)
|
|||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// RecordLuminosity
|
||||
//
|
||||
// Records minimum and maximum luminosity of a texture.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void RecordLuminosity(FImageSource* pic, int* minlum, int* maxlum)
|
||||
{
|
||||
auto bitmap = pic->GetCachedBitmap(nullptr, FImageSource::normal);
|
||||
auto pixels = bitmap.GetPixels();
|
||||
auto size = pic->GetWidth() * pic->GetHeight();
|
||||
|
||||
for (int x = 0; x < size; x++)
|
||||
{
|
||||
int xx = x * 4;
|
||||
if (pixels[xx + 3] > 0)
|
||||
{
|
||||
int lum = Luminance(pixels[xx + 2], pixels[xx + 1], pixels[xx]);
|
||||
if (lum < *minlum) *minlum = lum;
|
||||
if (lum > *maxlum) *maxlum = lum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// RecordAllTextureColors
|
||||
|
@ -660,7 +686,7 @@ int FFont::GetColorTranslation (EColorRange range, PalEntry *color) const
|
|||
{
|
||||
// Single pic fonts do not set up their translation table and must always return 0.
|
||||
if (Translations.Size() == 0) return 0;
|
||||
assert(Translations.Size() == NumTextColors);
|
||||
assert(Translations.Size() == (unsigned)NumTextColors);
|
||||
|
||||
if (noTranslate)
|
||||
{
|
||||
|
@ -969,27 +995,22 @@ int FFont::GetMaxAscender(const uint8_t* string) const
|
|||
void FFont::LoadTranslations()
|
||||
{
|
||||
unsigned int count = min<unsigned>(Chars.Size(), LastChar - FirstChar + 1);
|
||||
uint32_t usedcolors[256] = {};
|
||||
TArray<double> Luminosity;
|
||||
|
||||
if (count == 0) return;
|
||||
int minlum = 255, maxlum = 0;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
if (Chars[i].OriginalPic)
|
||||
{
|
||||
auto pic = Chars[i].OriginalPic->GetTexture()->GetImage();
|
||||
if (pic) RecordTextureColors(pic, usedcolors);
|
||||
RecordLuminosity(pic, &minlum, &maxlum);
|
||||
}
|
||||
}
|
||||
|
||||
int minlum = 0, maxlum = 0;
|
||||
GetLuminosity (usedcolors, Luminosity, &minlum, &maxlum);
|
||||
if (MinLum >= 0 && MinLum < minlum) minlum = MinLum;
|
||||
if (MaxLum > maxlum) maxlum = MaxLum;
|
||||
|
||||
// Here we can set everything to a luminosity translation.
|
||||
|
||||
// Create different translations for different color ranges
|
||||
Translations.Resize(NumTextColors);
|
||||
for (int i = 0; i < NumTextColors; i++)
|
||||
{
|
||||
|
|
|
@ -407,6 +407,7 @@ void FSingleLumpFont::LoadBMF(int lump, const uint8_t *data)
|
|||
count = LastChar - FirstChar + 1;
|
||||
Chars.Resize(count);
|
||||
// BMF palettes are only six bits per component. Fix that.
|
||||
Palette[0] = 0;
|
||||
for (i = 0; i < ActiveColors; ++i)
|
||||
{
|
||||
int r = (data[17 + i * 3] << 2) | (data[17 + i * 3] >> 4);
|
||||
|
@ -526,7 +527,7 @@ void FSingleLumpFont::FixupPalette (uint8_t *identity, const PalEntry *palette,
|
|||
double minlum = 100000000.0;
|
||||
|
||||
identity[0] = 0;
|
||||
palette += 3; // Skip the transparent color
|
||||
palette++; // Skip the transparent color
|
||||
|
||||
for (int i = 1; i < ActiveColors; ++i, palette ++)
|
||||
{
|
||||
|
|
|
@ -94,6 +94,7 @@ FFont *V_GetFont(const char *name, const char *fontlumpname)
|
|||
{
|
||||
if (!stricmp(name, "DBIGFONT")) name = "BigFont";
|
||||
else if (!stricmp(name, "CONFONT")) name = "ConsoleFont"; // several mods have used the name CONFONT directly and effectively duplicated the font.
|
||||
else if (!stricmp(name, "INDEXFON")) name = "IndexFont"; // Same here - for whatever reason some people had to use its 8 character name...
|
||||
FFont *font = FFont::FindFont (name);
|
||||
if (font == nullptr)
|
||||
{
|
||||
|
@ -415,19 +416,19 @@ void V_InitFontColors ()
|
|||
else if (sc.Compare ("Flat:"))
|
||||
{
|
||||
sc.MustGetString();
|
||||
logcolor = V_GetColor (nullptr, sc);
|
||||
logcolor = V_GetColor (sc);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get first color
|
||||
c = V_GetColor (nullptr, sc);
|
||||
c = V_GetColor (sc);
|
||||
tparm.Start[0] = RPART(c);
|
||||
tparm.Start[1] = GPART(c);
|
||||
tparm.Start[2] = BPART(c);
|
||||
|
||||
// Get second color
|
||||
sc.MustGetString();
|
||||
c = V_GetColor (nullptr, sc);
|
||||
c = V_GetColor (sc);
|
||||
tparm.End[0] = RPART(c);
|
||||
tparm.End[1] = GPART(c);
|
||||
tparm.End[2] = BPART(c);
|
||||
|
@ -681,13 +682,13 @@ void V_ApplyLuminosityTranslation(int translation, uint8_t* pixel, int size)
|
|||
int index = clamp(lumadjust, 0, 255);
|
||||
PalEntry newcol = remap[index];
|
||||
// extend the range if we find colors outside what initial analysis provided.
|
||||
if (gray < lum_min)
|
||||
if (gray < lum_min && lum_min != 0)
|
||||
{
|
||||
newcol.r = newcol.r * gray / lum_min;
|
||||
newcol.g = newcol.g * gray / lum_min;
|
||||
newcol.b = newcol.b * gray / lum_min;
|
||||
}
|
||||
else if (gray > lum_max)
|
||||
else if (gray > lum_max && lum_max != 0)
|
||||
{
|
||||
newcol.r = clamp(newcol.r * gray / lum_max, 0, 255);
|
||||
newcol.g = clamp(newcol.g * gray / lum_max, 0, 255);
|
||||
|
@ -873,6 +874,7 @@ void V_InitFonts()
|
|||
NewSmallFont = CreateHexLumpFont2("NewSmallFont", lump);
|
||||
CurrentConsoleFont = NewConsoleFont;
|
||||
ConFont = V_GetFont("ConsoleFont", "CONFONT");
|
||||
V_GetFont("IndexFont", "INDEXFON"); // detect potential replacements for this one.
|
||||
}
|
||||
|
||||
void V_LoadTranslations()
|
||||
|
@ -958,28 +960,3 @@ char* CleanseString(char* str)
|
|||
return str;
|
||||
}
|
||||
|
||||
|
||||
#include "c_dispatch.h"
|
||||
FGameTexture* GetBaseForChar(FGameTexture* t);
|
||||
CCMD(dumpfonts)
|
||||
{
|
||||
for (auto c : { "tilesmallfont", "tilebigfont", "smallfont2", "digifont", "indexfont" })
|
||||
{
|
||||
auto f = V_GetFont(c);
|
||||
if (f)
|
||||
{
|
||||
Printf("%s\n{\n", c);
|
||||
for (int i = 33; i < 127; i++)
|
||||
{
|
||||
auto ch = f->GetChar(i, CR_UNDEFINED, nullptr);
|
||||
if (ch)
|
||||
{
|
||||
ch = GetBaseForChar(ch);
|
||||
if (i == 34) Printf("\t\"\\\""); else Printf("\t%c", i);
|
||||
Printf(" %s\n", ch->GetName().GetChars());
|
||||
}
|
||||
}
|
||||
Printf("}\n\n");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -88,7 +88,7 @@ TArray<FBrokenLines> V_BreakLines (FFont *font, int maxwidth, const uint8_t *str
|
|||
{
|
||||
if (*string == '[')
|
||||
{
|
||||
const uint8_t *start = string;
|
||||
const uint8_t* start = string;
|
||||
while (*string != ']' && *string != '\0')
|
||||
{
|
||||
string++;
|
||||
|
@ -97,11 +97,6 @@ TArray<FBrokenLines> V_BreakLines (FFont *font, int maxwidth, const uint8_t *str
|
|||
{
|
||||
string++;
|
||||
}
|
||||
lastcolor = FString((const char *)start, string - start);
|
||||
}
|
||||
else
|
||||
{
|
||||
lastcolor = *string++;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
|
@ -130,6 +125,33 @@ TArray<FBrokenLines> V_BreakLines (FFont *font, int maxwidth, const uint8_t *str
|
|||
}
|
||||
|
||||
auto index = Lines.Reserve(1);
|
||||
for (const uint8_t* pos = start; pos < space; pos++)
|
||||
{
|
||||
if (*pos == TEXTCOLOR_ESCAPE)
|
||||
{
|
||||
pos++;
|
||||
if (*pos)
|
||||
{
|
||||
if (*pos == '[')
|
||||
{
|
||||
const uint8_t* cstart = pos;
|
||||
while (*pos != ']' && *pos != '\0')
|
||||
{
|
||||
pos++;
|
||||
}
|
||||
if (*pos != '\0')
|
||||
{
|
||||
pos++;
|
||||
}
|
||||
lastcolor = FString((const char*)cstart, pos - cstart);
|
||||
}
|
||||
else
|
||||
{
|
||||
lastcolor = *pos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
breakit (&Lines[index], font, start, space, linecolor);
|
||||
if (c == '\n' && !preservecolor)
|
||||
{
|
||||
|
|
|
@ -1036,6 +1036,7 @@ DEFINE_FIELD(DListMenuDescriptor, mFont)
|
|||
DEFINE_FIELD(DListMenuDescriptor, mFontColor)
|
||||
DEFINE_FIELD(DListMenuDescriptor, mFontColor2)
|
||||
DEFINE_FIELD(DListMenuDescriptor, mAnimatedTransition)
|
||||
DEFINE_FIELD(DListMenuDescriptor, mAnimated)
|
||||
DEFINE_FIELD(DListMenuDescriptor, mCenter)
|
||||
DEFINE_FIELD(DListMenuDescriptor, mVirtWidth)
|
||||
DEFINE_FIELD(DListMenuDescriptor, mVirtHeight)
|
||||
|
@ -1066,6 +1067,7 @@ DEFINE_FIELD(DImageScrollerDescriptor, textBackgroundBrightness)
|
|||
DEFINE_FIELD(DImageScrollerDescriptor,textFont)
|
||||
DEFINE_FIELD(DImageScrollerDescriptor, textScale)
|
||||
DEFINE_FIELD(DImageScrollerDescriptor, mAnimatedTransition)
|
||||
DEFINE_FIELD(DImageScrollerDescriptor, mAnimated)
|
||||
DEFINE_FIELD(DImageScrollerDescriptor, virtWidth)
|
||||
DEFINE_FIELD(DImageScrollerDescriptor, virtHeight)
|
||||
|
||||
|
|
|
@ -141,6 +141,7 @@ public:
|
|||
FFont *textFont;
|
||||
double textScale;
|
||||
bool mAnimatedTransition;
|
||||
bool mAnimated;
|
||||
int virtWidth, virtHeight;
|
||||
|
||||
};
|
||||
|
|
|
@ -348,6 +348,10 @@ static void DoParseListMenuBody(FScanner &sc, DListMenuDescriptor *desc, bool &s
|
|||
{
|
||||
desc->mAnimatedTransition = true;
|
||||
}
|
||||
else if (sc.Compare("animated"))
|
||||
{
|
||||
desc->mAnimated = true;
|
||||
}
|
||||
else if (sc.Compare("MouseWindow"))
|
||||
{
|
||||
sc.MustGetNumber();
|
||||
|
@ -463,7 +467,7 @@ static void DoParseListMenuBody(FScanner &sc, DListMenuDescriptor *desc, bool &s
|
|||
}
|
||||
else if (args[i] == TypeColor)
|
||||
{
|
||||
params.Push(V_GetColor(nullptr, sc));
|
||||
params.Push(V_GetColor(sc));
|
||||
}
|
||||
else if (args[i] == TypeFont)
|
||||
{
|
||||
|
@ -910,7 +914,7 @@ static void ParseOptionSettings(FScanner &sc)
|
|||
else if (sc.Compare("Linespacing"))
|
||||
{
|
||||
sc.MustGetNumber();
|
||||
OptionSettings.mLinespacing = sc.Number;
|
||||
// ignored
|
||||
}
|
||||
else if (sc.Compare("LabelOffset"))
|
||||
{
|
||||
|
@ -1032,7 +1036,7 @@ static void ParseOptionMenuBody(FScanner &sc, DOptionMenuDescriptor *desc, int i
|
|||
}
|
||||
else if (args[i] == TypeColor)
|
||||
{
|
||||
params.Push(V_GetColor(nullptr, sc));
|
||||
params.Push(V_GetColor(sc));
|
||||
}
|
||||
else if (args[i]->isIntCompatible())
|
||||
{
|
||||
|
@ -1216,6 +1220,10 @@ static void ParseImageScrollerBody(FScanner& sc, DImageScrollerDescriptor* desc)
|
|||
{
|
||||
desc->mAnimatedTransition = true;
|
||||
}
|
||||
else if (sc.Compare("animated"))
|
||||
{
|
||||
desc->mAnimated = true;
|
||||
}
|
||||
else if (sc.Compare("textBackground"))
|
||||
{
|
||||
sc.MustGetString();
|
||||
|
@ -1278,7 +1286,7 @@ static void ParseImageScrollerBody(FScanner& sc, DImageScrollerDescriptor* desc)
|
|||
}
|
||||
else if (args[i] == TypeColor)
|
||||
{
|
||||
params.Push(V_GetColor(nullptr, sc));
|
||||
params.Push(V_GetColor(sc));
|
||||
}
|
||||
else if (args[i]->isIntCompatible())
|
||||
{
|
||||
|
@ -1398,6 +1406,7 @@ void M_ParseMenuDefs()
|
|||
DefaultOptionMenuSettings = Create<DOptionMenuDescriptor>();
|
||||
DefaultListMenuSettings->Reset();
|
||||
DefaultOptionMenuSettings->Reset();
|
||||
OptionSettings.mLinespacing = 17;
|
||||
|
||||
int IWADMenu = fileSystem.CheckNumForName("MENUDEF", ns_global, fileSystem.GetIwadNum());
|
||||
|
||||
|
|
|
@ -90,8 +90,8 @@ static int FindGFXFile(FString & fn)
|
|||
if (lump != -1) return lump;
|
||||
|
||||
int best = -1;
|
||||
int dot = fn.LastIndexOf('.');
|
||||
int slash = fn.LastIndexOf('/');
|
||||
auto dot = fn.LastIndexOf('.');
|
||||
auto slash = fn.LastIndexOf('/');
|
||||
if (dot > slash) fn.Truncate(dot);
|
||||
|
||||
static const char * extensions[] = { ".png", ".jpg", ".tga", ".pcx", nullptr };
|
||||
|
|
|
@ -44,8 +44,8 @@ bool FOBJModel::Load(const char* fn, int lumpnum, const char* buffer, int length
|
|||
{
|
||||
// Ensure usemtl statements remain intact
|
||||
TArray<FString> mtlUsages;
|
||||
TArray<long> mtlUsageIdxs;
|
||||
long bpos = 0, nlpos = 0, slashpos = 0;
|
||||
TArray<ptrdiff_t> mtlUsageIdxs;
|
||||
ptrdiff_t bpos = 0, nlpos = 0, slashpos = 0;
|
||||
while (1)
|
||||
{
|
||||
bpos = objBuf.IndexOf("\nusemtl", bpos);
|
||||
|
@ -58,7 +58,7 @@ bool FOBJModel::Load(const char* fn, int lumpnum, const char* buffer, int length
|
|||
}
|
||||
if (nlpos == -1)
|
||||
{
|
||||
nlpos = (long)objBuf.Len();
|
||||
nlpos = objBuf.Len();
|
||||
}
|
||||
FString lineStr(objBuf.GetChars() + bpos, nlpos - bpos);
|
||||
mtlUsages.Push(lineStr);
|
||||
|
@ -76,7 +76,7 @@ bool FOBJModel::Load(const char* fn, int lumpnum, const char* buffer, int length
|
|||
nlpos = objBuf.IndexOf('\n', bpos);
|
||||
if (nlpos == -1)
|
||||
{
|
||||
nlpos = (long)objBuf.Len();
|
||||
nlpos = objBuf.Len();
|
||||
}
|
||||
memcpy(wObjBuf + bpos, mtlUsages[i].GetChars(), nlpos - bpos);
|
||||
}
|
||||
|
@ -240,13 +240,12 @@ bool FOBJModel::Load(const char* fn, int lumpnum, const char* buffer, int length
|
|||
*/
|
||||
template<typename T, size_t L> void FOBJModel::ParseVector(TArray<T> &array)
|
||||
{
|
||||
float coord[L];
|
||||
for (size_t axis = 0; axis < L; axis++)
|
||||
T vec;
|
||||
for (unsigned axis = 0; axis < L; axis++)
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
coord[axis] = (float)sc.Float;
|
||||
vec[axis] = (float)sc.Float;
|
||||
}
|
||||
T vec(coord);
|
||||
array.Push(vec);
|
||||
}
|
||||
|
||||
|
|
|
@ -210,8 +210,8 @@ void FVoxelModel::AddFace(int x1, int y1, int z1, int x2, int y2, int z2, int x3
|
|||
unsigned int indx[4];
|
||||
|
||||
vert.packedNormal = 0; // currently this is not being used for voxels.
|
||||
vert.u = (((col & 15) * 255 / 16) + 7) / 255.f;
|
||||
vert.v = (((col / 16) * 255 / 16) + 7) / 255.f;
|
||||
vert.u = (((col & 15) + 0.5f) / 16.f);
|
||||
vert.v = (((col / 16) + 0.5f) / 16.f);
|
||||
|
||||
vert.x = x1 - PivotX;
|
||||
vert.z = -y1 + PivotY;
|
||||
|
|
|
@ -74,7 +74,7 @@ static uint8_t *GetVoxelRemap(const uint8_t *pal)
|
|||
{
|
||||
// The voxel palette uses VGA colors, so we have to expand it
|
||||
// from 6 to 8 bits per component.
|
||||
remap[i] = BestColor((uint32_t *)GPalette.BaseColors,
|
||||
remap[i] = ColorMatcher.Pick(
|
||||
(oldpal[i*3 + 0] << 2) | (oldpal[i*3 + 0] >> 4),
|
||||
(oldpal[i*3 + 1] << 2) | (oldpal[i*3 + 1] >> 4),
|
||||
(oldpal[i*3 + 2] << 2) | (oldpal[i*3 + 2] >> 4));
|
||||
|
|
|
@ -229,6 +229,7 @@ DObject::DObject ()
|
|||
ObjNext = GC::Root;
|
||||
GCNext = nullptr;
|
||||
GC::Root = this;
|
||||
GC::AllocCount++;
|
||||
}
|
||||
|
||||
DObject::DObject (PClass *inClass)
|
||||
|
@ -238,6 +239,7 @@ DObject::DObject (PClass *inClass)
|
|||
ObjNext = GC::Root;
|
||||
GCNext = nullptr;
|
||||
GC::Root = this;
|
||||
GC::AllocCount++;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -275,6 +277,7 @@ DObject::~DObject ()
|
|||
|
||||
void DObject::Release()
|
||||
{
|
||||
if (GC::AllocCount > 0) GC::AllocCount--;
|
||||
DObject **probe;
|
||||
|
||||
// Unlink this object from the GC list.
|
||||
|
|
|
@ -108,6 +108,7 @@ namespace GC
|
|||
size_t AllocBytes;
|
||||
size_t Threshold;
|
||||
size_t Estimate;
|
||||
size_t AllocCount;
|
||||
DObject *Gray;
|
||||
DObject *Root;
|
||||
DObject *SoftRoots;
|
||||
|
|
|
@ -43,6 +43,9 @@ namespace GC
|
|||
// Number of bytes currently allocated through M_Malloc/M_Realloc.
|
||||
extern size_t AllocBytes;
|
||||
|
||||
// Number of allocated objects since last CheckGC call.
|
||||
extern size_t AllocCount;
|
||||
|
||||
// Amount of memory to allocate before triggering a collection.
|
||||
extern size_t Threshold;
|
||||
|
||||
|
@ -105,10 +108,15 @@ namespace GC
|
|||
}
|
||||
|
||||
// Check if it's time to collect, and do a collection step if it is.
|
||||
static inline void CheckGC()
|
||||
static inline bool CheckGC()
|
||||
{
|
||||
AllocCount = 0;
|
||||
if (AllocBytes >= Threshold)
|
||||
{
|
||||
Step();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Forces a collection to start now.
|
||||
|
@ -175,7 +183,7 @@ public:
|
|||
TObjPtr() = default;
|
||||
TObjPtr(const TObjPtr<T> &q) = default;
|
||||
|
||||
TObjPtr(T q) throw()
|
||||
TObjPtr(T q) noexcept
|
||||
: pp(q)
|
||||
{
|
||||
}
|
||||
|
@ -207,35 +215,35 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
T Get() throw()
|
||||
T Get() noexcept
|
||||
{
|
||||
return GC::ReadBarrier(pp);
|
||||
}
|
||||
|
||||
T ForceGet() throw() //for situations where the read barrier needs to be skipped.
|
||||
T ForceGet() noexcept //for situations where the read barrier needs to be skipped.
|
||||
{
|
||||
return pp;
|
||||
}
|
||||
|
||||
operator T() throw()
|
||||
operator T() noexcept
|
||||
{
|
||||
return GC::ReadBarrier(pp);
|
||||
}
|
||||
T &operator*()
|
||||
T &operator*() noexcept
|
||||
{
|
||||
T q = GC::ReadBarrier(pp);
|
||||
assert(q != NULL);
|
||||
return *q;
|
||||
}
|
||||
T operator->() throw()
|
||||
T operator->() noexcept
|
||||
{
|
||||
return GC::ReadBarrier(pp);
|
||||
}
|
||||
bool operator!=(T u) throw()
|
||||
bool operator!=(T u) noexcept
|
||||
{
|
||||
return GC::ReadBarrier(o) != u;
|
||||
}
|
||||
bool operator==(T u) throw()
|
||||
bool operator==(T u) noexcept
|
||||
{
|
||||
return GC::ReadBarrier(o) == u;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "s_soundinternal.h"
|
||||
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "c_console.h"
|
||||
#include "c_cvars.h"
|
||||
|
@ -89,20 +90,83 @@ struct NSOperatingSystemVersion
|
|||
|
||||
#endif // before 10.10
|
||||
|
||||
static bool ReadSystemVersionFromPlist(NSOperatingSystemVersion& version)
|
||||
{
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < 110000
|
||||
// The version returned by macOS depends on the SDK which the software has been built against.
|
||||
// When built against the 10.15 SDK or earlier, Big Sur returns 10.16 for compatibility with previous numbering.
|
||||
// When built against the 11.0 SDK, it returns 11.0 for forward compatibility.
|
||||
// https://eclecticlight.co/2020/08/13/macos-version-numbering-isnt-so-simple/
|
||||
|
||||
// It's impossible to load real SystemVersion.plist when linking with old SDK, i.e. when building for Intel CPU
|
||||
// Any attempt to read this file is redirected to SystemVersionCompat.plist silently
|
||||
// Workaround with the external process is needed in order to report correct macOS version
|
||||
|
||||
const char *const plistPath = "/System/Library/CoreServices/SystemVersion.plist";
|
||||
struct stat dummy;
|
||||
|
||||
if (stat(plistPath, &dummy) != 0)
|
||||
return false;
|
||||
|
||||
char commandLine[1024] = {};
|
||||
snprintf(commandLine, sizeof commandLine, "defaults read %s ProductVersion", plistPath);
|
||||
|
||||
FILE *const versionFile = popen(commandLine, "r");
|
||||
|
||||
if (versionFile == nullptr)
|
||||
return false;
|
||||
|
||||
NSOperatingSystemVersion plistVersion = {};
|
||||
char versionString[256] = {};
|
||||
|
||||
if (fgets(versionString, sizeof versionString, versionFile))
|
||||
{
|
||||
plistVersion.majorVersion = atoi(versionString);
|
||||
|
||||
if (const char *minorVersionString = strstr(versionString, "."))
|
||||
{
|
||||
minorVersionString++;
|
||||
plistVersion.minorVersion = atoi(minorVersionString);
|
||||
|
||||
if (const char *patchVersionString = strstr(minorVersionString, "."))
|
||||
{
|
||||
patchVersionString++;
|
||||
plistVersion.patchVersion = atoi(patchVersionString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(versionFile);
|
||||
|
||||
if (plistVersion.majorVersion != 0)
|
||||
{
|
||||
version = plistVersion;
|
||||
return true;
|
||||
}
|
||||
#endif // MAC_OS_X_VERSION_MAX_ALLOWED < 110000
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void I_DetectOS()
|
||||
{
|
||||
NSOperatingSystemVersion version = {};
|
||||
NSProcessInfo* const processInfo = [NSProcessInfo processInfo];
|
||||
|
||||
if ([processInfo respondsToSelector:@selector(operatingSystemVersion)])
|
||||
if (!ReadSystemVersionFromPlist(version))
|
||||
{
|
||||
version = [processInfo operatingSystemVersion];
|
||||
NSProcessInfo *const processInfo = [NSProcessInfo processInfo];
|
||||
|
||||
if ([processInfo respondsToSelector:@selector(operatingSystemVersion)])
|
||||
{
|
||||
version = [processInfo operatingSystemVersion];
|
||||
}
|
||||
}
|
||||
|
||||
const char* name = "Unknown version";
|
||||
|
||||
if (10 == version.majorVersion)
|
||||
switch (version.majorVersion)
|
||||
{
|
||||
case 10:
|
||||
switch (version.minorVersion)
|
||||
{
|
||||
case 9: name = "OS X Mavericks"; break;
|
||||
|
@ -114,13 +178,13 @@ void I_DetectOS()
|
|||
case 15: name = "macOS Catalina"; break;
|
||||
case 16: name = "macOS Big Sur"; break;
|
||||
}
|
||||
}
|
||||
else if (11 == version.majorVersion)
|
||||
{
|
||||
switch (version.minorVersion)
|
||||
{
|
||||
case 0: name = "macOS Big Sur"; break;
|
||||
}
|
||||
break;
|
||||
case 11:
|
||||
name = "macOS Big Sur";
|
||||
break;
|
||||
case 12:
|
||||
name = "macOS Monterey";
|
||||
break;
|
||||
}
|
||||
|
||||
char release[16] = "unknown";
|
||||
|
|
|
@ -52,8 +52,11 @@
|
|||
#include "v_text.h"
|
||||
#include "version.h"
|
||||
#include "printf.h"
|
||||
|
||||
#include "gl_framebuffer.h"
|
||||
#ifdef HAVE_GLES2
|
||||
#include "gles_framebuffer.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_VULKAN
|
||||
#include "vulkan/system/vk_framebuffer.h"
|
||||
#endif
|
||||
|
@ -462,7 +465,12 @@ public:
|
|||
|
||||
if (fb == nullptr)
|
||||
{
|
||||
fb = new OpenGLRenderer::OpenGLFrameBuffer(0, vid_fullscreen);
|
||||
#ifdef HAVE_GLES2
|
||||
if( (Args->CheckParm ("-gles2_renderer")) || (vid_preferbackend == 3) )
|
||||
fb = new OpenGLESRenderer::OpenGLFrameBuffer(0, vid_fullscreen);
|
||||
else
|
||||
#endif
|
||||
fb = new OpenGLRenderer::OpenGLFrameBuffer(0, vid_fullscreen);
|
||||
}
|
||||
|
||||
fb->SetWindow(ms_window);
|
||||
|
|
|
@ -46,6 +46,8 @@ TArray<FString> I_GetSteamPath();
|
|||
|
||||
TArray<FString> I_GetGogPaths();
|
||||
|
||||
TArray<FString> I_GetBethesdaPath();
|
||||
|
||||
// The ini could not be saved at exit
|
||||
bool I_WriteIniFailed ();
|
||||
|
||||
|
|
|
@ -50,3 +50,9 @@ TArray<FString> I_GetGogPaths()
|
|||
// GOG's Doom games are Windows only at the moment
|
||||
return TArray<FString>();
|
||||
}
|
||||
|
||||
TArray<FString> I_GetBethesdaPath()
|
||||
{
|
||||
// Bethesda.net Launcher is Windows only at the moment
|
||||
return TArray<FString>();
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ void Mac_I_FatalError(const char* errortext);
|
|||
void Unix_I_FatalError(const char* errortext)
|
||||
{
|
||||
// Close window or exit fullscreen and release mouse capture
|
||||
SDL_Quit();
|
||||
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
||||
|
||||
const char *str;
|
||||
if((str=getenv("KDE_FULL_SESSION")) && strcmp(str, "true") == 0)
|
||||
|
@ -204,7 +204,7 @@ void I_PrintStr(const char *cp)
|
|||
{ // gray
|
||||
if (v < 0.33) attrib = 0x8;
|
||||
else if (v < 0.90) attrib = 0x7;
|
||||
else attrib = 0x15;
|
||||
else attrib = 0xF;
|
||||
}
|
||||
|
||||
printData.AppendFormat("\033[%um",((attrib & 0x8) ? 90 : 30) + (attrib & 0x7));
|
||||
|
|
|
@ -50,7 +50,10 @@
|
|||
|
||||
#include "gl_renderer.h"
|
||||
#include "gl_framebuffer.h"
|
||||
|
||||
#ifdef HAVE_GLES2
|
||||
#include "gles_framebuffer.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_VULKAN
|
||||
#include "vulkan/system/vk_framebuffer.h"
|
||||
#endif
|
||||
|
@ -115,8 +118,6 @@ CCMD(vid_list_sdl_render_drivers)
|
|||
|
||||
namespace Priv
|
||||
{
|
||||
static const uint32_t VulkanWindowFlag = SDL_WINDOW_VULKAN;
|
||||
|
||||
SDL_Window *window;
|
||||
bool vulkanEnabled;
|
||||
bool softpolyEnabled;
|
||||
|
@ -149,6 +150,8 @@ namespace Priv
|
|||
{
|
||||
// Enforce minimum size limit
|
||||
SDL_SetWindowMinimumSize(Priv::window, VID_MIN_WIDTH, VID_MIN_HEIGHT);
|
||||
// Tell SDL to start sending text input on Wayland.
|
||||
if (strncasecmp(SDL_GetCurrentVideoDriver(), "wayland", 7) == 0) SDL_StartTextInput();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -408,7 +411,7 @@ SDLVideo::SDLVideo ()
|
|||
|
||||
if (Priv::vulkanEnabled)
|
||||
{
|
||||
Priv::CreateWindow(Priv::VulkanWindowFlag | SDL_WINDOW_HIDDEN);
|
||||
Priv::CreateWindow(SDL_WINDOW_VULKAN | SDL_WINDOW_HIDDEN | (vid_fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0));
|
||||
|
||||
if (Priv::window == nullptr)
|
||||
{
|
||||
|
@ -470,7 +473,12 @@ DFrameBuffer *SDLVideo::CreateFrameBuffer ()
|
|||
#endif
|
||||
if (fb == nullptr)
|
||||
{
|
||||
fb = new OpenGLRenderer::OpenGLFrameBuffer(0, vid_fullscreen);
|
||||
#ifdef HAVE_GLES2
|
||||
if( (Args->CheckParm ("-gles2_renderer")) || (vid_preferbackend == 3) )
|
||||
fb = new OpenGLESRenderer::OpenGLFrameBuffer(0, vid_fullscreen);
|
||||
else
|
||||
#endif
|
||||
fb = new OpenGLRenderer::OpenGLFrameBuffer(0, vid_fullscreen);
|
||||
}
|
||||
|
||||
return fb;
|
||||
|
|
|
@ -71,7 +71,7 @@ PFNWGLSWAPINTERVALEXTPROC myWglSwapIntervalExtProc;
|
|||
|
||||
SystemGLFrameBuffer::SystemGLFrameBuffer(void *hMonitor, bool fullscreen) : SystemBaseFrameBuffer(hMonitor, fullscreen)
|
||||
{
|
||||
if (!static_cast<Win32GLVideo *>(Video)->InitHardware(Window, 0))
|
||||
if (!static_cast<Win32GLVideo*>(Video)->InitHardware(Window, 0))
|
||||
{
|
||||
I_FatalError("Unable to initialize OpenGL");
|
||||
return;
|
||||
|
|
|
@ -545,6 +545,20 @@ LRESULT CALLBACK LConProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
bool restartrequest;
|
||||
|
||||
void CheckForRestart()
|
||||
{
|
||||
if (restartrequest)
|
||||
{
|
||||
HMODULE hModule = GetModuleHandleW(NULL);
|
||||
WCHAR path[MAX_PATH];
|
||||
GetModuleFileNameW(hModule, path, MAX_PATH);
|
||||
ShellExecuteW(NULL, L"open", path, GetCommandLineW(), NULL, SW_SHOWNORMAL);
|
||||
}
|
||||
restartrequest = false;
|
||||
}
|
||||
|
||||
INT_PTR CALLBACK ErrorPaneProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (msg)
|
||||
|
@ -559,11 +573,7 @@ INT_PTR CALLBACK ErrorPaneProc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lPara
|
|||
{
|
||||
if (LOWORD(wParam) == IDC_BUTTON1) // we pressed the restart button, so run GZDoom again
|
||||
{
|
||||
HMODULE hModule = GetModuleHandleW(NULL);
|
||||
WCHAR path[MAX_PATH];
|
||||
GetModuleFileNameW(hModule, path, MAX_PATH);
|
||||
|
||||
ShellExecuteW(NULL, L"open", path, GetCommandLineW(), NULL, SW_SHOWNORMAL);
|
||||
restartrequest = true;
|
||||
}
|
||||
PostQuitMessage (0);
|
||||
return TRUE;
|
||||
|
@ -969,6 +979,8 @@ int DoMain (HINSTANCE hInstance)
|
|||
atexit (UnCOM);
|
||||
|
||||
int ret = GameMain ();
|
||||
CheckForRestart();
|
||||
|
||||
DestroyCustomCursor();
|
||||
if (ret == 1337) // special exit code for 'norun'.
|
||||
{
|
||||
|
|
|
@ -74,16 +74,36 @@ bool UseKnownFolders()
|
|||
{
|
||||
return !iswritable;
|
||||
}
|
||||
std::wstring testpath = progdir.WideString() + L"writest";
|
||||
file = CreateFile(testpath.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL,
|
||||
CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL);
|
||||
if (file != INVALID_HANDLE_VALUE)
|
||||
// Consider 'Program Files' read only without actually checking.
|
||||
bool found = false;
|
||||
for (auto p : { L"ProgramFiles", L"ProgramFiles(x86)" })
|
||||
{
|
||||
CloseHandle(file);
|
||||
if (!batchrun) Printf("Using program directory for storage\n");
|
||||
iswritable = true;
|
||||
return false;
|
||||
wchar_t buffer1[256];
|
||||
if (GetEnvironmentVariable(p, buffer1, 256))
|
||||
{
|
||||
FString envpath(buffer1);
|
||||
FixPathSeperator(envpath);
|
||||
if (progdir.MakeLower().IndexOf(envpath.MakeLower()) == 0)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
std::wstring testpath = progdir.WideString() + L"writest";
|
||||
file = CreateFile(testpath.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL,
|
||||
CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL);
|
||||
if (file != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
CloseHandle(file);
|
||||
if (!batchrun) Printf("Using program directory for storage\n");
|
||||
iswritable = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!batchrun) Printf("Using known folders for storage\n");
|
||||
iswritable = false;
|
||||
|
|
|
@ -199,7 +199,7 @@ void I_DetectOS(void)
|
|||
}
|
||||
else if (info.dwMajorVersion == 10)
|
||||
{
|
||||
osname = (info.wProductType == VER_NT_WORKSTATION) ? "10 (or higher)" : "Server 2016 (or higher)";
|
||||
osname = (info.wProductType == VER_NT_WORKSTATION) ? (info.dwBuildNumber >= 22000 ? "11 (or higher)" : "10") : "Server 2016 (or higher)";
|
||||
sys_ostype = 3; // modern OS
|
||||
}
|
||||
break;
|
||||
|
@ -510,7 +510,6 @@ 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, IDC_WELCOME_FULLSCREEN, BM_SETCHECK, vid_fullscreen ? BST_CHECKED : BST_UNCHECKED, 0 );
|
||||
switch (vid_preferbackend)
|
||||
{
|
||||
|
@ -520,6 +519,11 @@ BOOL CALLBACK IWADBoxCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lPa
|
|||
case 2:
|
||||
SendDlgItemMessage( hDlg, IDC_WELCOME_VULKAN3, BM_SETCHECK, BST_CHECKED, 0 );
|
||||
break;
|
||||
#ifdef HAVE_GLES2
|
||||
case 3:
|
||||
SendDlgItemMessage( hDlg, IDC_WELCOME_VULKAN4, BM_SETCHECK, BST_CHECKED, 0 );
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
SendDlgItemMessage( hDlg, IDC_WELCOME_VULKAN1, BM_SETCHECK, BST_CHECKED, 0 );
|
||||
break;
|
||||
|
@ -574,6 +578,11 @@ BOOL CALLBACK IWADBoxCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lPa
|
|||
SetQueryIWad(hDlg);
|
||||
// [SP] Upstreamed from Zandronum
|
||||
vid_fullscreen = SendDlgItemMessage( hDlg, IDC_WELCOME_FULLSCREEN, BM_GETCHECK, 0, 0 ) == BST_CHECKED;
|
||||
#ifdef HAVE_GLES2
|
||||
if (SendDlgItemMessage(hDlg, IDC_WELCOME_VULKAN4, BM_GETCHECK, 0, 0) == BST_CHECKED)
|
||||
vid_preferbackend = 3;
|
||||
else
|
||||
#endif
|
||||
if (SendDlgItemMessage(hDlg, IDC_WELCOME_VULKAN3, BM_GETCHECK, 0, 0) == BST_CHECKED)
|
||||
vid_preferbackend = 2;
|
||||
else if (SendDlgItemMessage(hDlg, IDC_WELCOME_VULKAN2, BM_GETCHECK, 0, 0) == BST_CHECKED)
|
||||
|
|
|
@ -53,6 +53,9 @@ TArray<FString> I_GetSteamPath();
|
|||
// [GZ] Same deal for GOG paths
|
||||
TArray<FString> I_GetGogPaths();
|
||||
|
||||
// Again for the Bethesda.net Launcher path
|
||||
TArray<FString> I_GetBethesdaPath();
|
||||
|
||||
// Damn Microsoft for doing Get/SetWindowLongPtr half-assed. Instead of
|
||||
// giving them proper prototypes under Win32, they are just macros for
|
||||
// Get/SetWindowLong, meaning they take LONGs and not LONG_PTRs.
|
||||
|
|
|
@ -97,6 +97,7 @@
|
|||
#define IDC_RADIO3 1086
|
||||
#define IDC_WELCOME_VULKAN3 1086
|
||||
#define IDCE_ROOM 1087
|
||||
#define IDC_WELCOME_VULKAN4 1187
|
||||
#define IDCS_ROOM 1088
|
||||
#define IDCE_ROOMHF 1089
|
||||
#define IDCS_ROOMHF 1090
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
#include "win32basevideo.h"
|
||||
#include "cmdlib.h"
|
||||
|
||||
CVAR(Int, vid_adapter, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
CVAR(Int, vid_adapter, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -69,6 +69,12 @@ Win32BaseVideo::Win32BaseVideo()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
HMONITOR GetPrimaryMonitorHandle()
|
||||
{
|
||||
const POINT ptZero = { 0, 0 };
|
||||
return MonitorFromPoint(ptZero, MONITOR_DEFAULTTOPRIMARY);
|
||||
}
|
||||
|
||||
struct MonitorEnumState
|
||||
{
|
||||
int curIdx;
|
||||
|
@ -116,24 +122,29 @@ void Win32BaseVideo::GetDisplayDeviceName()
|
|||
mes.curIdx = 1;
|
||||
mes.hFoundMonitor = nullptr;
|
||||
|
||||
// Could also use EnumDisplayDevices, I guess. That might work.
|
||||
if (EnumDisplayMonitors(0, 0, &GetDisplayDeviceNameMonitorEnumProc, LPARAM(&mes)))
|
||||
if (vid_adapter == 0)
|
||||
{
|
||||
if (mes.hFoundMonitor)
|
||||
mes.hFoundMonitor = GetPrimaryMonitorHandle();
|
||||
}
|
||||
|
||||
// Could also use EnumDisplayDevices, I guess. That might work.
|
||||
else EnumDisplayMonitors(0, 0, &GetDisplayDeviceNameMonitorEnumProc, LPARAM(&mes));
|
||||
|
||||
if (mes.hFoundMonitor)
|
||||
{
|
||||
MONITORINFOEXA mi;
|
||||
|
||||
mi.cbSize = sizeof mi;
|
||||
|
||||
if (GetMonitorInfoA(mes.hFoundMonitor, &mi))
|
||||
{
|
||||
MONITORINFOEXA mi;
|
||||
strcpy(m_DisplayDeviceBuffer, mi.szDevice);
|
||||
m_DisplayDeviceName = m_DisplayDeviceBuffer;
|
||||
|
||||
mi.cbSize = sizeof mi;
|
||||
|
||||
if (GetMonitorInfoA(mes.hFoundMonitor, &mi))
|
||||
{
|
||||
strcpy(m_DisplayDeviceBuffer, mi.szDevice);
|
||||
m_DisplayDeviceName = m_DisplayDeviceBuffer;
|
||||
|
||||
m_hMonitor = mes.hFoundMonitor;
|
||||
}
|
||||
m_hMonitor = mes.hFoundMonitor;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -53,6 +53,9 @@
|
|||
#include "win32glvideo.h"
|
||||
|
||||
#include "gl_framebuffer.h"
|
||||
#ifdef HAVE_GLES2
|
||||
#include "gles_framebuffer.h"
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
HGLRC zd_wglCreateContext(HDC Arg1);
|
||||
|
@ -62,6 +65,7 @@ PROC zd_wglGetProcAddress(LPCSTR name);
|
|||
}
|
||||
|
||||
EXTERN_CVAR(Int, vid_adapter)
|
||||
EXTERN_CVAR(Int, vid_preferbackend)
|
||||
EXTERN_CVAR(Bool, vid_hdr)
|
||||
|
||||
CUSTOM_CVAR(Bool, gl_debug, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
|
||||
|
@ -105,7 +109,13 @@ DFrameBuffer *Win32GLVideo::CreateFrameBuffer()
|
|||
{
|
||||
SystemGLFrameBuffer *fb;
|
||||
|
||||
fb = new OpenGLRenderer::OpenGLFrameBuffer(m_hMonitor, vid_fullscreen);
|
||||
#ifdef HAVE_GLES2
|
||||
if ((Args->CheckParm("-gles2_renderer")) || (vid_preferbackend == 3) )
|
||||
fb = new OpenGLESRenderer::OpenGLFrameBuffer(m_hMonitor, vid_fullscreen);
|
||||
else
|
||||
#endif
|
||||
fb = new OpenGLRenderer::OpenGLFrameBuffer(m_hMonitor, vid_fullscreen);
|
||||
|
||||
return fb;
|
||||
}
|
||||
|
||||
|
|
|
@ -170,6 +170,29 @@ void GLBuffer::Resize(size_t newsize)
|
|||
}
|
||||
}
|
||||
|
||||
void GLBuffer::GPUDropSync()
|
||||
{
|
||||
if (mGLSync != NULL)
|
||||
{
|
||||
glDeleteSync(mGLSync);
|
||||
}
|
||||
|
||||
mGLSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
}
|
||||
|
||||
void GLBuffer::GPUWaitSync()
|
||||
{
|
||||
GLenum status = glClientWaitSync(mGLSync, GL_SYNC_FLUSH_COMMANDS_BIT, 1000 * 1000 * 50); // Wait for a max of 50ms...
|
||||
|
||||
if (status != GL_ALREADY_SIGNALED && status != GL_CONDITION_SATISFIED)
|
||||
{
|
||||
//Printf("Error on glClientWaitSync: %d\n", status);
|
||||
}
|
||||
|
||||
glDeleteSync(mGLSync);
|
||||
|
||||
mGLSync = NULL;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "buffers.h"
|
||||
#include "gl_load.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// silence bogus warning C4250: 'GLVertexBuffer': inherits 'GLBuffer::GLBuffer::SetData' via dominance
|
||||
|
@ -19,6 +20,7 @@ protected:
|
|||
int mAllocationSize = 0;
|
||||
bool mPersistent = false;
|
||||
bool nomap = true;
|
||||
GLsync mGLSync = 0;
|
||||
|
||||
GLBuffer(int usetype);
|
||||
~GLBuffer();
|
||||
|
@ -29,6 +31,9 @@ protected:
|
|||
void Resize(size_t newsize) override;
|
||||
void *Lock(unsigned int size) override;
|
||||
void Unlock() override;
|
||||
|
||||
void GPUDropSync();
|
||||
void GPUWaitSync();
|
||||
public:
|
||||
void Bind();
|
||||
};
|
||||
|
|
|
@ -65,6 +65,7 @@ EXTERN_CVAR (Bool, vid_vsync)
|
|||
EXTERN_CVAR(Bool, r_drawvoxels)
|
||||
EXTERN_CVAR(Int, gl_tonemap)
|
||||
EXTERN_CVAR(Bool, cl_capfps)
|
||||
EXTERN_CVAR(Int, gl_pipeline_depth);
|
||||
|
||||
void gl_LoadExtensions();
|
||||
void gl_PrintStartupLog();
|
||||
|
@ -133,6 +134,9 @@ void OpenGLFrameBuffer::InitializeState()
|
|||
|
||||
gl_LoadExtensions();
|
||||
|
||||
mPipelineNbr = clamp(*gl_pipeline_depth, 1, HW_MAX_PIPELINE_BUFFERS);
|
||||
mPipelineType = gl_pipeline_depth > 0;
|
||||
|
||||
// Move some state to the framebuffer object for easier access.
|
||||
hwcaps = gl.flags;
|
||||
glslversion = gl.glslversion;
|
||||
|
@ -164,10 +168,10 @@ void OpenGLFrameBuffer::InitializeState()
|
|||
|
||||
SetViewportRects(nullptr);
|
||||
|
||||
mVertexData = new FFlatVertexBuffer(GetWidth(), GetHeight());
|
||||
mVertexData = new FFlatVertexBuffer(GetWidth(), GetHeight(), screen->mPipelineNbr);
|
||||
mSkyData = new FSkyVertexBuffer;
|
||||
mViewpoints = new HWViewpointBuffer;
|
||||
mLights = new FLightBuffer();
|
||||
mViewpoints = new HWViewpointBuffer(screen->mPipelineNbr);
|
||||
mLights = new FLightBuffer(screen->mPipelineNbr);
|
||||
GLRenderer = new FGLRenderer(this);
|
||||
GLRenderer->Initialize(GetWidth(), GetHeight());
|
||||
static_cast<GLDataBuffer*>(mLights->GetBuffer())->BindBase();
|
||||
|
@ -256,10 +260,25 @@ void OpenGLFrameBuffer::Swap()
|
|||
bool swapbefore = gl_finishbeforeswap && camtexcount == 0;
|
||||
Finish.Reset();
|
||||
Finish.Clock();
|
||||
if (swapbefore) glFinish();
|
||||
FPSLimit();
|
||||
SwapBuffers();
|
||||
if (!swapbefore) glFinish();
|
||||
if (gl_pipeline_depth < 1)
|
||||
{
|
||||
if (swapbefore) glFinish();
|
||||
FPSLimit();
|
||||
SwapBuffers();
|
||||
if (!swapbefore) glFinish();
|
||||
}
|
||||
else
|
||||
{
|
||||
mVertexData->DropSync();
|
||||
|
||||
FPSLimit();
|
||||
SwapBuffers();
|
||||
|
||||
mVertexData->NextPipelineBuffer();
|
||||
mVertexData->WaitSync();
|
||||
|
||||
RenderState()->SetVertexBuffer(screen->mVertexData); // Needed for Raze because it does not reset it
|
||||
}
|
||||
Finish.Unclock();
|
||||
camtexcount = 0;
|
||||
FHardwareTexture::UnbindAll();
|
||||
|
|
|
@ -124,9 +124,7 @@ bool FGLRenderState::ApplyShader()
|
|||
activeShader->muDesaturation.Set(mStreamData.uDesaturationFactor);
|
||||
activeShader->muFogEnabled.Set(fogset);
|
||||
|
||||
int f = mTextureModeFlags;
|
||||
if (!mBrightmapEnabled) f &= ~(TEXF_Brightmap | TEXF_Glowmap);
|
||||
activeShader->muTextureMode.Set((mTextureMode == TM_NORMAL && mTempTM == TM_OPAQUE ? TM_OPAQUE : mTextureMode) | f);
|
||||
activeShader->muTextureMode.Set(GetTextureModeAndFlags(mTempTM));
|
||||
activeShader->muLightParms.Set(mLightParms);
|
||||
activeShader->muFogColor.Set(mStreamData.uFogColor);
|
||||
activeShader->muObjectColor.Set(mStreamData.uObjectColor);
|
||||
|
@ -204,7 +202,7 @@ bool FGLRenderState::ApplyShader()
|
|||
size_t start, size;
|
||||
index = screen->mLights->GetBinding(index, &start, &size);
|
||||
|
||||
if (start != mLastMappedLightIndex)
|
||||
if (start != mLastMappedLightIndex || screen->mPipelineNbr > 1) // If multiple buffers always bind
|
||||
{
|
||||
mLastMappedLightIndex = start;
|
||||
static_cast<GLDataBuffer*>(screen->mLights->GetBuffer())->BindRange(nullptr, start, size);
|
||||
|
|
|
@ -382,7 +382,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
|
|||
vp_comb = "#version 430 core\n#define SHADER_STORAGE_LIGHTS\n";
|
||||
}
|
||||
|
||||
if (gl.flags & RFL_SHADER_STORAGE_BUFFER)
|
||||
if ((gl.flags & RFL_SHADER_STORAGE_BUFFER) && screen->allowSSBO())
|
||||
{
|
||||
vp_comb << "#define SUPPORTS_SHADOWMAPS\n";
|
||||
}
|
||||
|
@ -404,7 +404,8 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
|
|||
|
||||
if (*proc_prog_lump != '#')
|
||||
{
|
||||
int pp_lump = fileSystem.CheckNumForFullName(proc_prog_lump);
|
||||
int pp_lump = fileSystem.CheckNumForFullName(proc_prog_lump, 0); // if it's a core shader, ignore overrides by user mods.
|
||||
if (pp_lump == -1) pp_lump = fileSystem.CheckNumForFullName(proc_prog_lump);
|
||||
if (pp_lump == -1) I_Error("Unable to load '%s'", proc_prog_lump);
|
||||
FileData pp_data = fileSystem.ReadFile(pp_lump);
|
||||
|
||||
|
|
125
source/common/rendering/gles/glad/include/EGL/eglplatform.h
Normal file
125
source/common/rendering/gles/glad/include/EGL/eglplatform.h
Normal file
|
@ -0,0 +1,125 @@
|
|||
#ifndef __eglplatform_h_
|
||||
#define __eglplatform_h_
|
||||
|
||||
/*
|
||||
** Copyright (c) 2007-2013 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
/* Platform-specific types and definitions for egl.h
|
||||
* $Revision: 23432 $ on $Date: 2013-10-09 00:57:24 -0700 (Wed, 09 Oct 2013) $
|
||||
*
|
||||
* Adopters may modify khrplatform.h and this file to suit their platform.
|
||||
* You are encouraged to submit all modifications to the Khronos group so that
|
||||
* they can be included in future versions of this file. Please submit changes
|
||||
* by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla)
|
||||
* by filing a bug against product "EGL" component "Registry".
|
||||
*/
|
||||
|
||||
#include <KHR/khrplatform.h>
|
||||
|
||||
/* Macros used in EGL function prototype declarations.
|
||||
*
|
||||
* EGL functions should be prototyped as:
|
||||
*
|
||||
* EGLAPI return-type EGLAPIENTRY eglFunction(arguments);
|
||||
* typedef return-type (EXPAPIENTRYP PFNEGLFUNCTIONPROC) (arguments);
|
||||
*
|
||||
* KHRONOS_APICALL and KHRONOS_APIENTRY are defined in KHR/khrplatform.h
|
||||
*/
|
||||
|
||||
#ifndef EGLAPI
|
||||
#define EGLAPI KHRONOS_APICALL
|
||||
#endif
|
||||
|
||||
#ifndef EGLAPIENTRY
|
||||
#define EGLAPIENTRY KHRONOS_APIENTRY
|
||||
#endif
|
||||
#define EGLAPIENTRYP EGLAPIENTRY*
|
||||
|
||||
/* The types NativeDisplayType, NativeWindowType, and NativePixmapType
|
||||
* are aliases of window-system-dependent types, such as X Display * or
|
||||
* Windows Device Context. They must be defined in platform-specific
|
||||
* code below. The EGL-prefixed versions of Native*Type are the same
|
||||
* types, renamed in EGL 1.3 so all types in the API start with "EGL".
|
||||
*
|
||||
* Khronos STRONGLY RECOMMENDS that you use the default definitions
|
||||
* provided below, since these changes affect both binary and source
|
||||
* portability of applications using EGL running on different EGL
|
||||
* implementations.
|
||||
*/
|
||||
|
||||
#if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
||||
typedef HDC EGLNativeDisplayType;
|
||||
typedef HBITMAP EGLNativePixmapType;
|
||||
typedef HWND EGLNativeWindowType;
|
||||
|
||||
#elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */
|
||||
|
||||
typedef int EGLNativeDisplayType;
|
||||
typedef void *EGLNativeWindowType;
|
||||
typedef void *EGLNativePixmapType;
|
||||
|
||||
#elif defined(__ANDROID__) || defined(ANDROID)
|
||||
|
||||
#include <android/native_window.h>
|
||||
|
||||
struct egl_native_pixmap_t;
|
||||
|
||||
typedef struct ANativeWindow* EGLNativeWindowType;
|
||||
typedef struct egl_native_pixmap_t* EGLNativePixmapType;
|
||||
typedef void* EGLNativeDisplayType;
|
||||
|
||||
#elif defined(__unix__) || defined(__APPLE__)
|
||||
|
||||
/* X11 (tentative) */
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
typedef Display *EGLNativeDisplayType;
|
||||
typedef Pixmap EGLNativePixmapType;
|
||||
typedef Window EGLNativeWindowType;
|
||||
|
||||
#else
|
||||
#error "Platform not recognized"
|
||||
#endif
|
||||
|
||||
/* EGL 1.2 types, renamed for consistency in EGL 1.3 */
|
||||
typedef EGLNativeDisplayType NativeDisplayType;
|
||||
typedef EGLNativePixmapType NativePixmapType;
|
||||
typedef EGLNativeWindowType NativeWindowType;
|
||||
|
||||
|
||||
/* Define EGLint. This must be a signed integral type large enough to contain
|
||||
* all legal attribute names and values passed into and out of EGL, whether
|
||||
* their type is boolean, bitmask, enumerant (symbolic constant), integer,
|
||||
* handle, or other. While in general a 32-bit integer will suffice, if
|
||||
* handles are 64 bit types, then EGLint should be defined as a signed 64-bit
|
||||
* integer type.
|
||||
*/
|
||||
typedef khronos_int32_t EGLint;
|
||||
|
||||
#endif /* __eglplatform_h */
|
290
source/common/rendering/gles/glad/include/KHR/khrplatform.h
Normal file
290
source/common/rendering/gles/glad/include/KHR/khrplatform.h
Normal file
|
@ -0,0 +1,290 @@
|
|||
#ifndef __khrplatform_h_
|
||||
#define __khrplatform_h_
|
||||
|
||||
/*
|
||||
** Copyright (c) 2008-2018 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
/* Khronos platform-specific types and definitions.
|
||||
*
|
||||
* The master copy of khrplatform.h is maintained in the Khronos EGL
|
||||
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
|
||||
* The last semantic modification to khrplatform.h was at commit ID:
|
||||
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692
|
||||
*
|
||||
* Adopters may modify this file to suit their platform. Adopters are
|
||||
* encouraged to submit platform specific modifications to the Khronos
|
||||
* group so that they can be included in future versions of this file.
|
||||
* Please submit changes by filing pull requests or issues on
|
||||
* the EGL Registry repository linked above.
|
||||
*
|
||||
*
|
||||
* See the Implementer's Guidelines for information about where this file
|
||||
* should be located on your system and for more details of its use:
|
||||
* http://www.khronos.org/registry/implementers_guide.pdf
|
||||
*
|
||||
* This file should be included as
|
||||
* #include <KHR/khrplatform.h>
|
||||
* by Khronos client API header files that use its types and defines.
|
||||
*
|
||||
* The types in khrplatform.h should only be used to define API-specific types.
|
||||
*
|
||||
* Types defined in khrplatform.h:
|
||||
* khronos_int8_t signed 8 bit
|
||||
* khronos_uint8_t unsigned 8 bit
|
||||
* khronos_int16_t signed 16 bit
|
||||
* khronos_uint16_t unsigned 16 bit
|
||||
* khronos_int32_t signed 32 bit
|
||||
* khronos_uint32_t unsigned 32 bit
|
||||
* khronos_int64_t signed 64 bit
|
||||
* khronos_uint64_t unsigned 64 bit
|
||||
* khronos_intptr_t signed same number of bits as a pointer
|
||||
* khronos_uintptr_t unsigned same number of bits as a pointer
|
||||
* khronos_ssize_t signed size
|
||||
* khronos_usize_t unsigned size
|
||||
* khronos_float_t signed 32 bit floating point
|
||||
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
|
||||
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
|
||||
* nanoseconds
|
||||
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
|
||||
* khronos_boolean_enum_t enumerated boolean type. This should
|
||||
* only be used as a base type when a client API's boolean type is
|
||||
* an enum. Client APIs which use an integer or other type for
|
||||
* booleans cannot use this as the base type for their boolean.
|
||||
*
|
||||
* Tokens defined in khrplatform.h:
|
||||
*
|
||||
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
|
||||
*
|
||||
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
|
||||
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
|
||||
*
|
||||
* Calling convention macros defined in this file:
|
||||
* KHRONOS_APICALL
|
||||
* KHRONOS_APIENTRY
|
||||
* KHRONOS_APIATTRIBUTES
|
||||
*
|
||||
* These may be used in function prototypes as:
|
||||
*
|
||||
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
|
||||
* int arg1,
|
||||
* int arg2) KHRONOS_APIATTRIBUTES;
|
||||
*/
|
||||
|
||||
#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC)
|
||||
# define KHRONOS_STATIC 1
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APICALL
|
||||
*-------------------------------------------------------------------------
|
||||
* This precedes the return type of the function in the function prototype.
|
||||
*/
|
||||
#if defined(KHRONOS_STATIC)
|
||||
/* If the preprocessor constant KHRONOS_STATIC is defined, make the
|
||||
* header compatible with static linking. */
|
||||
# define KHRONOS_APICALL
|
||||
#elif defined(_WIN32)
|
||||
# define KHRONOS_APICALL __declspec(dllimport)
|
||||
#elif defined (__SYMBIAN32__)
|
||||
# define KHRONOS_APICALL IMPORT_C
|
||||
#elif defined(__ANDROID__)
|
||||
# define KHRONOS_APICALL __attribute__((visibility("default")))
|
||||
#else
|
||||
# define KHRONOS_APICALL
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APIENTRY
|
||||
*-------------------------------------------------------------------------
|
||||
* This follows the return type of the function and precedes the function
|
||||
* name in the function prototype.
|
||||
*/
|
||||
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
|
||||
/* Win32 but not WinCE */
|
||||
# define KHRONOS_APIENTRY __stdcall
|
||||
#else
|
||||
# define KHRONOS_APIENTRY
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Definition of KHRONOS_APIATTRIBUTES
|
||||
*-------------------------------------------------------------------------
|
||||
* This follows the closing parenthesis of the function prototype arguments.
|
||||
*/
|
||||
#if defined (__ARMCC_2__)
|
||||
#define KHRONOS_APIATTRIBUTES __softfp
|
||||
#else
|
||||
#define KHRONOS_APIATTRIBUTES
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* basic type definitions
|
||||
*-----------------------------------------------------------------------*/
|
||||
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
|
||||
|
||||
|
||||
/*
|
||||
* Using <stdint.h>
|
||||
*/
|
||||
#include <stdint.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(__VMS ) || defined(__sgi)
|
||||
|
||||
/*
|
||||
* Using <inttypes.h>
|
||||
*/
|
||||
#include <inttypes.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
|
||||
|
||||
/*
|
||||
* Win32
|
||||
*/
|
||||
typedef __int32 khronos_int32_t;
|
||||
typedef unsigned __int32 khronos_uint32_t;
|
||||
typedef __int64 khronos_int64_t;
|
||||
typedef unsigned __int64 khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif defined(__sun__) || defined(__digital__)
|
||||
|
||||
/*
|
||||
* Sun or Digital
|
||||
*/
|
||||
typedef int khronos_int32_t;
|
||||
typedef unsigned int khronos_uint32_t;
|
||||
#if defined(__arch64__) || defined(_LP64)
|
||||
typedef long int khronos_int64_t;
|
||||
typedef unsigned long int khronos_uint64_t;
|
||||
#else
|
||||
typedef long long int khronos_int64_t;
|
||||
typedef unsigned long long int khronos_uint64_t;
|
||||
#endif /* __arch64__ */
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#elif 0
|
||||
|
||||
/*
|
||||
* Hypothetical platform with no float or int64 support
|
||||
*/
|
||||
typedef int khronos_int32_t;
|
||||
typedef unsigned int khronos_uint32_t;
|
||||
#define KHRONOS_SUPPORT_INT64 0
|
||||
#define KHRONOS_SUPPORT_FLOAT 0
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* Generic fallback
|
||||
*/
|
||||
#include <stdint.h>
|
||||
typedef int32_t khronos_int32_t;
|
||||
typedef uint32_t khronos_uint32_t;
|
||||
typedef int64_t khronos_int64_t;
|
||||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Types that are (so far) the same on all platforms
|
||||
*/
|
||||
typedef signed char khronos_int8_t;
|
||||
typedef unsigned char khronos_uint8_t;
|
||||
typedef signed short int khronos_int16_t;
|
||||
typedef unsigned short int khronos_uint16_t;
|
||||
|
||||
/*
|
||||
* Types that differ between LLP64 and LP64 architectures - in LLP64,
|
||||
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
|
||||
* to be the only LLP64 architecture in current use.
|
||||
*/
|
||||
#ifdef _WIN64
|
||||
typedef signed long long int khronos_intptr_t;
|
||||
typedef unsigned long long int khronos_uintptr_t;
|
||||
typedef signed long long int khronos_ssize_t;
|
||||
typedef unsigned long long int khronos_usize_t;
|
||||
#else
|
||||
typedef signed long int khronos_intptr_t;
|
||||
typedef unsigned long int khronos_uintptr_t;
|
||||
typedef signed long int khronos_ssize_t;
|
||||
typedef unsigned long int khronos_usize_t;
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_FLOAT
|
||||
/*
|
||||
* Float type
|
||||
*/
|
||||
typedef float khronos_float_t;
|
||||
#endif
|
||||
|
||||
#if KHRONOS_SUPPORT_INT64
|
||||
/* Time types
|
||||
*
|
||||
* These types can be used to represent a time interval in nanoseconds or
|
||||
* an absolute Unadjusted System Time. Unadjusted System Time is the number
|
||||
* of nanoseconds since some arbitrary system event (e.g. since the last
|
||||
* time the system booted). The Unadjusted System Time is an unsigned
|
||||
* 64 bit value that wraps back to 0 every 584 years. Time intervals
|
||||
* may be either signed or unsigned.
|
||||
*/
|
||||
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
|
||||
typedef khronos_int64_t khronos_stime_nanoseconds_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Dummy value used to pad enum types to 32 bits.
|
||||
*/
|
||||
#ifndef KHRONOS_MAX_ENUM
|
||||
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Enumerated boolean type
|
||||
*
|
||||
* Values other than zero should be considered to be true. Therefore
|
||||
* comparisons should not be made against KHRONOS_TRUE.
|
||||
*/
|
||||
typedef enum {
|
||||
KHRONOS_FALSE = 0,
|
||||
KHRONOS_TRUE = 1,
|
||||
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
|
||||
} khronos_boolean_enum_t;
|
||||
|
||||
#endif /* __khrplatform_h_ */
|
874
source/common/rendering/gles/glad/include/glad/glad.h
Normal file
874
source/common/rendering/gles/glad/include/glad/glad.h
Normal file
|
@ -0,0 +1,874 @@
|
|||
/*
|
||||
|
||||
OpenGL ES loader generated by glad 0.1.34 on Fri Mar 19 17:04:24 2021.
|
||||
|
||||
Language/Generator: C/C++
|
||||
Specification: gl
|
||||
APIs: gles2=2.0
|
||||
Profile: compatibility
|
||||
Extensions:
|
||||
|
||||
Loader: True
|
||||
Local files: False
|
||||
Omit khrplatform: False
|
||||
Reproducible: False
|
||||
|
||||
Commandline:
|
||||
--profile="compatibility" --api="gles2=2.0" --generator="c" --spec="gl" --extensions=""
|
||||
Online:
|
||||
https://glad.dav1d.de/#profile=compatibility&language=c&specification=gl&loader=on&api=gles2%3D2.0
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __glad_h_
|
||||
#define __glad_h_
|
||||
|
||||
#ifdef __gl2_h_
|
||||
#error OpenGL ES 2 header already included, remove this include, glad already provides it
|
||||
#endif
|
||||
#define __gl2_h_
|
||||
|
||||
#ifdef __gl3_h_
|
||||
#error OpenGL ES 3 header already included, remove this include, glad already provides it
|
||||
#endif
|
||||
#define __gl3_h_
|
||||
|
||||
#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
|
||||
#define APIENTRY __stdcall
|
||||
#endif
|
||||
|
||||
#ifndef APIENTRY
|
||||
#define APIENTRY
|
||||
#endif
|
||||
#ifndef APIENTRYP
|
||||
#define APIENTRYP APIENTRY *
|
||||
#endif
|
||||
|
||||
#ifndef GLAPIENTRY
|
||||
#define GLAPIENTRY APIENTRY
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct gladGLversionStruct {
|
||||
int major;
|
||||
int minor;
|
||||
};
|
||||
|
||||
typedef void* (* GLADloadproc)(const char *name);
|
||||
|
||||
#ifndef GLAPI
|
||||
# if defined(GLAD_GLAPI_EXPORT)
|
||||
# if defined(_WIN32) || defined(__CYGWIN__)
|
||||
# if defined(GLAD_GLAPI_EXPORT_BUILD)
|
||||
# if defined(__GNUC__)
|
||||
# define GLAPI __attribute__ ((dllexport)) extern
|
||||
# else
|
||||
# define GLAPI __declspec(dllexport) extern
|
||||
# endif
|
||||
# else
|
||||
# if defined(__GNUC__)
|
||||
# define GLAPI __attribute__ ((dllimport)) extern
|
||||
# else
|
||||
# define GLAPI __declspec(dllimport) extern
|
||||
# endif
|
||||
# endif
|
||||
# elif defined(__GNUC__) && defined(GLAD_GLAPI_EXPORT_BUILD)
|
||||
# define GLAPI __attribute__ ((visibility ("default"))) extern
|
||||
# else
|
||||
# define GLAPI extern
|
||||
# endif
|
||||
# else
|
||||
# define GLAPI extern
|
||||
# endif
|
||||
#endif
|
||||
|
||||
GLAPI struct gladGLversionStruct GLVersion;
|
||||
GLAPI int gladLoadGLES2Loader(GLADloadproc);
|
||||
|
||||
#include <KHR/khrplatform.h>
|
||||
typedef unsigned int GLenum;
|
||||
typedef unsigned char GLboolean;
|
||||
typedef unsigned int GLbitfield;
|
||||
typedef void GLvoid;
|
||||
typedef khronos_int8_t GLbyte;
|
||||
typedef khronos_uint8_t GLubyte;
|
||||
typedef khronos_int16_t GLshort;
|
||||
typedef khronos_uint16_t GLushort;
|
||||
typedef int GLint;
|
||||
typedef unsigned int GLuint;
|
||||
typedef khronos_int32_t GLclampx;
|
||||
typedef int GLsizei;
|
||||
typedef khronos_float_t GLfloat;
|
||||
typedef khronos_float_t GLclampf;
|
||||
typedef double GLdouble;
|
||||
typedef double GLclampd;
|
||||
typedef void *GLeglClientBufferEXT;
|
||||
typedef void *GLeglImageOES;
|
||||
typedef char GLchar;
|
||||
typedef char GLcharARB;
|
||||
#ifdef __APPLE__
|
||||
typedef void *GLhandleARB;
|
||||
#else
|
||||
typedef unsigned int GLhandleARB;
|
||||
#endif
|
||||
typedef khronos_uint16_t GLhalf;
|
||||
typedef khronos_uint16_t GLhalfARB;
|
||||
typedef khronos_int32_t GLfixed;
|
||||
typedef khronos_intptr_t GLintptr;
|
||||
typedef khronos_intptr_t GLintptrARB;
|
||||
typedef khronos_ssize_t GLsizeiptr;
|
||||
typedef khronos_ssize_t GLsizeiptrARB;
|
||||
typedef khronos_int64_t GLint64;
|
||||
typedef khronos_int64_t GLint64EXT;
|
||||
typedef khronos_uint64_t GLuint64;
|
||||
typedef khronos_uint64_t GLuint64EXT;
|
||||
typedef struct __GLsync *GLsync;
|
||||
struct _cl_context;
|
||||
struct _cl_event;
|
||||
typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
|
||||
typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
|
||||
typedef void (APIENTRY *GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
|
||||
typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam);
|
||||
typedef unsigned short GLhalfNV;
|
||||
typedef GLintptr GLvdpauSurfaceNV;
|
||||
typedef void (APIENTRY *GLVULKANPROCNV)(void);
|
||||
#define GL_DEPTH_BUFFER_BIT 0x00000100
|
||||
#define GL_STENCIL_BUFFER_BIT 0x00000400
|
||||
#define GL_COLOR_BUFFER_BIT 0x00004000
|
||||
#define GL_FALSE 0
|
||||
#define GL_TRUE 1
|
||||
#define GL_POINTS 0x0000
|
||||
#define GL_LINES 0x0001
|
||||
#define GL_LINE_LOOP 0x0002
|
||||
#define GL_LINE_STRIP 0x0003
|
||||
#define GL_TRIANGLES 0x0004
|
||||
#define GL_TRIANGLE_STRIP 0x0005
|
||||
#define GL_TRIANGLE_FAN 0x0006
|
||||
#define GL_ZERO 0
|
||||
#define GL_ONE 1
|
||||
#define GL_SRC_COLOR 0x0300
|
||||
#define GL_ONE_MINUS_SRC_COLOR 0x0301
|
||||
#define GL_SRC_ALPHA 0x0302
|
||||
#define GL_ONE_MINUS_SRC_ALPHA 0x0303
|
||||
#define GL_DST_ALPHA 0x0304
|
||||
#define GL_ONE_MINUS_DST_ALPHA 0x0305
|
||||
#define GL_DST_COLOR 0x0306
|
||||
#define GL_ONE_MINUS_DST_COLOR 0x0307
|
||||
#define GL_SRC_ALPHA_SATURATE 0x0308
|
||||
#define GL_FUNC_ADD 0x8006
|
||||
#define GL_BLEND_EQUATION 0x8009
|
||||
#define GL_BLEND_EQUATION_RGB 0x8009
|
||||
#define GL_BLEND_EQUATION_ALPHA 0x883D
|
||||
#define GL_FUNC_SUBTRACT 0x800A
|
||||
#define GL_FUNC_REVERSE_SUBTRACT 0x800B
|
||||
#define GL_BLEND_DST_RGB 0x80C8
|
||||
#define GL_BLEND_SRC_RGB 0x80C9
|
||||
#define GL_BLEND_DST_ALPHA 0x80CA
|
||||
#define GL_BLEND_SRC_ALPHA 0x80CB
|
||||
#define GL_CONSTANT_COLOR 0x8001
|
||||
#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
|
||||
#define GL_CONSTANT_ALPHA 0x8003
|
||||
#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
|
||||
#define GL_BLEND_COLOR 0x8005
|
||||
#define GL_ARRAY_BUFFER 0x8892
|
||||
#define GL_ELEMENT_ARRAY_BUFFER 0x8893
|
||||
#define GL_ARRAY_BUFFER_BINDING 0x8894
|
||||
#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
|
||||
#define GL_STREAM_DRAW 0x88E0
|
||||
#define GL_STATIC_DRAW 0x88E4
|
||||
#define GL_DYNAMIC_DRAW 0x88E8
|
||||
#define GL_BUFFER_SIZE 0x8764
|
||||
#define GL_BUFFER_USAGE 0x8765
|
||||
#define GL_CURRENT_VERTEX_ATTRIB 0x8626
|
||||
#define GL_FRONT 0x0404
|
||||
#define GL_BACK 0x0405
|
||||
#define GL_FRONT_AND_BACK 0x0408
|
||||
#define GL_TEXTURE_2D 0x0DE1
|
||||
#define GL_CULL_FACE 0x0B44
|
||||
#define GL_BLEND 0x0BE2
|
||||
#define GL_DITHER 0x0BD0
|
||||
#define GL_STENCIL_TEST 0x0B90
|
||||
#define GL_DEPTH_TEST 0x0B71
|
||||
#define GL_SCISSOR_TEST 0x0C11
|
||||
#define GL_POLYGON_OFFSET_FILL 0x8037
|
||||
#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
|
||||
#define GL_SAMPLE_COVERAGE 0x80A0
|
||||
#define GL_NO_ERROR 0
|
||||
#define GL_INVALID_ENUM 0x0500
|
||||
#define GL_INVALID_VALUE 0x0501
|
||||
#define GL_INVALID_OPERATION 0x0502
|
||||
#define GL_OUT_OF_MEMORY 0x0505
|
||||
#define GL_CW 0x0900
|
||||
#define GL_CCW 0x0901
|
||||
#define GL_LINE_WIDTH 0x0B21
|
||||
#define GL_ALIASED_POINT_SIZE_RANGE 0x846D
|
||||
#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
|
||||
#define GL_CULL_FACE_MODE 0x0B45
|
||||
#define GL_FRONT_FACE 0x0B46
|
||||
#define GL_DEPTH_RANGE 0x0B70
|
||||
#define GL_DEPTH_WRITEMASK 0x0B72
|
||||
#define GL_DEPTH_CLEAR_VALUE 0x0B73
|
||||
#define GL_DEPTH_FUNC 0x0B74
|
||||
#define GL_STENCIL_CLEAR_VALUE 0x0B91
|
||||
#define GL_STENCIL_FUNC 0x0B92
|
||||
#define GL_STENCIL_FAIL 0x0B94
|
||||
#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95
|
||||
#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96
|
||||
#define GL_STENCIL_REF 0x0B97
|
||||
#define GL_STENCIL_VALUE_MASK 0x0B93
|
||||
#define GL_STENCIL_WRITEMASK 0x0B98
|
||||
#define GL_STENCIL_BACK_FUNC 0x8800
|
||||
#define GL_STENCIL_BACK_FAIL 0x8801
|
||||
#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802
|
||||
#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803
|
||||
#define GL_STENCIL_BACK_REF 0x8CA3
|
||||
#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4
|
||||
#define GL_STENCIL_BACK_WRITEMASK 0x8CA5
|
||||
#define GL_VIEWPORT 0x0BA2
|
||||
#define GL_SCISSOR_BOX 0x0C10
|
||||
#define GL_COLOR_CLEAR_VALUE 0x0C22
|
||||
#define GL_COLOR_WRITEMASK 0x0C23
|
||||
#define GL_UNPACK_ALIGNMENT 0x0CF5
|
||||
#define GL_PACK_ALIGNMENT 0x0D05
|
||||
#define GL_MAX_TEXTURE_SIZE 0x0D33
|
||||
#define GL_MAX_VIEWPORT_DIMS 0x0D3A
|
||||
#define GL_SUBPIXEL_BITS 0x0D50
|
||||
#define GL_RED_BITS 0x0D52
|
||||
#define GL_GREEN_BITS 0x0D53
|
||||
#define GL_BLUE_BITS 0x0D54
|
||||
#define GL_ALPHA_BITS 0x0D55
|
||||
#define GL_DEPTH_BITS 0x0D56
|
||||
#define GL_STENCIL_BITS 0x0D57
|
||||
#define GL_POLYGON_OFFSET_UNITS 0x2A00
|
||||
#define GL_POLYGON_OFFSET_FACTOR 0x8038
|
||||
#define GL_TEXTURE_BINDING_2D 0x8069
|
||||
#define GL_SAMPLE_BUFFERS 0x80A8
|
||||
#define GL_SAMPLES 0x80A9
|
||||
#define GL_SAMPLE_COVERAGE_VALUE 0x80AA
|
||||
#define GL_SAMPLE_COVERAGE_INVERT 0x80AB
|
||||
#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
|
||||
#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
|
||||
#define GL_DONT_CARE 0x1100
|
||||
#define GL_FASTEST 0x1101
|
||||
#define GL_NICEST 0x1102
|
||||
#define GL_GENERATE_MIPMAP_HINT 0x8192
|
||||
#define GL_BYTE 0x1400
|
||||
#define GL_UNSIGNED_BYTE 0x1401
|
||||
#define GL_SHORT 0x1402
|
||||
#define GL_UNSIGNED_SHORT 0x1403
|
||||
#define GL_INT 0x1404
|
||||
#define GL_UNSIGNED_INT 0x1405
|
||||
#define GL_FLOAT 0x1406
|
||||
#define GL_FIXED 0x140C
|
||||
#define GL_DEPTH_COMPONENT 0x1902
|
||||
#define GL_ALPHA 0x1906
|
||||
#define GL_RGB 0x1907
|
||||
#define GL_RGBA 0x1908
|
||||
#define GL_LUMINANCE 0x1909
|
||||
#define GL_LUMINANCE_ALPHA 0x190A
|
||||
#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
|
||||
#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
|
||||
#define GL_UNSIGNED_SHORT_5_6_5 0x8363
|
||||
#define GL_FRAGMENT_SHADER 0x8B30
|
||||
#define GL_VERTEX_SHADER 0x8B31
|
||||
#define GL_MAX_VERTEX_ATTRIBS 0x8869
|
||||
#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
|
||||
#define GL_MAX_VARYING_VECTORS 0x8DFC
|
||||
#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
|
||||
#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
|
||||
#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
|
||||
#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
|
||||
#define GL_SHADER_TYPE 0x8B4F
|
||||
#define GL_DELETE_STATUS 0x8B80
|
||||
#define GL_LINK_STATUS 0x8B82
|
||||
#define GL_VALIDATE_STATUS 0x8B83
|
||||
#define GL_ATTACHED_SHADERS 0x8B85
|
||||
#define GL_ACTIVE_UNIFORMS 0x8B86
|
||||
#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
|
||||
#define GL_ACTIVE_ATTRIBUTES 0x8B89
|
||||
#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
|
||||
#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
|
||||
#define GL_CURRENT_PROGRAM 0x8B8D
|
||||
#define GL_NEVER 0x0200
|
||||
#define GL_LESS 0x0201
|
||||
#define GL_EQUAL 0x0202
|
||||
#define GL_LEQUAL 0x0203
|
||||
#define GL_GREATER 0x0204
|
||||
#define GL_NOTEQUAL 0x0205
|
||||
#define GL_GEQUAL 0x0206
|
||||
#define GL_ALWAYS 0x0207
|
||||
#define GL_KEEP 0x1E00
|
||||
#define GL_REPLACE 0x1E01
|
||||
#define GL_INCR 0x1E02
|
||||
#define GL_DECR 0x1E03
|
||||
#define GL_INVERT 0x150A
|
||||
#define GL_INCR_WRAP 0x8507
|
||||
#define GL_DECR_WRAP 0x8508
|
||||
#define GL_VENDOR 0x1F00
|
||||
#define GL_RENDERER 0x1F01
|
||||
#define GL_VERSION 0x1F02
|
||||
#define GL_EXTENSIONS 0x1F03
|
||||
#define GL_NEAREST 0x2600
|
||||
#define GL_LINEAR 0x2601
|
||||
#define GL_NEAREST_MIPMAP_NEAREST 0x2700
|
||||
#define GL_LINEAR_MIPMAP_NEAREST 0x2701
|
||||
#define GL_NEAREST_MIPMAP_LINEAR 0x2702
|
||||
#define GL_LINEAR_MIPMAP_LINEAR 0x2703
|
||||
#define GL_TEXTURE_MAG_FILTER 0x2800
|
||||
#define GL_TEXTURE_MIN_FILTER 0x2801
|
||||
#define GL_TEXTURE_WRAP_S 0x2802
|
||||
#define GL_TEXTURE_WRAP_T 0x2803
|
||||
#define GL_TEXTURE 0x1702
|
||||
#define GL_TEXTURE_CUBE_MAP 0x8513
|
||||
#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514
|
||||
#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
|
||||
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
|
||||
#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
|
||||
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
|
||||
#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
|
||||
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
|
||||
#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C
|
||||
#define GL_TEXTURE0 0x84C0
|
||||
#define GL_TEXTURE1 0x84C1
|
||||
#define GL_TEXTURE2 0x84C2
|
||||
#define GL_TEXTURE3 0x84C3
|
||||
#define GL_TEXTURE4 0x84C4
|
||||
#define GL_TEXTURE5 0x84C5
|
||||
#define GL_TEXTURE6 0x84C6
|
||||
#define GL_TEXTURE7 0x84C7
|
||||
#define GL_TEXTURE8 0x84C8
|
||||
#define GL_TEXTURE9 0x84C9
|
||||
#define GL_TEXTURE10 0x84CA
|
||||
#define GL_TEXTURE11 0x84CB
|
||||
#define GL_TEXTURE12 0x84CC
|
||||
#define GL_TEXTURE13 0x84CD
|
||||
#define GL_TEXTURE14 0x84CE
|
||||
#define GL_TEXTURE15 0x84CF
|
||||
#define GL_TEXTURE16 0x84D0
|
||||
#define GL_TEXTURE17 0x84D1
|
||||
#define GL_TEXTURE18 0x84D2
|
||||
#define GL_TEXTURE19 0x84D3
|
||||
#define GL_TEXTURE20 0x84D4
|
||||
#define GL_TEXTURE21 0x84D5
|
||||
#define GL_TEXTURE22 0x84D6
|
||||
#define GL_TEXTURE23 0x84D7
|
||||
#define GL_TEXTURE24 0x84D8
|
||||
#define GL_TEXTURE25 0x84D9
|
||||
#define GL_TEXTURE26 0x84DA
|
||||
#define GL_TEXTURE27 0x84DB
|
||||
#define GL_TEXTURE28 0x84DC
|
||||
#define GL_TEXTURE29 0x84DD
|
||||
#define GL_TEXTURE30 0x84DE
|
||||
#define GL_TEXTURE31 0x84DF
|
||||
#define GL_ACTIVE_TEXTURE 0x84E0
|
||||
#define GL_REPEAT 0x2901
|
||||
#define GL_CLAMP_TO_EDGE 0x812F
|
||||
#define GL_MIRRORED_REPEAT 0x8370
|
||||
#define GL_FLOAT_VEC2 0x8B50
|
||||
#define GL_FLOAT_VEC3 0x8B51
|
||||
#define GL_FLOAT_VEC4 0x8B52
|
||||
#define GL_INT_VEC2 0x8B53
|
||||
#define GL_INT_VEC3 0x8B54
|
||||
#define GL_INT_VEC4 0x8B55
|
||||
#define GL_BOOL 0x8B56
|
||||
#define GL_BOOL_VEC2 0x8B57
|
||||
#define GL_BOOL_VEC3 0x8B58
|
||||
#define GL_BOOL_VEC4 0x8B59
|
||||
#define GL_FLOAT_MAT2 0x8B5A
|
||||
#define GL_FLOAT_MAT3 0x8B5B
|
||||
#define GL_FLOAT_MAT4 0x8B5C
|
||||
#define GL_SAMPLER_2D 0x8B5E
|
||||
#define GL_SAMPLER_CUBE 0x8B60
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
|
||||
#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
|
||||
#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A
|
||||
#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B
|
||||
#define GL_COMPILE_STATUS 0x8B81
|
||||
#define GL_INFO_LOG_LENGTH 0x8B84
|
||||
#define GL_SHADER_SOURCE_LENGTH 0x8B88
|
||||
#define GL_SHADER_COMPILER 0x8DFA
|
||||
#define GL_SHADER_BINARY_FORMATS 0x8DF8
|
||||
#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9
|
||||
#define GL_LOW_FLOAT 0x8DF0
|
||||
#define GL_MEDIUM_FLOAT 0x8DF1
|
||||
#define GL_HIGH_FLOAT 0x8DF2
|
||||
#define GL_LOW_INT 0x8DF3
|
||||
#define GL_MEDIUM_INT 0x8DF4
|
||||
#define GL_HIGH_INT 0x8DF5
|
||||
#define GL_FRAMEBUFFER 0x8D40
|
||||
#define GL_RENDERBUFFER 0x8D41
|
||||
#define GL_RGBA4 0x8056
|
||||
#define GL_RGB5_A1 0x8057
|
||||
#define GL_RGB565 0x8D62
|
||||
#define GL_DEPTH_COMPONENT16 0x81A5
|
||||
#define GL_STENCIL_INDEX8 0x8D48
|
||||
#define GL_RENDERBUFFER_WIDTH 0x8D42
|
||||
#define GL_RENDERBUFFER_HEIGHT 0x8D43
|
||||
#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44
|
||||
#define GL_RENDERBUFFER_RED_SIZE 0x8D50
|
||||
#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51
|
||||
#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52
|
||||
#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53
|
||||
#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54
|
||||
#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2
|
||||
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3
|
||||
#define GL_COLOR_ATTACHMENT0 0x8CE0
|
||||
#define GL_DEPTH_ATTACHMENT 0x8D00
|
||||
#define GL_STENCIL_ATTACHMENT 0x8D20
|
||||
#define GL_NONE 0
|
||||
#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
|
||||
#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
|
||||
#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
|
||||
#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9
|
||||
#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
|
||||
#define GL_FRAMEBUFFER_BINDING 0x8CA6
|
||||
#define GL_RENDERBUFFER_BINDING 0x8CA7
|
||||
#define GL_MAX_RENDERBUFFER_SIZE 0x84E8
|
||||
#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
|
||||
#ifndef GL_ES_VERSION_2_0
|
||||
#define GL_ES_VERSION_2_0 1
|
||||
GLAPI int GLAD_GL_ES_VERSION_2_0;
|
||||
typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC)(GLenum texture);
|
||||
GLAPI PFNGLACTIVETEXTUREPROC glad_glActiveTexture;
|
||||
#define glActiveTexture glad_glActiveTexture
|
||||
typedef void (APIENTRYP PFNGLATTACHSHADERPROC)(GLuint program, GLuint shader);
|
||||
GLAPI PFNGLATTACHSHADERPROC glad_glAttachShader;
|
||||
#define glAttachShader glad_glAttachShader
|
||||
typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONPROC)(GLuint program, GLuint index, const GLchar *name);
|
||||
GLAPI PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation;
|
||||
#define glBindAttribLocation glad_glBindAttribLocation
|
||||
typedef void (APIENTRYP PFNGLBINDBUFFERPROC)(GLenum target, GLuint buffer);
|
||||
GLAPI PFNGLBINDBUFFERPROC glad_glBindBuffer;
|
||||
#define glBindBuffer glad_glBindBuffer
|
||||
typedef void (APIENTRYP PFNGLBINDFRAMEBUFFERPROC)(GLenum target, GLuint framebuffer);
|
||||
GLAPI PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer;
|
||||
#define glBindFramebuffer glad_glBindFramebuffer
|
||||
typedef void (APIENTRYP PFNGLBINDRENDERBUFFERPROC)(GLenum target, GLuint renderbuffer);
|
||||
GLAPI PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer;
|
||||
#define glBindRenderbuffer glad_glBindRenderbuffer
|
||||
typedef void (APIENTRYP PFNGLBINDTEXTUREPROC)(GLenum target, GLuint texture);
|
||||
GLAPI PFNGLBINDTEXTUREPROC glad_glBindTexture;
|
||||
#define glBindTexture glad_glBindTexture
|
||||
typedef void (APIENTRYP PFNGLBLENDCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
|
||||
GLAPI PFNGLBLENDCOLORPROC glad_glBlendColor;
|
||||
#define glBlendColor glad_glBlendColor
|
||||
typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC)(GLenum mode);
|
||||
GLAPI PFNGLBLENDEQUATIONPROC glad_glBlendEquation;
|
||||
#define glBlendEquation glad_glBlendEquation
|
||||
typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC)(GLenum modeRGB, GLenum modeAlpha);
|
||||
GLAPI PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate;
|
||||
#define glBlendEquationSeparate glad_glBlendEquationSeparate
|
||||
typedef void (APIENTRYP PFNGLBLENDFUNCPROC)(GLenum sfactor, GLenum dfactor);
|
||||
GLAPI PFNGLBLENDFUNCPROC glad_glBlendFunc;
|
||||
#define glBlendFunc glad_glBlendFunc
|
||||
typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
|
||||
GLAPI PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate;
|
||||
#define glBlendFuncSeparate glad_glBlendFuncSeparate
|
||||
typedef void (APIENTRYP PFNGLBUFFERDATAPROC)(GLenum target, GLsizeiptr size, const void *data, GLenum usage);
|
||||
GLAPI PFNGLBUFFERDATAPROC glad_glBufferData;
|
||||
#define glBufferData glad_glBufferData
|
||||
typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC)(GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
|
||||
GLAPI PFNGLBUFFERSUBDATAPROC glad_glBufferSubData;
|
||||
#define glBufferSubData glad_glBufferSubData
|
||||
typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC)(GLenum target);
|
||||
GLAPI PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus;
|
||||
#define glCheckFramebufferStatus glad_glCheckFramebufferStatus
|
||||
typedef void (APIENTRYP PFNGLCLEARPROC)(GLbitfield mask);
|
||||
GLAPI PFNGLCLEARPROC glad_glClear;
|
||||
#define glClear glad_glClear
|
||||
typedef void (APIENTRYP PFNGLCLEARCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
|
||||
GLAPI PFNGLCLEARCOLORPROC glad_glClearColor;
|
||||
#define glClearColor glad_glClearColor
|
||||
typedef void (APIENTRYP PFNGLCLEARDEPTHFPROC)(GLfloat d);
|
||||
GLAPI PFNGLCLEARDEPTHFPROC glad_glClearDepthf;
|
||||
#define glClearDepthf glad_glClearDepthf
|
||||
typedef void (APIENTRYP PFNGLCLEARSTENCILPROC)(GLint s);
|
||||
GLAPI PFNGLCLEARSTENCILPROC glad_glClearStencil;
|
||||
#define glClearStencil glad_glClearStencil
|
||||
typedef void (APIENTRYP PFNGLCOLORMASKPROC)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
|
||||
GLAPI PFNGLCOLORMASKPROC glad_glColorMask;
|
||||
#define glColorMask glad_glColorMask
|
||||
typedef void (APIENTRYP PFNGLCOMPILESHADERPROC)(GLuint shader);
|
||||
GLAPI PFNGLCOMPILESHADERPROC glad_glCompileShader;
|
||||
#define glCompileShader glad_glCompileShader
|
||||
typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data);
|
||||
GLAPI PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D;
|
||||
#define glCompressedTexImage2D glad_glCompressedTexImage2D
|
||||
typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data);
|
||||
GLAPI PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D;
|
||||
#define glCompressedTexSubImage2D glad_glCompressedTexSubImage2D
|
||||
typedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
|
||||
GLAPI PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D;
|
||||
#define glCopyTexImage2D glad_glCopyTexImage2D
|
||||
typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
GLAPI PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D;
|
||||
#define glCopyTexSubImage2D glad_glCopyTexSubImage2D
|
||||
typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC)(void);
|
||||
GLAPI PFNGLCREATEPROGRAMPROC glad_glCreateProgram;
|
||||
#define glCreateProgram glad_glCreateProgram
|
||||
typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC)(GLenum type);
|
||||
GLAPI PFNGLCREATESHADERPROC glad_glCreateShader;
|
||||
#define glCreateShader glad_glCreateShader
|
||||
typedef void (APIENTRYP PFNGLCULLFACEPROC)(GLenum mode);
|
||||
GLAPI PFNGLCULLFACEPROC glad_glCullFace;
|
||||
#define glCullFace glad_glCullFace
|
||||
typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC)(GLsizei n, const GLuint *buffers);
|
||||
GLAPI PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers;
|
||||
#define glDeleteBuffers glad_glDeleteBuffers
|
||||
typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC)(GLsizei n, const GLuint *framebuffers);
|
||||
GLAPI PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers;
|
||||
#define glDeleteFramebuffers glad_glDeleteFramebuffers
|
||||
typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC)(GLuint program);
|
||||
GLAPI PFNGLDELETEPROGRAMPROC glad_glDeleteProgram;
|
||||
#define glDeleteProgram glad_glDeleteProgram
|
||||
typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSPROC)(GLsizei n, const GLuint *renderbuffers);
|
||||
GLAPI PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers;
|
||||
#define glDeleteRenderbuffers glad_glDeleteRenderbuffers
|
||||
typedef void (APIENTRYP PFNGLDELETESHADERPROC)(GLuint shader);
|
||||
GLAPI PFNGLDELETESHADERPROC glad_glDeleteShader;
|
||||
#define glDeleteShader glad_glDeleteShader
|
||||
typedef void (APIENTRYP PFNGLDELETETEXTURESPROC)(GLsizei n, const GLuint *textures);
|
||||
GLAPI PFNGLDELETETEXTURESPROC glad_glDeleteTextures;
|
||||
#define glDeleteTextures glad_glDeleteTextures
|
||||
typedef void (APIENTRYP PFNGLDEPTHFUNCPROC)(GLenum func);
|
||||
GLAPI PFNGLDEPTHFUNCPROC glad_glDepthFunc;
|
||||
#define glDepthFunc glad_glDepthFunc
|
||||
typedef void (APIENTRYP PFNGLDEPTHMASKPROC)(GLboolean flag);
|
||||
GLAPI PFNGLDEPTHMASKPROC glad_glDepthMask;
|
||||
#define glDepthMask glad_glDepthMask
|
||||
typedef void (APIENTRYP PFNGLDEPTHRANGEFPROC)(GLfloat n, GLfloat f);
|
||||
GLAPI PFNGLDEPTHRANGEFPROC glad_glDepthRangef;
|
||||
#define glDepthRangef glad_glDepthRangef
|
||||
typedef void (APIENTRYP PFNGLDETACHSHADERPROC)(GLuint program, GLuint shader);
|
||||
GLAPI PFNGLDETACHSHADERPROC glad_glDetachShader;
|
||||
#define glDetachShader glad_glDetachShader
|
||||
typedef void (APIENTRYP PFNGLDISABLEPROC)(GLenum cap);
|
||||
GLAPI PFNGLDISABLEPROC glad_glDisable;
|
||||
#define glDisable glad_glDisable
|
||||
typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC)(GLuint index);
|
||||
GLAPI PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray;
|
||||
#define glDisableVertexAttribArray glad_glDisableVertexAttribArray
|
||||
typedef void (APIENTRYP PFNGLDRAWARRAYSPROC)(GLenum mode, GLint first, GLsizei count);
|
||||
GLAPI PFNGLDRAWARRAYSPROC glad_glDrawArrays;
|
||||
#define glDrawArrays glad_glDrawArrays
|
||||
typedef void (APIENTRYP PFNGLDRAWELEMENTSPROC)(GLenum mode, GLsizei count, GLenum type, const void *indices);
|
||||
GLAPI PFNGLDRAWELEMENTSPROC glad_glDrawElements;
|
||||
#define glDrawElements glad_glDrawElements
|
||||
typedef void (APIENTRYP PFNGLENABLEPROC)(GLenum cap);
|
||||
GLAPI PFNGLENABLEPROC glad_glEnable;
|
||||
#define glEnable glad_glEnable
|
||||
typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC)(GLuint index);
|
||||
GLAPI PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray;
|
||||
#define glEnableVertexAttribArray glad_glEnableVertexAttribArray
|
||||
typedef void (APIENTRYP PFNGLFINISHPROC)(void);
|
||||
GLAPI PFNGLFINISHPROC glad_glFinish;
|
||||
#define glFinish glad_glFinish
|
||||
typedef void (APIENTRYP PFNGLFLUSHPROC)(void);
|
||||
GLAPI PFNGLFLUSHPROC glad_glFlush;
|
||||
#define glFlush glad_glFlush
|
||||
typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
|
||||
GLAPI PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer;
|
||||
#define glFramebufferRenderbuffer glad_glFramebufferRenderbuffer
|
||||
typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
|
||||
GLAPI PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D;
|
||||
#define glFramebufferTexture2D glad_glFramebufferTexture2D
|
||||
typedef void (APIENTRYP PFNGLFRONTFACEPROC)(GLenum mode);
|
||||
GLAPI PFNGLFRONTFACEPROC glad_glFrontFace;
|
||||
#define glFrontFace glad_glFrontFace
|
||||
typedef void (APIENTRYP PFNGLGENBUFFERSPROC)(GLsizei n, GLuint *buffers);
|
||||
GLAPI PFNGLGENBUFFERSPROC glad_glGenBuffers;
|
||||
#define glGenBuffers glad_glGenBuffers
|
||||
typedef void (APIENTRYP PFNGLGENERATEMIPMAPPROC)(GLenum target);
|
||||
GLAPI PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap;
|
||||
#define glGenerateMipmap glad_glGenerateMipmap
|
||||
typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSPROC)(GLsizei n, GLuint *framebuffers);
|
||||
GLAPI PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers;
|
||||
#define glGenFramebuffers glad_glGenFramebuffers
|
||||
typedef void (APIENTRYP PFNGLGENRENDERBUFFERSPROC)(GLsizei n, GLuint *renderbuffers);
|
||||
GLAPI PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers;
|
||||
#define glGenRenderbuffers glad_glGenRenderbuffers
|
||||
typedef void (APIENTRYP PFNGLGENTEXTURESPROC)(GLsizei n, GLuint *textures);
|
||||
GLAPI PFNGLGENTEXTURESPROC glad_glGenTextures;
|
||||
#define glGenTextures glad_glGenTextures
|
||||
typedef void (APIENTRYP PFNGLGETACTIVEATTRIBPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
|
||||
GLAPI PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib;
|
||||
#define glGetActiveAttrib glad_glGetActiveAttrib
|
||||
typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
|
||||
GLAPI PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform;
|
||||
#define glGetActiveUniform glad_glGetActiveUniform
|
||||
typedef void (APIENTRYP PFNGLGETATTACHEDSHADERSPROC)(GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders);
|
||||
GLAPI PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders;
|
||||
#define glGetAttachedShaders glad_glGetAttachedShaders
|
||||
typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC)(GLuint program, const GLchar *name);
|
||||
GLAPI PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation;
|
||||
#define glGetAttribLocation glad_glGetAttribLocation
|
||||
typedef void (APIENTRYP PFNGLGETBOOLEANVPROC)(GLenum pname, GLboolean *data);
|
||||
GLAPI PFNGLGETBOOLEANVPROC glad_glGetBooleanv;
|
||||
#define glGetBooleanv glad_glGetBooleanv
|
||||
typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint *params);
|
||||
GLAPI PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv;
|
||||
#define glGetBufferParameteriv glad_glGetBufferParameteriv
|
||||
typedef GLenum (APIENTRYP PFNGLGETERRORPROC)(void);
|
||||
GLAPI PFNGLGETERRORPROC glad_glGetError;
|
||||
#define glGetError glad_glGetError
|
||||
typedef void (APIENTRYP PFNGLGETFLOATVPROC)(GLenum pname, GLfloat *data);
|
||||
GLAPI PFNGLGETFLOATVPROC glad_glGetFloatv;
|
||||
#define glGetFloatv glad_glGetFloatv
|
||||
typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)(GLenum target, GLenum attachment, GLenum pname, GLint *params);
|
||||
GLAPI PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv;
|
||||
#define glGetFramebufferAttachmentParameteriv glad_glGetFramebufferAttachmentParameteriv
|
||||
typedef void (APIENTRYP PFNGLGETINTEGERVPROC)(GLenum pname, GLint *data);
|
||||
GLAPI PFNGLGETINTEGERVPROC glad_glGetIntegerv;
|
||||
#define glGetIntegerv glad_glGetIntegerv
|
||||
typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC)(GLuint program, GLenum pname, GLint *params);
|
||||
GLAPI PFNGLGETPROGRAMIVPROC glad_glGetProgramiv;
|
||||
#define glGetProgramiv glad_glGetProgramiv
|
||||
typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC)(GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
|
||||
GLAPI PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog;
|
||||
#define glGetProgramInfoLog glad_glGetProgramInfoLog
|
||||
typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint *params);
|
||||
GLAPI PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv;
|
||||
#define glGetRenderbufferParameteriv glad_glGetRenderbufferParameteriv
|
||||
typedef void (APIENTRYP PFNGLGETSHADERIVPROC)(GLuint shader, GLenum pname, GLint *params);
|
||||
GLAPI PFNGLGETSHADERIVPROC glad_glGetShaderiv;
|
||||
#define glGetShaderiv glad_glGetShaderiv
|
||||
typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC)(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
|
||||
GLAPI PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog;
|
||||
#define glGetShaderInfoLog glad_glGetShaderInfoLog
|
||||
typedef void (APIENTRYP PFNGLGETSHADERPRECISIONFORMATPROC)(GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision);
|
||||
GLAPI PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat;
|
||||
#define glGetShaderPrecisionFormat glad_glGetShaderPrecisionFormat
|
||||
typedef void (APIENTRYP PFNGLGETSHADERSOURCEPROC)(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source);
|
||||
GLAPI PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource;
|
||||
#define glGetShaderSource glad_glGetShaderSource
|
||||
typedef const GLubyte * (APIENTRYP PFNGLGETSTRINGPROC)(GLenum name);
|
||||
GLAPI PFNGLGETSTRINGPROC glad_glGetString;
|
||||
#define glGetString glad_glGetString
|
||||
typedef void (APIENTRYP PFNGLGETTEXPARAMETERFVPROC)(GLenum target, GLenum pname, GLfloat *params);
|
||||
GLAPI PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv;
|
||||
#define glGetTexParameterfv glad_glGetTexParameterfv
|
||||
typedef void (APIENTRYP PFNGLGETTEXPARAMETERIVPROC)(GLenum target, GLenum pname, GLint *params);
|
||||
GLAPI PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv;
|
||||
#define glGetTexParameteriv glad_glGetTexParameteriv
|
||||
typedef void (APIENTRYP PFNGLGETUNIFORMFVPROC)(GLuint program, GLint location, GLfloat *params);
|
||||
GLAPI PFNGLGETUNIFORMFVPROC glad_glGetUniformfv;
|
||||
#define glGetUniformfv glad_glGetUniformfv
|
||||
typedef void (APIENTRYP PFNGLGETUNIFORMIVPROC)(GLuint program, GLint location, GLint *params);
|
||||
GLAPI PFNGLGETUNIFORMIVPROC glad_glGetUniformiv;
|
||||
#define glGetUniformiv glad_glGetUniformiv
|
||||
typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC)(GLuint program, const GLchar *name);
|
||||
GLAPI PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation;
|
||||
#define glGetUniformLocation glad_glGetUniformLocation
|
||||
typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVPROC)(GLuint index, GLenum pname, GLfloat *params);
|
||||
GLAPI PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv;
|
||||
#define glGetVertexAttribfv glad_glGetVertexAttribfv
|
||||
typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC)(GLuint index, GLenum pname, GLint *params);
|
||||
GLAPI PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv;
|
||||
#define glGetVertexAttribiv glad_glGetVertexAttribiv
|
||||
typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC)(GLuint index, GLenum pname, void **pointer);
|
||||
GLAPI PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv;
|
||||
#define glGetVertexAttribPointerv glad_glGetVertexAttribPointerv
|
||||
typedef void (APIENTRYP PFNGLHINTPROC)(GLenum target, GLenum mode);
|
||||
GLAPI PFNGLHINTPROC glad_glHint;
|
||||
#define glHint glad_glHint
|
||||
typedef GLboolean (APIENTRYP PFNGLISBUFFERPROC)(GLuint buffer);
|
||||
GLAPI PFNGLISBUFFERPROC glad_glIsBuffer;
|
||||
#define glIsBuffer glad_glIsBuffer
|
||||
typedef GLboolean (APIENTRYP PFNGLISENABLEDPROC)(GLenum cap);
|
||||
GLAPI PFNGLISENABLEDPROC glad_glIsEnabled;
|
||||
#define glIsEnabled glad_glIsEnabled
|
||||
typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFERPROC)(GLuint framebuffer);
|
||||
GLAPI PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer;
|
||||
#define glIsFramebuffer glad_glIsFramebuffer
|
||||
typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC)(GLuint program);
|
||||
GLAPI PFNGLISPROGRAMPROC glad_glIsProgram;
|
||||
#define glIsProgram glad_glIsProgram
|
||||
typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFERPROC)(GLuint renderbuffer);
|
||||
GLAPI PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer;
|
||||
#define glIsRenderbuffer glad_glIsRenderbuffer
|
||||
typedef GLboolean (APIENTRYP PFNGLISSHADERPROC)(GLuint shader);
|
||||
GLAPI PFNGLISSHADERPROC glad_glIsShader;
|
||||
#define glIsShader glad_glIsShader
|
||||
typedef GLboolean (APIENTRYP PFNGLISTEXTUREPROC)(GLuint texture);
|
||||
GLAPI PFNGLISTEXTUREPROC glad_glIsTexture;
|
||||
#define glIsTexture glad_glIsTexture
|
||||
typedef void (APIENTRYP PFNGLLINEWIDTHPROC)(GLfloat width);
|
||||
GLAPI PFNGLLINEWIDTHPROC glad_glLineWidth;
|
||||
#define glLineWidth glad_glLineWidth
|
||||
typedef void (APIENTRYP PFNGLLINKPROGRAMPROC)(GLuint program);
|
||||
GLAPI PFNGLLINKPROGRAMPROC glad_glLinkProgram;
|
||||
#define glLinkProgram glad_glLinkProgram
|
||||
typedef void (APIENTRYP PFNGLPIXELSTOREIPROC)(GLenum pname, GLint param);
|
||||
GLAPI PFNGLPIXELSTOREIPROC glad_glPixelStorei;
|
||||
#define glPixelStorei glad_glPixelStorei
|
||||
typedef void (APIENTRYP PFNGLPOLYGONOFFSETPROC)(GLfloat factor, GLfloat units);
|
||||
GLAPI PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset;
|
||||
#define glPolygonOffset glad_glPolygonOffset
|
||||
typedef void (APIENTRYP PFNGLREADPIXELSPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);
|
||||
GLAPI PFNGLREADPIXELSPROC glad_glReadPixels;
|
||||
#define glReadPixels glad_glReadPixels
|
||||
typedef void (APIENTRYP PFNGLRELEASESHADERCOMPILERPROC)(void);
|
||||
GLAPI PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler;
|
||||
#define glReleaseShaderCompiler glad_glReleaseShaderCompiler
|
||||
typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
|
||||
GLAPI PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage;
|
||||
#define glRenderbufferStorage glad_glRenderbufferStorage
|
||||
typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC)(GLfloat value, GLboolean invert);
|
||||
GLAPI PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage;
|
||||
#define glSampleCoverage glad_glSampleCoverage
|
||||
typedef void (APIENTRYP PFNGLSCISSORPROC)(GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
GLAPI PFNGLSCISSORPROC glad_glScissor;
|
||||
#define glScissor glad_glScissor
|
||||
typedef void (APIENTRYP PFNGLSHADERBINARYPROC)(GLsizei count, const GLuint *shaders, GLenum binaryFormat, const void *binary, GLsizei length);
|
||||
GLAPI PFNGLSHADERBINARYPROC glad_glShaderBinary;
|
||||
#define glShaderBinary glad_glShaderBinary
|
||||
typedef void (APIENTRYP PFNGLSHADERSOURCEPROC)(GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
|
||||
GLAPI PFNGLSHADERSOURCEPROC glad_glShaderSource;
|
||||
#define glShaderSource glad_glShaderSource
|
||||
typedef void (APIENTRYP PFNGLSTENCILFUNCPROC)(GLenum func, GLint ref, GLuint mask);
|
||||
GLAPI PFNGLSTENCILFUNCPROC glad_glStencilFunc;
|
||||
#define glStencilFunc glad_glStencilFunc
|
||||
typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC)(GLenum face, GLenum func, GLint ref, GLuint mask);
|
||||
GLAPI PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate;
|
||||
#define glStencilFuncSeparate glad_glStencilFuncSeparate
|
||||
typedef void (APIENTRYP PFNGLSTENCILMASKPROC)(GLuint mask);
|
||||
GLAPI PFNGLSTENCILMASKPROC glad_glStencilMask;
|
||||
#define glStencilMask glad_glStencilMask
|
||||
typedef void (APIENTRYP PFNGLSTENCILMASKSEPARATEPROC)(GLenum face, GLuint mask);
|
||||
GLAPI PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate;
|
||||
#define glStencilMaskSeparate glad_glStencilMaskSeparate
|
||||
typedef void (APIENTRYP PFNGLSTENCILOPPROC)(GLenum fail, GLenum zfail, GLenum zpass);
|
||||
GLAPI PFNGLSTENCILOPPROC glad_glStencilOp;
|
||||
#define glStencilOp glad_glStencilOp
|
||||
typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEPROC)(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
|
||||
GLAPI PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate;
|
||||
#define glStencilOpSeparate glad_glStencilOpSeparate
|
||||
typedef void (APIENTRYP PFNGLTEXIMAGE2DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
|
||||
GLAPI PFNGLTEXIMAGE2DPROC glad_glTexImage2D;
|
||||
#define glTexImage2D glad_glTexImage2D
|
||||
typedef void (APIENTRYP PFNGLTEXPARAMETERFPROC)(GLenum target, GLenum pname, GLfloat param);
|
||||
GLAPI PFNGLTEXPARAMETERFPROC glad_glTexParameterf;
|
||||
#define glTexParameterf glad_glTexParameterf
|
||||
typedef void (APIENTRYP PFNGLTEXPARAMETERFVPROC)(GLenum target, GLenum pname, const GLfloat *params);
|
||||
GLAPI PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv;
|
||||
#define glTexParameterfv glad_glTexParameterfv
|
||||
typedef void (APIENTRYP PFNGLTEXPARAMETERIPROC)(GLenum target, GLenum pname, GLint param);
|
||||
GLAPI PFNGLTEXPARAMETERIPROC glad_glTexParameteri;
|
||||
#define glTexParameteri glad_glTexParameteri
|
||||
typedef void (APIENTRYP PFNGLTEXPARAMETERIVPROC)(GLenum target, GLenum pname, const GLint *params);
|
||||
GLAPI PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv;
|
||||
#define glTexParameteriv glad_glTexParameteriv
|
||||
typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
|
||||
GLAPI PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D;
|
||||
#define glTexSubImage2D glad_glTexSubImage2D
|
||||
typedef void (APIENTRYP PFNGLUNIFORM1FPROC)(GLint location, GLfloat v0);
|
||||
GLAPI PFNGLUNIFORM1FPROC glad_glUniform1f;
|
||||
#define glUniform1f glad_glUniform1f
|
||||
typedef void (APIENTRYP PFNGLUNIFORM1FVPROC)(GLint location, GLsizei count, const GLfloat *value);
|
||||
GLAPI PFNGLUNIFORM1FVPROC glad_glUniform1fv;
|
||||
#define glUniform1fv glad_glUniform1fv
|
||||
typedef void (APIENTRYP PFNGLUNIFORM1IPROC)(GLint location, GLint v0);
|
||||
GLAPI PFNGLUNIFORM1IPROC glad_glUniform1i;
|
||||
#define glUniform1i glad_glUniform1i
|
||||
typedef void (APIENTRYP PFNGLUNIFORM1IVPROC)(GLint location, GLsizei count, const GLint *value);
|
||||
GLAPI PFNGLUNIFORM1IVPROC glad_glUniform1iv;
|
||||
#define glUniform1iv glad_glUniform1iv
|
||||
typedef void (APIENTRYP PFNGLUNIFORM2FPROC)(GLint location, GLfloat v0, GLfloat v1);
|
||||
GLAPI PFNGLUNIFORM2FPROC glad_glUniform2f;
|
||||
#define glUniform2f glad_glUniform2f
|
||||
typedef void (APIENTRYP PFNGLUNIFORM2FVPROC)(GLint location, GLsizei count, const GLfloat *value);
|
||||
GLAPI PFNGLUNIFORM2FVPROC glad_glUniform2fv;
|
||||
#define glUniform2fv glad_glUniform2fv
|
||||
typedef void (APIENTRYP PFNGLUNIFORM2IPROC)(GLint location, GLint v0, GLint v1);
|
||||
GLAPI PFNGLUNIFORM2IPROC glad_glUniform2i;
|
||||
#define glUniform2i glad_glUniform2i
|
||||
typedef void (APIENTRYP PFNGLUNIFORM2IVPROC)(GLint location, GLsizei count, const GLint *value);
|
||||
GLAPI PFNGLUNIFORM2IVPROC glad_glUniform2iv;
|
||||
#define glUniform2iv glad_glUniform2iv
|
||||
typedef void (APIENTRYP PFNGLUNIFORM3FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
|
||||
GLAPI PFNGLUNIFORM3FPROC glad_glUniform3f;
|
||||
#define glUniform3f glad_glUniform3f
|
||||
typedef void (APIENTRYP PFNGLUNIFORM3FVPROC)(GLint location, GLsizei count, const GLfloat *value);
|
||||
GLAPI PFNGLUNIFORM3FVPROC glad_glUniform3fv;
|
||||
#define glUniform3fv glad_glUniform3fv
|
||||
typedef void (APIENTRYP PFNGLUNIFORM3IPROC)(GLint location, GLint v0, GLint v1, GLint v2);
|
||||
GLAPI PFNGLUNIFORM3IPROC glad_glUniform3i;
|
||||
#define glUniform3i glad_glUniform3i
|
||||
typedef void (APIENTRYP PFNGLUNIFORM3IVPROC)(GLint location, GLsizei count, const GLint *value);
|
||||
GLAPI PFNGLUNIFORM3IVPROC glad_glUniform3iv;
|
||||
#define glUniform3iv glad_glUniform3iv
|
||||
typedef void (APIENTRYP PFNGLUNIFORM4FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
|
||||
GLAPI PFNGLUNIFORM4FPROC glad_glUniform4f;
|
||||
#define glUniform4f glad_glUniform4f
|
||||
typedef void (APIENTRYP PFNGLUNIFORM4FVPROC)(GLint location, GLsizei count, const GLfloat *value);
|
||||
GLAPI PFNGLUNIFORM4FVPROC glad_glUniform4fv;
|
||||
#define glUniform4fv glad_glUniform4fv
|
||||
typedef void (APIENTRYP PFNGLUNIFORM4IPROC)(GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
|
||||
GLAPI PFNGLUNIFORM4IPROC glad_glUniform4i;
|
||||
#define glUniform4i glad_glUniform4i
|
||||
typedef void (APIENTRYP PFNGLUNIFORM4IVPROC)(GLint location, GLsizei count, const GLint *value);
|
||||
GLAPI PFNGLUNIFORM4IVPROC glad_glUniform4iv;
|
||||
#define glUniform4iv glad_glUniform4iv
|
||||
typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
|
||||
GLAPI PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv;
|
||||
#define glUniformMatrix2fv glad_glUniformMatrix2fv
|
||||
typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
|
||||
GLAPI PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv;
|
||||
#define glUniformMatrix3fv glad_glUniformMatrix3fv
|
||||
typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
|
||||
GLAPI PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv;
|
||||
#define glUniformMatrix4fv glad_glUniformMatrix4fv
|
||||
typedef void (APIENTRYP PFNGLUSEPROGRAMPROC)(GLuint program);
|
||||
GLAPI PFNGLUSEPROGRAMPROC glad_glUseProgram;
|
||||
#define glUseProgram glad_glUseProgram
|
||||
typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC)(GLuint program);
|
||||
GLAPI PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram;
|
||||
#define glValidateProgram glad_glValidateProgram
|
||||
typedef void (APIENTRYP PFNGLVERTEXATTRIB1FPROC)(GLuint index, GLfloat x);
|
||||
GLAPI PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f;
|
||||
#define glVertexAttrib1f glad_glVertexAttrib1f
|
||||
typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVPROC)(GLuint index, const GLfloat *v);
|
||||
GLAPI PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv;
|
||||
#define glVertexAttrib1fv glad_glVertexAttrib1fv
|
||||
typedef void (APIENTRYP PFNGLVERTEXATTRIB2FPROC)(GLuint index, GLfloat x, GLfloat y);
|
||||
GLAPI PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f;
|
||||
#define glVertexAttrib2f glad_glVertexAttrib2f
|
||||
typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVPROC)(GLuint index, const GLfloat *v);
|
||||
GLAPI PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv;
|
||||
#define glVertexAttrib2fv glad_glVertexAttrib2fv
|
||||
typedef void (APIENTRYP PFNGLVERTEXATTRIB3FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z);
|
||||
GLAPI PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f;
|
||||
#define glVertexAttrib3f glad_glVertexAttrib3f
|
||||
typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVPROC)(GLuint index, const GLfloat *v);
|
||||
GLAPI PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv;
|
||||
#define glVertexAttrib3fv glad_glVertexAttrib3fv
|
||||
typedef void (APIENTRYP PFNGLVERTEXATTRIB4FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
|
||||
GLAPI PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f;
|
||||
#define glVertexAttrib4f glad_glVertexAttrib4f
|
||||
typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVPROC)(GLuint index, const GLfloat *v);
|
||||
GLAPI PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv;
|
||||
#define glVertexAttrib4fv glad_glVertexAttrib4fv
|
||||
typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
|
||||
GLAPI PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer;
|
||||
#define glVertexAttribPointer glad_glVertexAttribPointer
|
||||
typedef void (APIENTRYP PFNGLVIEWPORTPROC)(GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
GLAPI PFNGLVIEWPORTPROC glad_glViewport;
|
||||
#define glViewport glad_glViewport
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
267
source/common/rendering/gles/glad/include/glad/glad_egl.h
Normal file
267
source/common/rendering/gles/glad/include/glad/glad_egl.h
Normal file
|
@ -0,0 +1,267 @@
|
|||
/*
|
||||
|
||||
EGL loader generated by glad 0.1.34 on Sat Feb 20 22:54:45 2021.
|
||||
|
||||
Language/Generator: C/C++
|
||||
Specification: egl
|
||||
APIs: egl=1.4
|
||||
Profile: -
|
||||
Extensions:
|
||||
|
||||
Loader: True
|
||||
Local files: False
|
||||
Omit khrplatform: False
|
||||
Reproducible: False
|
||||
|
||||
Commandline:
|
||||
--api="egl=1.4" --generator="c" --spec="egl" --extensions=""
|
||||
Online:
|
||||
https://glad.dav1d.de/#language=c&specification=egl&loader=on&api=egl%3D1.4
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __glad_egl_h_
|
||||
|
||||
#ifdef __egl_h_
|
||||
#error EGL header already included, remove this include, glad already provides it
|
||||
#endif
|
||||
|
||||
#define __glad_egl_h_
|
||||
#define __egl_h_
|
||||
|
||||
#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
|
||||
#define APIENTRY __stdcall
|
||||
#endif
|
||||
|
||||
#ifndef APIENTRY
|
||||
#define APIENTRY
|
||||
#endif
|
||||
#ifndef APIENTRYP
|
||||
#define APIENTRYP APIENTRY *
|
||||
#endif
|
||||
#ifndef GLAPI
|
||||
#define GLAPI extern
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void* (* GLADloadproc)(const char *name);
|
||||
|
||||
GLAPI int gladLoadEGL(void);
|
||||
GLAPI int gladLoadEGLLoader(GLADloadproc);
|
||||
|
||||
#include <KHR/khrplatform.h>
|
||||
#include <EGL/eglplatform.h>
|
||||
|
||||
#define EGL_CAST(X,V) (X)(V)
|
||||
|
||||
struct AHardwareBuffer;
|
||||
struct wl_buffer;
|
||||
struct wl_display;
|
||||
struct wl_resource;
|
||||
typedef unsigned int EGLBoolean;
|
||||
typedef unsigned int EGLenum;
|
||||
typedef intptr_t EGLAttribKHR;
|
||||
typedef intptr_t EGLAttrib;
|
||||
typedef void *EGLClientBuffer;
|
||||
typedef void *EGLConfig;
|
||||
typedef void *EGLContext;
|
||||
typedef void *EGLDeviceEXT;
|
||||
typedef void *EGLDisplay;
|
||||
typedef void *EGLImage;
|
||||
typedef void *EGLImageKHR;
|
||||
typedef void *EGLLabelKHR;
|
||||
typedef void *EGLObjectKHR;
|
||||
typedef void *EGLOutputLayerEXT;
|
||||
typedef void *EGLOutputPortEXT;
|
||||
typedef void *EGLStreamKHR;
|
||||
typedef void *EGLSurface;
|
||||
typedef void *EGLSync;
|
||||
typedef void *EGLSyncKHR;
|
||||
typedef void *EGLSyncNV;
|
||||
typedef void (*__eglMustCastToProperFunctionPointerType)(void);
|
||||
typedef khronos_utime_nanoseconds_t EGLTimeKHR;
|
||||
typedef khronos_utime_nanoseconds_t EGLTime;
|
||||
typedef khronos_utime_nanoseconds_t EGLTimeNV;
|
||||
typedef khronos_utime_nanoseconds_t EGLuint64NV;
|
||||
typedef khronos_uint64_t EGLuint64KHR;
|
||||
typedef khronos_stime_nanoseconds_t EGLnsecsANDROID;
|
||||
typedef int EGLNativeFileDescriptorKHR;
|
||||
typedef khronos_ssize_t EGLsizeiANDROID;
|
||||
typedef void (*EGLSetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, const void *value, EGLsizeiANDROID valueSize);
|
||||
typedef EGLsizeiANDROID (*EGLGetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, void *value, EGLsizeiANDROID valueSize);
|
||||
struct EGLClientPixmapHI {
|
||||
void *pData;
|
||||
EGLint iWidth;
|
||||
EGLint iHeight;
|
||||
EGLint iStride;
|
||||
};
|
||||
typedef void (APIENTRY *EGLDEBUGPROCKHR)(EGLenum error,const char *command,EGLint messageType,EGLLabelKHR threadLabel,EGLLabelKHR objectLabel,const char* message);
|
||||
#define PFNEGLBINDWAYLANDDISPLAYWL PFNEGLBINDWAYLANDDISPLAYWLPROC
|
||||
#define PFNEGLUNBINDWAYLANDDISPLAYWL PFNEGLUNBINDWAYLANDDISPLAYWLPROC
|
||||
#define PFNEGLQUERYWAYLANDBUFFERWL PFNEGLQUERYWAYLANDBUFFERWLPROC
|
||||
#define PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWL PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWLPROC
|
||||
#define EGL_ALPHA_SIZE 0x3021
|
||||
#define EGL_BAD_ACCESS 0x3002
|
||||
#define EGL_BAD_ALLOC 0x3003
|
||||
#define EGL_BAD_ATTRIBUTE 0x3004
|
||||
#define EGL_BAD_CONFIG 0x3005
|
||||
#define EGL_BAD_CONTEXT 0x3006
|
||||
#define EGL_BAD_CURRENT_SURFACE 0x3007
|
||||
#define EGL_BAD_DISPLAY 0x3008
|
||||
#define EGL_BAD_MATCH 0x3009
|
||||
#define EGL_BAD_NATIVE_PIXMAP 0x300A
|
||||
#define EGL_BAD_NATIVE_WINDOW 0x300B
|
||||
#define EGL_BAD_PARAMETER 0x300C
|
||||
#define EGL_BAD_SURFACE 0x300D
|
||||
#define EGL_BLUE_SIZE 0x3022
|
||||
#define EGL_BUFFER_SIZE 0x3020
|
||||
#define EGL_CONFIG_CAVEAT 0x3027
|
||||
#define EGL_CONFIG_ID 0x3028
|
||||
#define EGL_CORE_NATIVE_ENGINE 0x305B
|
||||
#define EGL_DEPTH_SIZE 0x3025
|
||||
#define EGL_DONT_CARE EGL_CAST(EGLint,-1)
|
||||
#define EGL_DRAW 0x3059
|
||||
#define EGL_EXTENSIONS 0x3055
|
||||
#define EGL_FALSE 0
|
||||
#define EGL_GREEN_SIZE 0x3023
|
||||
#define EGL_HEIGHT 0x3056
|
||||
#define EGL_LARGEST_PBUFFER 0x3058
|
||||
#define EGL_LEVEL 0x3029
|
||||
#define EGL_MAX_PBUFFER_HEIGHT 0x302A
|
||||
#define EGL_MAX_PBUFFER_PIXELS 0x302B
|
||||
#define EGL_MAX_PBUFFER_WIDTH 0x302C
|
||||
#define EGL_NATIVE_RENDERABLE 0x302D
|
||||
#define EGL_NATIVE_VISUAL_ID 0x302E
|
||||
#define EGL_NATIVE_VISUAL_TYPE 0x302F
|
||||
#define EGL_NONE 0x3038
|
||||
#define EGL_NON_CONFORMANT_CONFIG 0x3051
|
||||
#define EGL_NOT_INITIALIZED 0x3001
|
||||
#define EGL_NO_CONTEXT EGL_CAST(EGLContext,0)
|
||||
#define EGL_NO_DISPLAY EGL_CAST(EGLDisplay,0)
|
||||
#define EGL_NO_SURFACE EGL_CAST(EGLSurface,0)
|
||||
#define EGL_PBUFFER_BIT 0x0001
|
||||
#define EGL_PIXMAP_BIT 0x0002
|
||||
#define EGL_READ 0x305A
|
||||
#define EGL_RED_SIZE 0x3024
|
||||
#define EGL_SAMPLES 0x3031
|
||||
#define EGL_SAMPLE_BUFFERS 0x3032
|
||||
#define EGL_SLOW_CONFIG 0x3050
|
||||
#define EGL_STENCIL_SIZE 0x3026
|
||||
#define EGL_SUCCESS 0x3000
|
||||
#define EGL_SURFACE_TYPE 0x3033
|
||||
#define EGL_TRANSPARENT_BLUE_VALUE 0x3035
|
||||
#define EGL_TRANSPARENT_GREEN_VALUE 0x3036
|
||||
#define EGL_TRANSPARENT_RED_VALUE 0x3037
|
||||
#define EGL_TRANSPARENT_RGB 0x3052
|
||||
#define EGL_TRANSPARENT_TYPE 0x3034
|
||||
#define EGL_TRUE 1
|
||||
#define EGL_VENDOR 0x3053
|
||||
#define EGL_VERSION 0x3054
|
||||
#define EGL_WIDTH 0x3057
|
||||
#define EGL_WINDOW_BIT 0x0004
|
||||
#define EGL_BACK_BUFFER 0x3084
|
||||
#define EGL_BIND_TO_TEXTURE_RGB 0x3039
|
||||
#define EGL_BIND_TO_TEXTURE_RGBA 0x303A
|
||||
#define EGL_CONTEXT_LOST 0x300E
|
||||
#define EGL_MIN_SWAP_INTERVAL 0x303B
|
||||
#define EGL_MAX_SWAP_INTERVAL 0x303C
|
||||
#define EGL_MIPMAP_TEXTURE 0x3082
|
||||
#define EGL_MIPMAP_LEVEL 0x3083
|
||||
#define EGL_NO_TEXTURE 0x305C
|
||||
#define EGL_TEXTURE_2D 0x305F
|
||||
#define EGL_TEXTURE_FORMAT 0x3080
|
||||
#define EGL_TEXTURE_RGB 0x305D
|
||||
#define EGL_TEXTURE_RGBA 0x305E
|
||||
#define EGL_TEXTURE_TARGET 0x3081
|
||||
#define EGL_ALPHA_FORMAT 0x3088
|
||||
#define EGL_ALPHA_FORMAT_NONPRE 0x308B
|
||||
#define EGL_ALPHA_FORMAT_PRE 0x308C
|
||||
#define EGL_ALPHA_MASK_SIZE 0x303E
|
||||
#define EGL_BUFFER_PRESERVED 0x3094
|
||||
#define EGL_BUFFER_DESTROYED 0x3095
|
||||
#define EGL_CLIENT_APIS 0x308D
|
||||
#define EGL_COLORSPACE 0x3087
|
||||
#define EGL_COLORSPACE_sRGB 0x3089
|
||||
#define EGL_COLORSPACE_LINEAR 0x308A
|
||||
#define EGL_COLOR_BUFFER_TYPE 0x303F
|
||||
#define EGL_CONTEXT_CLIENT_TYPE 0x3097
|
||||
#define EGL_DISPLAY_SCALING 10000
|
||||
#define EGL_HORIZONTAL_RESOLUTION 0x3090
|
||||
#define EGL_LUMINANCE_BUFFER 0x308F
|
||||
#define EGL_LUMINANCE_SIZE 0x303D
|
||||
#define EGL_OPENGL_ES_BIT 0x0001
|
||||
#define EGL_OPENVG_BIT 0x0002
|
||||
#define EGL_OPENGL_ES_API 0x30A0
|
||||
#define EGL_OPENVG_API 0x30A1
|
||||
#define EGL_OPENVG_IMAGE 0x3096
|
||||
#define EGL_PIXEL_ASPECT_RATIO 0x3092
|
||||
#define EGL_RENDERABLE_TYPE 0x3040
|
||||
#define EGL_RENDER_BUFFER 0x3086
|
||||
#define EGL_RGB_BUFFER 0x308E
|
||||
#define EGL_SINGLE_BUFFER 0x3085
|
||||
#define EGL_SWAP_BEHAVIOR 0x3093
|
||||
#define EGL_UNKNOWN EGL_CAST(EGLint,-1)
|
||||
#define EGL_VERTICAL_RESOLUTION 0x3091
|
||||
#define EGL_CONFORMANT 0x3042
|
||||
#define EGL_CONTEXT_CLIENT_VERSION 0x3098
|
||||
#define EGL_MATCH_NATIVE_PIXMAP 0x3041
|
||||
#define EGL_OPENGL_ES2_BIT 0x0004
|
||||
#define EGL_VG_ALPHA_FORMAT 0x3088
|
||||
#define EGL_VG_ALPHA_FORMAT_NONPRE 0x308B
|
||||
#define EGL_VG_ALPHA_FORMAT_PRE 0x308C
|
||||
#define EGL_VG_ALPHA_FORMAT_PRE_BIT 0x0040
|
||||
#define EGL_VG_COLORSPACE 0x3087
|
||||
#define EGL_VG_COLORSPACE_sRGB 0x3089
|
||||
#define EGL_VG_COLORSPACE_LINEAR 0x308A
|
||||
#define EGL_VG_COLORSPACE_LINEAR_BIT 0x0020
|
||||
#define EGL_DEFAULT_DISPLAY EGL_CAST(EGLNativeDisplayType,0)
|
||||
#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200
|
||||
#define EGL_MULTISAMPLE_RESOLVE 0x3099
|
||||
#define EGL_MULTISAMPLE_RESOLVE_DEFAULT 0x309A
|
||||
#define EGL_MULTISAMPLE_RESOLVE_BOX 0x309B
|
||||
#define EGL_OPENGL_API 0x30A2
|
||||
#define EGL_OPENGL_BIT 0x0008
|
||||
#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400
|
||||
EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
|
||||
EGLBoolean eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target);
|
||||
EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
|
||||
EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
|
||||
EGLSurface eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list);
|
||||
EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list);
|
||||
EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx);
|
||||
EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface);
|
||||
EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
|
||||
EGLBoolean eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
|
||||
EGLDisplay eglGetCurrentDisplay(void);
|
||||
EGLSurface eglGetCurrentSurface(EGLint readdraw);
|
||||
EGLDisplay eglGetDisplay(EGLNativeDisplayType display_id);
|
||||
EGLint eglGetError(void);
|
||||
__eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname);
|
||||
EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor);
|
||||
EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
|
||||
EGLBoolean eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value);
|
||||
const char *eglQueryString(EGLDisplay dpy, EGLint name);
|
||||
EGLBoolean eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
|
||||
EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface);
|
||||
EGLBoolean eglTerminate(EGLDisplay dpy);
|
||||
EGLBoolean eglWaitGL(void);
|
||||
EGLBoolean eglWaitNative(EGLint engine);
|
||||
EGLBoolean eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
|
||||
EGLBoolean eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
|
||||
EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
|
||||
EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval);
|
||||
EGLBoolean eglBindAPI(EGLenum api);
|
||||
EGLenum eglQueryAPI(void);
|
||||
EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list);
|
||||
EGLBoolean eglReleaseThread(void);
|
||||
EGLBoolean eglWaitClient(void);
|
||||
EGLContext eglGetCurrentContext(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
475
source/common/rendering/gles/glad/src/glad.c
Normal file
475
source/common/rendering/gles/glad/src/glad.c
Normal file
|
@ -0,0 +1,475 @@
|
|||
/*
|
||||
|
||||
OpenGL ES loader generated by glad 0.1.34 on Fri Mar 19 17:04:24 2021.
|
||||
|
||||
Language/Generator: C/C++
|
||||
Specification: gl
|
||||
APIs: gles2=2.0
|
||||
Profile: compatibility
|
||||
Extensions:
|
||||
|
||||
Loader: True
|
||||
Local files: False
|
||||
Omit khrplatform: False
|
||||
Reproducible: False
|
||||
|
||||
Commandline:
|
||||
--profile="compatibility" --api="gles2=2.0" --generator="c" --spec="gl" --extensions=""
|
||||
Online:
|
||||
https://glad.dav1d.de/#profile=compatibility&language=c&specification=gl&loader=on&api=gles2%3D2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <glad/glad.h>
|
||||
|
||||
struct gladGLversionStruct GLVersion = { 0, 0 };
|
||||
|
||||
#if defined(GL_ES_VERSION_3_0) || defined(GL_VERSION_3_0)
|
||||
#define _GLAD_IS_SOME_NEW_VERSION 1
|
||||
#endif
|
||||
|
||||
static int max_loaded_major;
|
||||
static int max_loaded_minor;
|
||||
|
||||
static const char *exts = NULL;
|
||||
static int num_exts_i = 0;
|
||||
static char **exts_i = NULL;
|
||||
|
||||
static int get_exts(void) {
|
||||
#ifdef _GLAD_IS_SOME_NEW_VERSION
|
||||
if(max_loaded_major < 3) {
|
||||
#endif
|
||||
exts = (const char *)glGetString(GL_EXTENSIONS);
|
||||
#ifdef _GLAD_IS_SOME_NEW_VERSION
|
||||
} else {
|
||||
unsigned int index;
|
||||
|
||||
num_exts_i = 0;
|
||||
glGetIntegerv(GL_NUM_EXTENSIONS, &num_exts_i);
|
||||
if (num_exts_i > 0) {
|
||||
exts_i = (char **)malloc((size_t)num_exts_i * (sizeof *exts_i));
|
||||
}
|
||||
|
||||
if (exts_i == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for(index = 0; index < (unsigned)num_exts_i; index++) {
|
||||
const char *gl_str_tmp = (const char*)glGetStringi(GL_EXTENSIONS, index);
|
||||
size_t len = strlen(gl_str_tmp);
|
||||
|
||||
char *local_str = (char*)malloc((len+1) * sizeof(char));
|
||||
if(local_str != NULL) {
|
||||
memcpy(local_str, gl_str_tmp, (len+1) * sizeof(char));
|
||||
}
|
||||
exts_i[index] = local_str;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void free_exts(void) {
|
||||
if (exts_i != NULL) {
|
||||
int index;
|
||||
for(index = 0; index < num_exts_i; index++) {
|
||||
free((char *)exts_i[index]);
|
||||
}
|
||||
free((void *)exts_i);
|
||||
exts_i = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int has_ext(const char *ext) {
|
||||
#ifdef _GLAD_IS_SOME_NEW_VERSION
|
||||
if(max_loaded_major < 3) {
|
||||
#endif
|
||||
const char *extensions;
|
||||
const char *loc;
|
||||
const char *terminator;
|
||||
extensions = exts;
|
||||
if(extensions == NULL || ext == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
while(1) {
|
||||
loc = strstr(extensions, ext);
|
||||
if(loc == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
terminator = loc + strlen(ext);
|
||||
if((loc == extensions || *(loc - 1) == ' ') &&
|
||||
(*terminator == ' ' || *terminator == '\0')) {
|
||||
return 1;
|
||||
}
|
||||
extensions = terminator;
|
||||
}
|
||||
#ifdef _GLAD_IS_SOME_NEW_VERSION
|
||||
} else {
|
||||
int index;
|
||||
if(exts_i == NULL) return 0;
|
||||
for(index = 0; index < num_exts_i; index++) {
|
||||
const char *e = exts_i[index];
|
||||
|
||||
if(exts_i[index] != NULL && strcmp(e, ext) == 0) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
int GLAD_GL_ES_VERSION_2_0 = 0;
|
||||
PFNGLACTIVETEXTUREPROC glad_glActiveTexture = NULL;
|
||||
PFNGLATTACHSHADERPROC glad_glAttachShader = NULL;
|
||||
PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation = NULL;
|
||||
PFNGLBINDBUFFERPROC glad_glBindBuffer = NULL;
|
||||
PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer = NULL;
|
||||
PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer = NULL;
|
||||
PFNGLBINDTEXTUREPROC glad_glBindTexture = NULL;
|
||||
PFNGLBLENDCOLORPROC glad_glBlendColor = NULL;
|
||||
PFNGLBLENDEQUATIONPROC glad_glBlendEquation = NULL;
|
||||
PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate = NULL;
|
||||
PFNGLBLENDFUNCPROC glad_glBlendFunc = NULL;
|
||||
PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate = NULL;
|
||||
PFNGLBUFFERDATAPROC glad_glBufferData = NULL;
|
||||
PFNGLBUFFERSUBDATAPROC glad_glBufferSubData = NULL;
|
||||
PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus = NULL;
|
||||
PFNGLCLEARPROC glad_glClear = NULL;
|
||||
PFNGLCLEARCOLORPROC glad_glClearColor = NULL;
|
||||
PFNGLCLEARDEPTHFPROC glad_glClearDepthf = NULL;
|
||||
PFNGLCLEARSTENCILPROC glad_glClearStencil = NULL;
|
||||
PFNGLCOLORMASKPROC glad_glColorMask = NULL;
|
||||
PFNGLCOMPILESHADERPROC glad_glCompileShader = NULL;
|
||||
PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D = NULL;
|
||||
PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D = NULL;
|
||||
PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D = NULL;
|
||||
PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D = NULL;
|
||||
PFNGLCREATEPROGRAMPROC glad_glCreateProgram = NULL;
|
||||
PFNGLCREATESHADERPROC glad_glCreateShader = NULL;
|
||||
PFNGLCULLFACEPROC glad_glCullFace = NULL;
|
||||
PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers = NULL;
|
||||
PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers = NULL;
|
||||
PFNGLDELETEPROGRAMPROC glad_glDeleteProgram = NULL;
|
||||
PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers = NULL;
|
||||
PFNGLDELETESHADERPROC glad_glDeleteShader = NULL;
|
||||
PFNGLDELETETEXTURESPROC glad_glDeleteTextures = NULL;
|
||||
PFNGLDEPTHFUNCPROC glad_glDepthFunc = NULL;
|
||||
PFNGLDEPTHMASKPROC glad_glDepthMask = NULL;
|
||||
PFNGLDEPTHRANGEFPROC glad_glDepthRangef = NULL;
|
||||
PFNGLDETACHSHADERPROC glad_glDetachShader = NULL;
|
||||
PFNGLDISABLEPROC glad_glDisable = NULL;
|
||||
PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray = NULL;
|
||||
PFNGLDRAWARRAYSPROC glad_glDrawArrays = NULL;
|
||||
PFNGLDRAWELEMENTSPROC glad_glDrawElements = NULL;
|
||||
PFNGLENABLEPROC glad_glEnable = NULL;
|
||||
PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray = NULL;
|
||||
PFNGLFINISHPROC glad_glFinish = NULL;
|
||||
PFNGLFLUSHPROC glad_glFlush = NULL;
|
||||
PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer = NULL;
|
||||
PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D = NULL;
|
||||
PFNGLFRONTFACEPROC glad_glFrontFace = NULL;
|
||||
PFNGLGENBUFFERSPROC glad_glGenBuffers = NULL;
|
||||
PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers = NULL;
|
||||
PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers = NULL;
|
||||
PFNGLGENTEXTURESPROC glad_glGenTextures = NULL;
|
||||
PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap = NULL;
|
||||
PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib = NULL;
|
||||
PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform = NULL;
|
||||
PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders = NULL;
|
||||
PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation = NULL;
|
||||
PFNGLGETBOOLEANVPROC glad_glGetBooleanv = NULL;
|
||||
PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv = NULL;
|
||||
PFNGLGETERRORPROC glad_glGetError = NULL;
|
||||
PFNGLGETFLOATVPROC glad_glGetFloatv = NULL;
|
||||
PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv = NULL;
|
||||
PFNGLGETINTEGERVPROC glad_glGetIntegerv = NULL;
|
||||
PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog = NULL;
|
||||
PFNGLGETPROGRAMIVPROC glad_glGetProgramiv = NULL;
|
||||
PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv = NULL;
|
||||
PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog = NULL;
|
||||
PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat = NULL;
|
||||
PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource = NULL;
|
||||
PFNGLGETSHADERIVPROC glad_glGetShaderiv = NULL;
|
||||
PFNGLGETSTRINGPROC glad_glGetString = NULL;
|
||||
PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv = NULL;
|
||||
PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv = NULL;
|
||||
PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation = NULL;
|
||||
PFNGLGETUNIFORMFVPROC glad_glGetUniformfv = NULL;
|
||||
PFNGLGETUNIFORMIVPROC glad_glGetUniformiv = NULL;
|
||||
PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv = NULL;
|
||||
PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv = NULL;
|
||||
PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv = NULL;
|
||||
PFNGLHINTPROC glad_glHint = NULL;
|
||||
PFNGLISBUFFERPROC glad_glIsBuffer = NULL;
|
||||
PFNGLISENABLEDPROC glad_glIsEnabled = NULL;
|
||||
PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer = NULL;
|
||||
PFNGLISPROGRAMPROC glad_glIsProgram = NULL;
|
||||
PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer = NULL;
|
||||
PFNGLISSHADERPROC glad_glIsShader = NULL;
|
||||
PFNGLISTEXTUREPROC glad_glIsTexture = NULL;
|
||||
PFNGLLINEWIDTHPROC glad_glLineWidth = NULL;
|
||||
PFNGLLINKPROGRAMPROC glad_glLinkProgram = NULL;
|
||||
PFNGLPIXELSTOREIPROC glad_glPixelStorei = NULL;
|
||||
PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset = NULL;
|
||||
PFNGLREADPIXELSPROC glad_glReadPixels = NULL;
|
||||
PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler = NULL;
|
||||
PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage = NULL;
|
||||
PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage = NULL;
|
||||
PFNGLSCISSORPROC glad_glScissor = NULL;
|
||||
PFNGLSHADERBINARYPROC glad_glShaderBinary = NULL;
|
||||
PFNGLSHADERSOURCEPROC glad_glShaderSource = NULL;
|
||||
PFNGLSTENCILFUNCPROC glad_glStencilFunc = NULL;
|
||||
PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate = NULL;
|
||||
PFNGLSTENCILMASKPROC glad_glStencilMask = NULL;
|
||||
PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate = NULL;
|
||||
PFNGLSTENCILOPPROC glad_glStencilOp = NULL;
|
||||
PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate = NULL;
|
||||
PFNGLTEXIMAGE2DPROC glad_glTexImage2D = NULL;
|
||||
PFNGLTEXPARAMETERFPROC glad_glTexParameterf = NULL;
|
||||
PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv = NULL;
|
||||
PFNGLTEXPARAMETERIPROC glad_glTexParameteri = NULL;
|
||||
PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv = NULL;
|
||||
PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D = NULL;
|
||||
PFNGLUNIFORM1FPROC glad_glUniform1f = NULL;
|
||||
PFNGLUNIFORM1FVPROC glad_glUniform1fv = NULL;
|
||||
PFNGLUNIFORM1IPROC glad_glUniform1i = NULL;
|
||||
PFNGLUNIFORM1IVPROC glad_glUniform1iv = NULL;
|
||||
PFNGLUNIFORM2FPROC glad_glUniform2f = NULL;
|
||||
PFNGLUNIFORM2FVPROC glad_glUniform2fv = NULL;
|
||||
PFNGLUNIFORM2IPROC glad_glUniform2i = NULL;
|
||||
PFNGLUNIFORM2IVPROC glad_glUniform2iv = NULL;
|
||||
PFNGLUNIFORM3FPROC glad_glUniform3f = NULL;
|
||||
PFNGLUNIFORM3FVPROC glad_glUniform3fv = NULL;
|
||||
PFNGLUNIFORM3IPROC glad_glUniform3i = NULL;
|
||||
PFNGLUNIFORM3IVPROC glad_glUniform3iv = NULL;
|
||||
PFNGLUNIFORM4FPROC glad_glUniform4f = NULL;
|
||||
PFNGLUNIFORM4FVPROC glad_glUniform4fv = NULL;
|
||||
PFNGLUNIFORM4IPROC glad_glUniform4i = NULL;
|
||||
PFNGLUNIFORM4IVPROC glad_glUniform4iv = NULL;
|
||||
PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv = NULL;
|
||||
PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv = NULL;
|
||||
PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv = NULL;
|
||||
PFNGLUSEPROGRAMPROC glad_glUseProgram = NULL;
|
||||
PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram = NULL;
|
||||
PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f = NULL;
|
||||
PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv = NULL;
|
||||
PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f = NULL;
|
||||
PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv = NULL;
|
||||
PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f = NULL;
|
||||
PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv = NULL;
|
||||
PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f = NULL;
|
||||
PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv = NULL;
|
||||
PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer = NULL;
|
||||
PFNGLVIEWPORTPROC glad_glViewport = NULL;
|
||||
static void load_GL_ES_VERSION_2_0(GLADloadproc load) {
|
||||
if(!GLAD_GL_ES_VERSION_2_0) return;
|
||||
glad_glActiveTexture = (PFNGLACTIVETEXTUREPROC)load("glActiveTexture");
|
||||
glad_glAttachShader = (PFNGLATTACHSHADERPROC)load("glAttachShader");
|
||||
glad_glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)load("glBindAttribLocation");
|
||||
glad_glBindBuffer = (PFNGLBINDBUFFERPROC)load("glBindBuffer");
|
||||
glad_glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)load("glBindFramebuffer");
|
||||
glad_glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)load("glBindRenderbuffer");
|
||||
glad_glBindTexture = (PFNGLBINDTEXTUREPROC)load("glBindTexture");
|
||||
glad_glBlendColor = (PFNGLBLENDCOLORPROC)load("glBlendColor");
|
||||
glad_glBlendEquation = (PFNGLBLENDEQUATIONPROC)load("glBlendEquation");
|
||||
glad_glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC)load("glBlendEquationSeparate");
|
||||
glad_glBlendFunc = (PFNGLBLENDFUNCPROC)load("glBlendFunc");
|
||||
glad_glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC)load("glBlendFuncSeparate");
|
||||
glad_glBufferData = (PFNGLBUFFERDATAPROC)load("glBufferData");
|
||||
glad_glBufferSubData = (PFNGLBUFFERSUBDATAPROC)load("glBufferSubData");
|
||||
glad_glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)load("glCheckFramebufferStatus");
|
||||
glad_glClear = (PFNGLCLEARPROC)load("glClear");
|
||||
glad_glClearColor = (PFNGLCLEARCOLORPROC)load("glClearColor");
|
||||
glad_glClearDepthf = (PFNGLCLEARDEPTHFPROC)load("glClearDepthf");
|
||||
glad_glClearStencil = (PFNGLCLEARSTENCILPROC)load("glClearStencil");
|
||||
glad_glColorMask = (PFNGLCOLORMASKPROC)load("glColorMask");
|
||||
glad_glCompileShader = (PFNGLCOMPILESHADERPROC)load("glCompileShader");
|
||||
glad_glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)load("glCompressedTexImage2D");
|
||||
glad_glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)load("glCompressedTexSubImage2D");
|
||||
glad_glCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC)load("glCopyTexImage2D");
|
||||
glad_glCopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC)load("glCopyTexSubImage2D");
|
||||
glad_glCreateProgram = (PFNGLCREATEPROGRAMPROC)load("glCreateProgram");
|
||||
glad_glCreateShader = (PFNGLCREATESHADERPROC)load("glCreateShader");
|
||||
glad_glCullFace = (PFNGLCULLFACEPROC)load("glCullFace");
|
||||
glad_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)load("glDeleteBuffers");
|
||||
glad_glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)load("glDeleteFramebuffers");
|
||||
glad_glDeleteProgram = (PFNGLDELETEPROGRAMPROC)load("glDeleteProgram");
|
||||
glad_glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)load("glDeleteRenderbuffers");
|
||||
glad_glDeleteShader = (PFNGLDELETESHADERPROC)load("glDeleteShader");
|
||||
glad_glDeleteTextures = (PFNGLDELETETEXTURESPROC)load("glDeleteTextures");
|
||||
glad_glDepthFunc = (PFNGLDEPTHFUNCPROC)load("glDepthFunc");
|
||||
glad_glDepthMask = (PFNGLDEPTHMASKPROC)load("glDepthMask");
|
||||
glad_glDepthRangef = (PFNGLDEPTHRANGEFPROC)load("glDepthRangef");
|
||||
glad_glDetachShader = (PFNGLDETACHSHADERPROC)load("glDetachShader");
|
||||
glad_glDisable = (PFNGLDISABLEPROC)load("glDisable");
|
||||
glad_glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)load("glDisableVertexAttribArray");
|
||||
glad_glDrawArrays = (PFNGLDRAWARRAYSPROC)load("glDrawArrays");
|
||||
glad_glDrawElements = (PFNGLDRAWELEMENTSPROC)load("glDrawElements");
|
||||
glad_glEnable = (PFNGLENABLEPROC)load("glEnable");
|
||||
glad_glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)load("glEnableVertexAttribArray");
|
||||
glad_glFinish = (PFNGLFINISHPROC)load("glFinish");
|
||||
glad_glFlush = (PFNGLFLUSHPROC)load("glFlush");
|
||||
glad_glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)load("glFramebufferRenderbuffer");
|
||||
glad_glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)load("glFramebufferTexture2D");
|
||||
glad_glFrontFace = (PFNGLFRONTFACEPROC)load("glFrontFace");
|
||||
glad_glGenBuffers = (PFNGLGENBUFFERSPROC)load("glGenBuffers");
|
||||
glad_glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)load("glGenerateMipmap");
|
||||
glad_glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)load("glGenFramebuffers");
|
||||
glad_glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)load("glGenRenderbuffers");
|
||||
glad_glGenTextures = (PFNGLGENTEXTURESPROC)load("glGenTextures");
|
||||
glad_glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC)load("glGetActiveAttrib");
|
||||
glad_glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC)load("glGetActiveUniform");
|
||||
glad_glGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC)load("glGetAttachedShaders");
|
||||
glad_glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)load("glGetAttribLocation");
|
||||
glad_glGetBooleanv = (PFNGLGETBOOLEANVPROC)load("glGetBooleanv");
|
||||
glad_glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC)load("glGetBufferParameteriv");
|
||||
glad_glGetError = (PFNGLGETERRORPROC)load("glGetError");
|
||||
glad_glGetFloatv = (PFNGLGETFLOATVPROC)load("glGetFloatv");
|
||||
glad_glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)load("glGetFramebufferAttachmentParameteriv");
|
||||
glad_glGetIntegerv = (PFNGLGETINTEGERVPROC)load("glGetIntegerv");
|
||||
glad_glGetProgramiv = (PFNGLGETPROGRAMIVPROC)load("glGetProgramiv");
|
||||
glad_glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)load("glGetProgramInfoLog");
|
||||
glad_glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)load("glGetRenderbufferParameteriv");
|
||||
glad_glGetShaderiv = (PFNGLGETSHADERIVPROC)load("glGetShaderiv");
|
||||
glad_glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)load("glGetShaderInfoLog");
|
||||
glad_glGetShaderPrecisionFormat = (PFNGLGETSHADERPRECISIONFORMATPROC)load("glGetShaderPrecisionFormat");
|
||||
glad_glGetShaderSource = (PFNGLGETSHADERSOURCEPROC)load("glGetShaderSource");
|
||||
glad_glGetString = (PFNGLGETSTRINGPROC)load("glGetString");
|
||||
glad_glGetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC)load("glGetTexParameterfv");
|
||||
glad_glGetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC)load("glGetTexParameteriv");
|
||||
glad_glGetUniformfv = (PFNGLGETUNIFORMFVPROC)load("glGetUniformfv");
|
||||
glad_glGetUniformiv = (PFNGLGETUNIFORMIVPROC)load("glGetUniformiv");
|
||||
glad_glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)load("glGetUniformLocation");
|
||||
glad_glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC)load("glGetVertexAttribfv");
|
||||
glad_glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC)load("glGetVertexAttribiv");
|
||||
glad_glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC)load("glGetVertexAttribPointerv");
|
||||
glad_glHint = (PFNGLHINTPROC)load("glHint");
|
||||
glad_glIsBuffer = (PFNGLISBUFFERPROC)load("glIsBuffer");
|
||||
glad_glIsEnabled = (PFNGLISENABLEDPROC)load("glIsEnabled");
|
||||
glad_glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC)load("glIsFramebuffer");
|
||||
glad_glIsProgram = (PFNGLISPROGRAMPROC)load("glIsProgram");
|
||||
glad_glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC)load("glIsRenderbuffer");
|
||||
glad_glIsShader = (PFNGLISSHADERPROC)load("glIsShader");
|
||||
glad_glIsTexture = (PFNGLISTEXTUREPROC)load("glIsTexture");
|
||||
glad_glLineWidth = (PFNGLLINEWIDTHPROC)load("glLineWidth");
|
||||
glad_glLinkProgram = (PFNGLLINKPROGRAMPROC)load("glLinkProgram");
|
||||
glad_glPixelStorei = (PFNGLPIXELSTOREIPROC)load("glPixelStorei");
|
||||
glad_glPolygonOffset = (PFNGLPOLYGONOFFSETPROC)load("glPolygonOffset");
|
||||
glad_glReadPixels = (PFNGLREADPIXELSPROC)load("glReadPixels");
|
||||
glad_glReleaseShaderCompiler = (PFNGLRELEASESHADERCOMPILERPROC)load("glReleaseShaderCompiler");
|
||||
glad_glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)load("glRenderbufferStorage");
|
||||
glad_glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC)load("glSampleCoverage");
|
||||
glad_glScissor = (PFNGLSCISSORPROC)load("glScissor");
|
||||
glad_glShaderBinary = (PFNGLSHADERBINARYPROC)load("glShaderBinary");
|
||||
glad_glShaderSource = (PFNGLSHADERSOURCEPROC)load("glShaderSource");
|
||||
glad_glStencilFunc = (PFNGLSTENCILFUNCPROC)load("glStencilFunc");
|
||||
glad_glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC)load("glStencilFuncSeparate");
|
||||
glad_glStencilMask = (PFNGLSTENCILMASKPROC)load("glStencilMask");
|
||||
glad_glStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC)load("glStencilMaskSeparate");
|
||||
glad_glStencilOp = (PFNGLSTENCILOPPROC)load("glStencilOp");
|
||||
glad_glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC)load("glStencilOpSeparate");
|
||||
glad_glTexImage2D = (PFNGLTEXIMAGE2DPROC)load("glTexImage2D");
|
||||
glad_glTexParameterf = (PFNGLTEXPARAMETERFPROC)load("glTexParameterf");
|
||||
glad_glTexParameterfv = (PFNGLTEXPARAMETERFVPROC)load("glTexParameterfv");
|
||||
glad_glTexParameteri = (PFNGLTEXPARAMETERIPROC)load("glTexParameteri");
|
||||
glad_glTexParameteriv = (PFNGLTEXPARAMETERIVPROC)load("glTexParameteriv");
|
||||
glad_glTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC)load("glTexSubImage2D");
|
||||
glad_glUniform1f = (PFNGLUNIFORM1FPROC)load("glUniform1f");
|
||||
glad_glUniform1fv = (PFNGLUNIFORM1FVPROC)load("glUniform1fv");
|
||||
glad_glUniform1i = (PFNGLUNIFORM1IPROC)load("glUniform1i");
|
||||
glad_glUniform1iv = (PFNGLUNIFORM1IVPROC)load("glUniform1iv");
|
||||
glad_glUniform2f = (PFNGLUNIFORM2FPROC)load("glUniform2f");
|
||||
glad_glUniform2fv = (PFNGLUNIFORM2FVPROC)load("glUniform2fv");
|
||||
glad_glUniform2i = (PFNGLUNIFORM2IPROC)load("glUniform2i");
|
||||
glad_glUniform2iv = (PFNGLUNIFORM2IVPROC)load("glUniform2iv");
|
||||
glad_glUniform3f = (PFNGLUNIFORM3FPROC)load("glUniform3f");
|
||||
glad_glUniform3fv = (PFNGLUNIFORM3FVPROC)load("glUniform3fv");
|
||||
glad_glUniform3i = (PFNGLUNIFORM3IPROC)load("glUniform3i");
|
||||
glad_glUniform3iv = (PFNGLUNIFORM3IVPROC)load("glUniform3iv");
|
||||
glad_glUniform4f = (PFNGLUNIFORM4FPROC)load("glUniform4f");
|
||||
glad_glUniform4fv = (PFNGLUNIFORM4FVPROC)load("glUniform4fv");
|
||||
glad_glUniform4i = (PFNGLUNIFORM4IPROC)load("glUniform4i");
|
||||
glad_glUniform4iv = (PFNGLUNIFORM4IVPROC)load("glUniform4iv");
|
||||
glad_glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC)load("glUniformMatrix2fv");
|
||||
glad_glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)load("glUniformMatrix3fv");
|
||||
glad_glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)load("glUniformMatrix4fv");
|
||||
glad_glUseProgram = (PFNGLUSEPROGRAMPROC)load("glUseProgram");
|
||||
glad_glValidateProgram = (PFNGLVALIDATEPROGRAMPROC)load("glValidateProgram");
|
||||
glad_glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC)load("glVertexAttrib1f");
|
||||
glad_glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC)load("glVertexAttrib1fv");
|
||||
glad_glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC)load("glVertexAttrib2f");
|
||||
glad_glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC)load("glVertexAttrib2fv");
|
||||
glad_glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC)load("glVertexAttrib3f");
|
||||
glad_glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC)load("glVertexAttrib3fv");
|
||||
glad_glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC)load("glVertexAttrib4f");
|
||||
glad_glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC)load("glVertexAttrib4fv");
|
||||
glad_glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)load("glVertexAttribPointer");
|
||||
glad_glViewport = (PFNGLVIEWPORTPROC)load("glViewport");
|
||||
}
|
||||
static int find_extensionsGLES2(void) {
|
||||
if (!get_exts()) return 0;
|
||||
(void)&has_ext;
|
||||
free_exts();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void find_coreGLES2(void) {
|
||||
|
||||
/* Thank you @elmindreda
|
||||
* https://github.com/elmindreda/greg/blob/master/templates/greg.c.in#L176
|
||||
* https://github.com/glfw/glfw/blob/master/src/context.c#L36
|
||||
*/
|
||||
int i, major, minor;
|
||||
|
||||
const char* version;
|
||||
const char* prefixes[] = {
|
||||
"OpenGL ES-CM ",
|
||||
"OpenGL ES-CL ",
|
||||
"OpenGL ES ",
|
||||
NULL
|
||||
};
|
||||
|
||||
version = (const char*) glGetString(GL_VERSION);
|
||||
if (!version) return;
|
||||
|
||||
for (i = 0; prefixes[i]; i++) {
|
||||
const size_t length = strlen(prefixes[i]);
|
||||
if (strncmp(version, prefixes[i], length) == 0) {
|
||||
version += length;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* PR #18 */
|
||||
#ifdef _MSC_VER
|
||||
sscanf_s(version, "%d.%d", &major, &minor);
|
||||
#else
|
||||
sscanf(version, "%d.%d", &major, &minor);
|
||||
#endif
|
||||
|
||||
GLVersion.major = major; GLVersion.minor = minor;
|
||||
max_loaded_major = major; max_loaded_minor = minor;
|
||||
GLAD_GL_ES_VERSION_2_0 = (major == 2 && minor >= 0) || major > 2;
|
||||
if (GLVersion.major > 2 || (GLVersion.major >= 2 && GLVersion.minor >= 0)) {
|
||||
max_loaded_major = 2;
|
||||
max_loaded_minor = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int gladLoadGLES2Loader(GLADloadproc load) {
|
||||
GLVersion.major = 0; GLVersion.minor = 0;
|
||||
glGetString = (PFNGLGETSTRINGPROC)load("glGetString");
|
||||
if(glGetString == NULL) return 0;
|
||||
if(glGetString(GL_VERSION) == NULL) return 0;
|
||||
find_coreGLES2();
|
||||
load_GL_ES_VERSION_2_0(load);
|
||||
|
||||
if (!find_extensionsGLES2()) return 0;
|
||||
return GLVersion.major != 0 || GLVersion.minor != 0;
|
||||
}
|
||||
|
45
source/common/rendering/gles/glad/src/glad_egl.c
Normal file
45
source/common/rendering/gles/glad/src/glad_egl.c
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
|
||||
EGL loader generated by glad 0.1.34 on Sat Feb 20 22:54:45 2021.
|
||||
|
||||
Language/Generator: C/C++
|
||||
Specification: egl
|
||||
APIs: egl=1.4
|
||||
Profile: -
|
||||
Extensions:
|
||||
|
||||
Loader: True
|
||||
Local files: False
|
||||
Omit khrplatform: False
|
||||
Reproducible: False
|
||||
|
||||
Commandline:
|
||||
--api="egl=1.4" --generator="c" --spec="egl" --extensions=""
|
||||
Online:
|
||||
https://glad.dav1d.de/#language=c&specification=egl&loader=on&api=egl%3D1.4
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <glad/glad_egl.h>
|
||||
|
||||
int gladLoadEGL(void) {
|
||||
return gladLoadEGLLoader((GLADloadproc)eglGetProcAddress);
|
||||
}
|
||||
|
||||
static int find_extensionsEGL(void) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void find_coreEGL(void) {
|
||||
}
|
||||
|
||||
int gladLoadEGLLoader(GLADloadproc load) {
|
||||
(void) load;
|
||||
find_coreEGL();
|
||||
|
||||
if (!find_extensionsEGL()) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
337
source/common/rendering/gles/gles_buffers.cpp
Normal file
337
source/common/rendering/gles/gles_buffers.cpp
Normal file
|
@ -0,0 +1,337 @@
|
|||
/*
|
||||
** gl_buffers.cpp
|
||||
** Low level vertex buffer class
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2018-2020 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 <algorithm>
|
||||
#include "gles_system.h"
|
||||
#include "gles_buffers.h"
|
||||
#include "gles_renderstate.h"
|
||||
#include "v_video.h"
|
||||
#include "flatvertices.h"
|
||||
|
||||
namespace OpenGLESRenderer
|
||||
{
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// basic buffer implementation
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static inline void InvalidateBufferState()
|
||||
{
|
||||
gl_RenderState.ResetVertexBuffer(); // force rebinding of buffers on next Apply call.
|
||||
}
|
||||
|
||||
GLBuffer::GLBuffer(int usetype)
|
||||
: mUseType(usetype)
|
||||
{
|
||||
if ((usetype == GL_ARRAY_BUFFER) || (usetype == GL_ELEMENT_ARRAY_BUFFER))
|
||||
{
|
||||
glGenBuffers(1, &mBufferId);
|
||||
isData = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
isData = true;
|
||||
}
|
||||
}
|
||||
|
||||
GLBuffer::~GLBuffer()
|
||||
{
|
||||
if (mBufferId != 0)
|
||||
{
|
||||
if (gles.useMappedBuffers)
|
||||
{
|
||||
glBindBuffer(mUseType, mBufferId);
|
||||
glUnmapBuffer(mUseType);
|
||||
}
|
||||
glBindBuffer(mUseType, 0);
|
||||
glDeleteBuffers(1, &mBufferId);
|
||||
}
|
||||
|
||||
if (memory)
|
||||
delete[] memory;
|
||||
}
|
||||
|
||||
void GLBuffer::Bind()
|
||||
{
|
||||
if (!isData)
|
||||
{
|
||||
glBindBuffer(mUseType, mBufferId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GLBuffer::SetData(size_t size, const void* data, bool staticdata)
|
||||
{
|
||||
if (isData || !gles.useMappedBuffers)
|
||||
{
|
||||
if (memory)
|
||||
delete[] memory;
|
||||
|
||||
memory = (char*)(new uint64_t[size / 8 + 16]);
|
||||
|
||||
if (data)
|
||||
memcpy(memory, data, size);
|
||||
}
|
||||
|
||||
if (!isData)
|
||||
{
|
||||
Bind();
|
||||
glBufferData(mUseType, size, data, staticdata ? GL_STATIC_DRAW : GL_STREAM_DRAW);
|
||||
}
|
||||
|
||||
if (!isData && gles.useMappedBuffers)
|
||||
{
|
||||
map = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
map = memory;
|
||||
}
|
||||
|
||||
buffersize = size;
|
||||
InvalidateBufferState();
|
||||
}
|
||||
|
||||
void GLBuffer::SetSubData(size_t offset, size_t size, const void *data)
|
||||
{
|
||||
Bind();
|
||||
|
||||
memcpy(memory + offset, data, size);
|
||||
|
||||
if (!isData)
|
||||
{
|
||||
glBufferSubData(mUseType, offset, size, data);
|
||||
}
|
||||
}
|
||||
|
||||
void GLBuffer::Upload(size_t start, size_t size)
|
||||
{
|
||||
if (!gles.useMappedBuffers)
|
||||
{
|
||||
Bind();
|
||||
|
||||
if(size)
|
||||
glBufferSubData(mUseType, start, size, memory + start);
|
||||
}
|
||||
}
|
||||
|
||||
void GLBuffer::Map()
|
||||
{
|
||||
if (!isData && gles.useMappedBuffers)
|
||||
{
|
||||
Bind();
|
||||
map = (FFlatVertex*)glMapBufferRange(mUseType, 0, buffersize, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
map = memory;
|
||||
}
|
||||
InvalidateBufferState();
|
||||
}
|
||||
|
||||
void GLBuffer::Unmap()
|
||||
{
|
||||
if (!isData && gles.useMappedBuffers)
|
||||
{
|
||||
Bind();
|
||||
glUnmapBuffer(mUseType);
|
||||
InvalidateBufferState();
|
||||
}
|
||||
}
|
||||
|
||||
void *GLBuffer::Lock(unsigned int size)
|
||||
{
|
||||
// This initializes this buffer as a static object with no data.
|
||||
SetData(size, nullptr, true);
|
||||
if (!isData && gles.useMappedBuffers)
|
||||
{
|
||||
return glMapBufferRange(mUseType, 0, size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
||||
void GLBuffer::Unlock()
|
||||
{
|
||||
if (!isData)
|
||||
{
|
||||
if (gles.useMappedBuffers)
|
||||
{
|
||||
Bind();
|
||||
glUnmapBuffer(mUseType);
|
||||
InvalidateBufferState();
|
||||
}
|
||||
else
|
||||
{
|
||||
Bind();
|
||||
glBufferData(mUseType, buffersize, map, GL_STATIC_DRAW);
|
||||
InvalidateBufferState();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GLBuffer::Resize(size_t newsize)
|
||||
{
|
||||
assert(!nomap); // only mappable buffers can be resized.
|
||||
if (newsize > buffersize && !nomap)
|
||||
{
|
||||
/*
|
||||
// reallocate the buffer with twice the size
|
||||
unsigned int oldbuffer = mBufferId;
|
||||
|
||||
// first unmap the old buffer
|
||||
Bind();
|
||||
glUnmapBuffer(mUseType);
|
||||
|
||||
glGenBuffers(1, &mBufferId);
|
||||
SetData(newsize, nullptr, false);
|
||||
glBindBuffer(GL_COPY_READ_BUFFER, oldbuffer);
|
||||
|
||||
// copy contents and delete the old buffer.
|
||||
glCopyBufferSubData(GL_COPY_READ_BUFFER, mUseType, 0, 0, buffersize);
|
||||
glBindBuffer(GL_COPY_READ_BUFFER, 0);
|
||||
glDeleteBuffers(1, &oldbuffer);
|
||||
buffersize = newsize;
|
||||
InvalidateBufferState();
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
void GLBuffer::GPUDropSync()
|
||||
{
|
||||
#if !(USE_GLES2) // Only applicable when running on desktop for now
|
||||
if (gles.useMappedBuffers && glFenceSync && glClientWaitSync)
|
||||
{
|
||||
if (mGLSync != NULL)
|
||||
{
|
||||
glDeleteSync(mGLSync);
|
||||
}
|
||||
|
||||
mGLSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void GLBuffer::GPUWaitSync()
|
||||
{
|
||||
#if !(USE_GLES2) // Only applicable when running on desktop for now
|
||||
if (gles.useMappedBuffers && glFenceSync && glClientWaitSync)
|
||||
{
|
||||
GLenum status = glClientWaitSync(mGLSync, GL_SYNC_FLUSH_COMMANDS_BIT, 1000 * 1000 * 50); // Wait for a max of 50ms...
|
||||
|
||||
if (status != GL_ALREADY_SIGNALED && status != GL_CONDITION_SATISFIED)
|
||||
{
|
||||
//Printf("Error on glClientWaitSync: %d\n", status);
|
||||
}
|
||||
|
||||
glDeleteSync(mGLSync);
|
||||
|
||||
mGLSync = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Vertex buffer implementation
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void GLVertexBuffer::SetFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs)
|
||||
{
|
||||
static int VFmtToGLFmt[] = { GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_UNSIGNED_BYTE, GL_FLOAT }; // TODO Fix last entry GL_INT_2_10_10_10_REV, normals for models will be broken
|
||||
static uint8_t VFmtToSize[] = {4, 3, 2, 1, 4, 4};
|
||||
|
||||
mStride = stride;
|
||||
mNumBindingPoints = numBindingPoints;
|
||||
|
||||
for(int i = 0; i < numAttributes; i++)
|
||||
{
|
||||
if (attrs[i].location >= 0 && attrs[i].location < VATTR_MAX)
|
||||
{
|
||||
auto & attrinf = mAttributeInfo[attrs[i].location];
|
||||
attrinf.format = VFmtToGLFmt[attrs[i].format];
|
||||
attrinf.size = VFmtToSize[attrs[i].format];
|
||||
attrinf.offset = attrs[i].offset;
|
||||
attrinf.bindingpoint = attrs[i].binding;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GLVertexBuffer::Bind(int *offsets)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
// This is what gets called from RenderState.Apply. It shouldn't be called anywhere else if the render state is in use
|
||||
GLBuffer::Bind();
|
||||
for(auto &attrinf : mAttributeInfo)
|
||||
{
|
||||
if (attrinf.size == 0)
|
||||
{
|
||||
glDisableVertexAttribArray(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
glEnableVertexAttribArray(i);
|
||||
size_t ofs = offsets == nullptr ? attrinf.offset : attrinf.offset + mStride * offsets[attrinf.bindingpoint];
|
||||
glVertexAttribPointer(i, attrinf.size, attrinf.format, attrinf.format != GL_FLOAT, (GLsizei)mStride, (void*)(intptr_t)ofs);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void GLDataBuffer::BindRange(FRenderState *state, size_t start, size_t length)
|
||||
{
|
||||
if (mBindingPoint == 3)// VIEWPOINT_BINDINGPOINT
|
||||
{
|
||||
static_cast<FGLRenderState*>(state)->ApplyViewport(memory + start);
|
||||
}
|
||||
}
|
||||
|
||||
void GLDataBuffer::BindBase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
GLVertexBuffer::GLVertexBuffer() : GLBuffer(GL_ARRAY_BUFFER) {}
|
||||
GLIndexBuffer::GLIndexBuffer() : GLBuffer(GL_ELEMENT_ARRAY_BUFFER) {}
|
||||
GLDataBuffer::GLDataBuffer(int bindingpoint, bool is_ssbo) : GLBuffer(0), mBindingPoint(bindingpoint) {}
|
||||
|
||||
}
|
82
source/common/rendering/gles/gles_buffers.h
Normal file
82
source/common/rendering/gles/gles_buffers.h
Normal file
|
@ -0,0 +1,82 @@
|
|||
#pragma once
|
||||
|
||||
#include "buffers.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// silence bogus warning C4250: 'GLVertexBuffer': inherits 'GLBuffer::GLBuffer::SetData' via dominance
|
||||
// According to internet infos, the warning is erroneously emitted in this case.
|
||||
#pragma warning(disable:4250)
|
||||
#endif
|
||||
|
||||
namespace OpenGLESRenderer
|
||||
{
|
||||
|
||||
class GLBuffer : virtual public IBuffer
|
||||
{
|
||||
protected:
|
||||
const int mUseType;
|
||||
unsigned int mBufferId = 0;
|
||||
int mAllocationSize = 0;
|
||||
bool mPersistent = false;
|
||||
bool nomap = true;
|
||||
GLsync mGLSync = 0;
|
||||
|
||||
bool isData = false;
|
||||
char *memory = nullptr;
|
||||
|
||||
GLBuffer(int usetype);
|
||||
~GLBuffer();
|
||||
void SetData(size_t size, const void *data, bool staticdata) override;
|
||||
void SetSubData(size_t offset, size_t size, const void *data) override;
|
||||
void Map() override;
|
||||
void Unmap() override;
|
||||
void Resize(size_t newsize) override;
|
||||
void *Lock(unsigned int size) override;
|
||||
void Unlock() override;
|
||||
|
||||
void GPUDropSync();
|
||||
void GPUWaitSync();
|
||||
public:
|
||||
void Bind();
|
||||
void Upload(size_t start, size_t end);
|
||||
};
|
||||
|
||||
|
||||
class GLVertexBuffer : public IVertexBuffer, public GLBuffer
|
||||
{
|
||||
// If this could use the modern (since GL 4.3) binding system, things would be simpler... :(
|
||||
struct GLVertexBufferAttribute
|
||||
{
|
||||
int bindingpoint;
|
||||
int format;
|
||||
int size;
|
||||
int offset;
|
||||
};
|
||||
|
||||
int mNumBindingPoints;
|
||||
GLVertexBufferAttribute mAttributeInfo[VATTR_MAX] = {}; // Thanks to OpenGL's state system this needs to contain info about every attribute that may ever be in use throughout the entire renderer.
|
||||
size_t mStride = 0;
|
||||
|
||||
public:
|
||||
GLVertexBuffer();
|
||||
void SetFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs) override;
|
||||
void Bind(int *offsets);
|
||||
};
|
||||
|
||||
class GLIndexBuffer : public IIndexBuffer, public GLBuffer
|
||||
{
|
||||
public:
|
||||
|
||||
GLIndexBuffer();
|
||||
};
|
||||
|
||||
class GLDataBuffer : public IDataBuffer, public GLBuffer
|
||||
{
|
||||
int mBindingPoint;
|
||||
public:
|
||||
GLDataBuffer(int bindingpoint, bool is_ssbo);
|
||||
void BindRange(FRenderState* state, size_t start, size_t length);
|
||||
void BindBase();
|
||||
};
|
||||
|
||||
}
|
496
source/common/rendering/gles/gles_framebuffer.cpp
Normal file
496
source/common/rendering/gles/gles_framebuffer.cpp
Normal file
|
@ -0,0 +1,496 @@
|
|||
/*
|
||||
** gl_framebuffer.cpp
|
||||
** Implementation of the non-hardware specific parts of the
|
||||
** OpenGL frame buffer
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2010-2020 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 "gles_system.h"
|
||||
#include "v_video.h"
|
||||
#include "m_png.h"
|
||||
#include "templates.h"
|
||||
#include "i_time.h"
|
||||
|
||||
#include "gles_framebuffer.h"
|
||||
#include "gles_renderer.h"
|
||||
#include "gles_samplers.h"
|
||||
#include "gles_renderbuffers.h"
|
||||
#include "hw_clock.h"
|
||||
#include "hw_vrmodes.h"
|
||||
#include "hw_skydome.h"
|
||||
#include "hw_viewpointbuffer.h"
|
||||
#include "hw_lightbuffer.h"
|
||||
#include "gles_shaderprogram.h"
|
||||
#include "r_videoscale.h"
|
||||
#include "gles_buffers.h"
|
||||
#include "gles_postprocessstate.h"
|
||||
#include "v_draw.h"
|
||||
#include "printf.h"
|
||||
#include "gles_hwtexture.h"
|
||||
|
||||
#include "flatvertices.h"
|
||||
#include "hw_cvars.h"
|
||||
|
||||
EXTERN_CVAR (Bool, vid_vsync)
|
||||
EXTERN_CVAR(Bool, r_drawvoxels)
|
||||
EXTERN_CVAR(Int, gl_tonemap)
|
||||
EXTERN_CVAR(Bool, cl_capfps)
|
||||
EXTERN_CVAR(Int, gl_pipeline_depth);
|
||||
|
||||
EXTERN_CVAR(Bool, gl_sort_textures);
|
||||
|
||||
void Draw2D(F2DDrawer *drawer, FRenderState &state);
|
||||
|
||||
extern bool vid_hdr_active;
|
||||
|
||||
namespace OpenGLESRenderer
|
||||
{
|
||||
FGLRenderer *GLRenderer;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
OpenGLFrameBuffer::OpenGLFrameBuffer(void *hMonitor, bool fullscreen) :
|
||||
Super(hMonitor, fullscreen)
|
||||
{
|
||||
// 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);
|
||||
FHardwareTexture::InitGlobalState();
|
||||
|
||||
// Make sure all global variables tracking OpenGL context state are reset..
|
||||
gl_RenderState.Reset();
|
||||
|
||||
GLRenderer = nullptr;
|
||||
}
|
||||
|
||||
OpenGLFrameBuffer::~OpenGLFrameBuffer()
|
||||
{
|
||||
PPResource::ResetAll();
|
||||
|
||||
if (mVertexData != nullptr) delete mVertexData;
|
||||
if (mSkyData != nullptr) delete mSkyData;
|
||||
if (mViewpoints != nullptr) delete mViewpoints;
|
||||
if (mLights != nullptr) delete mLights;
|
||||
mShadowMap.Reset();
|
||||
|
||||
if (GLRenderer)
|
||||
{
|
||||
delete GLRenderer;
|
||||
GLRenderer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Initializes the GL renderer
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void OpenGLFrameBuffer::InitializeState()
|
||||
{
|
||||
static bool first=true;
|
||||
|
||||
mPipelineNbr = gl_pipeline_depth == 0? std::min(4, HW_MAX_PIPELINE_BUFFERS) : clamp(*gl_pipeline_depth, 1, HW_MAX_PIPELINE_BUFFERS);
|
||||
mPipelineType = 1;
|
||||
|
||||
InitGLES();
|
||||
|
||||
// Move some state to the framebuffer object for easier access.
|
||||
hwcaps = gles.flags;
|
||||
vendorstring = gles.vendorstring;
|
||||
|
||||
glDepthFunc(GL_LESS);
|
||||
|
||||
glEnable(GL_DITHER);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
glClearDepthf(1.0f);
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
SetViewportRects(nullptr);
|
||||
|
||||
mVertexData = new FFlatVertexBuffer(GetWidth(), GetHeight(), mPipelineNbr);
|
||||
mSkyData = new FSkyVertexBuffer;
|
||||
mViewpoints = new HWViewpointBuffer(mPipelineNbr);
|
||||
mLights = new FLightBuffer(mPipelineNbr);
|
||||
GLRenderer = new FGLRenderer(this);
|
||||
GLRenderer->Initialize(GetWidth(), GetHeight());
|
||||
static_cast<GLDataBuffer*>(mLights->GetBuffer())->BindBase();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Updates the screen
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void OpenGLFrameBuffer::Update()
|
||||
{
|
||||
twoD.Reset();
|
||||
Flush3D.Reset();
|
||||
|
||||
Flush3D.Clock();
|
||||
GLRenderer->Flush();
|
||||
Flush3D.Unclock();
|
||||
|
||||
Swap();
|
||||
Super::Update();
|
||||
}
|
||||
|
||||
void OpenGLFrameBuffer::CopyScreenToBuffer(int width, int height, uint8_t* scr)
|
||||
{
|
||||
IntRect bounds;
|
||||
bounds.left = 0;
|
||||
bounds.top = 0;
|
||||
bounds.width = width;
|
||||
bounds.height = height;
|
||||
GLRenderer->CopyToBackbuffer(&bounds, false);
|
||||
|
||||
// strictly speaking not needed as the glReadPixels should block until the scene is rendered, but this is to safeguard against shitty drivers
|
||||
glFinish();
|
||||
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, scr);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Camera texture rendering
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void OpenGLFrameBuffer::RenderTextureView(FCanvasTexture* tex, std::function<void(IntRect &)> renderFunc)
|
||||
{
|
||||
GLRenderer->StartOffscreen();
|
||||
GLRenderer->BindToFrameBuffer(tex);
|
||||
|
||||
IntRect bounds;
|
||||
bounds.left = bounds.top = 0;
|
||||
bounds.width = FHardwareTexture::GetTexDimension(tex->GetWidth());
|
||||
bounds.height = FHardwareTexture::GetTexDimension(tex->GetHeight());
|
||||
|
||||
renderFunc(bounds);
|
||||
GLRenderer->EndOffscreen();
|
||||
|
||||
tex->SetUpdated(true);
|
||||
static_cast<OpenGLFrameBuffer*>(screen)->camtexcount++;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
const char* OpenGLFrameBuffer::DeviceName() const
|
||||
{
|
||||
return gles.modelstring;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Swap the buffers
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
|
||||
void OpenGLFrameBuffer::Swap()
|
||||
{
|
||||
|
||||
Finish.Reset();
|
||||
Finish.Clock();
|
||||
|
||||
mVertexData->DropSync();
|
||||
|
||||
FPSLimit();
|
||||
SwapBuffers();
|
||||
|
||||
mVertexData->NextPipelineBuffer();
|
||||
mVertexData->WaitSync();
|
||||
|
||||
RenderState()->SetVertexBuffer(screen->mVertexData); // Needed for Raze because it does not reset it
|
||||
|
||||
Finish.Unclock();
|
||||
camtexcount = 0;
|
||||
FHardwareTexture::UnbindAll();
|
||||
gl_RenderState.ClearLastMaterial();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Enable/disable vertical sync
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void OpenGLFrameBuffer::SetVSync(bool vsync)
|
||||
{
|
||||
Super::SetVSync(vsync);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void OpenGLFrameBuffer::SetTextureFilterMode()
|
||||
{
|
||||
if (GLRenderer != nullptr && GLRenderer->mSamplerManager != nullptr) GLRenderer->mSamplerManager->SetTextureFilterMode();
|
||||
}
|
||||
|
||||
IHardwareTexture *OpenGLFrameBuffer::CreateHardwareTexture(int numchannels)
|
||||
{
|
||||
return new FHardwareTexture(numchannels);
|
||||
}
|
||||
|
||||
void OpenGLFrameBuffer::PrecacheMaterial(FMaterial *mat, int translation)
|
||||
{
|
||||
if (mat->Source()->GetUseType() == ETextureType::SWCanvas) return;
|
||||
|
||||
int flags = mat->GetScaleFlags();
|
||||
int numLayers = mat->NumLayers();
|
||||
MaterialLayerInfo* layer;
|
||||
auto base = static_cast<FHardwareTexture*>(mat->GetLayer(0, translation, &layer));
|
||||
|
||||
if (base->BindOrCreate(layer->layerTexture, 0, CLAMP_NONE, translation, layer->scaleFlags))
|
||||
{
|
||||
for (int i = 1; i < numLayers; i++)
|
||||
{
|
||||
auto systex = static_cast<FHardwareTexture*>(mat->GetLayer(i, 0, &layer));
|
||||
systex->BindOrCreate(layer->layerTexture, i, CLAMP_NONE, 0, layer->scaleFlags);
|
||||
}
|
||||
}
|
||||
// unbind everything.
|
||||
FHardwareTexture::UnbindAll();
|
||||
gl_RenderState.ClearLastMaterial();
|
||||
}
|
||||
|
||||
IVertexBuffer *OpenGLFrameBuffer::CreateVertexBuffer()
|
||||
{
|
||||
return new GLVertexBuffer;
|
||||
}
|
||||
|
||||
IIndexBuffer *OpenGLFrameBuffer::CreateIndexBuffer()
|
||||
{
|
||||
return new GLIndexBuffer;
|
||||
}
|
||||
|
||||
IDataBuffer *OpenGLFrameBuffer::CreateDataBuffer(int bindingpoint, bool ssbo, bool needsresize)
|
||||
{
|
||||
return new GLDataBuffer(bindingpoint, ssbo);
|
||||
}
|
||||
|
||||
|
||||
void OpenGLFrameBuffer::SetViewportRects(IntRect *bounds)
|
||||
{
|
||||
Super::SetViewportRects(bounds);
|
||||
if (!bounds)
|
||||
{
|
||||
auto vrmode = VRMode::GetVRMode(true);
|
||||
vrmode->AdjustViewport(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FRenderState* OpenGLFrameBuffer::RenderState()
|
||||
{
|
||||
return &gl_RenderState;
|
||||
}
|
||||
|
||||
|
||||
void OpenGLFrameBuffer::FirstEye()
|
||||
{
|
||||
//GLRenderer->mBuffers->CurrentEye() = 0; // always begin at zero, in case eye count changed
|
||||
}
|
||||
|
||||
void OpenGLFrameBuffer::NextEye(int eyecount)
|
||||
{
|
||||
//GLRenderer->mBuffers->NextEye(eyecount);
|
||||
}
|
||||
|
||||
void OpenGLFrameBuffer::SetSceneRenderTarget(bool useSSAO)
|
||||
{
|
||||
#ifndef NO_RENDER_BUFFER
|
||||
GLRenderer->mBuffers->BindSceneFB(useSSAO);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
void OpenGLFrameBuffer::WaitForCommands(bool finish)
|
||||
{
|
||||
glFinish();
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void OpenGLFrameBuffer::BeginFrame()
|
||||
{
|
||||
SetViewportRects(nullptr);
|
||||
if (GLRenderer != nullptr)
|
||||
GLRenderer->BeginFrame();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Takes a screenshot
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
TArray<uint8_t> OpenGLFrameBuffer::GetScreenshotBuffer(int &pitch, ESSType &color_type, float &gamma)
|
||||
{
|
||||
const auto &viewport = mOutputLetterbox;
|
||||
|
||||
// Grab what is in the back buffer.
|
||||
// We cannot rely on SCREENWIDTH/HEIGHT here because the output may have been scaled.
|
||||
TArray<uint8_t> pixels;
|
||||
pixels.Resize(viewport.width * viewport.height * 3);
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
glReadPixels(viewport.left, viewport.top, viewport.width, viewport.height, GL_RGB, GL_UNSIGNED_BYTE, &pixels[0]);
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 4);
|
||||
|
||||
// Copy to screenshot buffer:
|
||||
int w = SCREENWIDTH;
|
||||
int h = SCREENHEIGHT;
|
||||
|
||||
TArray<uint8_t> ScreenshotBuffer(w * h * 3, true);
|
||||
|
||||
float rcpWidth = 1.0f / w;
|
||||
float rcpHeight = 1.0f / h;
|
||||
for (int y = 0; y < h; y++)
|
||||
{
|
||||
for (int x = 0; x < w; x++)
|
||||
{
|
||||
float u = (x + 0.5f) * rcpWidth;
|
||||
float v = (y + 0.5f) * rcpHeight;
|
||||
int sx = u * viewport.width;
|
||||
int sy = v * viewport.height;
|
||||
int sindex = (sx + sy * viewport.width) * 3;
|
||||
int dindex = (x + (h - y - 1) * w) * 3;
|
||||
ScreenshotBuffer[dindex] = pixels[sindex];
|
||||
ScreenshotBuffer[dindex + 1] = pixels[sindex + 1];
|
||||
ScreenshotBuffer[dindex + 2] = pixels[sindex + 2];
|
||||
}
|
||||
}
|
||||
|
||||
pitch = w * 3;
|
||||
color_type = SS_RGB;
|
||||
|
||||
// Screenshot should not use gamma correction if it was already applied to rendered image
|
||||
gamma = 1;
|
||||
if (vid_hdr_active && vid_fullscreen)
|
||||
gamma *= 2.2f;
|
||||
return ScreenshotBuffer;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// 2D drawing
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void OpenGLFrameBuffer::Draw2D()
|
||||
{
|
||||
if (GLRenderer != nullptr)
|
||||
{
|
||||
GLRenderer->mBuffers->BindCurrentFB();
|
||||
::Draw2D(twod, gl_RenderState);
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLFrameBuffer::PostProcessScene(bool swscene, int fixedcm, float flash, const std::function<void()> &afterBloomDrawEndScene2D)
|
||||
{
|
||||
//if (!swscene) GLRenderer->mBuffers->BlitSceneToTexture(); // Copy the resulting scene to the current post process texture
|
||||
GLRenderer->PostProcessScene(fixedcm, flash, afterBloomDrawEndScene2D);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLFrameBuffer :: 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.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FTexture *OpenGLFrameBuffer::WipeStartScreen()
|
||||
{
|
||||
const auto &viewport = screen->mScreenViewport;
|
||||
|
||||
auto tex = new FWrapperTexture(viewport.width, viewport.height, 1);
|
||||
tex->GetSystemTexture()->CreateTexture(nullptr, viewport.width, viewport.height, 0, false, "WipeStartScreen");
|
||||
glFinish();
|
||||
static_cast<FHardwareTexture*>(tex->GetSystemTexture())->Bind(0, false);
|
||||
|
||||
GLRenderer->mBuffers->BindCurrentFB();
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, viewport.left, viewport.top, viewport.width, viewport.height);
|
||||
return tex;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLFrameBuffer :: WipeEndScreen
|
||||
//
|
||||
// The screen we want to animate to has just been drawn.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FTexture *OpenGLFrameBuffer::WipeEndScreen()
|
||||
{
|
||||
GLRenderer->Flush();
|
||||
const auto &viewport = screen->mScreenViewport;
|
||||
auto tex = new FWrapperTexture(viewport.width, viewport.height, 1);
|
||||
tex->GetSystemTexture()->CreateTexture(NULL, viewport.width, viewport.height, 0, false, "WipeEndScreen");
|
||||
glFinish();
|
||||
static_cast<FHardwareTexture*>(tex->GetSystemTexture())->Bind(0, false);
|
||||
GLRenderer->mBuffers->BindCurrentFB();
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, viewport.left, viewport.top, viewport.width, viewport.height);
|
||||
return tex;
|
||||
}
|
||||
|
||||
}
|
73
source/common/rendering/gles/gles_framebuffer.h
Normal file
73
source/common/rendering/gles/gles_framebuffer.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
#ifndef __GLES_FRAMEBUFFER
|
||||
#define __GLES_FRAMEBUFFER
|
||||
|
||||
#include "gl_sysfb.h"
|
||||
#include "m_png.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace OpenGLESRenderer
|
||||
{
|
||||
|
||||
class FHardwareTexture;
|
||||
class FGLDebug;
|
||||
|
||||
class OpenGLFrameBuffer : public SystemGLFrameBuffer
|
||||
{
|
||||
typedef SystemGLFrameBuffer Super;
|
||||
|
||||
void RenderTextureView(FCanvasTexture* tex, std::function<void(IntRect &)> renderFunc) override;
|
||||
|
||||
public:
|
||||
|
||||
explicit OpenGLFrameBuffer() {}
|
||||
OpenGLFrameBuffer(void *hMonitor, bool fullscreen) ;
|
||||
~OpenGLFrameBuffer();
|
||||
|
||||
void InitializeState() override;
|
||||
void Update() override;
|
||||
|
||||
void FirstEye() override;
|
||||
void NextEye(int eyecount) override;
|
||||
void SetSceneRenderTarget(bool useSSAO) override;
|
||||
void WaitForCommands(bool finish) override;
|
||||
void CopyScreenToBuffer(int width, int height, uint8_t* buffer) override;
|
||||
bool FlipSavePic() const override { return true; }
|
||||
|
||||
FRenderState* RenderState() override;
|
||||
|
||||
const char* DeviceName() const override;
|
||||
void SetTextureFilterMode() override;
|
||||
IHardwareTexture *CreateHardwareTexture(int numchannels) override;
|
||||
void PrecacheMaterial(FMaterial *mat, int translation) override;
|
||||
void BeginFrame() override;
|
||||
void SetViewportRects(IntRect *bounds) override;
|
||||
IVertexBuffer *CreateVertexBuffer() override;
|
||||
IIndexBuffer *CreateIndexBuffer() override;
|
||||
IDataBuffer *CreateDataBuffer(int bindingpoint, bool ssbo, bool needsresize) override;
|
||||
|
||||
// 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 TArray<uint8_t> GetScreenshotBuffer(int &pitch, ESSType &color_type, float &gamma) override;
|
||||
|
||||
void Swap();
|
||||
bool IsHWGammaActive() const { return HWGammaActive; }
|
||||
|
||||
void SetVSync(bool vsync) override;
|
||||
|
||||
void Draw2D() override;
|
||||
void PostProcessScene(bool swscene, int fixedcm, float flash, const std::function<void()> &afterBloomDrawEndScene2D) override;
|
||||
|
||||
bool HWGammaActive = false; // Are we using hardware or software gamma?
|
||||
std::shared_ptr<FGLDebug> mDebug; // Debug API
|
||||
|
||||
FTexture *WipeStartScreen() override;
|
||||
FTexture *WipeEndScreen() override;
|
||||
|
||||
int camtexcount = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //__GL_FRAMEBUFFER
|
331
source/common/rendering/gles/gles_hwtexture.cpp
Normal file
331
source/common/rendering/gles/gles_hwtexture.cpp
Normal file
|
@ -0,0 +1,331 @@
|
|||
/*
|
||||
** gl_hwtexture.cpp
|
||||
** GL texture abstraction
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2019 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 "gles_system.h"
|
||||
#include "templates.h"
|
||||
#include "c_cvars.h"
|
||||
#include "hw_material.h"
|
||||
|
||||
#include "hw_cvars.h"
|
||||
#include "gles_renderer.h"
|
||||
#include "gles_samplers.h"
|
||||
#include "gles_renderstate.h"
|
||||
#include "gles_hwtexture.h"
|
||||
|
||||
namespace OpenGLESRenderer
|
||||
{
|
||||
|
||||
|
||||
TexFilter_s TexFilter[] = {
|
||||
{GL_NEAREST, GL_NEAREST, false},
|
||||
{GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST, true},
|
||||
{GL_LINEAR, GL_LINEAR, false},
|
||||
{GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR, true},
|
||||
{GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, true},
|
||||
{GL_NEAREST_MIPMAP_LINEAR, GL_NEAREST, true},
|
||||
{GL_LINEAR_MIPMAP_LINEAR, GL_NEAREST, true},
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Static texture data
|
||||
//
|
||||
//===========================================================================
|
||||
unsigned int FHardwareTexture::lastbound[FHardwareTexture::MAX_TEXTURES];
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Loads the texture image into the hardware
|
||||
//
|
||||
// NOTE: For some strange reason I was unable to find the source buffer
|
||||
// should be one line higher than the actual texture. I got extremely
|
||||
// strange crashes deep inside the GL driver when I didn't do it!
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, const char *name)
|
||||
{
|
||||
int rh,rw;
|
||||
int texformat = GL_RGBA;// TexFormat[gl_texture_format];
|
||||
bool deletebuffer=false;
|
||||
|
||||
// When running in SW mode buffer will be null, so set it to the texBuffer already created
|
||||
// There could be other use cases I do not know about which means this is a bad idea..
|
||||
if (buffer == nullptr)
|
||||
buffer = texBuffer;
|
||||
|
||||
bool firstCall = glTexID == 0;
|
||||
if (firstCall)
|
||||
{
|
||||
glGenTextures(1, &glTexID);
|
||||
}
|
||||
|
||||
int textureBinding = UINT_MAX;
|
||||
if (texunit == -1) glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding);
|
||||
if (texunit > 0) glActiveTexture(GL_TEXTURE0+texunit);
|
||||
if (texunit >= 0) lastbound[texunit] = glTexID;
|
||||
glBindTexture(GL_TEXTURE_2D, glTexID);
|
||||
|
||||
|
||||
rw = GetTexDimension(w);
|
||||
rh = GetTexDimension(h);
|
||||
|
||||
if (!buffer)
|
||||
{
|
||||
// The texture must at least be initialized if no data is present.
|
||||
mipmapped = false;
|
||||
buffer=(unsigned char *)calloc(4,rw * (rh+1));
|
||||
deletebuffer=true;
|
||||
//texheight=-h;
|
||||
}
|
||||
else
|
||||
{
|
||||
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(w, h, rw, rh, buffer, scaledbuffer);
|
||||
deletebuffer=true;
|
||||
buffer=scaledbuffer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
// store the physical size.
|
||||
|
||||
int sourcetype;
|
||||
|
||||
|
||||
#if USE_GLES2
|
||||
sourcetype = GL_BGRA;
|
||||
texformat = GL_BGRA;
|
||||
#else
|
||||
if (glTextureBytes == 1)
|
||||
{
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
sourcetype = GL_RED;
|
||||
texformat = GL_R8;
|
||||
}
|
||||
else
|
||||
{
|
||||
sourcetype = GL_BGRA;
|
||||
texformat = GL_RGBA;
|
||||
}
|
||||
#endif
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, texformat, rw, rh, 0, sourcetype, GL_UNSIGNED_BYTE, buffer);
|
||||
|
||||
if (deletebuffer && buffer) free(buffer);
|
||||
|
||||
if (mipmap && TexFilter[gl_texture_filter].mipmapping)
|
||||
{
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
mipmapped = true;
|
||||
}
|
||||
|
||||
if (texunit > 0) glActiveTexture(GL_TEXTURE0);
|
||||
else if (texunit == -1) glBindTexture(GL_TEXTURE_2D, textureBinding);
|
||||
return glTexID;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
bufferpitch = w;
|
||||
|
||||
if (texBuffer)
|
||||
delete[] texBuffer;
|
||||
|
||||
texBuffer = new uint8_t[(w * h) * texelsize];
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t* FHardwareTexture::MapBuffer()
|
||||
{
|
||||
return texBuffer;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Destroys the texture
|
||||
//
|
||||
//===========================================================================
|
||||
FHardwareTexture::~FHardwareTexture()
|
||||
{
|
||||
if (glTexID != 0) glDeleteTextures(1, &glTexID);
|
||||
|
||||
if (texBuffer)
|
||||
delete[] texBuffer;
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Binds this patch
|
||||
//
|
||||
//===========================================================================
|
||||
unsigned int FHardwareTexture::Bind(int texunit, bool needmipmap)
|
||||
{
|
||||
if (glTexID != 0)
|
||||
{
|
||||
if (lastbound[texunit] == glTexID) return glTexID;
|
||||
lastbound[texunit] = glTexID;
|
||||
if (texunit != 0) glActiveTexture(GL_TEXTURE0 + texunit);
|
||||
glBindTexture(GL_TEXTURE_2D, glTexID);
|
||||
// Check if we need mipmaps on a texture that was creted without them.
|
||||
if (needmipmap && !mipmapped && TexFilter[gl_texture_filter].mipmapping)
|
||||
{
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
mipmapped = true;
|
||||
}
|
||||
if (texunit != 0) glActiveTexture(GL_TEXTURE0);
|
||||
return glTexID;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FHardwareTexture::Unbind(int texunit)
|
||||
{
|
||||
if (lastbound[texunit] != 0)
|
||||
{
|
||||
if (texunit != 0) glActiveTexture(GL_TEXTURE0+texunit);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
if (texunit != 0) glActiveTexture(GL_TEXTURE0);
|
||||
lastbound[texunit] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void FHardwareTexture::UnbindAll()
|
||||
{
|
||||
for(int texunit = 0; texunit < 16; texunit++)
|
||||
{
|
||||
Unbind(texunit);
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Creates a depth buffer for this texture
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
int FHardwareTexture::GetDepthBuffer(int width, int height)
|
||||
{
|
||||
if (glDepthID == 0)
|
||||
{
|
||||
glGenRenderbuffers(1, &glDepthID);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, glDepthID);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8,
|
||||
GetTexDimension(width), GetTexDimension(height));
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
}
|
||||
return glDepthID;
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Binds this texture's surfaces to the current framrbuffer
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FHardwareTexture::BindToFrameBuffer(int width, int height)
|
||||
{
|
||||
width = GetTexDimension(width);
|
||||
height = GetTexDimension(height);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glTexID, 0);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, GetDepthBuffer(width, height));
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, GetDepthBuffer(width, height));
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Binds a texture to the renderer
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
bool FHardwareTexture::BindOrCreate(FTexture *tex, int texunit, int clampmode, int translation, int flags)
|
||||
{
|
||||
int usebright = false;
|
||||
|
||||
bool needmipmap = (clampmode <= CLAMP_XY) && !forcenofilter;
|
||||
|
||||
// Bind it to the system.
|
||||
if (!Bind(texunit, needmipmap))
|
||||
{
|
||||
if (flags & CTF_Indexed)
|
||||
{
|
||||
glTextureBytes = 1;
|
||||
forcenofilter = true;
|
||||
needmipmap = false;
|
||||
}
|
||||
int w = 0, h = 0;
|
||||
|
||||
// Create this texture
|
||||
|
||||
FTextureBuffer texbuffer;
|
||||
|
||||
if (!tex->isHardwareCanvas())
|
||||
{
|
||||
texbuffer = tex->CreateTexBuffer(translation, flags | CTF_ProcessData);
|
||||
w = texbuffer.mWidth;
|
||||
h = texbuffer.mHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
w = tex->GetWidth();
|
||||
h = tex->GetHeight();
|
||||
}
|
||||
if (!CreateTexture(texbuffer.mBuffer, w, h, texunit, needmipmap, "FHardwareTexture.BindOrCreate"))
|
||||
{
|
||||
// could not create texture
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (forcenofilter && clampmode <= CLAMP_XY) clampmode += CLAMP_NOFILTER - CLAMP_NONE;
|
||||
GLRenderer->mSamplerManager->Bind(texunit, clampmode, 255);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
83
source/common/rendering/gles/gles_hwtexture.h
Normal file
83
source/common/rendering/gles/gles_hwtexture.h
Normal file
|
@ -0,0 +1,83 @@
|
|||
#pragma once
|
||||
class FBitmap;
|
||||
class FTexture;
|
||||
|
||||
#include "tarray.h"
|
||||
#include "hw_ihwtexture.h"
|
||||
|
||||
|
||||
#ifdef LoadImage
|
||||
#undef LoadImage
|
||||
#endif
|
||||
|
||||
#define SHADED_TEXTURE -1
|
||||
#define DIRECT_PALETTE -2
|
||||
|
||||
#include "tarray.h"
|
||||
#include "gles_system.h"
|
||||
#include "hw_ihwtexture.h"
|
||||
|
||||
class FCanvasTexture;
|
||||
|
||||
namespace OpenGLESRenderer
|
||||
{
|
||||
|
||||
class FHardwareTexture : public IHardwareTexture
|
||||
{
|
||||
public:
|
||||
|
||||
static unsigned int lastbound[MAX_TEXTURES];
|
||||
|
||||
static int GetTexDimension(int value)
|
||||
{
|
||||
if (value > gles.max_texturesize) return gles.max_texturesize;
|
||||
return value;
|
||||
}
|
||||
|
||||
static void InitGlobalState() { for (int i = 0; i < MAX_TEXTURES; i++) lastbound[i] = 0; }
|
||||
|
||||
private:
|
||||
|
||||
bool forcenofilter;
|
||||
|
||||
unsigned int glTexID = 0;
|
||||
unsigned int glDepthID = 0; // only used by camera textures
|
||||
uint8_t* texBuffer;
|
||||
|
||||
int glTextureBytes;
|
||||
bool mipmapped = false;
|
||||
|
||||
int GetDepthBuffer(int w, int h);
|
||||
|
||||
public:
|
||||
FHardwareTexture(int numchannels = 4, bool disablefilter = false)
|
||||
{
|
||||
forcenofilter = disablefilter;
|
||||
glTextureBytes = numchannels;
|
||||
|
||||
texBuffer = nullptr;
|
||||
}
|
||||
|
||||
~FHardwareTexture();
|
||||
|
||||
static void Unbind(int texunit);
|
||||
static void UnbindAll();
|
||||
|
||||
void BindToFrameBuffer(int w, int h);
|
||||
|
||||
unsigned int Bind(int texunit, bool needmipmap);
|
||||
bool BindOrCreate(FTexture* tex, int texunit, int clampmode, int translation, int flags);
|
||||
|
||||
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, const char* name);
|
||||
unsigned int GetTextureHandle()
|
||||
{
|
||||
return glTexID;
|
||||
}
|
||||
|
||||
int numChannels() { return glTextureBytes; }
|
||||
};
|
||||
|
||||
}
|
227
source/common/rendering/gles/gles_postprocess.cpp
Normal file
227
source/common/rendering/gles/gles_postprocess.cpp
Normal file
|
@ -0,0 +1,227 @@
|
|||
/*
|
||||
** Postprocessing framework
|
||||
** Copyright (c) 2016-2020 Magnus Norddahl
|
||||
**
|
||||
** This software is provided 'as-is', without any express or implied
|
||||
** warranty. In no event will the authors be held liable for any damages
|
||||
** arising from the use of this software.
|
||||
**
|
||||
** Permission is granted to anyone to use this software for any purpose,
|
||||
** including commercial applications, and to alter it and redistribute it
|
||||
** freely, subject to the following restrictions:
|
||||
**
|
||||
** 1. The origin of this software must not be misrepresented; you must not
|
||||
** claim that you wrote the original software. If you use this software
|
||||
** in a product, an acknowledgment in the product documentation would be
|
||||
** appreciated but is not required.
|
||||
** 2. Altered source versions must be plainly marked as such, and must not be
|
||||
** misrepresented as being the original software.
|
||||
** 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "gles_system.h"
|
||||
#include "m_png.h"
|
||||
#include "gles_buffers.h"
|
||||
#include "gles_framebuffer.h"
|
||||
#include "gles_renderbuffers.h"
|
||||
#include "gles_renderer.h"
|
||||
#include "gles_postprocessstate.h"
|
||||
#include "gles_shaderprogram.h"
|
||||
#include "hwrenderer/postprocessing/hw_postprocess.h"
|
||||
#include "hwrenderer/postprocessing/hw_postprocess_cvars.h"
|
||||
#include "flatvertices.h"
|
||||
#include "r_videoscale.h"
|
||||
#include "v_video.h"
|
||||
#include "templates.h"
|
||||
#include "hw_vrmodes.h"
|
||||
#include "v_draw.h"
|
||||
|
||||
extern bool vid_hdr_active;
|
||||
|
||||
|
||||
namespace OpenGLESRenderer
|
||||
{
|
||||
|
||||
int gl_dither_bpc = -1;
|
||||
|
||||
void FGLRenderer::RenderScreenQuad()
|
||||
{
|
||||
auto buffer = static_cast<GLVertexBuffer *>(screen->mVertexData->GetBufferObjects().first);
|
||||
buffer->Bind(nullptr);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, FFlatVertexBuffer::PRESENT_INDEX, 3);
|
||||
}
|
||||
|
||||
void FGLRenderer::PostProcessScene(int fixedcm, float flash, const std::function<void()> &afterBloomDrawEndScene2D)
|
||||
{
|
||||
#ifndef NO_RENDER_BUFFER
|
||||
mBuffers->BindCurrentFB();
|
||||
#endif
|
||||
if (afterBloomDrawEndScene2D) afterBloomDrawEndScene2D();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copies the rendered screen to its final destination
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void FGLRenderer::Flush()
|
||||
{
|
||||
CopyToBackbuffer(nullptr, true);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Gamma correct while copying to frame buffer
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void FGLRenderer::CopyToBackbuffer(const IntRect *bounds, bool applyGamma)
|
||||
{
|
||||
#ifdef NO_RENDER_BUFFER
|
||||
mBuffers->BindOutputFB();
|
||||
#endif
|
||||
screen->Draw2D(); // draw all pending 2D stuff before copying the buffer
|
||||
twod->Clear();
|
||||
|
||||
FGLPostProcessState savedState;
|
||||
savedState.SaveTextureBindings(2);
|
||||
|
||||
mBuffers->BindOutputFB();
|
||||
|
||||
IntRect box;
|
||||
if (bounds)
|
||||
{
|
||||
box = *bounds;
|
||||
}
|
||||
else
|
||||
{
|
||||
ClearBorders();
|
||||
box = screen->mOutputLetterbox;
|
||||
}
|
||||
|
||||
mBuffers->BindCurrentTexture(0);
|
||||
#ifndef NO_RENDER_BUFFER
|
||||
DrawPresentTexture(box, applyGamma);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FGLRenderer::DrawPresentTexture(const IntRect &box, bool applyGamma)
|
||||
{
|
||||
glViewport(box.left, box.top, box.width, box.height);
|
||||
|
||||
mBuffers->BindDitherTexture(1);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
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);
|
||||
}
|
||||
|
||||
mPresentShader->Bind();
|
||||
if (!applyGamma || framebuffer->IsHWGammaActive())
|
||||
{
|
||||
mPresentShader->Uniforms->InvGamma = 1.0f;
|
||||
mPresentShader->Uniforms->Contrast = 1.0f;
|
||||
mPresentShader->Uniforms->Brightness = 0.0f;
|
||||
mPresentShader->Uniforms->Saturation = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
mPresentShader->Uniforms->InvGamma = 1.0f / clamp<float>(vid_gamma, 0.1f, 4.f);
|
||||
mPresentShader->Uniforms->Contrast = clamp<float>(vid_contrast, 0.1f, 3.f);
|
||||
mPresentShader->Uniforms->Brightness = clamp<float>(vid_brightness, -0.8f, 0.8f);
|
||||
mPresentShader->Uniforms->Saturation = clamp<float>(vid_saturation, -15.0f, 15.f);
|
||||
mPresentShader->Uniforms->GrayFormula = static_cast<int>(gl_satformula);
|
||||
}
|
||||
if (vid_hdr_active && framebuffer->IsFullscreen())
|
||||
{
|
||||
// Full screen exclusive mode treats a rgba16f frame buffer as linear.
|
||||
// It probably will eventually in desktop mode too, but the DWM doesn't seem to support that.
|
||||
mPresentShader->Uniforms->HdrMode = 1;
|
||||
mPresentShader->Uniforms->ColorScale = (gl_dither_bpc == -1) ? 1023.0f : (float)((1 << gl_dither_bpc) - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
mPresentShader->Uniforms->HdrMode = 0;
|
||||
mPresentShader->Uniforms->ColorScale = (gl_dither_bpc == -1) ? 255.0f : (float)((1 << gl_dither_bpc) - 1);
|
||||
}
|
||||
mPresentShader->Uniforms->Scale = { screen->mScreenViewport.width / (float)mBuffers->GetWidth(), screen->mScreenViewport.height / (float)mBuffers->GetHeight() };
|
||||
mPresentShader->Uniforms->Offset = { 0.0f, 0.0f };
|
||||
mPresentShader->Uniforms.SetData();
|
||||
|
||||
|
||||
for (size_t n = 0; n < mPresentShader->Uniforms.mFields.size(); n++)
|
||||
{
|
||||
int index = -1;
|
||||
UniformFieldDesc desc = mPresentShader->Uniforms.mFields[n];
|
||||
int loc = mPresentShader->Uniforms.UniformLocation[n];
|
||||
switch (desc.Type)
|
||||
{
|
||||
case UniformType::Int:
|
||||
glUniform1i(loc, *((GLint*)(((char*)(&mPresentShader->Uniforms)) + desc.Offset)));
|
||||
break;
|
||||
case UniformType::Float:
|
||||
glUniform1f(loc, *((GLfloat*)(((char*)(&mPresentShader->Uniforms)) + desc.Offset)));
|
||||
break;
|
||||
case UniformType::Vec2:
|
||||
glUniform2fv(loc,1 , ((GLfloat*)(((char*)(&mPresentShader->Uniforms)) + desc.Offset)));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RenderScreenQuad();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Fills the black bars around the screen letterbox
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void FGLRenderer::ClearBorders()
|
||||
{
|
||||
const auto &box = screen->mOutputLetterbox;
|
||||
|
||||
int clientWidth = framebuffer->GetClientWidth();
|
||||
int clientHeight = framebuffer->GetClientHeight();
|
||||
if (clientWidth == 0 || clientHeight == 0)
|
||||
return;
|
||||
|
||||
glViewport(0, 0, clientWidth, clientHeight);
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
if (box.top > 0)
|
||||
{
|
||||
glScissor(0, 0, clientWidth, box.top);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
if (clientHeight - box.top - box.height > 0)
|
||||
{
|
||||
glScissor(0, box.top + box.height, clientWidth, clientHeight - box.top - box.height);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
if (box.left > 0)
|
||||
{
|
||||
glScissor(0, box.top, box.left, box.height);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
if (clientWidth - box.left - box.width > 0)
|
||||
{
|
||||
glScissor(box.left + box.width, box.top, clientWidth - box.left - box.width, box.height);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
}
|
118
source/common/rendering/gles/gles_postprocessstate.cpp
Normal file
118
source/common/rendering/gles/gles_postprocessstate.cpp
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
** Postprocessing framework
|
||||
** Copyright (c) 2016-2020 Magnus Norddahl
|
||||
**
|
||||
** This software is provided 'as-is', without any express or implied
|
||||
** warranty. In no event will the authors be held liable for any damages
|
||||
** arising from the use of this software.
|
||||
**
|
||||
** Permission is granted to anyone to use this software for any purpose,
|
||||
** including commercial applications, and to alter it and redistribute it
|
||||
** freely, subject to the following restrictions:
|
||||
**
|
||||
** 1. The origin of this software must not be misrepresented; you must not
|
||||
** claim that you wrote the original software. If you use this software
|
||||
** in a product, an acknowledgment in the product documentation would be
|
||||
** appreciated but is not required.
|
||||
** 2. Altered source versions must be plainly marked as such, and must not be
|
||||
** misrepresented as being the original software.
|
||||
** 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "templates.h"
|
||||
#include "gles_system.h"
|
||||
#include "gles_postprocessstate.h"
|
||||
|
||||
namespace OpenGLESRenderer
|
||||
{
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Saves state modified by post processing shaders
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
FGLPostProcessState::FGLPostProcessState()
|
||||
{
|
||||
glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTex);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
SaveTextureBindings(1);
|
||||
|
||||
glGetBooleanv(GL_BLEND, &blendEnabled);
|
||||
glGetBooleanv(GL_SCISSOR_TEST, &scissorEnabled);
|
||||
glGetBooleanv(GL_DEPTH_TEST, &depthEnabled);
|
||||
glGetIntegerv(GL_CURRENT_PROGRAM, ¤tProgram);
|
||||
glGetIntegerv(GL_BLEND_EQUATION_RGB, &blendEquationRgb);
|
||||
glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blendEquationAlpha);
|
||||
glGetIntegerv(GL_BLEND_SRC_RGB, &blendSrcRgb);
|
||||
glGetIntegerv(GL_BLEND_SRC_ALPHA, &blendSrcAlpha);
|
||||
glGetIntegerv(GL_BLEND_DST_RGB, &blendDestRgb);
|
||||
glGetIntegerv(GL_BLEND_DST_ALPHA, &blendDestAlpha);
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
void FGLPostProcessState::SaveTextureBindings(unsigned int numUnits)
|
||||
{
|
||||
while (textureBinding.Size() < numUnits)
|
||||
{
|
||||
unsigned int i = textureBinding.Size();
|
||||
|
||||
GLint texture;
|
||||
glActiveTexture(GL_TEXTURE0 + i);
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &texture);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
textureBinding.Push(texture);
|
||||
}
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Restores state at the end of post processing
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
FGLPostProcessState::~FGLPostProcessState()
|
||||
{
|
||||
if (blendEnabled)
|
||||
glEnable(GL_BLEND);
|
||||
else
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
if (scissorEnabled)
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
else
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
if (depthEnabled)
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
else
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
|
||||
glBlendEquationSeparate(blendEquationRgb, blendEquationAlpha);
|
||||
glBlendFuncSeparate(blendSrcRgb, blendDestRgb, blendSrcAlpha, blendDestAlpha);
|
||||
|
||||
glUseProgram(currentProgram);
|
||||
|
||||
// Fully unbind to avoid incomplete texture warnings from Nvidia's driver when gl_debug_level 4 is active
|
||||
for (unsigned int i = 0; i < textureBinding.Size(); i++)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0 + i);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
|
||||
for (unsigned int i = 0; i < textureBinding.Size(); i++)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0 + i);
|
||||
glBindTexture(GL_TEXTURE_2D, textureBinding[i]);
|
||||
}
|
||||
|
||||
glActiveTexture(activeTex);
|
||||
}
|
||||
|
||||
}
|
40
source/common/rendering/gles/gles_postprocessstate.h
Normal file
40
source/common/rendering/gles/gles_postprocessstate.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
#ifndef __GL_POSTPROCESSSTATE_H
|
||||
#define __GL_POSTPROCESSSTATE_H
|
||||
|
||||
#include <string.h>
|
||||
#include "matrix.h"
|
||||
#include "c_cvars.h"
|
||||
|
||||
namespace OpenGLESRenderer
|
||||
{
|
||||
|
||||
class FGLPostProcessState
|
||||
{
|
||||
public:
|
||||
FGLPostProcessState();
|
||||
~FGLPostProcessState();
|
||||
|
||||
void SaveTextureBindings(unsigned int numUnits);
|
||||
|
||||
private:
|
||||
FGLPostProcessState(const FGLPostProcessState &) = delete;
|
||||
FGLPostProcessState &operator=(const FGLPostProcessState &) = delete;
|
||||
|
||||
GLint activeTex;
|
||||
TArray<GLint> textureBinding;
|
||||
TArray<GLint> samplerBinding;
|
||||
GLboolean blendEnabled;
|
||||
GLboolean scissorEnabled;
|
||||
GLboolean depthEnabled;
|
||||
GLboolean multisampleEnabled;
|
||||
GLint currentProgram;
|
||||
GLint blendEquationRgb;
|
||||
GLint blendEquationAlpha;
|
||||
GLint blendSrcRgb;
|
||||
GLint blendSrcAlpha;
|
||||
GLint blendDestRgb;
|
||||
GLint blendDestAlpha;
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
433
source/common/rendering/gles/gles_renderbuffers.cpp
Normal file
433
source/common/rendering/gles/gles_renderbuffers.cpp
Normal file
|
@ -0,0 +1,433 @@
|
|||
/*
|
||||
** Postprocessing framework
|
||||
** Copyright (c) 2016-2020 Magnus Norddahl
|
||||
**
|
||||
** This software is provided 'as-is', without any express or implied
|
||||
** warranty. In no event will the authors be held liable for any damages
|
||||
** arising from the use of this software.
|
||||
**
|
||||
** Permission is granted to anyone to use this software for any purpose,
|
||||
** including commercial applications, and to alter it and redistribute it
|
||||
** freely, subject to the following restrictions:
|
||||
**
|
||||
** 1. The origin of this software must not be misrepresented; you must not
|
||||
** claim that you wrote the original software. If you use this software
|
||||
** in a product, an acknowledgment in the product documentation would be
|
||||
** appreciated but is not required.
|
||||
** 2. Altered source versions must be plainly marked as such, and must not be
|
||||
** misrepresented as being the original software.
|
||||
** 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "gles_system.h"
|
||||
#include "v_video.h"
|
||||
#include "printf.h"
|
||||
#include "hw_cvars.h"
|
||||
#include "gles_renderer.h"
|
||||
#include "gles_renderbuffers.h"
|
||||
#include "gles_postprocessstate.h"
|
||||
#include "gles_shaderprogram.h"
|
||||
#include "gles_buffers.h"
|
||||
#include "templates.h"
|
||||
#include <random>
|
||||
|
||||
EXTERN_CVAR(Int, gl_debug_level)
|
||||
|
||||
namespace OpenGLESRenderer
|
||||
{
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Initialize render buffers and textures used in rendering passes
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FGLRenderBuffers::FGLRenderBuffers()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Free render buffer resources
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FGLRenderBuffers::~FGLRenderBuffers()
|
||||
{
|
||||
ClearScene();
|
||||
|
||||
DeleteTexture(mDitherTexture);
|
||||
}
|
||||
|
||||
void FGLRenderBuffers::ClearScene()
|
||||
{
|
||||
DeleteFrameBuffer(mSceneFB);
|
||||
DeleteRenderBuffer(mSceneDepthStencilBuf);
|
||||
DeleteRenderBuffer(mSceneStencilBuf);
|
||||
}
|
||||
|
||||
void FGLRenderBuffers::DeleteTexture(PPGLTexture& tex)
|
||||
{
|
||||
if (tex.handle != 0)
|
||||
glDeleteTextures(1, &tex.handle);
|
||||
tex.handle = 0;
|
||||
}
|
||||
|
||||
void FGLRenderBuffers::DeleteRenderBuffer(PPGLRenderBuffer& buf)
|
||||
{
|
||||
if (buf.handle != 0)
|
||||
glDeleteRenderbuffers(1, &buf.handle);
|
||||
buf.handle = 0;
|
||||
}
|
||||
|
||||
void FGLRenderBuffers::DeleteFrameBuffer(PPGLFrameBuffer& fb)
|
||||
{
|
||||
if (fb.handle != 0)
|
||||
glDeleteFramebuffers(1, &fb.handle);
|
||||
fb.handle = 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Makes sure all render buffers have sizes suitable for rending at the
|
||||
// specified resolution
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderBuffers::Setup(int width, int height, int sceneWidth, int sceneHeight)
|
||||
{
|
||||
if (width <= 0 || height <= 0)
|
||||
I_FatalError("Requested invalid render buffer sizes: screen = %dx%d", width, height);
|
||||
|
||||
GLint activeTex;
|
||||
GLint textureBinding;
|
||||
glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTex);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding);
|
||||
|
||||
if (width != mWidth || height != mHeight)
|
||||
CreatePipeline(width, height);
|
||||
|
||||
if (width != mWidth || height != mHeight )
|
||||
CreateScene(width, height);
|
||||
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
mSceneWidth = sceneWidth;
|
||||
mSceneHeight = sceneHeight;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, textureBinding);
|
||||
glActiveTexture(activeTex);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
if (FailedCreate)
|
||||
{
|
||||
ClearScene();
|
||||
mWidth = 0;
|
||||
mHeight = 0;
|
||||
mSceneWidth = 0;
|
||||
mSceneHeight = 0;
|
||||
I_FatalError("Unable to create render buffers.");
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Creates the scene buffers
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderBuffers::CreateScene(int width, int height)
|
||||
{
|
||||
ClearScene();
|
||||
if(gles.depthStencilAvailable)
|
||||
mSceneDepthStencilBuf = CreateRenderBuffer("SceneDepthStencil", GL_DEPTH24_STENCIL8, width, height);
|
||||
else
|
||||
{
|
||||
mSceneDepthStencilBuf = CreateRenderBuffer("SceneDepthStencil", GL_DEPTH_COMPONENT16, width, height);
|
||||
mSceneStencilBuf = CreateRenderBuffer("SceneStencil", GL_STENCIL_INDEX8, width, height);
|
||||
}
|
||||
mSceneFB= CreateFrameBuffer("SceneFB", mSceneTex, mSceneDepthStencilBuf, mSceneStencilBuf);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Creates the buffers needed for post processing steps
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderBuffers::CreatePipeline(int width, int height)
|
||||
{
|
||||
mSceneTex = Create2DTexture("PipelineTexture", GL_RGBA, width, height);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Creates a 2D texture defaulting to linear filtering and clamp to edge
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
PPGLTexture FGLRenderBuffers::Create2DTexture(const char* name, GLuint format, int width, int height, const void* data)
|
||||
{
|
||||
PPGLTexture tex;
|
||||
tex.Width = width;
|
||||
tex.Height = height;
|
||||
glGenTextures(1, &tex.handle);
|
||||
glBindTexture(GL_TEXTURE_2D, tex.handle);
|
||||
|
||||
GLenum dataformat = 0, datatype = 0;
|
||||
/*
|
||||
switch (format)
|
||||
{
|
||||
case GL_RGBA: dataformat = GL_RGBA; datatype = GL_UNSIGNED_BYTE; break;
|
||||
|
||||
case GL_RGBA16: dataformat = GL_RGBA; datatype = GL_UNSIGNED_SHORT; break;
|
||||
case GL_RGBA16F: dataformat = GL_RGBA; datatype = GL_FLOAT; break;
|
||||
case GL_RGBA32F: dataformat = GL_RGBA; datatype = GL_FLOAT; break;
|
||||
case GL_RGBA16_SNORM: dataformat = GL_RGBA; datatype = GL_SHORT; break;
|
||||
case GL_R32F: dataformat = GL_RED; datatype = GL_FLOAT; break;
|
||||
case GL_R16F: dataformat = GL_RED; datatype = GL_FLOAT; break;
|
||||
case GL_RG32F: dataformat = GL_RG; datatype = GL_FLOAT; break;
|
||||
case GL_RG16F: dataformat = GL_RG; datatype = GL_FLOAT; break;
|
||||
case GL_RGB10_A2: dataformat = GL_RGBA; datatype = GL_UNSIGNED_INT_10_10_10_2; break;
|
||||
case GL_DEPTH_COMPONENT24: dataformat = GL_DEPTH_COMPONENT; datatype = GL_FLOAT; break;
|
||||
|
||||
case GL_STENCIL_INDEX8: dataformat = GL_STENCIL_INDEX8_OES; datatype = GL_INT; break;
|
||||
case GL_DEPTH24_STENCIL8_OES: dataformat = GL_DEPTH_STENCIL_OES; datatype = GL_UNSIGNED_INT_24_8; break;
|
||||
default: I_FatalError("Unknown format passed to FGLRenderBuffers.Create2DTexture");
|
||||
}
|
||||
*/
|
||||
format = GL_RGBA;
|
||||
dataformat = GL_RGBA;
|
||||
datatype = GL_UNSIGNED_BYTE;
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, dataformat, datatype, data);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
return tex;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Creates a render buffer
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
PPGLRenderBuffer FGLRenderBuffers::CreateRenderBuffer(const char* name, GLuint format, int width, int height)
|
||||
{
|
||||
PPGLRenderBuffer buf;
|
||||
glGenRenderbuffers(1, &buf.handle);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, buf.handle);
|
||||
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, format, width, height);
|
||||
return buf;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Creates a frame buffer
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
PPGLFrameBuffer FGLRenderBuffers::CreateFrameBuffer(const char* name, PPGLTexture colorbuffer)
|
||||
{
|
||||
PPGLFrameBuffer fb;
|
||||
glGenFramebuffers(1, &fb.handle);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fb.handle);
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer.handle, 0);
|
||||
if (CheckFrameBufferCompleteness())
|
||||
ClearFrameBuffer(false, false);
|
||||
return fb;
|
||||
}
|
||||
|
||||
PPGLFrameBuffer FGLRenderBuffers::CreateFrameBuffer(const char* name, PPGLTexture colorbuffer, PPGLRenderBuffer depthstencil, PPGLRenderBuffer stencil)
|
||||
{
|
||||
PPGLFrameBuffer fb;
|
||||
glGenFramebuffers(1, &fb.handle);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fb.handle);
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer.handle, 0);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthstencil.handle);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, gles.depthStencilAvailable ? depthstencil.handle : stencil.handle);
|
||||
if (CheckFrameBufferCompleteness())
|
||||
ClearFrameBuffer(true, true);
|
||||
return fb;
|
||||
}
|
||||
|
||||
PPGLFrameBuffer FGLRenderBuffers::CreateFrameBuffer(const char* name, PPGLRenderBuffer colorbuffer, PPGLRenderBuffer depthstencil, PPGLRenderBuffer stencil)
|
||||
{
|
||||
PPGLFrameBuffer fb;
|
||||
glGenFramebuffers(1, &fb.handle);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fb.handle);
|
||||
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuffer.handle);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthstencil.handle);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, gles.depthStencilAvailable ? depthstencil.handle : stencil.handle);
|
||||
if (CheckFrameBufferCompleteness())
|
||||
ClearFrameBuffer(true, true);
|
||||
return fb;
|
||||
}
|
||||
|
||||
PPGLFrameBuffer FGLRenderBuffers::CreateFrameBuffer(const char* name, PPGLTexture colorbuffer0, PPGLTexture colorbuffer1, PPGLTexture colorbuffer2, PPGLTexture depthstencil, PPGLRenderBuffer stencil)
|
||||
{
|
||||
PPGLFrameBuffer fb;
|
||||
glGenFramebuffers(1, &fb.handle);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fb.handle);
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer0.handle, 0);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthstencil.handle);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, gles.depthStencilAvailable ? depthstencil.handle : stencil.handle);
|
||||
|
||||
if (CheckFrameBufferCompleteness())
|
||||
ClearFrameBuffer(true, true);
|
||||
return fb;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Verifies that the frame buffer setup is valid
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FGLRenderBuffers::CheckFrameBufferCompleteness()
|
||||
{
|
||||
GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
if (result == GL_FRAMEBUFFER_COMPLETE)
|
||||
return true;
|
||||
|
||||
bool FailedCreate = true;
|
||||
|
||||
|
||||
FString error = "glCheckFramebufferStatus failed: ";
|
||||
switch (result)
|
||||
{
|
||||
default: error.AppendFormat("error code %d", (int)result); break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: error << "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT"; break;
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: error << "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"; break;
|
||||
case GL_FRAMEBUFFER_UNSUPPORTED: error << "GL_FRAMEBUFFER_UNSUPPORTED"; break;
|
||||
}
|
||||
Printf("%s\n", error.GetChars());
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Clear frame buffer to make sure it never contains uninitialized data
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderBuffers::ClearFrameBuffer(bool stencil, bool depth)
|
||||
{
|
||||
GLboolean scissorEnabled;
|
||||
GLint stencilValue;
|
||||
GLfloat depthValue;
|
||||
glGetBooleanv(GL_SCISSOR_TEST, &scissorEnabled);
|
||||
glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &stencilValue);
|
||||
glGetFloatv(GL_DEPTH_CLEAR_VALUE, &depthValue);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
glClearDepthf(0.0f);
|
||||
glClearStencil(0);
|
||||
GLenum flags = GL_COLOR_BUFFER_BIT;
|
||||
if (stencil)
|
||||
flags |= GL_STENCIL_BUFFER_BIT;
|
||||
if (depth)
|
||||
flags |= GL_DEPTH_BUFFER_BIT;
|
||||
glClear(flags);
|
||||
glClearStencil(stencilValue);
|
||||
glClearDepthf(depthValue);
|
||||
if (scissorEnabled)
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
|
||||
void FGLRenderBuffers::BindDitherTexture(int texunit)
|
||||
{
|
||||
if (!mDitherTexture)
|
||||
{
|
||||
static const float data[64] =
|
||||
{
|
||||
.0078125, .2578125, .1328125, .3828125, .0234375, .2734375, .1484375, .3984375,
|
||||
.7578125, .5078125, .8828125, .6328125, .7734375, .5234375, .8984375, .6484375,
|
||||
.0703125, .3203125, .1953125, .4453125, .0859375, .3359375, .2109375, .4609375,
|
||||
.8203125, .5703125, .9453125, .6953125, .8359375, .5859375, .9609375, .7109375,
|
||||
.0390625, .2890625, .1640625, .4140625, .0546875, .3046875, .1796875, .4296875,
|
||||
.7890625, .5390625, .9140625, .6640625, .8046875, .5546875, .9296875, .6796875,
|
||||
.1015625, .3515625, .2265625, .4765625, .1171875, .3671875, .2421875, .4921875,
|
||||
.8515625, .6015625, .9765625, .7265625, .8671875, .6171875, .9921875, .7421875,
|
||||
};
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + texunit);
|
||||
mDitherTexture = Create2DTexture("DitherTexture", GL_RGBA, 8, 8, data);
|
||||
}
|
||||
mDitherTexture.Bind(1, GL_NEAREST, GL_REPEAT);
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Makes the scene frame buffer active (multisample, depth, stecil, etc.)
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderBuffers::BindSceneFB(bool sceneData)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mSceneFB.handle);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Binds the current scene/effect/hud texture to the specified texture unit
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderBuffers::BindCurrentTexture(int index, int filter, int wrap)
|
||||
{
|
||||
mSceneTex.Bind(index, filter, wrap);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Makes the frame buffer for the current texture active
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderBuffers::BindCurrentFB()
|
||||
{
|
||||
#ifndef NO_RENDER_BUFFER
|
||||
mSceneFB.Bind();
|
||||
#endif
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Makes the screen frame buffer active
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderBuffers::BindOutputFB()
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Returns true if render buffers are supported and should be used
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FGLRenderBuffers::FailedCreate = false;
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace OpenGLRenderer
|
152
source/common/rendering/gles/gles_renderbuffers.h
Normal file
152
source/common/rendering/gles/gles_renderbuffers.h
Normal file
|
@ -0,0 +1,152 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "hwrenderer/postprocessing/hw_postprocess.h"
|
||||
|
||||
namespace OpenGLESRenderer
|
||||
{
|
||||
|
||||
class FGLRenderBuffers;
|
||||
|
||||
class PPGLTexture
|
||||
{
|
||||
public:
|
||||
void Bind(int index, int filter = GL_NEAREST, int wrap = GL_CLAMP_TO_EDGE)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0 + index);
|
||||
glBindTexture(GL_TEXTURE_2D, handle);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap);
|
||||
}
|
||||
|
||||
int Width = -1;
|
||||
int Height = -1;
|
||||
|
||||
explicit operator bool() const { return handle != 0; }
|
||||
|
||||
private:
|
||||
GLuint handle = 0;
|
||||
|
||||
friend class FGLRenderBuffers;
|
||||
friend class PPGLTextureBackend;
|
||||
};
|
||||
|
||||
class PPGLFrameBuffer
|
||||
{
|
||||
public:
|
||||
void Bind()
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, handle);
|
||||
}
|
||||
|
||||
explicit operator bool() const { return handle != 0; }
|
||||
|
||||
private:
|
||||
GLuint handle = 0;
|
||||
|
||||
friend class FGLRenderBuffers;
|
||||
friend class PPGLTextureBackend;
|
||||
};
|
||||
|
||||
class PPGLRenderBuffer
|
||||
{
|
||||
private:
|
||||
GLuint handle = 0;
|
||||
|
||||
explicit operator bool() const { return handle != 0; }
|
||||
|
||||
friend class FGLRenderBuffers;
|
||||
};
|
||||
|
||||
class PPGLTextureBackend : public PPTextureBackend
|
||||
{
|
||||
public:
|
||||
~PPGLTextureBackend()
|
||||
{
|
||||
if (Tex.handle != 0)
|
||||
{
|
||||
glDeleteTextures(1, &Tex.handle);
|
||||
Tex.handle = 0;
|
||||
}
|
||||
if (FB.handle != 0)
|
||||
{
|
||||
glDeleteFramebuffers(1, &FB.handle);
|
||||
FB.handle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
PPGLTexture Tex;
|
||||
PPGLFrameBuffer FB;
|
||||
};
|
||||
|
||||
class FShaderProgram;
|
||||
|
||||
|
||||
class FGLRenderBuffers
|
||||
{
|
||||
public:
|
||||
FGLRenderBuffers();
|
||||
~FGLRenderBuffers();
|
||||
|
||||
void Setup(int width, int height, int sceneWidth, int sceneHeight);
|
||||
|
||||
void BindSceneFB(bool sceneData);
|
||||
|
||||
|
||||
void BindCurrentTexture(int index, int filter = GL_NEAREST, int wrap = GL_CLAMP_TO_EDGE);
|
||||
void BindCurrentFB();
|
||||
void BindNextFB();
|
||||
void NextTexture();
|
||||
|
||||
|
||||
void BindOutputFB();
|
||||
|
||||
void BindDitherTexture(int texunit);
|
||||
|
||||
int GetWidth() const { return mWidth; }
|
||||
int GetHeight() const { return mHeight; }
|
||||
|
||||
int GetSceneWidth() const { return mSceneWidth; }
|
||||
int GetSceneHeight() const { return mSceneHeight; }
|
||||
|
||||
private:
|
||||
void ClearScene();
|
||||
|
||||
void CreateScene(int width, int height);
|
||||
void CreatePipeline(int width, int height);
|
||||
|
||||
PPGLTexture Create2DTexture(const char *name, GLuint format, int width, int height, const void *data = nullptr);
|
||||
PPGLRenderBuffer CreateRenderBuffer(const char *name, GLuint format, int width, int height);
|
||||
PPGLFrameBuffer CreateFrameBuffer(const char *name, PPGLTexture colorbuffer);
|
||||
PPGLFrameBuffer CreateFrameBuffer(const char *name, PPGLTexture colorbuffer, PPGLRenderBuffer depthstencil, PPGLRenderBuffer stencil);
|
||||
PPGLFrameBuffer CreateFrameBuffer(const char *name, PPGLRenderBuffer colorbuffer, PPGLRenderBuffer depthstencil, PPGLRenderBuffer stencil);
|
||||
PPGLFrameBuffer CreateFrameBuffer(const char *name, PPGLTexture colorbuffer0, PPGLTexture colorbuffer1, PPGLTexture colorbuffer2, PPGLTexture depthstencil, PPGLRenderBuffer stencil);
|
||||
bool CheckFrameBufferCompleteness();
|
||||
void ClearFrameBuffer(bool stencil, bool depth);
|
||||
void DeleteTexture(PPGLTexture &handle);
|
||||
void DeleteRenderBuffer(PPGLRenderBuffer &handle);
|
||||
void DeleteFrameBuffer(PPGLFrameBuffer &handle);
|
||||
|
||||
int mWidth = 0;
|
||||
int mHeight = 0;
|
||||
int mSceneWidth = 0;
|
||||
int mSceneHeight = 0;
|
||||
|
||||
// Buffers for the scene
|
||||
PPGLTexture mSceneDepthStencilTex;
|
||||
PPGLTexture mSceneTex;
|
||||
PPGLRenderBuffer mSceneDepthStencilBuf;
|
||||
PPGLRenderBuffer mSceneStencilBuf; // This is only use when combined depth-stencil is not avaliable
|
||||
PPGLFrameBuffer mSceneFB;
|
||||
bool mSceneUsesTextures = false;
|
||||
|
||||
PPGLTexture mDitherTexture;
|
||||
|
||||
static bool FailedCreate;
|
||||
|
||||
friend class GLPPRenderState;
|
||||
};
|
||||
|
||||
}
|
159
source/common/rendering/gles/gles_renderer.cpp
Normal file
159
source/common/rendering/gles/gles_renderer.cpp
Normal file
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
** gl_renderer.cpp
|
||||
** Renderer interface
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2005-2020 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 "gles_system.h"
|
||||
#include "files.h"
|
||||
#include "v_video.h"
|
||||
#include "m_png.h"
|
||||
#include "filesystem.h"
|
||||
#include "i_time.h"
|
||||
#include "cmdlib.h"
|
||||
#include "version.h"
|
||||
#include "gles_framebuffer.h"
|
||||
#include "hw_cvars.h"
|
||||
#include "gles_renderer.h"
|
||||
#include "gles_hwtexture.h"
|
||||
#include "gles_renderstate.h"
|
||||
#include "gles_samplers.h"
|
||||
#include "gles_renderbuffers.h"
|
||||
#include "gles_shaderprogram.h"
|
||||
#include "flatvertices.h"
|
||||
#include "hw_lightbuffer.h"
|
||||
#include "r_videoscale.h"
|
||||
#include "model.h"
|
||||
#include "gles_postprocessstate.h"
|
||||
#include "gles_buffers.h"
|
||||
#include "texturemanager.h"
|
||||
|
||||
EXTERN_CVAR(Int, screenblocks)
|
||||
|
||||
namespace OpenGLESRenderer
|
||||
{
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Renderer interface
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Initialize
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb)
|
||||
{
|
||||
framebuffer = fb;
|
||||
}
|
||||
|
||||
void FGLRenderer::Initialize(int width, int height)
|
||||
{
|
||||
mScreenBuffers = new FGLRenderBuffers();
|
||||
mBuffers = mScreenBuffers;
|
||||
mPresentShader = new FPresentShader();
|
||||
|
||||
mFBID = 0;
|
||||
mOldFBID = 0;
|
||||
|
||||
mShaderManager = new FShaderManager;
|
||||
mSamplerManager = new FSamplerManager;
|
||||
}
|
||||
|
||||
FGLRenderer::~FGLRenderer()
|
||||
{
|
||||
FlushModels();
|
||||
TexMan.FlushAll();
|
||||
if (mShaderManager != nullptr) delete mShaderManager;
|
||||
if (mFBID != 0) glDeleteFramebuffers(1, &mFBID);
|
||||
|
||||
if (mBuffers) delete mBuffers;
|
||||
if (mPresentShader) delete mPresentShader;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
bool FGLRenderer::StartOffscreen()
|
||||
{
|
||||
bool firstBind = (mFBID == 0);
|
||||
if (mFBID == 0)
|
||||
glGenFramebuffers(1, &mFBID);
|
||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &mOldFBID);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFBID);
|
||||
return true;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FGLRenderer::EndOffscreen()
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mOldFBID);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FGLRenderer::BindToFrameBuffer(FTexture *tex)
|
||||
{
|
||||
auto BaseLayer = static_cast<FHardwareTexture*>(tex->GetHardwareTexture(0, 0));
|
||||
// must create the hardware texture first
|
||||
BaseLayer->BindOrCreate(tex, 0, 0, 0, 0);
|
||||
FHardwareTexture::Unbind(0);
|
||||
gl_RenderState.ClearLastMaterial();
|
||||
BaseLayer->BindToFrameBuffer(tex->GetWidth(), tex->GetHeight());
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FGLRenderer::BeginFrame()
|
||||
{
|
||||
mScreenBuffers->Setup(screen->mScreenViewport.width, screen->mScreenViewport.height, screen->mSceneViewport.width, screen->mSceneViewport.height);
|
||||
}
|
||||
|
||||
}
|
106
source/common/rendering/gles/gles_renderer.h
Normal file
106
source/common/rendering/gles/gles_renderer.h
Normal file
|
@ -0,0 +1,106 @@
|
|||
#ifndef __GL_RENDERER_H
|
||||
#define __GL_RENDERER_H
|
||||
|
||||
#include "v_video.h"
|
||||
#include "vectors.h"
|
||||
#include "matrix.h"
|
||||
#include "gles_renderbuffers.h"
|
||||
#include <functional>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4244)
|
||||
#endif
|
||||
|
||||
struct particle_t;
|
||||
class FCanvasTexture;
|
||||
class FFlatVertexBuffer;
|
||||
class FSkyVertexBuffer;
|
||||
class HWPortal;
|
||||
class FLightBuffer;
|
||||
class DPSprite;
|
||||
class FGLRenderBuffers;
|
||||
class FGL2DDrawer;
|
||||
class SWSceneDrawer;
|
||||
class HWViewpointBuffer;
|
||||
struct FRenderViewpoint;
|
||||
|
||||
namespace OpenGLESRenderer
|
||||
{
|
||||
class FHardwareTexture;
|
||||
class FShaderManager;
|
||||
class FSamplerManager;
|
||||
class OpenGLFrameBuffer;
|
||||
class FPresentShaderBase;
|
||||
class FPresentShader;
|
||||
class FPresent3DCheckerShader;
|
||||
class FPresent3DColumnShader;
|
||||
class FPresent3DRowShader;
|
||||
class FShadowMapShader;
|
||||
|
||||
class FGLRenderer
|
||||
{
|
||||
public:
|
||||
|
||||
OpenGLFrameBuffer *framebuffer;
|
||||
int mMirrorCount = 0;
|
||||
int mPlaneMirrorCount = 0;
|
||||
FShaderManager *mShaderManager = nullptr;
|
||||
FSamplerManager* mSamplerManager = nullptr;
|
||||
unsigned int mFBID = 0;
|
||||
unsigned int mStencilValue = 0;
|
||||
|
||||
int mOldFBID = 0;
|
||||
|
||||
FGLRenderBuffers *mBuffers = nullptr;
|
||||
FGLRenderBuffers *mScreenBuffers = nullptr;
|
||||
FPresentShader *mPresentShader = nullptr;
|
||||
|
||||
//FRotator mAngles;
|
||||
|
||||
FGLRenderer(OpenGLFrameBuffer *fb);
|
||||
~FGLRenderer() ;
|
||||
|
||||
void Initialize(int width, int height);
|
||||
|
||||
void ClearBorders();
|
||||
|
||||
void PresentStereo();
|
||||
void RenderScreenQuad();
|
||||
void PostProcessScene(int fixedcm, float flash, const std::function<void()> &afterBloomDrawEndScene2D);
|
||||
|
||||
void CopyToBackbuffer(const IntRect *bounds, bool applyGamma);
|
||||
void DrawPresentTexture(const IntRect &box, bool applyGamma);
|
||||
void Flush();
|
||||
void BeginFrame();
|
||||
|
||||
bool StartOffscreen();
|
||||
void EndOffscreen();
|
||||
|
||||
void BindToFrameBuffer(FTexture* tex);
|
||||
|
||||
private:
|
||||
|
||||
bool QuadStereoCheckInitialRenderContextState();
|
||||
void PresentAnaglyph(bool r, bool g, bool b);
|
||||
void PresentSideBySide(int);
|
||||
void PresentTopBottom();
|
||||
void prepareInterleavedPresent(FPresentShaderBase& shader);
|
||||
void PresentColumnInterleaved();
|
||||
void PresentRowInterleaved();
|
||||
void PresentCheckerInterleaved();
|
||||
void PresentQuadStereo();
|
||||
|
||||
};
|
||||
|
||||
struct TexFilter_s
|
||||
{
|
||||
int minfilter;
|
||||
int magfilter;
|
||||
bool mipmapping;
|
||||
} ;
|
||||
|
||||
|
||||
extern FGLRenderer *GLRenderer;
|
||||
|
||||
}
|
||||
#endif
|
742
source/common/rendering/gles/gles_renderstate.cpp
Normal file
742
source/common/rendering/gles/gles_renderstate.cpp
Normal file
|
@ -0,0 +1,742 @@
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright(C) 2009-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_renderstate.cpp
|
||||
** Render state maintenance
|
||||
**
|
||||
*/
|
||||
|
||||
#include "templates.h"
|
||||
#include "gles_system.h"
|
||||
#include "hw_cvars.h"
|
||||
#include "flatvertices.h"
|
||||
#include "gles_shader.h"
|
||||
#include "gles_renderer.h"
|
||||
#include "hw_lightbuffer.h"
|
||||
#include "gles_renderbuffers.h"
|
||||
#include "gles_hwtexture.h"
|
||||
#include "gles_buffers.h"
|
||||
#include "gles_renderer.h"
|
||||
#include "gles_samplers.h"
|
||||
|
||||
#include "hw_clock.h"
|
||||
#include "printf.h"
|
||||
|
||||
#include "hwrenderer/data/hw_viewpointbuffer.h"
|
||||
|
||||
namespace OpenGLESRenderer
|
||||
{
|
||||
|
||||
FGLRenderState gl_RenderState;
|
||||
|
||||
static VSMatrix identityMatrix(1);
|
||||
|
||||
static void matrixToGL(const VSMatrix &mat, int loc)
|
||||
{
|
||||
glUniformMatrix4fv(loc, 1, false, (float*)&mat);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// This only gets called once upon setup.
|
||||
// With OpenGL the state is persistent and cannot be cleared, once set up.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderState::Reset()
|
||||
{
|
||||
FRenderState::Reset();
|
||||
mVertexBuffer = mCurrentVertexBuffer = nullptr;
|
||||
mGlossiness = 0.0f;
|
||||
mSpecularLevel = 0.0f;
|
||||
mShaderTimer = 0.0f;
|
||||
|
||||
stRenderStyle = DefaultRenderStyle();
|
||||
stSrcBlend = stDstBlend = -1;
|
||||
stBlendEquation = -1;
|
||||
stAlphaTest = 0;
|
||||
mLastDepthClamp = true;
|
||||
|
||||
mEffectState = 0;
|
||||
activeShader = nullptr;
|
||||
|
||||
mCurrentVertexBuffer = nullptr;
|
||||
mCurrentVertexOffsets[0] = mVertexOffsets[0] = 0;
|
||||
mCurrentIndexBuffer = nullptr;
|
||||
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Apply shader settings
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FGLRenderState::ApplyShader()
|
||||
{
|
||||
static const float nulvec[] = { 0.f, 0.f, 0.f, 0.f };
|
||||
|
||||
ShaderFlavourData flavour;
|
||||
|
||||
// Need to calc light data now in order to select correct shader
|
||||
float* lightPtr = NULL;
|
||||
int modLights = 0;
|
||||
int subLights = 0;
|
||||
int addLights = 0;
|
||||
int totalLights = 0;
|
||||
|
||||
flavour.hasSpotLight = false;
|
||||
|
||||
if (mLightIndex >= 0)
|
||||
{
|
||||
lightPtr = ((float*)screen->mLights->GetBuffer()->Memory());
|
||||
lightPtr += ((int64_t)mLightIndex * 4);
|
||||
//float array[64];
|
||||
//memcpy(array, ptr, 4 * 64);
|
||||
|
||||
// Calculate how much light data there is to upload, this is stored in the first 4 floats
|
||||
modLights = int(lightPtr[1]) / LIGHT_VEC4_NUM;
|
||||
subLights = (int(lightPtr[2]) - int(lightPtr[1])) / LIGHT_VEC4_NUM;
|
||||
addLights = (int(lightPtr[3]) - int(lightPtr[2])) / LIGHT_VEC4_NUM;
|
||||
|
||||
// Here we limit the number of lights, but dont' change the light data so priority has to be mod, sub then add
|
||||
if (modLights > (int)gles.maxlights)
|
||||
modLights = gles.maxlights;
|
||||
|
||||
if (modLights + subLights > (int)gles.maxlights)
|
||||
subLights = gles.maxlights - modLights;
|
||||
|
||||
if (modLights + subLights + addLights > (int)gles.maxlights)
|
||||
addLights = gles.maxlights - modLights - subLights;
|
||||
|
||||
totalLights = modLights + subLights + addLights;
|
||||
|
||||
// Skip passed the first 4 floats so the upload below only contains light data
|
||||
lightPtr += 4;
|
||||
|
||||
float* findSpotsPtr = lightPtr + 11; // The 11th float contains '1' if the light is a spot light, see hw_dynlightdata.cpp
|
||||
|
||||
for (int n = 0; n < totalLights; n++)
|
||||
{
|
||||
if (*findSpotsPtr > 0) // This is a spot light
|
||||
{
|
||||
flavour.hasSpotLight = true;
|
||||
break;
|
||||
}
|
||||
findSpotsPtr += LIGHT_VEC4_NUM * 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int tm = GetTextureModeAndFlags(mTempTM);
|
||||
flavour.textureMode = tm & 0xffff;
|
||||
flavour.texFlags = tm >> 16; //Move flags to start of word
|
||||
|
||||
if (mTextureClamp && flavour.textureMode == TM_NORMAL) flavour.textureMode = TM_CLAMPY; // fixme. Clamp can now be combined with all modes.
|
||||
|
||||
if (flavour.textureMode == -1)
|
||||
flavour.textureMode = 0;
|
||||
|
||||
|
||||
flavour.blendFlags = (int)(mStreamData.uTextureAddColor.a + 0.01);
|
||||
|
||||
flavour.twoDFog = false;
|
||||
flavour.fogEnabled = false;
|
||||
flavour.fogEquationRadial = false;
|
||||
flavour.colouredFog = false;
|
||||
|
||||
flavour.fogEquationRadial = (gl_fogmode == 2);
|
||||
|
||||
flavour.twoDFog = false;
|
||||
flavour.fogEnabled = false;
|
||||
flavour.colouredFog = false;
|
||||
|
||||
if (mFogEnabled)
|
||||
{
|
||||
if (mFogEnabled == 2)
|
||||
{
|
||||
flavour.twoDFog = true;
|
||||
}
|
||||
else if (gl_fogmode)
|
||||
{
|
||||
flavour.fogEnabled = true;
|
||||
|
||||
if ((GetFogColor() & 0xffffff) != 0)
|
||||
flavour.colouredFog = true;
|
||||
}
|
||||
}
|
||||
|
||||
flavour.doDesaturate = mStreamData.uDesaturationFactor != 0;
|
||||
flavour.useULightLevel = (mLightParms[3] >= 0); //#define uLightLevel uLightAttr.a
|
||||
|
||||
// Yes create shaders for all combinations of active lights to avoid more branches
|
||||
flavour.dynLightsMod = (modLights > 0);
|
||||
flavour.dynLightsSub = (subLights > 0);
|
||||
flavour.dynLightsAdd = (addLights > 0);
|
||||
|
||||
flavour.useObjectColor2 = (mStreamData.uObjectColor2.a > 0);
|
||||
flavour.useGlowTopColor = mGlowEnabled && (mStreamData.uGlowTopColor[3] > 0);
|
||||
flavour.useGlowBottomColor = mGlowEnabled && (mStreamData.uGlowBottomColor[3] > 0);
|
||||
|
||||
flavour.useColorMap = (mColorMapSpecial >= CM_FIRSTSPECIALCOLORMAP) || (mColorMapFlash != 1);
|
||||
|
||||
flavour.buildLighting = (mHwUniforms->mPalLightLevels >> 16) == 5; // Build engine mode
|
||||
flavour.bandedSwLight = !!(mHwUniforms->mPalLightLevels & 0xFF);
|
||||
|
||||
#ifdef NPOT_EMULATION
|
||||
flavour.npotEmulation = (mStreamData.uNpotEmulation.Y != 0);
|
||||
#endif
|
||||
|
||||
if (mSpecialEffect > EFF_NONE)
|
||||
{
|
||||
activeShader = GLRenderer->mShaderManager->BindEffect(mSpecialEffect, mPassType, flavour);
|
||||
}
|
||||
else
|
||||
{
|
||||
activeShader = GLRenderer->mShaderManager->Get(mTextureEnabled ? mEffectState : SHADER_NoTexture, mAlphaThreshold >= 0.f, mPassType);
|
||||
|
||||
activeShader->Bind(flavour);
|
||||
}
|
||||
|
||||
|
||||
if (mHwUniforms)
|
||||
{
|
||||
activeShader->cur->muProjectionMatrix.Set(&mHwUniforms->mProjectionMatrix);
|
||||
activeShader->cur->muViewMatrix.Set(&mHwUniforms->mViewMatrix);
|
||||
activeShader->cur->muNormalViewMatrix.Set(&mHwUniforms->mNormalViewMatrix);
|
||||
|
||||
activeShader->cur->muCameraPos.Set(&mHwUniforms->mCameraPos.X);
|
||||
activeShader->cur->muClipLine.Set(&mHwUniforms->mClipLine.X);
|
||||
|
||||
activeShader->cur->muGlobVis.Set(mHwUniforms->mGlobVis);
|
||||
|
||||
activeShader->cur->muPalLightLevels.Set(mHwUniforms->mPalLightLevels & 0xFF); // JUST pass the pal levels, clear the top bits
|
||||
activeShader->cur->muViewHeight.Set(mHwUniforms->mViewHeight);
|
||||
activeShader->cur->muClipHeight.Set(mHwUniforms->mClipHeight);
|
||||
activeShader->cur->muClipHeightDirection.Set(mHwUniforms->mClipHeightDirection);
|
||||
//activeShader->cur->muShadowmapFilter.Set(mHwUniforms->mShadowmapFilter);
|
||||
}
|
||||
|
||||
glVertexAttrib4fv(VATTR_COLOR, &mStreamData.uVertexColor.X);
|
||||
glVertexAttrib4fv(VATTR_NORMAL, &mStreamData.uVertexNormal.X);
|
||||
|
||||
activeShader->cur->muDesaturation.Set(mStreamData.uDesaturationFactor);
|
||||
//activeShader->cur->muFogEnabled.Set(fogset);
|
||||
|
||||
activeShader->cur->muLightParms.Set(mLightParms);
|
||||
activeShader->cur->muFogColor.Set(mStreamData.uFogColor);
|
||||
activeShader->cur->muObjectColor.Set(mStreamData.uObjectColor);
|
||||
activeShader->cur->muDynLightColor.Set(&mStreamData.uDynLightColor.X);
|
||||
activeShader->cur->muInterpolationFactor.Set(mStreamData.uInterpolationFactor);
|
||||
activeShader->cur->muTimer.Set((double)(screen->FrameTime - firstFrame) * (double)mShaderTimer / 1000.);
|
||||
activeShader->cur->muAlphaThreshold.Set(mAlphaThreshold);
|
||||
activeShader->cur->muClipSplit.Set(mClipSplit);
|
||||
activeShader->cur->muSpecularMaterial.Set(mGlossiness, mSpecularLevel);
|
||||
activeShader->cur->muAddColor.Set(mStreamData.uAddColor);
|
||||
activeShader->cur->muTextureAddColor.Set(mStreamData.uTextureAddColor);
|
||||
activeShader->cur->muTextureModulateColor.Set(mStreamData.uTextureModulateColor);
|
||||
activeShader->cur->muTextureBlendColor.Set(mStreamData.uTextureBlendColor);
|
||||
activeShader->cur->muDetailParms.Set(&mStreamData.uDetailParms.X);
|
||||
#ifdef NPOT_EMULATION
|
||||
activeShader->cur->muNpotEmulation.Set(&mStreamData.uNpotEmulation.X);
|
||||
#endif
|
||||
|
||||
if (flavour.useColorMap)
|
||||
{
|
||||
if (mColorMapSpecial < CM_FIRSTSPECIALCOLORMAP || mColorMapSpecial >= CM_MAXCOLORMAP)
|
||||
{
|
||||
activeShader->cur->muFixedColormapStart.Set( 0,0,0, mColorMapFlash );
|
||||
activeShader->cur->muFixedColormapRange.Set( 0,0,0, 1.f );
|
||||
}
|
||||
else
|
||||
{
|
||||
FSpecialColormap* scm = &SpecialColormaps[mColorMapSpecial - CM_FIRSTSPECIALCOLORMAP];
|
||||
|
||||
//uniforms.MapStart = { scm->ColorizeStart[0], scm->ColorizeStart[1], scm->ColorizeStart[2], flash };
|
||||
activeShader->cur->muFixedColormapStart.Set( scm->ColorizeStart[0], scm->ColorizeStart[1], scm->ColorizeStart[2], mColorMapFlash );
|
||||
activeShader->cur->muFixedColormapRange.Set( scm->ColorizeEnd[0] - scm->ColorizeStart[0],
|
||||
scm->ColorizeEnd[1] - scm->ColorizeStart[1], scm->ColorizeEnd[2] - scm->ColorizeStart[2], 0.f );
|
||||
}
|
||||
}
|
||||
|
||||
if (mGlowEnabled || activeShader->cur->currentglowstate)
|
||||
{
|
||||
activeShader->cur->muGlowTopColor.Set(&mStreamData.uGlowTopColor.X);
|
||||
activeShader->cur->muGlowBottomColor.Set(&mStreamData.uGlowBottomColor.X);
|
||||
activeShader->cur->muGlowTopPlane.Set(&mStreamData.uGlowTopPlane.X);
|
||||
activeShader->cur->muGlowBottomPlane.Set(&mStreamData.uGlowBottomPlane.X);
|
||||
activeShader->cur->currentglowstate = mGlowEnabled;
|
||||
}
|
||||
|
||||
if (mGradientEnabled || activeShader->cur->currentgradientstate)
|
||||
{
|
||||
activeShader->cur->muObjectColor2.Set(mStreamData.uObjectColor2);
|
||||
activeShader->cur->muGradientTopPlane.Set(&mStreamData.uGradientTopPlane.X);
|
||||
activeShader->cur->muGradientBottomPlane.Set(&mStreamData.uGradientBottomPlane.X);
|
||||
activeShader->cur->currentgradientstate = mGradientEnabled;
|
||||
}
|
||||
|
||||
if (mSplitEnabled || activeShader->cur->currentsplitstate)
|
||||
{
|
||||
activeShader->cur->muSplitTopPlane.Set(&mStreamData.uSplitTopPlane.X);
|
||||
activeShader->cur->muSplitBottomPlane.Set(&mStreamData.uSplitBottomPlane.X);
|
||||
activeShader->cur->currentsplitstate = mSplitEnabled;
|
||||
}
|
||||
|
||||
|
||||
if (mTextureMatrixEnabled)
|
||||
{
|
||||
matrixToGL(mTextureMatrix, activeShader->cur->texturematrix_index);
|
||||
activeShader->cur->currentTextureMatrixState = true;
|
||||
}
|
||||
else if (activeShader->cur->currentTextureMatrixState)
|
||||
{
|
||||
activeShader->cur->currentTextureMatrixState = false;
|
||||
matrixToGL(identityMatrix, activeShader->cur->texturematrix_index);
|
||||
}
|
||||
|
||||
if (mModelMatrixEnabled)
|
||||
{
|
||||
matrixToGL(mModelMatrix, activeShader->cur->modelmatrix_index);
|
||||
VSMatrix norm;
|
||||
norm.computeNormalMatrix(mModelMatrix);
|
||||
matrixToGL(norm, activeShader->cur->normalmodelmatrix_index);
|
||||
activeShader->cur->currentModelMatrixState = true;
|
||||
}
|
||||
else if (activeShader->cur->currentModelMatrixState)
|
||||
{
|
||||
activeShader->cur->currentModelMatrixState = false;
|
||||
matrixToGL(identityMatrix, activeShader->cur->modelmatrix_index);
|
||||
matrixToGL(identityMatrix, activeShader->cur->normalmodelmatrix_index);
|
||||
}
|
||||
|
||||
// Upload the light data
|
||||
if (mLightIndex >= 0)
|
||||
{
|
||||
// Calculate the total number of vec4s we need
|
||||
int totalVectors = totalLights * LIGHT_VEC4_NUM;
|
||||
|
||||
if (totalVectors > (int)gles.numlightvectors)
|
||||
totalVectors = gles.numlightvectors;
|
||||
|
||||
glUniform4fv(activeShader->cur->lights_index, totalVectors, lightPtr);
|
||||
|
||||
int range[4] = { 0,
|
||||
modLights * LIGHT_VEC4_NUM,
|
||||
(modLights + subLights) * LIGHT_VEC4_NUM,
|
||||
(modLights + subLights + addLights) * LIGHT_VEC4_NUM };
|
||||
|
||||
activeShader->cur->muLightRange.Set(range);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Apply State
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderState::ApplyState()
|
||||
{
|
||||
if (mRenderStyle != stRenderStyle)
|
||||
{
|
||||
ApplyBlendMode();
|
||||
stRenderStyle = mRenderStyle;
|
||||
}
|
||||
|
||||
if (mSplitEnabled != stSplitEnabled)
|
||||
{
|
||||
/*
|
||||
if (mSplitEnabled)
|
||||
{
|
||||
glEnable(GL_CLIP_DISTANCE3);
|
||||
glEnable(GL_CLIP_DISTANCE4);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_CLIP_DISTANCE3);
|
||||
glDisable(GL_CLIP_DISTANCE4);
|
||||
}
|
||||
*/
|
||||
stSplitEnabled = mSplitEnabled;
|
||||
}
|
||||
|
||||
if (mMaterial.mChanged)
|
||||
{
|
||||
ApplyMaterial(mMaterial.mMaterial, mMaterial.mClampMode, mMaterial.mTranslation, mMaterial.mOverrideShader);
|
||||
mMaterial.mChanged = false;
|
||||
}
|
||||
|
||||
if (mBias.mChanged)
|
||||
{
|
||||
if (mBias.mFactor == 0 && mBias.mUnits == 0)
|
||||
{
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
}
|
||||
else
|
||||
{
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
}
|
||||
glPolygonOffset(mBias.mFactor, mBias.mUnits);
|
||||
mBias.mChanged = false;
|
||||
}
|
||||
}
|
||||
|
||||
void FGLRenderState::ApplyBuffers()
|
||||
{
|
||||
if (mVertexBuffer != mCurrentVertexBuffer || mVertexOffsets[0] != mCurrentVertexOffsets[0] || mVertexOffsets[1] != mCurrentVertexOffsets[1])
|
||||
{
|
||||
assert(mVertexBuffer != nullptr);
|
||||
static_cast<GLVertexBuffer*>(mVertexBuffer)->Bind(mVertexOffsets);
|
||||
mCurrentVertexBuffer = mVertexBuffer;
|
||||
mCurrentVertexOffsets[0] = mVertexOffsets[0];
|
||||
mCurrentVertexOffsets[1] = mVertexOffsets[1];
|
||||
}
|
||||
if (mIndexBuffer != mCurrentIndexBuffer)
|
||||
{
|
||||
if (mIndexBuffer) static_cast<GLIndexBuffer*>(mIndexBuffer)->Bind();
|
||||
mCurrentIndexBuffer = mIndexBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
void FGLRenderState::Apply()
|
||||
{
|
||||
ApplyState();
|
||||
ApplyBuffers();
|
||||
ApplyShader();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Binds a texture to the renderer
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FGLRenderState::ApplyMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader)
|
||||
{
|
||||
if (mat->Source()->isHardwareCanvas())
|
||||
{
|
||||
mTempTM = TM_OPAQUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mTempTM = TM_NORMAL;
|
||||
}
|
||||
auto tex = mat->Source();
|
||||
mEffectState = overrideshader >= 0 ? overrideshader : mat->GetShaderIndex();
|
||||
mShaderTimer = tex->GetShaderSpeed();
|
||||
SetSpecular(tex->GetGlossiness(), tex->GetSpecularLevel());
|
||||
if (tex->isHardwareCanvas()) static_cast<FCanvasTexture*>(tex->GetTexture())->NeedUpdate();
|
||||
|
||||
clampmode = tex->GetClampMode(clampmode);
|
||||
|
||||
// avoid rebinding the same texture multiple times.
|
||||
if (mat == lastMaterial && lastClamp == clampmode && translation == lastTranslation) return;
|
||||
lastMaterial = mat;
|
||||
lastClamp = clampmode;
|
||||
lastTranslation = translation;
|
||||
|
||||
int usebright = false;
|
||||
int maxbound = 0;
|
||||
|
||||
int numLayers = mat->NumLayers();
|
||||
MaterialLayerInfo* layer;
|
||||
auto base = static_cast<FHardwareTexture*>(mat->GetLayer(0, translation, &layer));
|
||||
|
||||
if (base->BindOrCreate(tex->GetTexture(), 0, clampmode, translation, layer->scaleFlags))
|
||||
{
|
||||
if (!(layer->scaleFlags & CTF_Indexed))
|
||||
{
|
||||
for (int i = 1; i < numLayers; i++)
|
||||
{
|
||||
auto systex = static_cast<FHardwareTexture*>(mat->GetLayer(i, 0, &layer));
|
||||
// fixme: Upscale flags must be disabled for certain layers.
|
||||
systex->BindOrCreate(layer->layerTexture, i, clampmode, 0, layer->scaleFlags);
|
||||
maxbound = i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 1; i < 3; i++)
|
||||
{
|
||||
auto systex = static_cast<FHardwareTexture*>(mat->GetLayer(i, translation, &layer));
|
||||
GLRenderer->mSamplerManager->Bind(i, CLAMP_NONE, 255);
|
||||
systex->Bind(i, false);
|
||||
maxbound = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
// unbind everything from the last texture that's still active
|
||||
for (int i = maxbound + 1; i <= maxBoundMaterial; i++)
|
||||
{
|
||||
FHardwareTexture::Unbind(i);
|
||||
maxBoundMaterial = maxbound;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Apply blend mode from RenderStyle
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderState::ApplyBlendMode()
|
||||
{
|
||||
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, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA };
|
||||
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[mRenderStyle.SrcAlpha%STYLEALPHA_MAX];
|
||||
int dstblend = blendstyles[mRenderStyle.DestAlpha%STYLEALPHA_MAX];
|
||||
int blendequation = renderops[mRenderStyle.BlendOp & 15];
|
||||
|
||||
if (blendequation == -1) // This was a fuzz style.
|
||||
{
|
||||
srcblend = GL_DST_COLOR;
|
||||
dstblend = GL_ONE_MINUS_SRC_ALPHA;
|
||||
blendequation = GL_FUNC_ADD;
|
||||
}
|
||||
|
||||
// Checks must be disabled until all draw code has been converted.
|
||||
if (srcblend != stSrcBlend || dstblend != stDstBlend)
|
||||
{
|
||||
stSrcBlend = srcblend;
|
||||
stDstBlend = dstblend;
|
||||
glBlendFunc(srcblend, dstblend);
|
||||
}
|
||||
if (blendequation != stBlendEquation)
|
||||
{
|
||||
stBlendEquation = blendequation;
|
||||
glBlendEquation(blendequation);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// API dependent draw calls
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static int dt2gl[] = { GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_FAN, GL_TRIANGLE_STRIP };
|
||||
|
||||
void FGLRenderState::Draw(int dt, int index, int count, bool apply)
|
||||
{
|
||||
if (apply)
|
||||
{
|
||||
Apply();
|
||||
}
|
||||
drawcalls.Clock();
|
||||
glDrawArrays(dt2gl[dt], index, count);
|
||||
drawcalls.Unclock();
|
||||
}
|
||||
|
||||
void FGLRenderState::DrawIndexed(int dt, int index, int count, bool apply)
|
||||
{
|
||||
if (apply)
|
||||
{
|
||||
Apply();
|
||||
}
|
||||
drawcalls.Clock();
|
||||
glDrawElements(dt2gl[dt], count, GL_UNSIGNED_INT, (void*)(intptr_t)(index * sizeof(uint32_t)));
|
||||
drawcalls.Unclock();
|
||||
}
|
||||
|
||||
void FGLRenderState::SetDepthMask(bool on)
|
||||
{
|
||||
glDepthMask(on);
|
||||
}
|
||||
|
||||
void FGLRenderState::SetDepthFunc(int func)
|
||||
{
|
||||
static int df2gl[] = { GL_LESS, GL_LEQUAL, GL_ALWAYS };
|
||||
glDepthFunc(df2gl[func]);
|
||||
}
|
||||
|
||||
void FGLRenderState::SetDepthRange(float min, float max)
|
||||
{
|
||||
glDepthRangef(min, max);
|
||||
}
|
||||
|
||||
void FGLRenderState::SetColorMask(bool r, bool g, bool b, bool a)
|
||||
{
|
||||
glColorMask(r, g, b, a);
|
||||
}
|
||||
|
||||
void FGLRenderState::SetStencil(int offs, int op, int flags = -1)
|
||||
{
|
||||
static int op2gl[] = { GL_KEEP, GL_INCR, GL_DECR };
|
||||
|
||||
glStencilFunc(GL_EQUAL, screen->stencilValue + offs, ~0); // draw sky into stencil
|
||||
glStencilOp(GL_KEEP, GL_KEEP, op2gl[op]); // this stage doesn't modify the stencil
|
||||
|
||||
if (flags != -1)
|
||||
{
|
||||
bool cmon = !(flags & SF_ColorMaskOff);
|
||||
glColorMask(cmon, cmon, cmon, cmon); // don't write to the graphics buffer
|
||||
glDepthMask(!(flags & SF_DepthMaskOff));
|
||||
}
|
||||
}
|
||||
|
||||
void FGLRenderState::ToggleState(int state, bool on)
|
||||
{
|
||||
if (on)
|
||||
{
|
||||
glEnable(state);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(state);
|
||||
}
|
||||
}
|
||||
|
||||
void FGLRenderState::SetCulling(int mode)
|
||||
{
|
||||
if (mode != Cull_None)
|
||||
{
|
||||
glEnable(GL_CULL_FACE);
|
||||
glFrontFace(mode == Cull_CCW ? GL_CCW : GL_CW);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_CULL_FACE);
|
||||
}
|
||||
}
|
||||
|
||||
void FGLRenderState::EnableClipDistance(int num, bool state)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void FGLRenderState::Clear(int targets)
|
||||
{
|
||||
// This always clears to default values.
|
||||
int gltarget = 0;
|
||||
if (targets & CT_Depth)
|
||||
{
|
||||
gltarget |= GL_DEPTH_BUFFER_BIT;
|
||||
|
||||
glClearDepthf(1);
|
||||
}
|
||||
if (targets & CT_Stencil)
|
||||
{
|
||||
gltarget |= GL_STENCIL_BUFFER_BIT;
|
||||
glClearStencil(0);
|
||||
}
|
||||
if (targets & CT_Color)
|
||||
{
|
||||
gltarget |= GL_COLOR_BUFFER_BIT;
|
||||
glClearColor(screen->mSceneClearColor[0], screen->mSceneClearColor[1], screen->mSceneClearColor[2], screen->mSceneClearColor[3]);
|
||||
}
|
||||
glClear(gltarget);
|
||||
}
|
||||
|
||||
void FGLRenderState::EnableStencil(bool on)
|
||||
{
|
||||
ToggleState(GL_STENCIL_TEST, on);
|
||||
}
|
||||
|
||||
void FGLRenderState::SetScissor(int x, int y, int w, int h)
|
||||
{
|
||||
if (w > -1)
|
||||
{
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glScissor(x, y, w, h);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
}
|
||||
|
||||
void FGLRenderState::SetViewport(int x, int y, int w, int h)
|
||||
{
|
||||
glViewport(x, y, w, h);
|
||||
}
|
||||
|
||||
void FGLRenderState::EnableDepthTest(bool on)
|
||||
{
|
||||
ToggleState(GL_DEPTH_TEST, on);
|
||||
}
|
||||
|
||||
void FGLRenderState::EnableMultisampling(bool on)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void FGLRenderState::EnableLineSmooth(bool on)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void FGLRenderState::ClearScreen()
|
||||
{
|
||||
|
||||
screen->mViewpoints->Set2D(*this, SCREENWIDTH, SCREENHEIGHT);
|
||||
SetColor(0, 0, 0);
|
||||
Apply();
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, FFlatVertexBuffer::FULLSCREEN_INDEX, 4);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Below are less frequently altrered state settings which do not get
|
||||
// buffered by the state object, but set directly instead.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FGLRenderState::SetDepthClamp(bool on)
|
||||
{
|
||||
bool res = mLastDepthClamp;
|
||||
|
||||
if (gles.depthClampAvailable)
|
||||
{
|
||||
if (!on) glDisable(GL_DEPTH_CLAMP);
|
||||
else glEnable(GL_DEPTH_CLAMP);
|
||||
}
|
||||
|
||||
mLastDepthClamp = on;
|
||||
return res;
|
||||
}
|
||||
void FGLRenderState::ApplyViewport(void* data)
|
||||
{
|
||||
mHwUniforms = reinterpret_cast<HWViewpointUniforms*>(static_cast<uint8_t*>(data));
|
||||
|
||||
}
|
||||
}
|
152
source/common/rendering/gles/gles_renderstate.h
Normal file
152
source/common/rendering/gles/gles_renderstate.h
Normal file
|
@ -0,0 +1,152 @@
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright(C) 2009-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/
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
#ifndef __GL_RENDERSTATE_H
|
||||
#define __GL_RENDERSTATE_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <string.h>
|
||||
#include "matrix.h"
|
||||
#include "hw_renderstate.h"
|
||||
#include "hw_material.h"
|
||||
#include "c_cvars.h"
|
||||
#include "hwrenderer/data/hw_viewpointuniforms.h"
|
||||
|
||||
namespace OpenGLESRenderer
|
||||
{
|
||||
|
||||
class FShader;
|
||||
struct HWSectorPlane;
|
||||
|
||||
class FGLRenderState final : public FRenderState
|
||||
{
|
||||
uint8_t mLastDepthClamp : 1;
|
||||
|
||||
float mGlossiness, mSpecularLevel;
|
||||
float mShaderTimer;
|
||||
|
||||
int mEffectState;
|
||||
int mTempTM = TM_NORMAL;
|
||||
|
||||
FRenderStyle stRenderStyle;
|
||||
int stSrcBlend, stDstBlend;
|
||||
bool stAlphaTest;
|
||||
bool stSplitEnabled;
|
||||
int stBlendEquation;
|
||||
|
||||
FShader *activeShader;
|
||||
|
||||
int mNumDrawBuffers = 1;
|
||||
|
||||
bool ApplyShader();
|
||||
void ApplyState();
|
||||
|
||||
// Texture binding state
|
||||
FMaterial *lastMaterial = nullptr;
|
||||
int lastClamp = 0;
|
||||
int lastTranslation = 0;
|
||||
int maxBoundMaterial = -1;
|
||||
size_t mLastMappedLightIndex = SIZE_MAX;
|
||||
|
||||
IVertexBuffer *mCurrentVertexBuffer;
|
||||
int mCurrentVertexOffsets[2]; // one per binding point
|
||||
IIndexBuffer *mCurrentIndexBuffer;
|
||||
|
||||
HWViewpointUniforms* mHwUniforms = nullptr;
|
||||
|
||||
public:
|
||||
|
||||
FGLRenderState()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
void Reset();
|
||||
|
||||
void ClearLastMaterial()
|
||||
{
|
||||
lastMaterial = nullptr;
|
||||
}
|
||||
|
||||
void ApplyMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader);
|
||||
|
||||
void Apply();
|
||||
void ApplyBuffers();
|
||||
void ApplyBlendMode();
|
||||
|
||||
void ResetVertexBuffer()
|
||||
{
|
||||
// forces rebinding with the next 'apply' call.
|
||||
mCurrentVertexBuffer = nullptr;
|
||||
mCurrentIndexBuffer = nullptr;
|
||||
}
|
||||
|
||||
void SetSpecular(float glossiness, float specularLevel)
|
||||
{
|
||||
mGlossiness = glossiness;
|
||||
mSpecularLevel = specularLevel;
|
||||
}
|
||||
|
||||
void EnableDrawBuffers(int count, bool apply = false) override
|
||||
{
|
||||
/*
|
||||
count = std::min(count, 3);
|
||||
if (mNumDrawBuffers != count)
|
||||
{
|
||||
static GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 };
|
||||
glDrawBuffers(count, buffers);
|
||||
mNumDrawBuffers = count;
|
||||
}
|
||||
if (apply) Apply();
|
||||
*/
|
||||
}
|
||||
|
||||
void ToggleState(int state, bool on);
|
||||
|
||||
void ClearScreen() override;
|
||||
void Draw(int dt, int index, int count, bool apply = true) override;
|
||||
void DrawIndexed(int dt, int index, int count, bool apply = true) override;
|
||||
|
||||
bool SetDepthClamp(bool on) override;
|
||||
void SetDepthMask(bool on) override;
|
||||
void SetDepthFunc(int func) override;
|
||||
void SetDepthRange(float min, float max) override;
|
||||
void SetColorMask(bool r, bool g, bool b, bool a) override;
|
||||
void SetStencil(int offs, int op, int flags) override;
|
||||
void SetCulling(int mode) override;
|
||||
void EnableClipDistance(int num, bool state) override;
|
||||
void Clear(int targets) override;
|
||||
void EnableStencil(bool on) override;
|
||||
void SetScissor(int x, int y, int w, int h) override;
|
||||
void SetViewport(int x, int y, int w, int h) override;
|
||||
void EnableDepthTest(bool on) override;
|
||||
void EnableMultisampling(bool on) override;
|
||||
void EnableLineSmooth(bool on) override;
|
||||
|
||||
void ApplyViewport(void* data);
|
||||
};
|
||||
|
||||
extern FGLRenderState gl_RenderState;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
196
source/common/rendering/gles/gles_samplers.cpp
Normal file
196
source/common/rendering/gles/gles_samplers.cpp
Normal file
|
@ -0,0 +1,196 @@
|
|||
/*
|
||||
** gl_samplers.cpp
|
||||
**
|
||||
** Texture sampler handling
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2015-2019 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 "gles_system.h"
|
||||
#include "c_cvars.h"
|
||||
|
||||
#include "hw_cvars.h"
|
||||
|
||||
#include "gles_renderer.h"
|
||||
#include "gles_samplers.h"
|
||||
#include "hw_material.h"
|
||||
#include "i_interface.h"
|
||||
|
||||
namespace OpenGLESRenderer
|
||||
{
|
||||
|
||||
extern TexFilter_s TexFilter[];
|
||||
|
||||
|
||||
FSamplerManager::FSamplerManager()
|
||||
{
|
||||
SetTextureFilterMode();
|
||||
}
|
||||
|
||||
FSamplerManager::~FSamplerManager()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void FSamplerManager::UnbindAll()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
uint8_t FSamplerManager::Bind(int texunit, int num, int lastval)
|
||||
{
|
||||
|
||||
int filter = sysCallbacks.DisableTextureFilter && sysCallbacks.DisableTextureFilter() ? 0 : gl_texture_filter;
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + texunit);
|
||||
switch (num)
|
||||
{
|
||||
case CLAMP_NONE:
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
if (lastval >= CLAMP_XY_NOMIP)
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[filter].minfilter);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[filter].magfilter);
|
||||
}
|
||||
break;
|
||||
|
||||
case CLAMP_X:
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
if (lastval >= CLAMP_XY_NOMIP)
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[filter].minfilter);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[filter].magfilter);
|
||||
}
|
||||
break;
|
||||
|
||||
case CLAMP_Y:
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
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[filter].minfilter);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[filter].magfilter);
|
||||
}
|
||||
break;
|
||||
|
||||
case CLAMP_XY:
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
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[filter].minfilter);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[filter].magfilter);
|
||||
}
|
||||
break;
|
||||
|
||||
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[filter].magfilter);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[filter].magfilter);
|
||||
break;
|
||||
|
||||
case CLAMP_NOFILTER:
|
||||
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, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
break;
|
||||
|
||||
case CLAMP_NOFILTER_X:
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
break;
|
||||
|
||||
case CLAMP_NOFILTER_Y:
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
break;
|
||||
|
||||
case CLAMP_NOFILTER_XY:
|
||||
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, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
break;
|
||||
|
||||
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[filter].magfilter);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[filter].magfilter);
|
||||
break;
|
||||
}
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
return 255;
|
||||
}
|
||||
|
||||
|
||||
void FSamplerManager::SetTextureFilterMode()
|
||||
{
|
||||
/*
|
||||
GLRenderer->FlushTextures();
|
||||
|
||||
GLint bounds[IHardwareTexture::MAX_TEXTURES];
|
||||
|
||||
// Unbind all
|
||||
for(int i = IHardwareTexture::MAX_TEXTURES-1; i >= 0; i--)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0 + i);
|
||||
glGetIntegerv(GL_SAMPLER_BINDING, &bounds[i]);
|
||||
glBindSampler(i, 0);
|
||||
}
|
||||
|
||||
int filter = sysCallbacks.DisableTextureFilter && sysCallbacks.DisableTextureFilter() ? 0 : gl_texture_filter;
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
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, filter > 0? gl_texture_filter_anisotropic : 1.0);
|
||||
}
|
||||
glSamplerParameteri(mSamplers[CLAMP_XY_NOMIP], GL_TEXTURE_MIN_FILTER, TexFilter[filter].magfilter);
|
||||
glSamplerParameteri(mSamplers[CLAMP_XY_NOMIP], GL_TEXTURE_MAG_FILTER, TexFilter[filter].magfilter);
|
||||
glSamplerParameteri(mSamplers[CLAMP_CAMTEX], GL_TEXTURE_MIN_FILTER, TexFilter[filter].magfilter);
|
||||
glSamplerParameteri(mSamplers[CLAMP_CAMTEX], GL_TEXTURE_MAG_FILTER, TexFilter[filter].magfilter);
|
||||
for(int i = 0; i < IHardwareTexture::MAX_TEXTURES; i++)
|
||||
{
|
||||
glBindSampler(i, bounds[i]);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
}
|
27
source/common/rendering/gles/gles_samplers.h
Normal file
27
source/common/rendering/gles/gles_samplers.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
#ifndef __GLES_SAMPLERS_H
|
||||
#define __GLES_SAMPLERS_H
|
||||
|
||||
#include "gles_hwtexture.h"
|
||||
#include "textures.h"
|
||||
|
||||
namespace OpenGLESRenderer
|
||||
{
|
||||
|
||||
|
||||
class FSamplerManager
|
||||
{
|
||||
void UnbindAll();
|
||||
|
||||
public:
|
||||
|
||||
FSamplerManager();
|
||||
~FSamplerManager();
|
||||
|
||||
uint8_t Bind(int texunit, int num, int lastval);
|
||||
void SetTextureFilterMode();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
955
source/common/rendering/gles/gles_shader.cpp
Normal file
955
source/common/rendering/gles/gles_shader.cpp
Normal file
|
@ -0,0 +1,955 @@
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright(C) 2004-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_shader.cpp
|
||||
**
|
||||
** GLSL shader handling
|
||||
**
|
||||
*/
|
||||
|
||||
#include "gles_system.h"
|
||||
#include "c_cvars.h"
|
||||
#include "v_video.h"
|
||||
#include "filesystem.h"
|
||||
#include "engineerrors.h"
|
||||
#include "cmdlib.h"
|
||||
#include "md5.h"
|
||||
#include "gles_shader.h"
|
||||
#include "hw_shaderpatcher.h"
|
||||
#include "shaderuniforms.h"
|
||||
#include "hw_viewpointuniforms.h"
|
||||
#include "hw_lightbuffer.h"
|
||||
#include "i_specialpaths.h"
|
||||
#include "printf.h"
|
||||
#include "version.h"
|
||||
|
||||
#include "matrix.h"
|
||||
#include "gles_renderer.h"
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
namespace OpenGLESRenderer
|
||||
{
|
||||
|
||||
CVAR(Int, gles_glsl_precision, 2, 0); // 0 = low, 1 = medium, 2 = high
|
||||
|
||||
FString GetGLSLPrecision()
|
||||
{
|
||||
FString str = "precision highp int;\n \
|
||||
precision highp float;\n";
|
||||
|
||||
if (gles_glsl_precision == 0)
|
||||
str.Substitute("highp", "lowp");
|
||||
else if (gles_glsl_precision == 1)
|
||||
str.Substitute("highp", "mediump");
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
struct ProgramBinary
|
||||
{
|
||||
uint32_t format;
|
||||
TArray<uint8_t> data;
|
||||
};
|
||||
|
||||
static const char *ShaderMagic = "ZDSC";
|
||||
|
||||
static std::map<FString, std::unique_ptr<ProgramBinary>> ShaderCache; // Not a TMap because it doesn't support unique_ptr move semantics
|
||||
|
||||
bool IsShaderCacheActive()
|
||||
{
|
||||
static bool active = true;
|
||||
static bool firstcall = true;
|
||||
|
||||
if (firstcall)
|
||||
{
|
||||
const char *vendor = (const char *)glGetString(GL_VENDOR);
|
||||
active = !(strstr(vendor, "Intel") == nullptr);
|
||||
firstcall = false;
|
||||
}
|
||||
return active;
|
||||
}
|
||||
|
||||
static FString CalcProgramBinaryChecksum(const FString &vertex, const FString &fragment)
|
||||
{
|
||||
const GLubyte *vendor = glGetString(GL_VENDOR);
|
||||
const GLubyte *renderer = glGetString(GL_RENDERER);
|
||||
const GLubyte *version = glGetString(GL_VERSION);
|
||||
|
||||
uint8_t digest[16];
|
||||
MD5Context md5;
|
||||
md5.Update(vendor, (unsigned int)strlen((const char*)vendor));
|
||||
md5.Update(renderer, (unsigned int)strlen((const char*)renderer));
|
||||
md5.Update(version, (unsigned int)strlen((const char*)version));
|
||||
md5.Update((const uint8_t *)vertex.GetChars(), (unsigned int)vertex.Len());
|
||||
md5.Update((const uint8_t *)fragment.GetChars(), (unsigned int)fragment.Len());
|
||||
md5.Final(digest);
|
||||
|
||||
char hexdigest[33];
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
int v = digest[i] >> 4;
|
||||
hexdigest[i * 2] = v < 10 ? ('0' + v) : ('a' + v - 10);
|
||||
v = digest[i] & 15;
|
||||
hexdigest[i * 2 + 1] = v < 10 ? ('0' + v) : ('a' + v - 10);
|
||||
}
|
||||
hexdigest[32] = 0;
|
||||
return hexdigest;
|
||||
}
|
||||
|
||||
static FString CreateProgramCacheName(bool create)
|
||||
{
|
||||
FString path = M_GetCachePath(create);
|
||||
if (create) CreatePath(path);
|
||||
path << "/shadercache.zdsc";
|
||||
return path;
|
||||
}
|
||||
|
||||
static void LoadShaders()
|
||||
{
|
||||
static bool loaded = false;
|
||||
if (loaded)
|
||||
return;
|
||||
loaded = true;
|
||||
|
||||
try
|
||||
{
|
||||
FString path = CreateProgramCacheName(false);
|
||||
FileReader fr;
|
||||
if (!fr.OpenFile(path))
|
||||
I_Error("Could not open shader file");
|
||||
|
||||
char magic[4];
|
||||
fr.Read(magic, 4);
|
||||
if (memcmp(magic, ShaderMagic, 4) != 0)
|
||||
I_Error("Not a shader cache file");
|
||||
|
||||
uint32_t count = fr.ReadUInt32();
|
||||
if (count > 512)
|
||||
I_Error("Too many shaders cached");
|
||||
|
||||
for (uint32_t i = 0; i < count; i++)
|
||||
{
|
||||
char hexdigest[33];
|
||||
if (fr.Read(hexdigest, 32) != 32)
|
||||
I_Error("Read error");
|
||||
hexdigest[32] = 0;
|
||||
|
||||
std::unique_ptr<ProgramBinary> binary(new ProgramBinary());
|
||||
binary->format = fr.ReadUInt32();
|
||||
uint32_t size = fr.ReadUInt32();
|
||||
if (size > 1024 * 1024)
|
||||
I_Error("Shader too big, probably file corruption");
|
||||
|
||||
binary->data.Resize(size);
|
||||
if (fr.Read(binary->data.Data(), binary->data.Size()) != binary->data.Size())
|
||||
I_Error("Read error");
|
||||
|
||||
ShaderCache[hexdigest] = std::move(binary);
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
ShaderCache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
static void SaveShaders()
|
||||
{
|
||||
FString path = CreateProgramCacheName(true);
|
||||
std::unique_ptr<FileWriter> fw(FileWriter::Open(path));
|
||||
if (fw)
|
||||
{
|
||||
uint32_t count = (uint32_t)ShaderCache.size();
|
||||
fw->Write(ShaderMagic, 4);
|
||||
fw->Write(&count, sizeof(uint32_t));
|
||||
for (const auto &it : ShaderCache)
|
||||
{
|
||||
uint32_t size = it.second->data.Size();
|
||||
fw->Write(it.first.GetChars(), 32);
|
||||
fw->Write(&it.second->format, sizeof(uint32_t));
|
||||
fw->Write(&size, sizeof(uint32_t));
|
||||
fw->Write(it.second->data.Data(), it.second->data.Size());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TArray<uint8_t> LoadCachedProgramBinary(const FString &vertex, const FString &fragment, uint32_t &binaryFormat)
|
||||
{
|
||||
LoadShaders();
|
||||
|
||||
auto it = ShaderCache.find(CalcProgramBinaryChecksum(vertex, fragment));
|
||||
if (it != ShaderCache.end())
|
||||
{
|
||||
binaryFormat = it->second->format;
|
||||
return it->second->data;
|
||||
}
|
||||
else
|
||||
{
|
||||
binaryFormat = 0;
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
void SaveCachedProgramBinary(const FString &vertex, const FString &fragment, const TArray<uint8_t> &binary, uint32_t binaryFormat)
|
||||
{
|
||||
auto &entry = ShaderCache[CalcProgramBinaryChecksum(vertex, fragment)];
|
||||
entry.reset(new ProgramBinary());
|
||||
entry->format = binaryFormat;
|
||||
entry->data = binary;
|
||||
|
||||
SaveShaders();
|
||||
}
|
||||
|
||||
bool FShader::Configure(const char* name, const char* vert_prog_lump, const char* fragprog, const char* fragprog2, const char* light_fragprog, const char* defines)
|
||||
{
|
||||
mVertProg = vert_prog_lump;
|
||||
mFragProg = fragprog;
|
||||
mFragProg2 = fragprog2;
|
||||
mLightProg = light_fragprog;
|
||||
mDefinesBase = defines;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FShader::LoadVariant()
|
||||
{
|
||||
//mDefinesBase
|
||||
Load(mName.GetChars(), mVertProg, mFragProg, mFragProg2, mLightProg, mDefinesBase);
|
||||
}
|
||||
|
||||
bool FShader::Load(const char * name, const char * vert_prog_lump_, const char * frag_prog_lump_, const char * proc_prog_lump_, const char * light_fragprog_, const char * defines)
|
||||
{
|
||||
ShaderVariantData* shaderData = new ShaderVariantData();
|
||||
|
||||
FString vert_prog_lump = vert_prog_lump_;
|
||||
FString frag_prog_lump = frag_prog_lump_;
|
||||
FString proc_prog_lump = proc_prog_lump_;
|
||||
FString light_fragprog = light_fragprog_;
|
||||
|
||||
vert_prog_lump.Substitute("shaders/", "shaders_gles/");
|
||||
frag_prog_lump.Substitute("shaders/", "shaders_gles/");
|
||||
proc_prog_lump.Substitute("shaders/", "shaders_gles/");
|
||||
light_fragprog.Substitute("shaders/", "shaders_gles/");
|
||||
|
||||
//light_fragprog.Substitute("material_pbr", "material_normal");
|
||||
|
||||
if(light_fragprog.Len())
|
||||
light_fragprog = "shaders_gles/glsl/material_normal.fp"; // NOTE: Always use normal material for now, ignore others
|
||||
|
||||
|
||||
static char buffer[10000];
|
||||
FString error;
|
||||
|
||||
FString i_data = GetGLSLPrecision();
|
||||
|
||||
i_data += R"(
|
||||
|
||||
// light buffers
|
||||
uniform vec4 lights[MAXIMUM_LIGHT_VECTORS];
|
||||
|
||||
uniform mat4 ProjectionMatrix;
|
||||
uniform mat4 ViewMatrix;
|
||||
uniform mat4 NormalViewMatrix;
|
||||
|
||||
uniform vec4 uCameraPos;
|
||||
uniform vec4 uClipLine;
|
||||
|
||||
uniform float uGlobVis; // uGlobVis = R_GetGlobVis(r_visibility) / 32.0
|
||||
uniform int uPalLightLevels;
|
||||
uniform int uViewHeight; // Software fuzz scaling
|
||||
uniform float uClipHeight;
|
||||
uniform float uClipHeightDirection;
|
||||
uniform int uShadowmapFilter;
|
||||
|
||||
uniform int uTextureMode;
|
||||
uniform vec2 uClipSplit;
|
||||
uniform float uAlphaThreshold;
|
||||
|
||||
// colors
|
||||
uniform vec4 uObjectColor;
|
||||
uniform vec4 uObjectColor2;
|
||||
uniform vec4 uDynLightColor;
|
||||
uniform vec4 uAddColor;
|
||||
uniform vec4 uTextureBlendColor;
|
||||
uniform vec4 uTextureModulateColor;
|
||||
uniform vec4 uTextureAddColor;
|
||||
uniform vec4 uFogColor;
|
||||
uniform float uDesaturationFactor;
|
||||
uniform float uInterpolationFactor;
|
||||
|
||||
// Glowing walls stuff
|
||||
uniform vec4 uGlowTopPlane;
|
||||
uniform vec4 uGlowTopColor;
|
||||
uniform vec4 uGlowBottomPlane;
|
||||
uniform vec4 uGlowBottomColor;
|
||||
|
||||
uniform vec4 uGradientTopPlane;
|
||||
uniform vec4 uGradientBottomPlane;
|
||||
|
||||
uniform vec4 uSplitTopPlane;
|
||||
uniform vec4 uSplitBottomPlane;
|
||||
|
||||
uniform vec4 uDetailParms;
|
||||
// Lighting + Fog
|
||||
uniform vec4 uLightAttr;
|
||||
#define uLightLevel uLightAttr.a
|
||||
#define uFogDensity uLightAttr.b
|
||||
#define uLightFactor uLightAttr.g
|
||||
#define uLightDist uLightAttr.r
|
||||
//uniform int uFogEnabled;
|
||||
|
||||
// dynamic lights
|
||||
uniform ivec4 uLightRange;
|
||||
|
||||
// Blinn glossiness and specular level
|
||||
uniform vec2 uSpecularMaterial;
|
||||
|
||||
// matrices
|
||||
uniform mat4 ModelMatrix;
|
||||
uniform mat4 NormalModelMatrix;
|
||||
uniform mat4 TextureMatrix;
|
||||
|
||||
uniform vec4 uFixedColormapStart;
|
||||
uniform vec4 uFixedColormapRange;
|
||||
|
||||
// textures
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D ShadowMap;
|
||||
uniform sampler2D texture2;
|
||||
uniform sampler2D texture3;
|
||||
uniform sampler2D texture4;
|
||||
uniform sampler2D texture5;
|
||||
uniform sampler2D texture6;
|
||||
uniform sampler2D texture7;
|
||||
uniform sampler2D texture8;
|
||||
uniform sampler2D texture9;
|
||||
uniform sampler2D texture10;
|
||||
uniform sampler2D texture11;
|
||||
|
||||
// timer data
|
||||
uniform float timer;
|
||||
|
||||
// material types
|
||||
#if defined(SPECULAR)
|
||||
#define normaltexture texture2
|
||||
#define speculartexture texture3
|
||||
#define brighttexture texture4
|
||||
#define detailtexture texture5
|
||||
#define glowtexture texture6
|
||||
#elif defined(PBR)
|
||||
#define normaltexture texture2
|
||||
#define metallictexture texture3
|
||||
#define roughnesstexture texture4
|
||||
#define aotexture texture5
|
||||
#define brighttexture texture6
|
||||
#define detailtexture texture7
|
||||
#define glowtexture texture8
|
||||
#else
|
||||
#define brighttexture texture2
|
||||
#define detailtexture texture3
|
||||
#define glowtexture texture4
|
||||
#endif
|
||||
)";
|
||||
|
||||
#ifdef NPOT_EMULATION
|
||||
i_data += "#define NPOT_EMULATION\nuniform vec2 uNpotEmulation;\n";
|
||||
#endif
|
||||
|
||||
int vp_lump = fileSystem.CheckNumForFullName(vert_prog_lump, 0);
|
||||
if (vp_lump == -1) I_Error("Unable to load '%s'", vert_prog_lump.GetChars());
|
||||
FileData vp_data = fileSystem.ReadFile(vp_lump);
|
||||
|
||||
int fp_lump = fileSystem.CheckNumForFullName(frag_prog_lump, 0);
|
||||
if (fp_lump == -1) I_Error("Unable to load '%s'", frag_prog_lump.GetChars());
|
||||
FileData fp_data = fileSystem.ReadFile(fp_lump);
|
||||
|
||||
|
||||
|
||||
//
|
||||
// The following code uses GetChars on the strings to get rid of terminating 0 characters. Do not remove or the code may break!
|
||||
//
|
||||
FString vp_comb;
|
||||
|
||||
assert(screen->mLights != NULL);
|
||||
|
||||
bool lightbuffertype = screen->mLights->GetBufferType();
|
||||
unsigned int lightbuffersize = screen->mLights->GetBlockSize();
|
||||
|
||||
vp_comb.Format("#version 100\n#define NUM_UBO_LIGHTS %d\n#define NO_CLIPDISTANCE_SUPPORT\n", lightbuffersize);
|
||||
|
||||
FString fp_comb = vp_comb;
|
||||
vp_comb << defines << i_data.GetChars();
|
||||
fp_comb << "$placeholder$\n" << defines << i_data.GetChars();
|
||||
|
||||
vp_comb << "#line 1\n";
|
||||
fp_comb << "#line 1\n";
|
||||
|
||||
vp_comb << RemoveLayoutLocationDecl(vp_data.GetString(), "out").GetChars() << "\n";
|
||||
fp_comb << RemoveLayoutLocationDecl(fp_data.GetString(), "in").GetChars() << "\n";
|
||||
FString placeholder = "\n";
|
||||
|
||||
if (proc_prog_lump.Len())
|
||||
{
|
||||
fp_comb << "#line 1\n";
|
||||
|
||||
if (*proc_prog_lump != '#')
|
||||
{
|
||||
int pp_lump = fileSystem.CheckNumForFullName(proc_prog_lump);
|
||||
if (pp_lump == -1) I_Error("Unable to load '%s'", proc_prog_lump.GetChars());
|
||||
FileData pp_data = fileSystem.ReadFile(pp_lump);
|
||||
|
||||
if (pp_data.GetString().IndexOf("ProcessMaterial") < 0 && pp_data.GetString().IndexOf("SetupMaterial") < 0)
|
||||
{
|
||||
// this looks like an old custom hardware shader.
|
||||
|
||||
if (pp_data.GetString().IndexOf("GetTexCoord") >= 0)
|
||||
{
|
||||
int pl_lump = fileSystem.CheckNumForFullName("shaders_gles/glsl/func_defaultmat2.fp", 0);
|
||||
if (pl_lump == -1) I_Error("Unable to load '%s'", "shaders_gles/glsl/func_defaultmat2.fp");
|
||||
FileData pl_data = fileSystem.ReadFile(pl_lump);
|
||||
fp_comb << "\n" << pl_data.GetString().GetChars();
|
||||
}
|
||||
else
|
||||
{
|
||||
int pl_lump = fileSystem.CheckNumForFullName("shaders_gles/glsl/func_defaultmat.fp", 0);
|
||||
if (pl_lump == -1) I_Error("Unable to load '%s'", "shaders_gles/glsl/func_defaultmat.fp");
|
||||
FileData pl_data = fileSystem.ReadFile(pl_lump);
|
||||
fp_comb << "\n" << pl_data.GetString().GetChars();
|
||||
|
||||
if (pp_data.GetString().IndexOf("ProcessTexel") < 0)
|
||||
{
|
||||
// this looks like an even older custom hardware shader.
|
||||
// We need to replace the ProcessTexel call to make it work.
|
||||
|
||||
fp_comb.Substitute("material.Base = ProcessTexel();", "material.Base = Process(vec4(1.0));");
|
||||
}
|
||||
}
|
||||
|
||||
if (pp_data.GetString().IndexOf("ProcessLight") >= 0)
|
||||
{
|
||||
// The ProcessLight signatured changed. Forward to the old one.
|
||||
fp_comb << "\nvec4 ProcessLight(vec4 color);\n";
|
||||
fp_comb << "\nvec4 ProcessLight(Material material, vec4 color) { return ProcessLight(color); }\n";
|
||||
}
|
||||
}
|
||||
|
||||
fp_comb << RemoveLegacyUserUniforms(pp_data.GetString()).GetChars();
|
||||
fp_comb.Substitute("gl_TexCoord[0]", "vTexCoord"); // fix old custom shaders.
|
||||
|
||||
if (pp_data.GetString().IndexOf("ProcessLight") < 0)
|
||||
{
|
||||
int pl_lump = fileSystem.CheckNumForFullName("shaders_gles/glsl/func_defaultlight.fp", 0);
|
||||
if (pl_lump == -1) I_Error("Unable to load '%s'", "shaders_gles/glsl/func_defaultlight.fp");
|
||||
FileData pl_data = fileSystem.ReadFile(pl_lump);
|
||||
fp_comb << "\n" << pl_data.GetString().GetChars();
|
||||
}
|
||||
|
||||
// ProcessMaterial must be considered broken because it requires the user to fill in data they possibly cannot know all about.
|
||||
if (pp_data.GetString().IndexOf("ProcessMaterial") >= 0 && pp_data.GetString().IndexOf("SetupMaterial") < 0)
|
||||
{
|
||||
// This reactivates the old logic and disables all features that cannot be supported with that method.
|
||||
placeholder << "#define LEGACY_USER_SHADER\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Proc_prog_lump is not a lump name but the source itself (from generated shaders)
|
||||
fp_comb << proc_prog_lump.GetChars() + 1;
|
||||
}
|
||||
}
|
||||
fp_comb.Substitute("$placeholder$", placeholder);
|
||||
|
||||
if (light_fragprog.Len())
|
||||
{
|
||||
int pp_lump = fileSystem.CheckNumForFullName(light_fragprog, 0);
|
||||
if (pp_lump == -1) I_Error("Unable to load '%s'", light_fragprog.GetChars());
|
||||
FileData pp_data = fileSystem.ReadFile(pp_lump);
|
||||
fp_comb << pp_data.GetString().GetChars() << "\n";
|
||||
}
|
||||
|
||||
if (gles.flags & RFL_NO_CLIP_PLANES)
|
||||
{
|
||||
// On ATI's GL3 drivers we have to disable gl_ClipDistance because it's hopelessly broken.
|
||||
// This will cause some glitches and regressions but is the only way to avoid total display garbage.
|
||||
vp_comb.Substitute("gl_ClipDistance", "//");
|
||||
}
|
||||
|
||||
shaderData->hShader = glCreateProgram();
|
||||
|
||||
uint32_t binaryFormat = 0;
|
||||
TArray<uint8_t> binary;
|
||||
if (IsShaderCacheActive())
|
||||
binary = LoadCachedProgramBinary(vp_comb, fp_comb, binaryFormat);
|
||||
|
||||
bool linked = false;
|
||||
|
||||
if (!linked)
|
||||
{
|
||||
shaderData->hVertProg = glCreateShader(GL_VERTEX_SHADER);
|
||||
shaderData->hFragProg = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
|
||||
int vp_size = (int)vp_comb.Len();
|
||||
int fp_size = (int)fp_comb.Len();
|
||||
|
||||
const char *vp_ptr = vp_comb.GetChars();
|
||||
const char *fp_ptr = fp_comb.GetChars();
|
||||
|
||||
glShaderSource(shaderData->hVertProg, 1, &vp_ptr, &vp_size);
|
||||
glShaderSource(shaderData->hFragProg, 1, &fp_ptr, &fp_size);
|
||||
|
||||
glCompileShader(shaderData->hVertProg);
|
||||
glCompileShader(shaderData->hFragProg);
|
||||
|
||||
glAttachShader(shaderData->hShader, shaderData->hVertProg);
|
||||
glAttachShader(shaderData->hShader, shaderData->hFragProg);
|
||||
|
||||
|
||||
glBindAttribLocation(shaderData->hShader, VATTR_VERTEX, "aPosition");
|
||||
glBindAttribLocation(shaderData->hShader, VATTR_TEXCOORD, "aTexCoord");
|
||||
glBindAttribLocation(shaderData->hShader, VATTR_COLOR, "aColor");
|
||||
glBindAttribLocation(shaderData->hShader, VATTR_VERTEX2, "aVertex2");
|
||||
glBindAttribLocation(shaderData->hShader, VATTR_NORMAL, "aNormal");
|
||||
glBindAttribLocation(shaderData->hShader, VATTR_NORMAL2, "aNormal2");
|
||||
|
||||
|
||||
glLinkProgram(shaderData->hShader);
|
||||
|
||||
glGetShaderInfoLog(shaderData->hVertProg, 10000, NULL, buffer);
|
||||
if (*buffer)
|
||||
{
|
||||
error << "Vertex shader:\n" << buffer << "\n";
|
||||
}
|
||||
glGetShaderInfoLog(shaderData->hFragProg, 10000, NULL, buffer);
|
||||
if (*buffer)
|
||||
{
|
||||
error << "Fragment shader:\n" << buffer << "\n";
|
||||
}
|
||||
|
||||
glGetProgramInfoLog(shaderData->hShader, 10000, NULL, buffer);
|
||||
if (*buffer)
|
||||
{
|
||||
error << "Linking:\n" << buffer << "\n";
|
||||
}
|
||||
GLint status = 0;
|
||||
glGetProgramiv(shaderData->hShader, GL_LINK_STATUS, &status);
|
||||
linked = (status == GL_TRUE);
|
||||
|
||||
if (!linked)
|
||||
{
|
||||
// only print message if there's an error.
|
||||
I_Error("Init Shader '%s':\n%s\n", name, error.GetChars());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
shaderData->hVertProg = 0;
|
||||
shaderData->hFragProg = 0;
|
||||
}
|
||||
|
||||
shaderData->muProjectionMatrix.Init(shaderData->hShader, "ProjectionMatrix");
|
||||
shaderData->muViewMatrix.Init(shaderData->hShader, "ViewMatrix");
|
||||
shaderData->muNormalViewMatrix.Init(shaderData->hShader, "NormalViewMatrix");
|
||||
|
||||
//shaderData->ProjectionMatrix_index = glGetUniformLocation(shaderData->hShader, "ProjectionMatrix");
|
||||
//shaderData->ViewMatrix_index = glGetUniformLocation(shaderData->hShader, "ViewMatrix");
|
||||
//shaderData->NormalViewMatrix_index = glGetUniformLocation(shaderData->hShader, "NormalViewMatrix");
|
||||
|
||||
shaderData->muCameraPos.Init(shaderData->hShader, "uCameraPos");
|
||||
shaderData->muClipLine.Init(shaderData->hShader, "uClipLine");
|
||||
|
||||
shaderData->muGlobVis.Init(shaderData->hShader, "uGlobVis");
|
||||
shaderData->muPalLightLevels.Init(shaderData->hShader, "uPalLightLevels");
|
||||
shaderData->muViewHeight.Init(shaderData->hShader, "uViewHeight");
|
||||
shaderData->muClipHeight.Init(shaderData->hShader, "uClipHeight");
|
||||
shaderData->muClipHeightDirection.Init(shaderData->hShader, "uClipHeightDirection");
|
||||
shaderData->muShadowmapFilter.Init(shaderData->hShader, "uShadowmapFilter");
|
||||
|
||||
////
|
||||
|
||||
shaderData->muDesaturation.Init(shaderData->hShader, "uDesaturationFactor");
|
||||
shaderData->muFogEnabled.Init(shaderData->hShader, "uFogEnabled");
|
||||
shaderData->muTextureMode.Init(shaderData->hShader, "uTextureMode");
|
||||
shaderData->muLightParms.Init(shaderData->hShader, "uLightAttr");
|
||||
shaderData->muClipSplit.Init(shaderData->hShader, "uClipSplit");
|
||||
shaderData->muLightRange.Init(shaderData->hShader, "uLightRange");
|
||||
shaderData->muFogColor.Init(shaderData->hShader, "uFogColor");
|
||||
shaderData->muDynLightColor.Init(shaderData->hShader, "uDynLightColor");
|
||||
shaderData->muObjectColor.Init(shaderData->hShader, "uObjectColor");
|
||||
shaderData->muObjectColor2.Init(shaderData->hShader, "uObjectColor2");
|
||||
shaderData->muGlowBottomColor.Init(shaderData->hShader, "uGlowBottomColor");
|
||||
shaderData->muGlowTopColor.Init(shaderData->hShader, "uGlowTopColor");
|
||||
shaderData->muGlowBottomPlane.Init(shaderData->hShader, "uGlowBottomPlane");
|
||||
shaderData->muGlowTopPlane.Init(shaderData->hShader, "uGlowTopPlane");
|
||||
shaderData->muGradientBottomPlane.Init(shaderData->hShader, "uGradientBottomPlane");
|
||||
shaderData->muGradientTopPlane.Init(shaderData->hShader, "uGradientTopPlane");
|
||||
shaderData->muSplitBottomPlane.Init(shaderData->hShader, "uSplitBottomPlane");
|
||||
shaderData->muSplitTopPlane.Init(shaderData->hShader, "uSplitTopPlane");
|
||||
shaderData->muDetailParms.Init(shaderData->hShader, "uDetailParms");
|
||||
shaderData->muInterpolationFactor.Init(shaderData->hShader, "uInterpolationFactor");
|
||||
shaderData->muAlphaThreshold.Init(shaderData->hShader, "uAlphaThreshold");
|
||||
shaderData->muSpecularMaterial.Init(shaderData->hShader, "uSpecularMaterial");
|
||||
shaderData->muAddColor.Init(shaderData->hShader, "uAddColor");
|
||||
shaderData->muTextureAddColor.Init(shaderData->hShader, "uTextureAddColor");
|
||||
shaderData->muTextureModulateColor.Init(shaderData->hShader, "uTextureModulateColor");
|
||||
shaderData->muTextureBlendColor.Init(shaderData->hShader, "uTextureBlendColor");
|
||||
shaderData->muTimer.Init(shaderData->hShader, "timer");
|
||||
#ifdef NPOT_EMULATION
|
||||
shaderData->muNpotEmulation.Init(shaderData->hShader, "uNpotEmulation");
|
||||
#endif
|
||||
shaderData->muFixedColormapStart.Init(shaderData->hShader, "uFixedColormapStart");
|
||||
shaderData->muFixedColormapRange.Init(shaderData->hShader, "uFixedColormapRange");
|
||||
|
||||
shaderData->lights_index = glGetUniformLocation(shaderData->hShader, "lights");
|
||||
shaderData->modelmatrix_index = glGetUniformLocation(shaderData->hShader, "ModelMatrix");
|
||||
shaderData->texturematrix_index = glGetUniformLocation(shaderData->hShader, "TextureMatrix");
|
||||
shaderData->normalmodelmatrix_index = glGetUniformLocation(shaderData->hShader, "NormalModelMatrix");
|
||||
|
||||
|
||||
glUseProgram(shaderData->hShader);
|
||||
|
||||
// set up other texture units (if needed by the shader)
|
||||
for (int i = 2; i<16; i++)
|
||||
{
|
||||
char stringbuf[20];
|
||||
mysnprintf(stringbuf, 20, "texture%d", i);
|
||||
int tempindex = glGetUniformLocation(shaderData->hShader, stringbuf);
|
||||
if (tempindex >= 0) glUniform1i(tempindex, i - 1);
|
||||
}
|
||||
|
||||
int shadowmapindex = glGetUniformLocation(shaderData->hShader, "ShadowMap");
|
||||
if (shadowmapindex >= 0) glUniform1i(shadowmapindex, 16);
|
||||
|
||||
glUseProgram(0);
|
||||
|
||||
cur = shaderData;
|
||||
|
||||
return linked;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FShader::~FShader()
|
||||
{
|
||||
std::map<uint32_t, ShaderVariantData*>::iterator it = variants.begin();
|
||||
|
||||
while (it != variants.end())
|
||||
{
|
||||
glDeleteProgram(it->second->hShader);
|
||||
if (it->second->hVertProg != 0)
|
||||
glDeleteShader(it->second->hVertProg);
|
||||
if (it->second->hFragProg != 0)
|
||||
glDeleteShader(it->second->hFragProg);
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FShader::Bind(ShaderFlavourData& flavour)
|
||||
{
|
||||
uint32_t tag = CreateShaderTag(flavour);
|
||||
|
||||
auto pos = variants.find(tag);
|
||||
|
||||
if (pos == variants.end())
|
||||
{
|
||||
FString variantConfig = "\n";
|
||||
|
||||
variantConfig.AppendFormat("#define MAXIMUM_LIGHT_VECTORS %d\n", gles.numlightvectors);
|
||||
variantConfig.AppendFormat("#define DEF_TEXTURE_MODE %d\n", flavour.textureMode);
|
||||
variantConfig.AppendFormat("#define DEF_TEXTURE_FLAGS %d\n", flavour.texFlags);
|
||||
variantConfig.AppendFormat("#define DEF_BLEND_FLAGS %d\n", flavour.blendFlags);
|
||||
variantConfig.AppendFormat("#define DEF_FOG_2D %d\n", flavour.twoDFog);
|
||||
variantConfig.AppendFormat("#define DEF_FOG_ENABLED %d\n", flavour.fogEnabled);
|
||||
variantConfig.AppendFormat("#define DEF_FOG_RADIAL %d\n", flavour.fogEquationRadial);
|
||||
variantConfig.AppendFormat("#define DEF_FOG_COLOURED %d\n", flavour.colouredFog);
|
||||
variantConfig.AppendFormat("#define DEF_USE_U_LIGHT_LEVEL %d\n", flavour.useULightLevel);
|
||||
|
||||
variantConfig.AppendFormat("#define DEF_DO_DESATURATE %d\n", flavour.doDesaturate);
|
||||
|
||||
variantConfig.AppendFormat("#define DEF_DYNAMIC_LIGHTS_MOD %d\n", flavour.dynLightsMod);
|
||||
variantConfig.AppendFormat("#define DEF_DYNAMIC_LIGHTS_SUB %d\n", flavour.dynLightsSub);
|
||||
variantConfig.AppendFormat("#define DEF_DYNAMIC_LIGHTS_ADD %d\n", flavour.dynLightsAdd);
|
||||
|
||||
variantConfig.AppendFormat("#define DEF_USE_OBJECT_COLOR_2 %d\n", flavour.useObjectColor2);
|
||||
variantConfig.AppendFormat("#define DEF_USE_GLOW_TOP_COLOR %d\n", flavour.useGlowTopColor);
|
||||
variantConfig.AppendFormat("#define DEF_USE_GLOW_BOTTOM_COLOR %d\n", flavour.useGlowBottomColor);
|
||||
|
||||
variantConfig.AppendFormat("#define DEF_USE_COLOR_MAP %d\n", flavour.useColorMap);
|
||||
variantConfig.AppendFormat("#define DEF_BUILD_LIGHTING %d\n", flavour.buildLighting);
|
||||
variantConfig.AppendFormat("#define DEF_BANDED_SW_LIGHTING %d\n", flavour.bandedSwLight);
|
||||
|
||||
variantConfig.AppendFormat("#define USE_GLSL_V100 %d\n", gles.forceGLSLv100);
|
||||
|
||||
#ifdef NPOT_EMULATION
|
||||
variantConfig.AppendFormat("#define DEF_NPOT_EMULATION %d\n", flavour.npotEmulation);
|
||||
#endif
|
||||
|
||||
variantConfig.AppendFormat("#define DEF_HAS_SPOTLIGHT %d\n", flavour.hasSpotLight);
|
||||
|
||||
//Printf("Shader: %s, %08x %s", mFragProg2.GetChars(), tag, variantConfig.GetChars());
|
||||
|
||||
Load(mName.GetChars(), mVertProg, mFragProg, mFragProg2, mLightProg, mDefinesBase + variantConfig);
|
||||
|
||||
variants.insert(std::make_pair(tag, cur));
|
||||
}
|
||||
else
|
||||
{
|
||||
cur = pos->second;
|
||||
}
|
||||
|
||||
GLRenderer->mShaderManager->SetActiveShader(this->cur);
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Since all shaders are REQUIRED, any error here needs to be fatal
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FShader *FShaderCollection::Compile (const char *ShaderName, const char *ShaderPath, const char *LightModePath, const char *shaderdefines, bool usediscard, EPassType passType)
|
||||
{
|
||||
FString defines;
|
||||
defines += shaderdefines;
|
||||
// this can't be in the shader code due to ATI strangeness.
|
||||
if (!usediscard) defines += "#define NO_ALPHATEST\n";
|
||||
|
||||
FShader *shader = NULL;
|
||||
try
|
||||
{
|
||||
shader = new FShader(ShaderName);
|
||||
if (!shader->Configure(ShaderName, "shaders_gles/glsl/main.vp", "shaders_gles/glsl/main.fp", ShaderPath, LightModePath, defines.GetChars()))
|
||||
{
|
||||
I_FatalError("Unable to load shader %s\n", ShaderName);
|
||||
}
|
||||
}
|
||||
catch(CRecoverableError &err)
|
||||
{
|
||||
if (shader != NULL) delete shader;
|
||||
shader = NULL;
|
||||
I_FatalError("Unable to load shader %s:\n%s\n", ShaderName, err.GetMessage());
|
||||
}
|
||||
return shader;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FShaderManager::FShaderManager()
|
||||
{
|
||||
for (int passType = 0; passType < MAX_PASS_TYPES; passType++)
|
||||
mPassShaders.Push(new FShaderCollection((EPassType)passType));
|
||||
}
|
||||
|
||||
FShaderManager::~FShaderManager()
|
||||
{
|
||||
glUseProgram(0);
|
||||
mActiveShader = NULL;
|
||||
|
||||
for (auto collection : mPassShaders)
|
||||
delete collection;
|
||||
}
|
||||
|
||||
void FShaderManager::SetActiveShader(FShader::ShaderVariantData *sh)
|
||||
{
|
||||
if (mActiveShader != sh)
|
||||
{
|
||||
glUseProgram(sh!= NULL? sh->GetHandle() : 0);
|
||||
mActiveShader = sh;
|
||||
}
|
||||
}
|
||||
|
||||
FShader *FShaderManager::BindEffect(int effect, EPassType passType, ShaderFlavourData &flavour)
|
||||
{
|
||||
if (passType < mPassShaders.Size())
|
||||
return mPassShaders[passType]->BindEffect(effect, flavour);
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FShader *FShaderManager::Get(unsigned int eff, bool alphateston, EPassType passType)
|
||||
{
|
||||
if (passType < mPassShaders.Size())
|
||||
return mPassShaders[passType]->Get(eff, alphateston);
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FShaderCollection::FShaderCollection(EPassType passType)
|
||||
{
|
||||
CompileShaders(passType);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FShaderCollection::~FShaderCollection()
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FShaderCollection::CompileShaders(EPassType passType)
|
||||
{
|
||||
mMaterialShaders.Clear();
|
||||
mMaterialShadersNAT.Clear();
|
||||
for (int i = 0; i < MAX_EFFECTS; i++)
|
||||
{
|
||||
mEffectShaders[i] = NULL;
|
||||
}
|
||||
|
||||
for(int i=0;defaultshaders[i].ShaderName != NULL;i++)
|
||||
{
|
||||
FShader *shc = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc, defaultshaders[i].lightfunc, defaultshaders[i].Defines, true, passType);
|
||||
mMaterialShaders.Push(shc);
|
||||
if (i < SHADER_NoTexture)
|
||||
{
|
||||
FShader *shc = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc, defaultshaders[i].lightfunc, defaultshaders[i].Defines, false, passType);
|
||||
mMaterialShadersNAT.Push(shc);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
for(unsigned i = 0; i < usershaders.Size(); i++)
|
||||
{
|
||||
FString name = ExtractFileBase(usershaders[i].shader);
|
||||
FString defines = defaultshaders[usershaders[i].shaderType].Defines + usershaders[i].defines;
|
||||
FShader *shc = Compile(name, usershaders[i].shader, defaultshaders[usershaders[i].shaderType].lightfunc, defines, true, passType);
|
||||
mMaterialShaders.Push(shc);
|
||||
}
|
||||
#endif
|
||||
|
||||
for(int i=0;i<MAX_EFFECTS;i++)
|
||||
{
|
||||
FShader *eff = new FShader(effectshaders[i].ShaderName);
|
||||
if (!eff->Configure(effectshaders[i].ShaderName, effectshaders[i].vp, effectshaders[i].fp1,
|
||||
effectshaders[i].fp2, effectshaders[i].fp3, effectshaders[i].defines))
|
||||
{
|
||||
delete eff;
|
||||
}
|
||||
else mEffectShaders[i] = eff;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FShaderCollection::Clean()
|
||||
{
|
||||
for (unsigned int i = 0; i < mMaterialShadersNAT.Size(); i++)
|
||||
{
|
||||
if (mMaterialShadersNAT[i] != NULL) delete mMaterialShadersNAT[i];
|
||||
}
|
||||
for (unsigned int i = 0; i < mMaterialShaders.Size(); i++)
|
||||
{
|
||||
if (mMaterialShaders[i] != NULL) delete mMaterialShaders[i];
|
||||
}
|
||||
for (int i = 0; i < MAX_EFFECTS; i++)
|
||||
{
|
||||
if (mEffectShaders[i] != NULL) delete mEffectShaders[i];
|
||||
mEffectShaders[i] = NULL;
|
||||
}
|
||||
mMaterialShaders.Clear();
|
||||
mMaterialShadersNAT.Clear();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int FShaderCollection::Find(const char * shn)
|
||||
{
|
||||
FName sfn = shn;
|
||||
|
||||
for(unsigned int i=0;i<mMaterialShaders.Size();i++)
|
||||
{
|
||||
if (mMaterialShaders[i]->mName == sfn)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FShader *FShaderCollection::BindEffect(int effect, ShaderFlavourData& flavour)
|
||||
{
|
||||
if (effect >= 0 && effect < MAX_EFFECTS && mEffectShaders[effect] != NULL)
|
||||
{
|
||||
mEffectShaders[effect]->Bind(flavour);
|
||||
return mEffectShaders[effect];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void gl_DestroyUserShaders()
|
||||
{
|
||||
// todo
|
||||
}
|
||||
|
||||
}
|
489
source/common/rendering/gles/gles_shader.h
Normal file
489
source/common/rendering/gles/gles_shader.h
Normal file
|
@ -0,0 +1,489 @@
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright(C) 2004-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/
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
#ifndef __GL_SHADERS_H__
|
||||
#define __GL_SHADERS_H__
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "gles_renderstate.h"
|
||||
#include "name.h"
|
||||
|
||||
extern bool gl_shaderactive;
|
||||
|
||||
struct HWViewpointUniforms;
|
||||
|
||||
namespace OpenGLESRenderer
|
||||
{
|
||||
class FShaderCollection;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
class FUniform1i
|
||||
{
|
||||
int mIndex;
|
||||
|
||||
public:
|
||||
void Init(GLuint hShader, const GLchar *name)
|
||||
{
|
||||
mIndex = glGetUniformLocation(hShader, name);
|
||||
}
|
||||
|
||||
void Set(int newvalue)
|
||||
{
|
||||
glUniform1i(mIndex, newvalue);
|
||||
}
|
||||
};
|
||||
|
||||
class FBufferedUniform1i
|
||||
{
|
||||
int mBuffer;
|
||||
int mIndex;
|
||||
|
||||
public:
|
||||
void Init(GLuint hShader, const GLchar *name)
|
||||
{
|
||||
mIndex = glGetUniformLocation(hShader, name);
|
||||
mBuffer = 0;
|
||||
}
|
||||
|
||||
void Set(int newvalue)
|
||||
{
|
||||
if (newvalue != mBuffer)
|
||||
{
|
||||
mBuffer = newvalue;
|
||||
glUniform1i(mIndex, newvalue);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class FBufferedUniform4i
|
||||
{
|
||||
int mBuffer[4];
|
||||
int mIndex;
|
||||
|
||||
public:
|
||||
void Init(GLuint hShader, const GLchar *name)
|
||||
{
|
||||
mIndex = glGetUniformLocation(hShader, name);
|
||||
memset(mBuffer, 0, sizeof(mBuffer));
|
||||
}
|
||||
|
||||
void Set(const int *newvalue)
|
||||
{
|
||||
if (memcmp(newvalue, mBuffer, sizeof(mBuffer)))
|
||||
{
|
||||
memcpy(mBuffer, newvalue, sizeof(mBuffer));
|
||||
glUniform4iv(mIndex, 1, newvalue);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class FBufferedUniform1f
|
||||
{
|
||||
float mBuffer;
|
||||
int mIndex;
|
||||
|
||||
public:
|
||||
void Init(GLuint hShader, const GLchar *name)
|
||||
{
|
||||
mIndex = glGetUniformLocation(hShader, name);
|
||||
mBuffer = 0;
|
||||
}
|
||||
|
||||
void Set(float newvalue)
|
||||
{
|
||||
if (newvalue != mBuffer)
|
||||
{
|
||||
mBuffer = newvalue;
|
||||
glUniform1f(mIndex, newvalue);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class FBufferedUniform2f
|
||||
{
|
||||
float mBuffer[2];
|
||||
int mIndex;
|
||||
|
||||
public:
|
||||
void Init(GLuint hShader, const GLchar *name)
|
||||
{
|
||||
mIndex = glGetUniformLocation(hShader, name);
|
||||
memset(mBuffer, 0, sizeof(mBuffer));
|
||||
}
|
||||
|
||||
void Set(const float *newvalue)
|
||||
{
|
||||
if (memcmp(newvalue, mBuffer, sizeof(mBuffer)))
|
||||
{
|
||||
memcpy(mBuffer, newvalue, sizeof(mBuffer));
|
||||
glUniform2fv(mIndex, 1, newvalue);
|
||||
}
|
||||
}
|
||||
|
||||
void Set(float f1, float f2)
|
||||
{
|
||||
if (mBuffer[0] != f1 || mBuffer[1] != f2)
|
||||
{
|
||||
mBuffer[0] = f1;
|
||||
mBuffer[1] = f2;
|
||||
glUniform2fv(mIndex, 1, mBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class FBufferedUniform4f
|
||||
{
|
||||
float mBuffer[4];
|
||||
int mIndex;
|
||||
|
||||
public:
|
||||
void Init(GLuint hShader, const GLchar *name)
|
||||
{
|
||||
mIndex = glGetUniformLocation(hShader, name);
|
||||
memset(mBuffer, 0, sizeof(mBuffer));
|
||||
}
|
||||
|
||||
void Set(const float *newvalue)
|
||||
{
|
||||
if (memcmp(newvalue, mBuffer, sizeof(mBuffer)))
|
||||
{
|
||||
memcpy(mBuffer, newvalue, sizeof(mBuffer));
|
||||
glUniform4fv(mIndex, 1, newvalue);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class FUniform4f
|
||||
{
|
||||
int mIndex;
|
||||
|
||||
public:
|
||||
void Init(GLuint hShader, const GLchar *name)
|
||||
{
|
||||
mIndex = glGetUniformLocation(hShader, name);
|
||||
}
|
||||
|
||||
void Set(const float *newvalue)
|
||||
{
|
||||
glUniform4fv(mIndex, 1, newvalue);
|
||||
}
|
||||
|
||||
void Set(float a, float b, float c, float d)
|
||||
{
|
||||
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
|
||||
{
|
||||
FVector4PalEntry mBuffer;
|
||||
int mIndex;
|
||||
|
||||
public:
|
||||
void Init(GLuint hShader, const GLchar *name)
|
||||
{
|
||||
mIndex = glGetUniformLocation(hShader, name);
|
||||
mBuffer = 0;
|
||||
}
|
||||
|
||||
void Set(const FVector4PalEntry &newvalue)
|
||||
{
|
||||
if (newvalue != mBuffer)
|
||||
{
|
||||
mBuffer = newvalue;
|
||||
glUniform4f(mIndex, newvalue.r, newvalue.g, newvalue.b, newvalue.a);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class FBufferedUniformMat4fv
|
||||
{
|
||||
VSMatrix mBuffer;
|
||||
int mIndex;
|
||||
|
||||
public:
|
||||
void Init(GLuint hShader, const GLchar* name)
|
||||
{
|
||||
mIndex = glGetUniformLocation(hShader, name);
|
||||
mBuffer = 0;
|
||||
}
|
||||
|
||||
void Set(const VSMatrix* newvalue)
|
||||
{
|
||||
//if (memcmp(newvalue, &mBuffer, sizeof(mBuffer))) // Breaks 2D menu for some reason..
|
||||
{
|
||||
mBuffer = *newvalue;
|
||||
glUniformMatrix4fv(mIndex, 1, false, (float*)newvalue);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class ShaderFlavourData
|
||||
{
|
||||
public:
|
||||
int textureMode;
|
||||
int texFlags;
|
||||
int blendFlags;
|
||||
bool twoDFog;
|
||||
bool fogEnabled;
|
||||
bool fogEquationRadial;
|
||||
bool colouredFog;
|
||||
bool doDesaturate;
|
||||
bool dynLightsMod;
|
||||
bool dynLightsSub;
|
||||
bool dynLightsAdd;
|
||||
bool useULightLevel;
|
||||
bool useObjectColor2;
|
||||
bool useGlowTopColor;
|
||||
bool useGlowBottomColor;
|
||||
bool useColorMap;
|
||||
|
||||
bool buildLighting;
|
||||
bool bandedSwLight;
|
||||
|
||||
#ifdef NPOT_EMULATION
|
||||
bool npotEmulation;
|
||||
#endif
|
||||
|
||||
bool hasSpotLight;
|
||||
};
|
||||
|
||||
class FShader
|
||||
{
|
||||
friend class FShaderCollection;
|
||||
friend class FGLRenderState;
|
||||
|
||||
FName mName;
|
||||
|
||||
FString mVertProg;
|
||||
FString mFragProg;
|
||||
FString mFragProg2;
|
||||
FString mLightProg;
|
||||
FString mDefinesBase;
|
||||
|
||||
/////
|
||||
public: class ShaderVariantData
|
||||
{
|
||||
public:
|
||||
|
||||
unsigned int hShader = 0;
|
||||
unsigned int hVertProg = 0;
|
||||
unsigned int hFragProg = 0;
|
||||
|
||||
//int ProjectionMatrix_index = 0;
|
||||
//int ViewMatrix_index = 0;
|
||||
//int NormalViewMatrix_index = 0;
|
||||
|
||||
FBufferedUniformMat4fv muProjectionMatrix;
|
||||
FBufferedUniformMat4fv muViewMatrix;
|
||||
FBufferedUniformMat4fv muNormalViewMatrix;
|
||||
|
||||
FUniform4f muCameraPos;
|
||||
FUniform4f muClipLine;
|
||||
|
||||
FBufferedUniform1f muGlobVis;
|
||||
FBufferedUniform1i muPalLightLevels;
|
||||
FBufferedUniform1i muViewHeight;
|
||||
FBufferedUniform1f muClipHeight;
|
||||
FBufferedUniform1f muClipHeightDirection;
|
||||
FBufferedUniform1i muShadowmapFilter;
|
||||
/////
|
||||
|
||||
FBufferedUniform1f muDesaturation;
|
||||
FBufferedUniform1i muFogEnabled;
|
||||
FBufferedUniform1i muTextureMode;
|
||||
FBufferedUniform4f muLightParms;
|
||||
FBufferedUniform2f muClipSplit;
|
||||
FBufferedUniform4i muLightRange;
|
||||
FBufferedUniformPE muFogColor;
|
||||
FBufferedUniform4f muDynLightColor;
|
||||
FBufferedUniformPE muObjectColor;
|
||||
FBufferedUniformPE muObjectColor2;
|
||||
FBufferedUniformPE muAddColor;
|
||||
FBufferedUniformPE muTextureBlendColor;
|
||||
FBufferedUniformPE muTextureModulateColor;
|
||||
FBufferedUniformPE muTextureAddColor;
|
||||
FUniform4f muGlowBottomColor;
|
||||
FUniform4f muGlowTopColor;
|
||||
FUniform4f muGlowBottomPlane;
|
||||
FUniform4f muGlowTopPlane;
|
||||
FUniform4f muGradientBottomPlane;
|
||||
FUniform4f muGradientTopPlane;
|
||||
FUniform4f muSplitBottomPlane;
|
||||
FUniform4f muSplitTopPlane;
|
||||
FUniform4f muDetailParms;
|
||||
FBufferedUniform1f muInterpolationFactor;
|
||||
FBufferedUniform1f muAlphaThreshold;
|
||||
FBufferedUniform2f muSpecularMaterial;
|
||||
FBufferedUniform1f muTimer;
|
||||
#ifdef NPOT_EMULATION
|
||||
FBufferedUniform2f muNpotEmulation;
|
||||
#endif
|
||||
FUniform4f muFixedColormapStart;
|
||||
FUniform4f muFixedColormapRange;
|
||||
|
||||
|
||||
int lights_index = 0;
|
||||
int modelmatrix_index = 0;
|
||||
int normalmodelmatrix_index = 0;
|
||||
int texturematrix_index = 0;
|
||||
|
||||
int currentglowstate = 0;
|
||||
int currentgradientstate = 0;
|
||||
int currentsplitstate = 0;
|
||||
int currentcliplinestate = 0;
|
||||
int currentfixedcolormap = 0;
|
||||
bool currentTextureMatrixState = true;// by setting the matrix state to 'true' it is guaranteed to be set the first time the render state gets applied.
|
||||
bool currentModelMatrixState = true;
|
||||
|
||||
unsigned int GetHandle() const { return hShader; }
|
||||
};
|
||||
|
||||
std::map<uint32_t, ShaderVariantData*> variants;
|
||||
|
||||
ShaderVariantData* cur = 0;
|
||||
|
||||
public:
|
||||
FShader(const char *name)
|
||||
: mName(name)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
~FShader();
|
||||
|
||||
bool Load(const char * name, const char * vert_prog_lump, const char * fragprog, const char * fragprog2, const char * light_fragprog, const char *defines);
|
||||
bool Configure(const char* name, const char* vert_prog_lump, const char* fragprog, const char* fragprog2, const char* light_fragprog, const char* defines);
|
||||
|
||||
void LoadVariant();
|
||||
|
||||
|
||||
uint32_t CreateShaderTag(ShaderFlavourData &flavour)
|
||||
{
|
||||
uint32_t tag = 0;
|
||||
tag |= (flavour.textureMode & 0x7);
|
||||
|
||||
tag |= (flavour.texFlags & 7) << 3;
|
||||
|
||||
tag |= (flavour.blendFlags & 7) << 6;
|
||||
|
||||
tag |= (flavour.twoDFog & 1) << 7;
|
||||
tag |= (flavour.fogEnabled & 1) << 8;
|
||||
tag |= (flavour.fogEquationRadial & 1) << 9;
|
||||
tag |= (flavour.colouredFog & 1) << 10;
|
||||
|
||||
tag |= (flavour.doDesaturate & 1) << 11;
|
||||
|
||||
tag |= (flavour.dynLightsMod & 1) << 12;
|
||||
tag |= (flavour.dynLightsSub & 1) << 13;
|
||||
tag |= (flavour.dynLightsAdd & 1) << 14;
|
||||
tag |= (flavour.useULightLevel & 1) << 15;
|
||||
tag |= (flavour.useObjectColor2 & 1) << 16;
|
||||
tag |= (flavour.useGlowTopColor & 1) << 17;
|
||||
tag |= (flavour.useGlowBottomColor & 1) << 18;
|
||||
tag |= (flavour.useColorMap & 1) << 19;
|
||||
tag |= (flavour.buildLighting & 1) << 20;
|
||||
tag |= (flavour.bandedSwLight & 1) << 21;
|
||||
|
||||
#ifdef NPOT_EMULATION
|
||||
tag |= (flavour.npotEmulation & 1) << 22;
|
||||
#endif
|
||||
|
||||
tag |= (flavour.hasSpotLight & 1) << 23;
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
bool Bind(ShaderFlavourData& flavour);
|
||||
|
||||
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// The global shader manager
|
||||
//
|
||||
//==========================================================================
|
||||
class FShaderManager
|
||||
{
|
||||
public:
|
||||
FShaderManager();
|
||||
~FShaderManager();
|
||||
|
||||
FShader *BindEffect(int effect, EPassType passType, ShaderFlavourData& flavour);
|
||||
FShader *Get(unsigned int eff, bool alphateston, EPassType passType);
|
||||
|
||||
void SetActiveShader(FShader::ShaderVariantData *sh);
|
||||
private:
|
||||
|
||||
FShader::ShaderVariantData *mActiveShader = nullptr;
|
||||
TArray<FShaderCollection*> mPassShaders;
|
||||
|
||||
friend class FShader;
|
||||
};
|
||||
|
||||
class FShaderCollection
|
||||
{
|
||||
TArray<FShader*> mMaterialShaders;
|
||||
TArray<FShader*> mMaterialShadersNAT;
|
||||
FShader *mEffectShaders[MAX_EFFECTS];
|
||||
|
||||
void Clean();
|
||||
void CompileShaders(EPassType passType);
|
||||
|
||||
public:
|
||||
FShaderCollection(EPassType passType);
|
||||
~FShaderCollection();
|
||||
FShader *Compile(const char *ShaderName, const char *ShaderPath, const char *LightModePath, const char *shaderdefines, bool usediscard, EPassType passType);
|
||||
int Find(const char *mame);
|
||||
FShader *BindEffect(int effect, ShaderFlavourData& flavour);
|
||||
|
||||
FShader *Get(unsigned int eff, bool alphateston)
|
||||
{
|
||||
// indices 0-2 match the warping modes, 3 no texture, the following are custom
|
||||
if (!alphateston && eff <= 2)
|
||||
{
|
||||
return mMaterialShadersNAT[eff]; // Non-alphatest shaders are only created for default, warp1+2 and brightmap. The rest won't get used anyway
|
||||
}
|
||||
if (eff < mMaterialShaders.Size())
|
||||
{
|
||||
return mMaterialShaders[eff];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
293
source/common/rendering/gles/gles_shaderprogram.cpp
Normal file
293
source/common/rendering/gles/gles_shaderprogram.cpp
Normal file
|
@ -0,0 +1,293 @@
|
|||
/*
|
||||
** Postprocessing framework
|
||||
** Copyright (c) 2016-2020 Magnus Norddahl
|
||||
**
|
||||
** This software is provided 'as-is', without any express or implied
|
||||
** warranty. In no event will the authors be held liable for any damages
|
||||
** arising from the use of this software.
|
||||
**
|
||||
** Permission is granted to anyone to use this software for any purpose,
|
||||
** including commercial applications, and to alter it and redistribute it
|
||||
** freely, subject to the following restrictions:
|
||||
**
|
||||
** 1. The origin of this software must not be misrepresented; you must not
|
||||
** claim that you wrote the original software. If you use this software
|
||||
** in a product, an acknowledgment in the product documentation would be
|
||||
** appreciated but is not required.
|
||||
** 2. Altered source versions must be plainly marked as such, and must not be
|
||||
** misrepresented as being the original software.
|
||||
** 3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "gles_system.h"
|
||||
#include "v_video.h"
|
||||
#include "hw_cvars.h"
|
||||
#include "gles_shaderprogram.h"
|
||||
#include "hw_shaderpatcher.h"
|
||||
#include "filesystem.h"
|
||||
#include "printf.h"
|
||||
|
||||
namespace OpenGLESRenderer
|
||||
{
|
||||
|
||||
FString GetGLSLPrecision();
|
||||
|
||||
bool IsShaderCacheActive();
|
||||
TArray<uint8_t> LoadCachedProgramBinary(const FString &vertex, const FString &fragment, uint32_t &binaryFormat);
|
||||
void SaveCachedProgramBinary(const FString &vertex, const FString &fragment, const TArray<uint8_t> &binary, uint32_t binaryFormat);
|
||||
|
||||
FShaderProgram::FShaderProgram()
|
||||
{
|
||||
for (int i = 0; i < NumShaderTypes; i++)
|
||||
mShaders[i] = 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Free shader program resources
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FShaderProgram::~FShaderProgram()
|
||||
{
|
||||
if (mProgram != 0)
|
||||
glDeleteProgram(mProgram);
|
||||
|
||||
for (int i = 0; i < NumShaderTypes; i++)
|
||||
{
|
||||
if (mShaders[i] != 0)
|
||||
glDeleteShader(mShaders[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Creates an OpenGL shader object for the specified type of shader
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FShaderProgram::CreateShader(ShaderType type)
|
||||
{
|
||||
GLenum gltype = 0;
|
||||
switch (type)
|
||||
{
|
||||
default:
|
||||
case Vertex: gltype = GL_VERTEX_SHADER; break;
|
||||
case Fragment: gltype = GL_FRAGMENT_SHADER; break;
|
||||
}
|
||||
mShaders[type] = glCreateShader(gltype);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Compiles a shader and attaches it the program object
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FShaderProgram::Compile(ShaderType type, const char *lumpName, const char *defines, int maxGlslVersion)
|
||||
{
|
||||
int lump = fileSystem.CheckNumForFullName(lumpName);
|
||||
if (lump == -1) I_FatalError("Unable to load '%s'", lumpName);
|
||||
FString code = fileSystem.ReadFile(lump).GetString().GetChars();
|
||||
Compile(type, lumpName, code, defines, maxGlslVersion);
|
||||
}
|
||||
|
||||
void FShaderProgram::Compile(ShaderType type, const char *name, const FString &code, const char *defines, int maxGlslVersion)
|
||||
{
|
||||
mShaderNames[type] = name;
|
||||
mShaderSources[type] = PatchShader(type, code, defines, maxGlslVersion);
|
||||
}
|
||||
|
||||
void FShaderProgram::CompileShader(ShaderType type)
|
||||
{
|
||||
CreateShader(type);
|
||||
|
||||
const auto &handle = mShaders[type];
|
||||
|
||||
|
||||
const FString &patchedCode = mShaderSources[type];
|
||||
int lengths[1] = { (int)patchedCode.Len() };
|
||||
const char *sources[1] = { patchedCode.GetChars() };
|
||||
glShaderSource(handle, 1, sources, lengths);
|
||||
|
||||
glCompileShader(handle);
|
||||
|
||||
GLint status = 0;
|
||||
glGetShaderiv(handle, GL_COMPILE_STATUS, &status);
|
||||
if (status == GL_FALSE)
|
||||
{
|
||||
I_FatalError("Compile Shader '%s':\n%s\n", mShaderNames[type].GetChars(), GetShaderInfoLog(handle).GetChars());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mProgram == 0)
|
||||
mProgram = glCreateProgram();
|
||||
glAttachShader(mProgram, handle);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Links a program with the compiled shaders
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FShaderProgram::Link(const char *name)
|
||||
{
|
||||
|
||||
uint32_t binaryFormat = 0;
|
||||
TArray<uint8_t> binary;
|
||||
if (IsShaderCacheActive())
|
||||
binary = LoadCachedProgramBinary(mShaderSources[Vertex], mShaderSources[Fragment], binaryFormat);
|
||||
|
||||
bool loadedFromBinary = false;
|
||||
|
||||
if (!loadedFromBinary)
|
||||
{
|
||||
CompileShader(Vertex);
|
||||
CompileShader(Fragment);
|
||||
|
||||
glLinkProgram(mProgram);
|
||||
|
||||
GLint status = 0;
|
||||
glGetProgramiv(mProgram, GL_LINK_STATUS, &status);
|
||||
if (status == GL_FALSE)
|
||||
{
|
||||
I_FatalError("Link Shader '%s':\n%s\n", name, GetProgramInfoLog(mProgram).GetChars());
|
||||
}
|
||||
}
|
||||
|
||||
// This is only for old OpenGL which didn't allow to set the binding from within the shader.
|
||||
if (screen->glslversion < 4.20)
|
||||
{
|
||||
glUseProgram(mProgram);
|
||||
for (auto &uni : samplerstobind)
|
||||
{
|
||||
auto index = glGetUniformLocation(mProgram, uni.first);
|
||||
if (index >= 0)
|
||||
{
|
||||
glUniform1i(index, uni.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
samplerstobind.Clear();
|
||||
samplerstobind.ShrinkToFit();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Set uniform buffer location (only useful for GL 3.3)
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FShaderProgram::SetUniformBufferLocation(int index, const char *name)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Makes the shader the active program
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FShaderProgram::Bind()
|
||||
{
|
||||
glUseProgram(mProgram);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Returns the shader info log (warnings and compile errors)
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FString FShaderProgram::GetShaderInfoLog(GLuint handle)
|
||||
{
|
||||
static char buffer[10000];
|
||||
GLsizei length = 0;
|
||||
buffer[0] = 0;
|
||||
glGetShaderInfoLog(handle, 10000, &length, buffer);
|
||||
return FString(buffer);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Returns the program info log (warnings and compile errors)
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FString FShaderProgram::GetProgramInfoLog(GLuint handle)
|
||||
{
|
||||
static char buffer[10000];
|
||||
GLsizei length = 0;
|
||||
buffer[0] = 0;
|
||||
glGetProgramInfoLog(handle, 10000, &length, buffer);
|
||||
return FString(buffer);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Patches a shader to be compatible with the version of OpenGL in use
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FString FShaderProgram::PatchShader(ShaderType type, const FString &code, const char *defines, int maxGlslVersion)
|
||||
{
|
||||
FString patchedCode;
|
||||
|
||||
patchedCode.AppendFormat("#version %d\n", 100); // Set to GLES2
|
||||
|
||||
patchedCode += GetGLSLPrecision();
|
||||
|
||||
|
||||
if (defines)
|
||||
patchedCode << defines;
|
||||
|
||||
|
||||
patchedCode << "#line 1\n";
|
||||
patchedCode << RemoveLayoutLocationDecl(code, type == Vertex ? "out" : "in");
|
||||
|
||||
if (maxGlslVersion < 420)
|
||||
{
|
||||
// Here we must strip out all layout(binding) declarations for sampler uniforms and store them in 'samplerstobind' which can then be processed by the link function.
|
||||
patchedCode = RemoveSamplerBindings(patchedCode, samplerstobind);
|
||||
}
|
||||
|
||||
return patchedCode;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void FPresentShaderBase::Init(const char * vtx_shader_name, const char * program_name)
|
||||
{
|
||||
FString prolog = Uniforms.CreateDeclaration("Uniforms", PresentUniforms::Desc());
|
||||
|
||||
mShader.reset(new FShaderProgram());
|
||||
mShader->Compile(FShaderProgram::Vertex, "shaders_gles/pp/screenquad.vp", prolog, 330);
|
||||
mShader->Compile(FShaderProgram::Fragment, vtx_shader_name, prolog, 330);
|
||||
mShader->Link(program_name);
|
||||
mShader->Bind();
|
||||
Uniforms.Init();
|
||||
|
||||
Uniforms.UniformLocation.resize(Uniforms.mFields.size());
|
||||
|
||||
for (size_t n = 0; n < Uniforms.mFields.size(); n++)
|
||||
{
|
||||
int index = -1;
|
||||
UniformFieldDesc desc = Uniforms.mFields[n];
|
||||
index = glGetUniformLocation(mShader->mProgram, desc.Name);
|
||||
Uniforms.UniformLocation[n] = index;
|
||||
}
|
||||
}
|
||||
|
||||
void FPresentShader::Bind()
|
||||
{
|
||||
if (!mShader)
|
||||
{
|
||||
Init("shaders_gles/pp/present.fp", "shaders_gles/pp/present");
|
||||
}
|
||||
mShader->Bind();
|
||||
}
|
||||
|
||||
}
|
159
source/common/rendering/gles/gles_shaderprogram.h
Normal file
159
source/common/rendering/gles/gles_shaderprogram.h
Normal file
|
@ -0,0 +1,159 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "gles_system.h"
|
||||
#include "gles_shader.h"
|
||||
#include "hwrenderer/postprocessing/hw_postprocess.h"
|
||||
|
||||
namespace OpenGLESRenderer
|
||||
{
|
||||
|
||||
class FShaderProgram : public PPShaderBackend
|
||||
{
|
||||
public:
|
||||
FShaderProgram();
|
||||
~FShaderProgram();
|
||||
|
||||
enum ShaderType
|
||||
{
|
||||
Vertex,
|
||||
Fragment,
|
||||
NumShaderTypes
|
||||
};
|
||||
|
||||
void Compile(ShaderType type, const char *lumpName, const char *defines, int maxGlslVersion);
|
||||
void Compile(ShaderType type, const char *name, const FString &code, const char *defines, int maxGlslVersion);
|
||||
void Link(const char *name);
|
||||
void SetUniformBufferLocation(int index, const char *name);
|
||||
|
||||
void Bind();
|
||||
|
||||
GLuint Handle() { return mProgram; }
|
||||
//explicit operator bool() const { return mProgram != 0; }
|
||||
|
||||
std::unique_ptr<IDataBuffer> Uniforms;
|
||||
GLuint mProgram = 0;
|
||||
private:
|
||||
FShaderProgram(const FShaderProgram &) = delete;
|
||||
FShaderProgram &operator=(const FShaderProgram &) = delete;
|
||||
|
||||
void CompileShader(ShaderType type);
|
||||
FString PatchShader(ShaderType type, const FString &code, const char *defines, int maxGlslVersion);
|
||||
|
||||
void CreateShader(ShaderType type);
|
||||
FString GetShaderInfoLog(GLuint handle);
|
||||
FString GetProgramInfoLog(GLuint handle);
|
||||
|
||||
|
||||
GLuint mShaders[NumShaderTypes];
|
||||
FString mShaderSources[NumShaderTypes];
|
||||
FString mShaderNames[NumShaderTypes];
|
||||
TArray<std::pair<FString, int>> samplerstobind;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class ShaderUniformsGles
|
||||
{
|
||||
public:
|
||||
ShaderUniformsGles()
|
||||
{
|
||||
memset(&Values, 0, sizeof(Values));
|
||||
}
|
||||
|
||||
~ShaderUniformsGles()
|
||||
{
|
||||
if (mBuffer != nullptr)
|
||||
delete mBuffer;
|
||||
}
|
||||
|
||||
FString CreateDeclaration(const char* name, const std::vector<UniformFieldDesc>& fields)
|
||||
{
|
||||
mFields = fields;
|
||||
FString decl;
|
||||
decl += "\n";
|
||||
for (size_t i = 0; i < fields.size(); i++)
|
||||
{
|
||||
decl.AppendFormat("\tuniform %s %s;\n", GetTypeStr(fields[i].Type), fields[i].Name);
|
||||
}
|
||||
decl += "\n";
|
||||
return decl;
|
||||
}
|
||||
|
||||
void Init()
|
||||
{
|
||||
if (mBuffer == nullptr)
|
||||
mBuffer = screen->CreateDataBuffer(-1, false, false);
|
||||
}
|
||||
|
||||
void SetData()
|
||||
{
|
||||
if (mBuffer != nullptr)
|
||||
mBuffer->SetData(sizeof(T), &Values);
|
||||
}
|
||||
|
||||
IDataBuffer* GetBuffer() const
|
||||
{
|
||||
// OpenGL needs to mess around with this in ways that should not be part of the interface.
|
||||
return mBuffer;
|
||||
}
|
||||
|
||||
T* operator->() { return &Values; }
|
||||
const T* operator->() const { return &Values; }
|
||||
|
||||
T Values;
|
||||
|
||||
std::vector<UniformFieldDesc> mFields;
|
||||
std::vector<int> UniformLocation;
|
||||
|
||||
private:
|
||||
ShaderUniformsGles(const ShaderUniformsGles&) = delete;
|
||||
ShaderUniformsGles& operator=(const ShaderUniformsGles&) = delete;
|
||||
|
||||
IDataBuffer* mBuffer = nullptr;
|
||||
|
||||
private:
|
||||
static const char* GetTypeStr(UniformType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
default:
|
||||
case UniformType::Int: return "int";
|
||||
case UniformType::UInt: return "uint";
|
||||
case UniformType::Float: return "float";
|
||||
case UniformType::Vec2: return "vec2";
|
||||
case UniformType::Vec3: return "vec3";
|
||||
case UniformType::Vec4: return "vec4";
|
||||
case UniformType::IVec2: return "ivec2";
|
||||
case UniformType::IVec3: return "ivec3";
|
||||
case UniformType::IVec4: return "ivec4";
|
||||
case UniformType::UVec2: return "uvec2";
|
||||
case UniformType::UVec3: return "uvec3";
|
||||
case UniformType::UVec4: return "uvec4";
|
||||
case UniformType::Mat4: return "mat4";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class FPresentShaderBase
|
||||
{
|
||||
public:
|
||||
virtual ~FPresentShaderBase() {}
|
||||
virtual void Bind() = 0;
|
||||
|
||||
ShaderUniformsGles<PresentUniforms> Uniforms;
|
||||
|
||||
protected:
|
||||
virtual void Init(const char * vtx_shader_name, const char * program_name);
|
||||
std::unique_ptr<FShaderProgram> mShader;
|
||||
};
|
||||
|
||||
class FPresentShader : public FPresentShaderBase
|
||||
{
|
||||
public:
|
||||
void Bind() override;
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
195
source/common/rendering/gles/gles_system.cpp
Normal file
195
source/common/rendering/gles/gles_system.cpp
Normal file
|
@ -0,0 +1,195 @@
|
|||
|
||||
|
||||
#include "gles_system.h"
|
||||
#include "tarray.h"
|
||||
#include "v_video.h"
|
||||
#include "printf.h"
|
||||
|
||||
CVAR(Bool, gles_use_mapped_buffer, false, 0);
|
||||
CVAR(Bool, gles_force_glsl_v100, false, 0);
|
||||
CVAR(Int, gles_max_lights_per_surface, 32, 0);
|
||||
EXTERN_CVAR(Bool, gl_customshader);
|
||||
|
||||
|
||||
#if USE_GLES2
|
||||
|
||||
PFNGLMAPBUFFERRANGEEXTPROC glMapBufferRange = NULL;
|
||||
PFNGLUNMAPBUFFEROESPROC glUnmapBuffer = NULL;
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <dlfcn.h>
|
||||
|
||||
static void* LoadGLES2Proc(const char* name)
|
||||
{
|
||||
static void *glesLib = NULL;
|
||||
|
||||
if(!glesLib)
|
||||
{
|
||||
int flags = RTLD_LOCAL | RTLD_NOW;
|
||||
|
||||
glesLib = dlopen("libGLESv2_CM.so", flags);
|
||||
if(!glesLib)
|
||||
{
|
||||
glesLib = dlopen("libGLESv2.so", flags);
|
||||
}
|
||||
if(!glesLib)
|
||||
{
|
||||
glesLib = dlopen("libGLESv2.so.2", flags);
|
||||
}
|
||||
}
|
||||
|
||||
void * ret = NULL;
|
||||
ret = dlsym(glesLib, name);
|
||||
|
||||
if(!ret)
|
||||
{
|
||||
//LOGI("Failed to load: %s", name);
|
||||
}
|
||||
else
|
||||
{
|
||||
//LOGI("Loaded %s func OK", name);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#elif defined _WIN32
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
static HMODULE opengl32dll;
|
||||
static PROC(WINAPI* getprocaddress)(LPCSTR name);
|
||||
|
||||
static void* LoadGLES2Proc(const char* name)
|
||||
{
|
||||
HINSTANCE hGetProcIDDLL = LoadLibraryA("libGLESv2.dll");
|
||||
|
||||
int error = GetLastError();
|
||||
|
||||
void* addr = GetProcAddress(hGetProcIDDLL, name);
|
||||
if (!addr)
|
||||
{
|
||||
//exit(1);
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
return addr;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // USE_GLES2
|
||||
|
||||
static TArray<FString> m_Extensions;
|
||||
|
||||
|
||||
static void CollectExtensions()
|
||||
{
|
||||
const char* supported = (char*)glGetString(GL_EXTENSIONS);
|
||||
|
||||
if (nullptr != supported)
|
||||
{
|
||||
char* extensions = new char[strlen(supported) + 1];
|
||||
strcpy(extensions, supported);
|
||||
|
||||
char* extension = strtok(extensions, " ");
|
||||
|
||||
while (extension)
|
||||
{
|
||||
m_Extensions.Push(FString(extension));
|
||||
extension = strtok(nullptr, " ");
|
||||
}
|
||||
|
||||
delete[] extensions;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static bool CheckExtension(const char* ext)
|
||||
{
|
||||
for (unsigned int i = 0; i < m_Extensions.Size(); ++i)
|
||||
{
|
||||
if (m_Extensions[i].CompareNoCase(ext) == 0) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace OpenGLESRenderer
|
||||
{
|
||||
RenderContextGLES gles;
|
||||
|
||||
void InitGLES()
|
||||
{
|
||||
|
||||
#if USE_GLES2
|
||||
|
||||
if (!gladLoadGLES2Loader(&LoadGLES2Proc))
|
||||
{
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
glMapBufferRange = (PFNGLMAPBUFFERRANGEEXTPROC)LoadGLES2Proc("glMapBufferRange");
|
||||
glUnmapBuffer = (PFNGLUNMAPBUFFEROESPROC)LoadGLES2Proc("glUnmapBuffer");
|
||||
|
||||
#else
|
||||
static bool first = true;
|
||||
|
||||
if (first)
|
||||
{
|
||||
if (ogl_LoadFunctions() == ogl_LOAD_FAILED)
|
||||
{
|
||||
//I_FatalError("Failed to load OpenGL functions.");
|
||||
}
|
||||
}
|
||||
GLuint vao;
|
||||
glGenVertexArrays(1, &vao);
|
||||
glBindVertexArray(vao);
|
||||
#endif
|
||||
CollectExtensions();
|
||||
|
||||
Printf("GL_VENDOR: %s\n", glGetString(GL_VENDOR));
|
||||
Printf("GL_RENDERER: %s\n", glGetString(GL_RENDERER));
|
||||
Printf("GL_VERSION: %s\n", glGetString(GL_VERSION));
|
||||
Printf("GL_SHADING_LANGUAGE_VERSION: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||
Printf(PRINT_LOG, "GL_EXTENSIONS:\n");
|
||||
for (unsigned i = 0; i < m_Extensions.Size(); i++)
|
||||
{
|
||||
Printf(" %s\n", m_Extensions[i].GetChars());
|
||||
}
|
||||
|
||||
|
||||
gles.flags = RFL_NO_CLIP_PLANES;
|
||||
|
||||
gles.useMappedBuffers = gles_use_mapped_buffer;
|
||||
gles.forceGLSLv100 = gles_force_glsl_v100;
|
||||
gles.maxlights = gles_max_lights_per_surface;
|
||||
|
||||
gles.modelstring = (char*)glGetString(GL_RENDERER);
|
||||
gles.vendorstring = (char*)glGetString(GL_VENDOR);
|
||||
|
||||
gl_customshader = false;
|
||||
|
||||
GLint maxTextureSize[1];
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, maxTextureSize);
|
||||
|
||||
gles.max_texturesize = maxTextureSize[0];
|
||||
|
||||
Printf("GL_MAX_TEXTURE_SIZE: %d\n", gles.max_texturesize);
|
||||
|
||||
#if USE_GLES2
|
||||
gles.depthStencilAvailable = CheckExtension("GL_OES_packed_depth_stencil");
|
||||
gles.npotAvailable = CheckExtension("GL_OES_texture_npot");
|
||||
gles.depthClampAvailable = CheckExtension("GL_EXT_depth_clamp");
|
||||
#else
|
||||
gles.depthStencilAvailable = true;
|
||||
gles.npotAvailable = true;
|
||||
gles.useMappedBuffers = true;
|
||||
gles.depthClampAvailable = true;
|
||||
#endif
|
||||
|
||||
gles.numlightvectors = (gles.maxlights * LIGHT_VEC4_NUM);
|
||||
}
|
||||
}
|
93
source/common/rendering/gles/gles_system.h
Normal file
93
source/common/rendering/gles/gles_system.h
Normal file
|
@ -0,0 +1,93 @@
|
|||
#ifndef __GLES_SYSTEM_H
|
||||
#define __GLES_SYSTEM_H
|
||||
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <signal.h>
|
||||
#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__DragonFly__)
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#include <time.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#define USE_GLES2 0
|
||||
|
||||
#if (USE_GLES2)
|
||||
#include "glad/glad.h"
|
||||
|
||||
// Below are used extensions for GLES
|
||||
typedef void* (APIENTRYP PFNGLMAPBUFFERRANGEEXTPROC)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
|
||||
GLAPI PFNGLMAPBUFFERRANGEEXTPROC glMapBufferRange;
|
||||
|
||||
typedef GLboolean(APIENTRYP PFNGLUNMAPBUFFEROESPROC)(GLenum target);
|
||||
GLAPI PFNGLUNMAPBUFFEROESPROC glUnmapBuffer;
|
||||
|
||||
#define GL_DEPTH24_STENCIL8 0x88F0
|
||||
#define GL_MAP_PERSISTENT_BIT 0x0040
|
||||
#define GL_MAP_READ_BIT 0x0001
|
||||
#define GL_MAP_WRITE_BIT 0x0002
|
||||
#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020
|
||||
#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008
|
||||
#define GL_BGRA 0x80E1
|
||||
#define GL_DEPTH_CLAMP 0x864F
|
||||
|
||||
#else
|
||||
#include "gl_load/gl_load.h"
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <OpenGL/OpenGL.h>
|
||||
#endif
|
||||
|
||||
// This is the number of vec4s make up the light data
|
||||
#define LIGHT_VEC4_NUM 4
|
||||
|
||||
//#define NO_RENDER_BUFFER
|
||||
|
||||
//#define NPOT_EMULATION
|
||||
|
||||
namespace OpenGLESRenderer
|
||||
{
|
||||
struct RenderContextGLES
|
||||
{
|
||||
unsigned int flags;
|
||||
unsigned int maxlights;
|
||||
unsigned int numlightvectors;
|
||||
bool useMappedBuffers;
|
||||
bool depthStencilAvailable;
|
||||
bool npotAvailable;
|
||||
bool forceGLSLv100;
|
||||
bool depthClampAvailable;
|
||||
int max_texturesize;
|
||||
char* vendorstring;
|
||||
char* modelstring;
|
||||
};
|
||||
|
||||
extern RenderContextGLES gles;
|
||||
|
||||
void InitGLES();
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable : 4244) // MIPS
|
||||
#pragma warning(disable : 4136) // X86
|
||||
#pragma warning(disable : 4051) // ALPHA
|
||||
|
||||
#pragma warning(disable : 4018) // signed/unsigned mismatch
|
||||
#pragma warning(disable : 4305) // truncate from double to float
|
||||
#endif
|
||||
|
||||
#endif //__GL_PCH_H
|
|
@ -5,6 +5,14 @@
|
|||
|
||||
class FRenderState;
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#define HW_MAX_PIPELINE_BUFFERS 4
|
||||
#define HW_BLOCK_SSBO 1
|
||||
#else
|
||||
// On desktop this is only useful fpr letting the GPU run in parallel with the playsim and for that 2 buffers are enough.
|
||||
#define HW_MAX_PIPELINE_BUFFERS 2
|
||||
#endif
|
||||
|
||||
// The low level code needs to know which attributes exist.
|
||||
// OpenGL needs to change the state of all of them per buffer binding.
|
||||
// VAOs are mostly useless for this because they lump buffer and binding state together which the model code does not want.
|
||||
|
@ -54,10 +62,15 @@ public:
|
|||
virtual void *Lock(unsigned int size) = 0;
|
||||
virtual void Unlock() = 0;
|
||||
virtual void Resize(size_t newsize) = 0;
|
||||
|
||||
virtual void Upload(size_t start, size_t size) {} // For unmappable buffers
|
||||
|
||||
virtual void Map() {} // Only needed by old OpenGL but this needs to be in the interface.
|
||||
virtual void Unmap() {}
|
||||
void *Memory() { return map; }
|
||||
size_t Size() { return buffersize; }
|
||||
virtual void GPUDropSync() {}
|
||||
virtual void GPUWaitSync() {}
|
||||
};
|
||||
|
||||
class IVertexBuffer : virtual public IBuffer
|
||||
|
|
|
@ -45,7 +45,8 @@
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FFlatVertexBuffer::FFlatVertexBuffer(int width, int height)
|
||||
FFlatVertexBuffer::FFlatVertexBuffer(int width, int height, int pipelineNbr):
|
||||
mPipelineNbr(pipelineNbr)
|
||||
{
|
||||
vbo_shadowdata.Resize(NUM_RESERVED);
|
||||
|
||||
|
@ -78,19 +79,27 @@ FFlatVertexBuffer::FFlatVertexBuffer(int width, int height)
|
|||
vbo_shadowdata[18].Set(32767.0f, -32767.0f, 32767.0f, 0, 0);
|
||||
vbo_shadowdata[19].Set(32767.0f, -32767.0f, -32767.0f, 0, 0);
|
||||
|
||||
mVertexBuffer = screen->CreateVertexBuffer();
|
||||
mIndexBuffer = screen->CreateIndexBuffer();
|
||||
int data[4] = {};
|
||||
mIndexBuffer->SetData(4, data); // On Vulkan this may not be empty, so set some dummy defaults to avoid crashes.
|
||||
|
||||
unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex);
|
||||
mVertexBuffer->SetData(bytesize, nullptr, false);
|
||||
|
||||
static const FVertexBufferAttribute format[] = {
|
||||
{ 0, VATTR_VERTEX, VFmt_Float3, (int)myoffsetof(FFlatVertex, x) },
|
||||
{ 0, VATTR_TEXCOORD, VFmt_Float2, (int)myoffsetof(FFlatVertex, u) }
|
||||
};
|
||||
mVertexBuffer->SetFormat(1, 2, sizeof(FFlatVertex), format);
|
||||
for (int n = 0; n < mPipelineNbr; n++)
|
||||
{
|
||||
mVertexBufferPipeline[n] = screen->CreateVertexBuffer();
|
||||
|
||||
unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex);
|
||||
mVertexBufferPipeline[n]->SetData(bytesize, nullptr, false);
|
||||
|
||||
static const FVertexBufferAttribute format[] = {
|
||||
{ 0, VATTR_VERTEX, VFmt_Float3, (int)myoffsetof(FFlatVertex, x) },
|
||||
{ 0, VATTR_TEXCOORD, VFmt_Float2, (int)myoffsetof(FFlatVertex, u) }
|
||||
};
|
||||
|
||||
mVertexBufferPipeline[n]->SetFormat(1, 2, sizeof(FFlatVertex), format);
|
||||
}
|
||||
|
||||
mVertexBuffer = mVertexBufferPipeline[mPipelinePos];
|
||||
|
||||
mIndex = mCurIndex = NUM_RESERVED;
|
||||
mNumReserved = NUM_RESERVED;
|
||||
|
@ -105,8 +114,12 @@ FFlatVertexBuffer::FFlatVertexBuffer(int width, int height)
|
|||
|
||||
FFlatVertexBuffer::~FFlatVertexBuffer()
|
||||
{
|
||||
for (int n = 0; n < mPipelineNbr; n++)
|
||||
{
|
||||
delete mVertexBufferPipeline[n];
|
||||
}
|
||||
|
||||
delete mIndexBuffer;
|
||||
delete mVertexBuffer;
|
||||
mIndexBuffer = nullptr;
|
||||
mVertexBuffer = nullptr;
|
||||
}
|
||||
|
@ -153,8 +166,17 @@ std::pair<FFlatVertex *, unsigned int> FFlatVertexBuffer::AllocVertices(unsigned
|
|||
|
||||
void FFlatVertexBuffer::Copy(int start, int count)
|
||||
{
|
||||
Map();
|
||||
memcpy(GetBuffer(start), &vbo_shadowdata[0], count * sizeof(FFlatVertex));
|
||||
Unmap();
|
||||
IVertexBuffer* old = mVertexBuffer;
|
||||
|
||||
for (int n = 0; n < mPipelineNbr; n++)
|
||||
{
|
||||
mVertexBuffer = mVertexBufferPipeline[n];
|
||||
Map();
|
||||
memcpy(GetBuffer(start), &vbo_shadowdata[0], count * sizeof(FFlatVertex));
|
||||
Unmap();
|
||||
mVertexBuffer->Upload(start * sizeof(FFlatVertex), count * sizeof(FFlatVertex));
|
||||
}
|
||||
|
||||
mVertexBuffer = old;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,13 +45,20 @@ public:
|
|||
TArray<FFlatVertex> vbo_shadowdata;
|
||||
TArray<uint32_t> ibo_data;
|
||||
|
||||
IVertexBuffer *mVertexBuffer;
|
||||
int mPipelineNbr;
|
||||
int mPipelinePos = 0;
|
||||
|
||||
IVertexBuffer* mVertexBuffer;
|
||||
IVertexBuffer *mVertexBufferPipeline[HW_MAX_PIPELINE_BUFFERS];
|
||||
IIndexBuffer *mIndexBuffer;
|
||||
|
||||
|
||||
|
||||
unsigned int mIndex;
|
||||
std::atomic<unsigned int> mCurIndex;
|
||||
unsigned int mNumReserved;
|
||||
|
||||
unsigned int mMapStart;
|
||||
|
||||
static const unsigned int BUFFER_SIZE = 2000000;
|
||||
static const unsigned int BUFFER_SIZE_TO_USE = BUFFER_SIZE-500;
|
||||
|
@ -68,7 +75,7 @@ public:
|
|||
NUM_RESERVED = 20
|
||||
};
|
||||
|
||||
FFlatVertexBuffer(int width, int height);
|
||||
FFlatVertexBuffer(int width, int height, int pipelineNbr = 1);
|
||||
~FFlatVertexBuffer();
|
||||
|
||||
void OutputResized(int width, int height);
|
||||
|
@ -97,16 +104,40 @@ public:
|
|||
mCurIndex = mIndex;
|
||||
}
|
||||
|
||||
void NextPipelineBuffer()
|
||||
{
|
||||
mPipelinePos++;
|
||||
mPipelinePos %= mPipelineNbr;
|
||||
|
||||
mVertexBuffer = mVertexBufferPipeline[mPipelinePos];
|
||||
}
|
||||
|
||||
void Map()
|
||||
{
|
||||
mMapStart = mCurIndex;
|
||||
mVertexBuffer->Map();
|
||||
}
|
||||
|
||||
void Unmap()
|
||||
{
|
||||
mVertexBuffer->Unmap();
|
||||
mVertexBuffer->Upload(mMapStart * sizeof(FFlatVertex), (mCurIndex - mMapStart) * sizeof(FFlatVertex));
|
||||
}
|
||||
|
||||
void DropSync()
|
||||
{
|
||||
mVertexBuffer->GPUDropSync();
|
||||
}
|
||||
|
||||
void WaitSync()
|
||||
{
|
||||
mVertexBuffer->GPUWaitSync();
|
||||
}
|
||||
|
||||
int GetPipelinePos()
|
||||
{
|
||||
return mPipelinePos;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -69,11 +69,6 @@ CUSTOM_CVAR(Bool, gl_plane_reflection, true, CVAR_GLOBALCONFIG|CVAR_ARCHIVE)
|
|||
gl_plane_reflection_i = self;
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Bool, gl_render_precise, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
{
|
||||
gl_seamless=self;
|
||||
}
|
||||
|
||||
CUSTOM_CVARD(Float, vid_gamma, 1.f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "adjusts gamma component of gamma ramp")
|
||||
{
|
||||
if (self < 0) self = 1;
|
||||
|
|
|
@ -33,7 +33,8 @@ static const int ELEMENTS_PER_LIGHT = 4; // each light needs 4 vec4's.
|
|||
static const int ELEMENT_SIZE = (4*sizeof(float));
|
||||
|
||||
|
||||
FLightBuffer::FLightBuffer()
|
||||
FLightBuffer::FLightBuffer(int pipelineNbr):
|
||||
mPipelineNbr(pipelineNbr)
|
||||
{
|
||||
int maxNumberOfLights = 80000;
|
||||
|
||||
|
@ -43,7 +44,7 @@ FLightBuffer::FLightBuffer()
|
|||
// Hack alert: On Intel's GL driver SSBO's perform quite worse than UBOs.
|
||||
// We only want to disable using SSBOs for lights but not disable the feature entirely.
|
||||
// Note that using an uniform buffer here will limit the number of lights per surface so it isn't done for NVidia and AMD.
|
||||
if (screen->IsVulkan() || screen->IsPoly() || ((screen->hwcaps & RFL_SHADER_STORAGE_BUFFER) && !strstr(screen->vendorstring, "Intel")))
|
||||
if (screen->IsVulkan() || screen->IsPoly() || ((screen->hwcaps & RFL_SHADER_STORAGE_BUFFER) && screen->allowSSBO() && !strstr(screen->vendorstring, "Intel")))
|
||||
{
|
||||
mBufferType = true;
|
||||
mBlockAlign = 0;
|
||||
|
@ -56,11 +57,15 @@ FLightBuffer::FLightBuffer()
|
|||
mBlockSize = screen->maxuniformblock / ELEMENT_SIZE;
|
||||
mBlockAlign = screen->uniformblockalignment / ELEMENT_SIZE;
|
||||
mMaxUploadSize = (mBlockSize - mBlockAlign);
|
||||
mByteSize += screen->maxuniformblock; // to avoid mapping beyond the end of the buffer.
|
||||
|
||||
//mByteSize += screen->maxuniformblock; // to avoid mapping beyond the end of the buffer. REMOVED this...This can try to allocate 100's of MB..
|
||||
}
|
||||
|
||||
mBuffer = screen->CreateDataBuffer(LIGHTBUF_BINDINGPOINT, mBufferType, false);
|
||||
mBuffer->SetData(mByteSize, nullptr, false);
|
||||
for (int n = 0; n < mPipelineNbr; n++)
|
||||
{
|
||||
mBufferPipeline[n] = screen->CreateDataBuffer(LIGHTBUF_BINDINGPOINT, mBufferType, false);
|
||||
mBufferPipeline[n]->SetData(mByteSize, nullptr, false);
|
||||
}
|
||||
|
||||
Clear();
|
||||
}
|
||||
|
@ -73,6 +78,11 @@ FLightBuffer::~FLightBuffer()
|
|||
void FLightBuffer::Clear()
|
||||
{
|
||||
mIndex = 0;
|
||||
|
||||
mPipelinePos++;
|
||||
mPipelinePos %= mPipelineNbr;
|
||||
|
||||
mBuffer = mBufferPipeline[mPipelinePos];
|
||||
}
|
||||
|
||||
int FLightBuffer::UploadLights(FDynLightData &data)
|
||||
|
|
|
@ -12,6 +12,9 @@ class FRenderState;
|
|||
class FLightBuffer
|
||||
{
|
||||
IDataBuffer *mBuffer;
|
||||
IDataBuffer* mBufferPipeline[HW_MAX_PIPELINE_BUFFERS];
|
||||
int mPipelineNbr;
|
||||
int mPipelinePos = 0;
|
||||
|
||||
bool mBufferType;
|
||||
std::atomic<unsigned int> mIndex;
|
||||
|
@ -25,7 +28,7 @@ class FLightBuffer
|
|||
|
||||
public:
|
||||
|
||||
FLightBuffer();
|
||||
FLightBuffer(int pipelineNbr = 1);
|
||||
~FLightBuffer();
|
||||
void Clear();
|
||||
int UploadLights(FDynLightData &data);
|
||||
|
|
|
@ -219,6 +219,7 @@ protected:
|
|||
int mLightIndex;
|
||||
int mSpecialEffect;
|
||||
int mTextureMode;
|
||||
int mTextureClamp;
|
||||
int mTextureModeFlags;
|
||||
int mSoftLight;
|
||||
float mLightParms[4];
|
||||
|
@ -226,6 +227,10 @@ protected:
|
|||
float mAlphaThreshold;
|
||||
float mClipSplit[2];
|
||||
|
||||
|
||||
int mColorMapSpecial;
|
||||
float mColorMapFlash;
|
||||
|
||||
StreamData mStreamData = {};
|
||||
PalEntry mFogColor;
|
||||
|
||||
|
@ -255,6 +260,7 @@ public:
|
|||
mFogColor = 0xffffffff;
|
||||
mStreamData.uFogColor = mFogColor;
|
||||
mTextureMode = -1;
|
||||
mTextureClamp = 0;
|
||||
mTextureModeFlags = 0;
|
||||
mStreamData.uDesaturationFactor = 0.0f;
|
||||
mAlphaThreshold = 0.5f;
|
||||
|
@ -278,6 +284,9 @@ public:
|
|||
mBias.Reset();
|
||||
mPassType = NORMAL_PASS;
|
||||
|
||||
mColorMapSpecial = 0;
|
||||
mColorMapFlash = 1;
|
||||
|
||||
mVertexBuffer = nullptr;
|
||||
mVertexOffsets[0] = mVertexOffsets[1] = 0;
|
||||
mIndexBuffer = nullptr;
|
||||
|
@ -337,6 +346,12 @@ public:
|
|||
mStreamData.uDesaturationFactor = 0.0f;
|
||||
}
|
||||
|
||||
void SetTextureClamp(bool on)
|
||||
{
|
||||
if (on) mTextureClamp = TM_CLAMPY;
|
||||
else mTextureClamp = 0;
|
||||
}
|
||||
|
||||
void SetTextureMode(int mode)
|
||||
{
|
||||
mTextureMode = mode;
|
||||
|
@ -363,6 +378,14 @@ public:
|
|||
return mTextureMode;
|
||||
}
|
||||
|
||||
int GetTextureModeAndFlags(int tempTM)
|
||||
{
|
||||
int f = mTextureModeFlags;
|
||||
if (!mBrightmapEnabled) f &= ~(TEXF_Brightmap | TEXF_Glowmap);
|
||||
if (mTextureClamp) f |= TEXF_ClampY;
|
||||
return (mTextureMode == TM_NORMAL && tempTM == TM_OPAQUE ? TM_OPAQUE : mTextureMode) | f;
|
||||
}
|
||||
|
||||
void EnableTexture(bool on)
|
||||
{
|
||||
mTextureEnabled = on;
|
||||
|
@ -676,6 +699,12 @@ public:
|
|||
return mPassType;
|
||||
}
|
||||
|
||||
void SetSpecialColormap(int cm, float flash)
|
||||
{
|
||||
mColorMapSpecial = cm;
|
||||
mColorMapFlash = flash;
|
||||
}
|
||||
|
||||
// API-dependent render interface
|
||||
|
||||
// Draw commands
|
||||
|
|
|
@ -52,15 +52,15 @@ static bool IsGlslWhitespace(char c)
|
|||
}
|
||||
}
|
||||
|
||||
static FString NextGlslToken(const char *chars, long len, long &pos)
|
||||
static FString NextGlslToken(const char *chars, ptrdiff_t len, ptrdiff_t &pos)
|
||||
{
|
||||
// Eat whitespace
|
||||
long tokenStart = pos;
|
||||
ptrdiff_t tokenStart = pos;
|
||||
while (tokenStart != len && IsGlslWhitespace(chars[tokenStart]))
|
||||
tokenStart++;
|
||||
|
||||
// Find token end
|
||||
long tokenEnd = tokenStart;
|
||||
ptrdiff_t tokenEnd = tokenStart;
|
||||
while (tokenEnd != len && !IsGlslWhitespace(chars[tokenEnd]) && chars[tokenEnd] != ';')
|
||||
tokenEnd++;
|
||||
|
||||
|
@ -82,13 +82,13 @@ FString RemoveLegacyUserUniforms(FString code)
|
|||
|
||||
// The following code searches for legacy uniform declarations in the shader itself and replaces them with whitespace.
|
||||
|
||||
long len = (long)code.Len();
|
||||
ptrdiff_t len = code.Len();
|
||||
char *chars = code.LockBuffer();
|
||||
|
||||
long startIndex = 0;
|
||||
ptrdiff_t startIndex = 0;
|
||||
while (true)
|
||||
{
|
||||
long matchIndex = code.IndexOf("uniform", startIndex);
|
||||
ptrdiff_t matchIndex = code.IndexOf("uniform", startIndex);
|
||||
if (matchIndex == -1)
|
||||
break;
|
||||
|
||||
|
@ -98,7 +98,7 @@ FString RemoveLegacyUserUniforms(FString code)
|
|||
bool isKeywordEnd = matchIndex + 7 == len || IsGlslWhitespace(chars[matchIndex + 7]);
|
||||
if (isKeywordStart && isKeywordEnd)
|
||||
{
|
||||
long pos = matchIndex + 7;
|
||||
ptrdiff_t pos = matchIndex + 7;
|
||||
FString type = NextGlslToken(chars, len, pos);
|
||||
FString identifier = NextGlslToken(chars, len, pos);
|
||||
|
||||
|
@ -107,10 +107,10 @@ FString RemoveLegacyUserUniforms(FString code)
|
|||
|
||||
if (isLegacyUniformName)
|
||||
{
|
||||
long statementEndIndex = code.IndexOf(';', matchIndex + 7);
|
||||
ptrdiff_t statementEndIndex = code.IndexOf(';', matchIndex + 7);
|
||||
if (statementEndIndex == -1)
|
||||
statementEndIndex = len;
|
||||
for (long i = matchIndex; i <= statementEndIndex; i++)
|
||||
for (ptrdiff_t i = matchIndex; i <= statementEndIndex; i++)
|
||||
{
|
||||
if (!IsGlslWhitespace(chars[i]))
|
||||
chars[i] = ' ';
|
||||
|
@ -127,7 +127,7 @@ FString RemoveLegacyUserUniforms(FString code)
|
|||
// Modern GLSL only allows use of 'texture'.
|
||||
while (true)
|
||||
{
|
||||
long matchIndex = code.IndexOf("texture2d", startIndex);
|
||||
ptrdiff_t matchIndex = code.IndexOf("texture2d", startIndex);
|
||||
if (matchIndex == -1)
|
||||
break;
|
||||
|
||||
|
@ -148,14 +148,14 @@ FString RemoveLegacyUserUniforms(FString code)
|
|||
|
||||
FString RemoveSamplerBindings(FString code, TArray<std::pair<FString, int>> &samplerstobind)
|
||||
{
|
||||
long len = (long)code.Len();
|
||||
ptrdiff_t len = code.Len();
|
||||
char *chars = code.LockBuffer();
|
||||
|
||||
long startIndex = 0;
|
||||
long startpos, endpos;
|
||||
ptrdiff_t startIndex = 0;
|
||||
ptrdiff_t startpos, endpos;
|
||||
while (true)
|
||||
{
|
||||
long matchIndex = code.IndexOf("layout(binding", startIndex);
|
||||
ptrdiff_t matchIndex = code.IndexOf("layout(binding", startIndex);
|
||||
if (matchIndex == -1)
|
||||
break;
|
||||
|
||||
|
@ -165,7 +165,7 @@ FString RemoveSamplerBindings(FString code, TArray<std::pair<FString, int>> &sam
|
|||
bool isKeywordEnd = matchIndex + 14 == len || IsGlslWhitespace(chars[matchIndex + 14]) || chars[matchIndex + 14] == '=';
|
||||
if (isKeywordStart && isKeywordEnd)
|
||||
{
|
||||
long pos = matchIndex + 14;
|
||||
ptrdiff_t pos = matchIndex + 14;
|
||||
startpos = matchIndex;
|
||||
while (IsGlslWhitespace(chars[pos])) pos++;
|
||||
if (chars[pos] == '=')
|
||||
|
@ -175,7 +175,7 @@ FString RemoveSamplerBindings(FString code, TArray<std::pair<FString, int>> &sam
|
|||
auto val = strtol(&chars[pos], &p, 0);
|
||||
if (p != &chars[pos])
|
||||
{
|
||||
pos = long(p - chars);
|
||||
pos = (p - chars);
|
||||
while (IsGlslWhitespace(chars[pos])) pos++;
|
||||
if (chars[pos] == ')')
|
||||
{
|
||||
|
@ -216,17 +216,17 @@ FString RemoveSamplerBindings(FString code, TArray<std::pair<FString, int>> &sam
|
|||
|
||||
FString RemoveLayoutLocationDecl(FString code, const char *inoutkeyword)
|
||||
{
|
||||
long len = (long)code.Len();
|
||||
ptrdiff_t len = code.Len();
|
||||
char *chars = code.LockBuffer();
|
||||
|
||||
long startIndex = 0;
|
||||
ptrdiff_t startIndex = 0;
|
||||
while (true)
|
||||
{
|
||||
long matchIndex = code.IndexOf("layout(location", startIndex);
|
||||
ptrdiff_t matchIndex = code.IndexOf("layout(location", startIndex);
|
||||
if (matchIndex == -1)
|
||||
break;
|
||||
|
||||
long endIndex = matchIndex;
|
||||
ptrdiff_t endIndex = matchIndex;
|
||||
|
||||
// Find end of layout declaration
|
||||
while (chars[endIndex] != ')' && chars[endIndex] != 0)
|
||||
|
@ -255,7 +255,7 @@ FString RemoveLayoutLocationDecl(FString code, const char *inoutkeyword)
|
|||
if (keywordFound && IsGlslWhitespace(chars[endIndex + i]))
|
||||
{
|
||||
// yes - replace declaration with spaces
|
||||
for (long i = matchIndex; i < endIndex; i++)
|
||||
for (auto i = matchIndex; i < endIndex; i++)
|
||||
chars[i] = ' ';
|
||||
}
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue