- Backend update from GZDoom - mainly for GLES2 support.

This commit is contained in:
Christoph Oelckers 2021-09-18 12:20:28 +02:00
parent 11aea1c5d4
commit a3d9cd9a68
66 changed files with 9558 additions and 126 deletions

View file

@ -51,10 +51,12 @@ enum ETexMode
TM_OPAQUE, // (r, g, b, 1)
TM_INVERSE, // (1-r, 1-g, 1-b, a)
TM_ALPHATEXTURE, // (1, 1, 1, r)
TM_CLAMPY, // (r, g, b, (t >= 0.0 && t <= 1.0)? a:0)
TM_INVERTOPAQUE, // (1-r, 1-g, 1-b, 1)
TM_INVERTOPAQUE = 6, // (1-r, 1-g, 1-b, 1)
TM_FOGLAYER, // (renders a fog layer in the shape of the active texture)
TM_FIXEDCOLORMAP = TM_FOGLAYER, // repurposes the objectcolor uniforms to render a fixed colormap range. (Same constant because they cannot be used in the same context.
TM_CLAMPY = 0x1000, // (r, g, b, (t >= 0.0 && t <= 1.0)? a:0)
};
// Legacy render styles

View file

@ -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);

View file

@ -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
@ -468,7 +471,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;

View file

@ -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;

View file

@ -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;

View file

@ -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)

View file

@ -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

View file

@ -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;
}
}
}
//==========================================================================

View file

@ -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;
}

View file

@ -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;
}
//===========================================================================
//

View file

@ -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();
};

View file

@ -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();

View file

@ -204,7 +204,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);

View file

@ -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";
}

View file

@ -0,0 +1,303 @@
#ifndef __egl_h_
#define __egl_h_ 1
#ifdef __cplusplus
extern "C" {
#endif
/*
** Copyright (c) 2013-2014 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.
*/
/*
** This header is generated from the Khronos OpenGL / OpenGL ES XML
** API Registry. The current version of the Registry, generator scripts
** used to make the header, and the header can be found at
** http://www.opengl.org/registry/
**
** Khronos $Revision: 29318 $ on $Date: 2015-01-02 03:16:10 -0800 (Fri, 02 Jan 2015) $
*/
#include <EGL/eglplatform.h>
/* Generated on date 20150102 */
/* Generated C header for:
* API: egl
* Versions considered: .*
* Versions emitted: .*
* Default extensions included: None
* Additional extensions included: _nomatch_^
* Extensions removed: _nomatch_^
*/
#ifndef EGL_VERSION_1_0
#define EGL_VERSION_1_0 1
typedef unsigned int EGLBoolean;
typedef void *EGLDisplay;
#include <KHR/khrplatform.h>
#include <EGL/eglplatform.h>
typedef void *EGLConfig;
typedef void *EGLSurface;
typedef void *EGLContext;
typedef void (*__eglMustCastToProperFunctionPointerType)(void);
#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 ((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 ((EGLContext)0)
#define EGL_NO_DISPLAY ((EGLDisplay)0)
#define EGL_NO_SURFACE ((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
EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig (EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers (EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target);
EGLAPI EGLContext EGLAPIENTRY eglCreateContext (EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface (EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface (EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list);
EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface (EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext (EGLDisplay dpy, EGLContext ctx);
EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface (EGLDisplay dpy, EGLSurface surface);
EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib (EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs (EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay (void);
EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface (EGLint readdraw);
EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay (EGLNativeDisplayType display_id);
EGLAPI EGLint EGLAPIENTRY eglGetError (void);
EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress (const char *procname);
EGLAPI EGLBoolean EGLAPIENTRY eglInitialize (EGLDisplay dpy, EGLint *major, EGLint *minor);
EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent (EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext (EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value);
EGLAPI const char *EGLAPIENTRY eglQueryString (EGLDisplay dpy, EGLint name);
EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers (EGLDisplay dpy, EGLSurface surface);
EGLAPI EGLBoolean EGLAPIENTRY eglTerminate (EGLDisplay dpy);
EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL (void);
EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative (EGLint engine);
#endif /* EGL_VERSION_1_0 */
#ifndef EGL_VERSION_1_1
#define EGL_VERSION_1_1 1
#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
EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer);
EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage (EGLDisplay dpy, EGLSurface surface, EGLint buffer);
EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval (EGLDisplay dpy, EGLint interval);
#endif /* EGL_VERSION_1_1 */
#ifndef EGL_VERSION_1_2
#define EGL_VERSION_1_2 1
typedef unsigned int EGLenum;
typedef void *EGLClientBuffer;
#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 ((EGLint)-1)
#define EGL_VERTICAL_RESOLUTION 0x3091
EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI (EGLenum api);
EGLAPI EGLenum EGLAPIENTRY eglQueryAPI (void);
EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer (EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread (void);
EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient (void);
#endif /* EGL_VERSION_1_2 */
#ifndef EGL_VERSION_1_3
#define EGL_VERSION_1_3 1
#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
#endif /* EGL_VERSION_1_3 */
#ifndef EGL_VERSION_1_4
#define EGL_VERSION_1_4 1
#define EGL_DEFAULT_DISPLAY ((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
EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext (void);
#endif /* EGL_VERSION_1_4 */
#ifndef EGL_VERSION_1_5
#define EGL_VERSION_1_5 1
typedef void *EGLSync;
typedef intptr_t EGLAttrib;
typedef khronos_utime_nanoseconds_t EGLTime;
typedef void *EGLImage;
#define EGL_CONTEXT_MAJOR_VERSION 0x3098
#define EGL_CONTEXT_MINOR_VERSION 0x30FB
#define EGL_CONTEXT_OPENGL_PROFILE_MASK 0x30FD
#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY 0x31BD
#define EGL_NO_RESET_NOTIFICATION 0x31BE
#define EGL_LOSE_CONTEXT_ON_RESET 0x31BF
#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT 0x00000001
#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT 0x00000002
#define EGL_CONTEXT_OPENGL_DEBUG 0x31B0
#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE 0x31B1
#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS 0x31B2
#define EGL_OPENGL_ES3_BIT 0x00000040
#define EGL_CL_EVENT_HANDLE 0x309C
#define EGL_SYNC_CL_EVENT 0x30FE
#define EGL_SYNC_CL_EVENT_COMPLETE 0x30FF
#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE 0x30F0
#define EGL_SYNC_TYPE 0x30F7
#define EGL_SYNC_STATUS 0x30F1
#define EGL_SYNC_CONDITION 0x30F8
#define EGL_SIGNALED 0x30F2
#define EGL_UNSIGNALED 0x30F3
#define EGL_SYNC_FLUSH_COMMANDS_BIT 0x0001
#define EGL_FOREVER 0xFFFFFFFFFFFFFFFFull
#define EGL_TIMEOUT_EXPIRED 0x30F5
#define EGL_CONDITION_SATISFIED 0x30F6
#define EGL_NO_SYNC ((EGLSync)0)
#define EGL_SYNC_FENCE 0x30F9
#define EGL_GL_COLORSPACE 0x309D
#define EGL_GL_COLORSPACE_SRGB 0x3089
#define EGL_GL_COLORSPACE_LINEAR 0x308A
#define EGL_GL_RENDERBUFFER 0x30B9
#define EGL_GL_TEXTURE_2D 0x30B1
#define EGL_GL_TEXTURE_LEVEL 0x30BC
#define EGL_GL_TEXTURE_3D 0x30B2
#define EGL_GL_TEXTURE_ZOFFSET 0x30BD
#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x30B3
#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x30B4
#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x30B5
#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x30B6
#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x30B7
#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x30B8
#define EGL_IMAGE_PRESERVED 0x30D2
#define EGL_NO_IMAGE ((EGLImage)0)
EGLAPI EGLSync EGLAPIENTRY eglCreateSync (EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglDestroySync (EGLDisplay dpy, EGLSync sync);
EGLAPI EGLint EGLAPIENTRY eglClientWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout);
EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttrib (EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value);
EGLAPI EGLImage EGLAPIENTRY eglCreateImage (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImage (EGLDisplay dpy, EGLImage image);
EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplay (EGLenum platform, void *native_display, const EGLAttrib *attrib_list);
EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurface (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list);
EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurface (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglWaitSync (EGLDisplay dpy, EGLSync sync, EGLint flags);
#endif /* EGL_VERSION_1_5 */
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,826 @@
#ifndef __eglext_h_
#define __eglext_h_ 1
#ifdef __cplusplus
extern "C" {
#endif
/*
** Copyright (c) 2013-2014 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.
*/
/*
** This header is generated from the Khronos OpenGL / OpenGL ES XML
** API Registry. The current version of the Registry, generator scripts
** used to make the header, and the header can be found at
** http://www.opengl.org/registry/
**
** Khronos $Revision: 29318 $ on $Date: 2015-01-02 03:16:10 -0800 (Fri, 02 Jan 2015) $
*/
#include <EGL/eglplatform.h>
#define EGL_EGLEXT_VERSION 20150102
/* Generated C header for:
* API: egl
* Versions considered: .*
* Versions emitted: _nomatch_^
* Default extensions included: egl
* Additional extensions included: _nomatch_^
* Extensions removed: _nomatch_^
*/
#ifndef EGL_KHR_cl_event
#define EGL_KHR_cl_event 1
#define EGL_CL_EVENT_HANDLE_KHR 0x309C
#define EGL_SYNC_CL_EVENT_KHR 0x30FE
#define EGL_SYNC_CL_EVENT_COMPLETE_KHR 0x30FF
#endif /* EGL_KHR_cl_event */
#ifndef EGL_KHR_cl_event2
#define EGL_KHR_cl_event2 1
typedef void *EGLSyncKHR;
typedef intptr_t EGLAttribKHR;
typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNC64KHRPROC) (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSync64KHR (EGLDisplay dpy, EGLenum type, const EGLAttribKHR *attrib_list);
#endif
#endif /* EGL_KHR_cl_event2 */
#ifndef EGL_KHR_client_get_all_proc_addresses
#define EGL_KHR_client_get_all_proc_addresses 1
#endif /* EGL_KHR_client_get_all_proc_addresses */
#ifndef EGL_KHR_config_attribs
#define EGL_KHR_config_attribs 1
#define EGL_CONFORMANT_KHR 0x3042
#define EGL_VG_COLORSPACE_LINEAR_BIT_KHR 0x0020
#define EGL_VG_ALPHA_FORMAT_PRE_BIT_KHR 0x0040
#endif /* EGL_KHR_config_attribs */
#ifndef EGL_KHR_create_context
#define EGL_KHR_create_context 1
#define EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098
#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB
#define EGL_CONTEXT_FLAGS_KHR 0x30FC
#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30FD
#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31BD
#define EGL_NO_RESET_NOTIFICATION_KHR 0x31BE
#define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31BF
#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001
#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002
#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004
#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001
#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002
#define EGL_OPENGL_ES3_BIT_KHR 0x00000040
#endif /* EGL_KHR_create_context */
#ifndef EGL_KHR_fence_sync
#define EGL_KHR_fence_sync 1
#ifdef KHRONOS_SUPPORT_INT64
#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR 0x30F0
#define EGL_SYNC_CONDITION_KHR 0x30F8
#define EGL_SYNC_FENCE_KHR 0x30F9
#endif /* KHRONOS_SUPPORT_INT64 */
#endif /* EGL_KHR_fence_sync */
#ifndef EGL_KHR_get_all_proc_addresses
#define EGL_KHR_get_all_proc_addresses 1
#endif /* EGL_KHR_get_all_proc_addresses */
#ifndef EGL_KHR_gl_colorspace
#define EGL_KHR_gl_colorspace 1
#define EGL_GL_COLORSPACE_KHR 0x309D
#define EGL_GL_COLORSPACE_SRGB_KHR 0x3089
#define EGL_GL_COLORSPACE_LINEAR_KHR 0x308A
#endif /* EGL_KHR_gl_colorspace */
#ifndef EGL_KHR_gl_renderbuffer_image
#define EGL_KHR_gl_renderbuffer_image 1
#define EGL_GL_RENDERBUFFER_KHR 0x30B9
#endif /* EGL_KHR_gl_renderbuffer_image */
#ifndef EGL_KHR_gl_texture_2D_image
#define EGL_KHR_gl_texture_2D_image 1
#define EGL_GL_TEXTURE_2D_KHR 0x30B1
#define EGL_GL_TEXTURE_LEVEL_KHR 0x30BC
#endif /* EGL_KHR_gl_texture_2D_image */
#ifndef EGL_KHR_gl_texture_3D_image
#define EGL_KHR_gl_texture_3D_image 1
#define EGL_GL_TEXTURE_3D_KHR 0x30B2
#define EGL_GL_TEXTURE_ZOFFSET_KHR 0x30BD
#endif /* EGL_KHR_gl_texture_3D_image */
#ifndef EGL_KHR_gl_texture_cubemap_image
#define EGL_KHR_gl_texture_cubemap_image 1
#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR 0x30B3
#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR 0x30B4
#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR 0x30B5
#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR 0x30B6
#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR 0x30B7
#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR 0x30B8
#endif /* EGL_KHR_gl_texture_cubemap_image */
#ifndef EGL_KHR_image
#define EGL_KHR_image 1
typedef void *EGLImageKHR;
#define EGL_NATIVE_PIXMAP_KHR 0x30B0
#define EGL_NO_IMAGE_KHR ((EGLImageKHR)0)
typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEIMAGEKHRPROC) (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGLImageKHR image);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR (EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR (EGLDisplay dpy, EGLImageKHR image);
#endif
#endif /* EGL_KHR_image */
#ifndef EGL_KHR_image_base
#define EGL_KHR_image_base 1
#define EGL_IMAGE_PRESERVED_KHR 0x30D2
#endif /* EGL_KHR_image_base */
#ifndef EGL_KHR_image_pixmap
#define EGL_KHR_image_pixmap 1
#endif /* EGL_KHR_image_pixmap */
#ifndef EGL_KHR_lock_surface
#define EGL_KHR_lock_surface 1
#define EGL_READ_SURFACE_BIT_KHR 0x0001
#define EGL_WRITE_SURFACE_BIT_KHR 0x0002
#define EGL_LOCK_SURFACE_BIT_KHR 0x0080
#define EGL_OPTIMAL_FORMAT_BIT_KHR 0x0100
#define EGL_MATCH_FORMAT_KHR 0x3043
#define EGL_FORMAT_RGB_565_EXACT_KHR 0x30C0
#define EGL_FORMAT_RGB_565_KHR 0x30C1
#define EGL_FORMAT_RGBA_8888_EXACT_KHR 0x30C2
#define EGL_FORMAT_RGBA_8888_KHR 0x30C3
#define EGL_MAP_PRESERVE_PIXELS_KHR 0x30C4
#define EGL_LOCK_USAGE_HINT_KHR 0x30C5
#define EGL_BITMAP_POINTER_KHR 0x30C6
#define EGL_BITMAP_PITCH_KHR 0x30C7
#define EGL_BITMAP_ORIGIN_KHR 0x30C8
#define EGL_BITMAP_PIXEL_RED_OFFSET_KHR 0x30C9
#define EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR 0x30CA
#define EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR 0x30CB
#define EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR 0x30CC
#define EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR 0x30CD
#define EGL_LOWER_LEFT_KHR 0x30CE
#define EGL_UPPER_LEFT_KHR 0x30CF
typedef EGLBoolean (EGLAPIENTRYP PFNEGLLOCKSURFACEKHRPROC) (EGLDisplay dpy, EGLSurface surface, const EGLint *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLUNLOCKSURFACEKHRPROC) (EGLDisplay dpy, EGLSurface surface);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglLockSurfaceKHR (EGLDisplay dpy, EGLSurface surface, const EGLint *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglUnlockSurfaceKHR (EGLDisplay dpy, EGLSurface surface);
#endif
#endif /* EGL_KHR_lock_surface */
#ifndef EGL_KHR_lock_surface2
#define EGL_KHR_lock_surface2 1
#define EGL_BITMAP_PIXEL_SIZE_KHR 0x3110
#endif /* EGL_KHR_lock_surface2 */
#ifndef EGL_KHR_lock_surface3
#define EGL_KHR_lock_surface3 1
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACE64KHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLAttribKHR *value);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface64KHR (EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLAttribKHR *value);
#endif
#endif /* EGL_KHR_lock_surface3 */
#ifndef EGL_KHR_partial_update
#define EGL_KHR_partial_update 1
#define EGL_BUFFER_AGE_KHR 0x313D
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETDAMAGEREGIONKHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglSetDamageRegionKHR (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
#endif
#endif /* EGL_KHR_partial_update */
#ifndef EGL_KHR_platform_android
#define EGL_KHR_platform_android 1
#define EGL_PLATFORM_ANDROID_KHR 0x3141
#endif /* EGL_KHR_platform_android */
#ifndef EGL_KHR_platform_gbm
#define EGL_KHR_platform_gbm 1
#define EGL_PLATFORM_GBM_KHR 0x31D7
#endif /* EGL_KHR_platform_gbm */
#ifndef EGL_KHR_platform_wayland
#define EGL_KHR_platform_wayland 1
#define EGL_PLATFORM_WAYLAND_KHR 0x31D8
#endif /* EGL_KHR_platform_wayland */
#ifndef EGL_KHR_platform_x11
#define EGL_KHR_platform_x11 1
#define EGL_PLATFORM_X11_KHR 0x31D5
#define EGL_PLATFORM_X11_SCREEN_KHR 0x31D6
#endif /* EGL_KHR_platform_x11 */
#ifndef EGL_KHR_reusable_sync
#define EGL_KHR_reusable_sync 1
typedef khronos_utime_nanoseconds_t EGLTimeKHR;
#ifdef KHRONOS_SUPPORT_INT64
#define EGL_SYNC_STATUS_KHR 0x30F1
#define EGL_SIGNALED_KHR 0x30F2
#define EGL_UNSIGNALED_KHR 0x30F3
#define EGL_TIMEOUT_EXPIRED_KHR 0x30F5
#define EGL_CONDITION_SATISFIED_KHR 0x30F6
#define EGL_SYNC_TYPE_KHR 0x30F7
#define EGL_SYNC_REUSABLE_KHR 0x30FA
#define EGL_SYNC_FLUSH_COMMANDS_BIT_KHR 0x0001
#define EGL_FOREVER_KHR 0xFFFFFFFFFFFFFFFFull
#define EGL_NO_SYNC_KHR ((EGLSyncKHR)0)
typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNCKHRPROC) (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync);
typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR (EGLDisplay dpy, EGLSyncKHR sync);
EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode);
EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
#endif
#endif /* KHRONOS_SUPPORT_INT64 */
#endif /* EGL_KHR_reusable_sync */
#ifndef EGL_KHR_stream
#define EGL_KHR_stream 1
typedef void *EGLStreamKHR;
typedef khronos_uint64_t EGLuint64KHR;
#ifdef KHRONOS_SUPPORT_INT64
#define EGL_NO_STREAM_KHR ((EGLStreamKHR)0)
#define EGL_CONSUMER_LATENCY_USEC_KHR 0x3210
#define EGL_PRODUCER_FRAME_KHR 0x3212
#define EGL_CONSUMER_FRAME_KHR 0x3213
#define EGL_STREAM_STATE_KHR 0x3214
#define EGL_STREAM_STATE_CREATED_KHR 0x3215
#define EGL_STREAM_STATE_CONNECTING_KHR 0x3216
#define EGL_STREAM_STATE_EMPTY_KHR 0x3217
#define EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR 0x3218
#define EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR 0x3219
#define EGL_STREAM_STATE_DISCONNECTED_KHR 0x321A
#define EGL_BAD_STREAM_KHR 0x321B
#define EGL_BAD_STATE_KHR 0x321C
typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMKHRPROC) (EGLDisplay dpy, const EGLint *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSTREAMKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMU64KHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamKHR (EGLDisplay dpy, const EGLint *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglDestroyStreamKHR (EGLDisplay dpy, EGLStreamKHR stream);
EGLAPI EGLBoolean EGLAPIENTRY eglStreamAttribKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value);
EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value);
EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamu64KHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value);
#endif
#endif /* KHRONOS_SUPPORT_INT64 */
#endif /* EGL_KHR_stream */
#ifndef EGL_KHR_stream_consumer_gltexture
#define EGL_KHR_stream_consumer_gltexture 1
#ifdef EGL_KHR_stream
#define EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR 0x321E
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalKHR (EGLDisplay dpy, EGLStreamKHR stream);
EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerAcquireKHR (EGLDisplay dpy, EGLStreamKHR stream);
EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerReleaseKHR (EGLDisplay dpy, EGLStreamKHR stream);
#endif
#endif /* EGL_KHR_stream */
#endif /* EGL_KHR_stream_consumer_gltexture */
#ifndef EGL_KHR_stream_cross_process_fd
#define EGL_KHR_stream_cross_process_fd 1
typedef int EGLNativeFileDescriptorKHR;
#ifdef EGL_KHR_stream
#define EGL_NO_FILE_DESCRIPTOR_KHR ((EGLNativeFileDescriptorKHR)(-1))
typedef EGLNativeFileDescriptorKHR (EGLAPIENTRYP PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLNativeFileDescriptorKHR EGLAPIENTRY eglGetStreamFileDescriptorKHR (EGLDisplay dpy, EGLStreamKHR stream);
EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamFromFileDescriptorKHR (EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor);
#endif
#endif /* EGL_KHR_stream */
#endif /* EGL_KHR_stream_cross_process_fd */
#ifndef EGL_KHR_stream_fifo
#define EGL_KHR_stream_fifo 1
#ifdef EGL_KHR_stream
#define EGL_STREAM_FIFO_LENGTH_KHR 0x31FC
#define EGL_STREAM_TIME_NOW_KHR 0x31FD
#define EGL_STREAM_TIME_CONSUMER_KHR 0x31FE
#define EGL_STREAM_TIME_PRODUCER_KHR 0x31FF
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMTIMEKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamTimeKHR (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value);
#endif
#endif /* EGL_KHR_stream */
#endif /* EGL_KHR_stream_fifo */
#ifndef EGL_KHR_stream_producer_aldatalocator
#define EGL_KHR_stream_producer_aldatalocator 1
#ifdef EGL_KHR_stream
#endif /* EGL_KHR_stream */
#endif /* EGL_KHR_stream_producer_aldatalocator */
#ifndef EGL_KHR_stream_producer_eglsurface
#define EGL_KHR_stream_producer_eglsurface 1
#ifdef EGL_KHR_stream
#define EGL_STREAM_BIT_KHR 0x0800
typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC) (EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLSurface EGLAPIENTRY eglCreateStreamProducerSurfaceKHR (EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list);
#endif
#endif /* EGL_KHR_stream */
#endif /* EGL_KHR_stream_producer_eglsurface */
#ifndef EGL_KHR_surfaceless_context
#define EGL_KHR_surfaceless_context 1
#endif /* EGL_KHR_surfaceless_context */
#ifndef EGL_KHR_swap_buffers_with_damage
#define EGL_KHR_swap_buffers_with_damage 1
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEKHRPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageKHR (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
#endif
#endif /* EGL_KHR_swap_buffers_with_damage */
#ifndef EGL_KHR_vg_parent_image
#define EGL_KHR_vg_parent_image 1
#define EGL_VG_PARENT_IMAGE_KHR 0x30BA
#endif /* EGL_KHR_vg_parent_image */
#ifndef EGL_KHR_wait_sync
#define EGL_KHR_wait_sync 1
typedef EGLint (EGLAPIENTRYP PFNEGLWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLint EGLAPIENTRY eglWaitSyncKHR (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags);
#endif
#endif /* EGL_KHR_wait_sync */
#ifndef EGL_ANDROID_blob_cache
#define EGL_ANDROID_blob_cache 1
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);
typedef void (EGLAPIENTRYP PFNEGLSETBLOBCACHEFUNCSANDROIDPROC) (EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI void EGLAPIENTRY eglSetBlobCacheFuncsANDROID (EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get);
#endif
#endif /* EGL_ANDROID_blob_cache */
#ifndef EGL_ANDROID_framebuffer_target
#define EGL_ANDROID_framebuffer_target 1
#define EGL_FRAMEBUFFER_TARGET_ANDROID 0x3147
#endif /* EGL_ANDROID_framebuffer_target */
#ifndef EGL_ANDROID_image_native_buffer
#define EGL_ANDROID_image_native_buffer 1
#define EGL_NATIVE_BUFFER_ANDROID 0x3140
#endif /* EGL_ANDROID_image_native_buffer */
#ifndef EGL_ANDROID_native_fence_sync
#define EGL_ANDROID_native_fence_sync 1
#define EGL_SYNC_NATIVE_FENCE_ANDROID 0x3144
#define EGL_SYNC_NATIVE_FENCE_FD_ANDROID 0x3145
#define EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID 0x3146
#define EGL_NO_NATIVE_FENCE_FD_ANDROID -1
typedef EGLint (EGLAPIENTRYP PFNEGLDUPNATIVEFENCEFDANDROIDPROC) (EGLDisplay dpy, EGLSyncKHR sync);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLint EGLAPIENTRY eglDupNativeFenceFDANDROID (EGLDisplay dpy, EGLSyncKHR sync);
#endif
#endif /* EGL_ANDROID_native_fence_sync */
#ifndef EGL_ANDROID_recordable
#define EGL_ANDROID_recordable 1
#define EGL_RECORDABLE_ANDROID 0x3142
#endif /* EGL_ANDROID_recordable */
#ifndef EGL_ANGLE_d3d_share_handle_client_buffer
#define EGL_ANGLE_d3d_share_handle_client_buffer 1
#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200
#endif /* EGL_ANGLE_d3d_share_handle_client_buffer */
#ifndef EGL_ANGLE_query_surface_pointer
#define EGL_ANGLE_query_surface_pointer 1
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
#endif
#endif /* EGL_ANGLE_query_surface_pointer */
#ifndef EGL_ANGLE_surface_d3d_texture_2d_share_handle
#define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1
#endif /* EGL_ANGLE_surface_d3d_texture_2d_share_handle */
#ifndef EGL_ANGLE_window_fixed_size
#define EGL_ANGLE_window_fixed_size 1
#define EGL_FIXED_SIZE_ANGLE 0x3201
#endif /* EGL_ANGLE_window_fixed_size */
#ifndef EGL_ARM_pixmap_multisample_discard
#define EGL_ARM_pixmap_multisample_discard 1
#define EGL_DISCARD_SAMPLES_ARM 0x3286
#endif /* EGL_ARM_pixmap_multisample_discard */
#ifndef EGL_EXT_buffer_age
#define EGL_EXT_buffer_age 1
#define EGL_BUFFER_AGE_EXT 0x313D
#endif /* EGL_EXT_buffer_age */
#ifndef EGL_EXT_client_extensions
#define EGL_EXT_client_extensions 1
#endif /* EGL_EXT_client_extensions */
#ifndef EGL_EXT_create_context_robustness
#define EGL_EXT_create_context_robustness 1
#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT 0x30BF
#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT 0x3138
#define EGL_NO_RESET_NOTIFICATION_EXT 0x31BE
#define EGL_LOSE_CONTEXT_ON_RESET_EXT 0x31BF
#endif /* EGL_EXT_create_context_robustness */
#ifndef EGL_EXT_device_base
#define EGL_EXT_device_base 1
typedef void *EGLDeviceEXT;
#define EGL_NO_DEVICE_EXT ((EGLDeviceEXT)(0))
#define EGL_BAD_DEVICE_EXT 0x322B
#define EGL_DEVICE_EXT 0x322C
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICEATTRIBEXTPROC) (EGLDeviceEXT device, EGLint attribute, EGLAttrib *value);
typedef const char *(EGLAPIENTRYP PFNEGLQUERYDEVICESTRINGEXTPROC) (EGLDeviceEXT device, EGLint name);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICESEXTPROC) (EGLint max_devices, EGLDeviceEXT *devices, EGLint *num_devices);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDISPLAYATTRIBEXTPROC) (EGLDisplay dpy, EGLint attribute, EGLAttrib *value);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglQueryDeviceAttribEXT (EGLDeviceEXT device, EGLint attribute, EGLAttrib *value);
EGLAPI const char *EGLAPIENTRY eglQueryDeviceStringEXT (EGLDeviceEXT device, EGLint name);
EGLAPI EGLBoolean EGLAPIENTRY eglQueryDevicesEXT (EGLint max_devices, EGLDeviceEXT *devices, EGLint *num_devices);
EGLAPI EGLBoolean EGLAPIENTRY eglQueryDisplayAttribEXT (EGLDisplay dpy, EGLint attribute, EGLAttrib *value);
#endif
#endif /* EGL_EXT_device_base */
#ifndef EGL_EXT_device_drm
#define EGL_EXT_device_drm 1
#define EGL_DRM_DEVICE_FILE_EXT 0x3233
#endif /* EGL_EXT_device_drm */
#ifndef EGL_EXT_device_openwf
#define EGL_EXT_device_openwf 1
#define EGL_OPENWF_DEVICE_ID_EXT 0x3237
#endif /* EGL_EXT_device_openwf */
#ifndef EGL_EXT_image_dma_buf_import
#define EGL_EXT_image_dma_buf_import 1
#define EGL_LINUX_DMA_BUF_EXT 0x3270
#define EGL_LINUX_DRM_FOURCC_EXT 0x3271
#define EGL_DMA_BUF_PLANE0_FD_EXT 0x3272
#define EGL_DMA_BUF_PLANE0_OFFSET_EXT 0x3273
#define EGL_DMA_BUF_PLANE0_PITCH_EXT 0x3274
#define EGL_DMA_BUF_PLANE1_FD_EXT 0x3275
#define EGL_DMA_BUF_PLANE1_OFFSET_EXT 0x3276
#define EGL_DMA_BUF_PLANE1_PITCH_EXT 0x3277
#define EGL_DMA_BUF_PLANE2_FD_EXT 0x3278
#define EGL_DMA_BUF_PLANE2_OFFSET_EXT 0x3279
#define EGL_DMA_BUF_PLANE2_PITCH_EXT 0x327A
#define EGL_YUV_COLOR_SPACE_HINT_EXT 0x327B
#define EGL_SAMPLE_RANGE_HINT_EXT 0x327C
#define EGL_YUV_CHROMA_HORIZONTAL_SITING_HINT_EXT 0x327D
#define EGL_YUV_CHROMA_VERTICAL_SITING_HINT_EXT 0x327E
#define EGL_ITU_REC601_EXT 0x327F
#define EGL_ITU_REC709_EXT 0x3280
#define EGL_ITU_REC2020_EXT 0x3281
#define EGL_YUV_FULL_RANGE_EXT 0x3282
#define EGL_YUV_NARROW_RANGE_EXT 0x3283
#define EGL_YUV_CHROMA_SITING_0_EXT 0x3284
#define EGL_YUV_CHROMA_SITING_0_5_EXT 0x3285
#endif /* EGL_EXT_image_dma_buf_import */
#ifndef EGL_EXT_multiview_window
#define EGL_EXT_multiview_window 1
#define EGL_MULTIVIEW_VIEW_COUNT_EXT 0x3134
#endif /* EGL_EXT_multiview_window */
#ifndef EGL_EXT_output_base
#define EGL_EXT_output_base 1
typedef void *EGLOutputLayerEXT;
typedef void *EGLOutputPortEXT;
#define EGL_NO_OUTPUT_LAYER_EXT ((EGLOutputLayerEXT)0)
#define EGL_NO_OUTPUT_PORT_EXT ((EGLOutputPortEXT)0)
#define EGL_BAD_OUTPUT_LAYER_EXT 0x322D
#define EGL_BAD_OUTPUT_PORT_EXT 0x322E
#define EGL_SWAP_INTERVAL_EXT 0x322F
typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETOUTPUTLAYERSEXTPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputLayerEXT *layers, EGLint max_layers, EGLint *num_layers);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETOUTPUTPORTSEXTPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputPortEXT *ports, EGLint max_ports, EGLint *num_ports);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLOUTPUTLAYERATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib value);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib *value);
typedef const char *(EGLAPIENTRYP PFNEGLQUERYOUTPUTLAYERSTRINGEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint name);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLOUTPUTPORTATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib value);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYOUTPUTPORTATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib *value);
typedef const char *(EGLAPIENTRYP PFNEGLQUERYOUTPUTPORTSTRINGEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint name);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglGetOutputLayersEXT (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputLayerEXT *layers, EGLint max_layers, EGLint *num_layers);
EGLAPI EGLBoolean EGLAPIENTRY eglGetOutputPortsEXT (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputPortEXT *ports, EGLint max_ports, EGLint *num_ports);
EGLAPI EGLBoolean EGLAPIENTRY eglOutputLayerAttribEXT (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib value);
EGLAPI EGLBoolean EGLAPIENTRY eglQueryOutputLayerAttribEXT (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib *value);
EGLAPI const char *EGLAPIENTRY eglQueryOutputLayerStringEXT (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint name);
EGLAPI EGLBoolean EGLAPIENTRY eglOutputPortAttribEXT (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib value);
EGLAPI EGLBoolean EGLAPIENTRY eglQueryOutputPortAttribEXT (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib *value);
EGLAPI const char *EGLAPIENTRY eglQueryOutputPortStringEXT (EGLDisplay dpy, EGLOutputPortEXT port, EGLint name);
#endif
#endif /* EGL_EXT_output_base */
#ifndef EGL_EXT_output_drm
#define EGL_EXT_output_drm 1
#define EGL_DRM_CRTC_EXT 0x3234
#define EGL_DRM_PLANE_EXT 0x3235
#define EGL_DRM_CONNECTOR_EXT 0x3236
#endif /* EGL_EXT_output_drm */
#ifndef EGL_EXT_output_openwf
#define EGL_EXT_output_openwf 1
#define EGL_OPENWF_PIPELINE_ID_EXT 0x3238
#define EGL_OPENWF_PORT_ID_EXT 0x3239
#endif /* EGL_EXT_output_openwf */
#ifndef EGL_EXT_platform_base
#define EGL_EXT_platform_base 1
typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC) (EGLenum platform, void *native_display, const EGLint *attrib_list);
typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list);
typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC) (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplayEXT (EGLenum platform, void *native_display, const EGLint *attrib_list);
EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformWindowSurfaceEXT (EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list);
EGLAPI EGLSurface EGLAPIENTRY eglCreatePlatformPixmapSurfaceEXT (EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list);
#endif
#endif /* EGL_EXT_platform_base */
#ifndef EGL_EXT_platform_device
#define EGL_EXT_platform_device 1
#define EGL_PLATFORM_DEVICE_EXT 0x313F
#endif /* EGL_EXT_platform_device */
#ifndef EGL_EXT_platform_wayland
#define EGL_EXT_platform_wayland 1
#define EGL_PLATFORM_WAYLAND_EXT 0x31D8
#endif /* EGL_EXT_platform_wayland */
#ifndef EGL_EXT_platform_x11
#define EGL_EXT_platform_x11 1
#define EGL_PLATFORM_X11_EXT 0x31D5
#define EGL_PLATFORM_X11_SCREEN_EXT 0x31D6
#endif /* EGL_EXT_platform_x11 */
#ifndef EGL_EXT_protected_surface
#define EGL_EXT_protected_surface 1
#define EGL_PROTECTED_CONTENT_EXT 0x32C0
#endif /* EGL_EXT_protected_surface */
#ifndef EGL_EXT_stream_consumer_egloutput
#define EGL_EXT_stream_consumer_egloutput 1
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMEROUTPUTEXTPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLOutputLayerEXT layer);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerOutputEXT (EGLDisplay dpy, EGLStreamKHR stream, EGLOutputLayerEXT layer);
#endif
#endif /* EGL_EXT_stream_consumer_egloutput */
#ifndef EGL_EXT_swap_buffers_with_damage
#define EGL_EXT_swap_buffers_with_damage 1
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC) (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithDamageEXT (EGLDisplay dpy, EGLSurface surface, EGLint *rects, EGLint n_rects);
#endif
#endif /* EGL_EXT_swap_buffers_with_damage */
#ifndef EGL_HI_clientpixmap
#define EGL_HI_clientpixmap 1
struct EGLClientPixmapHI {
void *pData;
EGLint iWidth;
EGLint iHeight;
EGLint iStride;
};
#define EGL_CLIENT_PIXMAP_POINTER_HI 0x8F74
typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPIXMAPSURFACEHIPROC) (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI *pixmap);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurfaceHI (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI *pixmap);
#endif
#endif /* EGL_HI_clientpixmap */
#ifndef EGL_HI_colorformats
#define EGL_HI_colorformats 1
#define EGL_COLOR_FORMAT_HI 0x8F70
#define EGL_COLOR_RGB_HI 0x8F71
#define EGL_COLOR_RGBA_HI 0x8F72
#define EGL_COLOR_ARGB_HI 0x8F73
#endif /* EGL_HI_colorformats */
#ifndef EGL_IMG_context_priority
#define EGL_IMG_context_priority 1
#define EGL_CONTEXT_PRIORITY_LEVEL_IMG 0x3100
#define EGL_CONTEXT_PRIORITY_HIGH_IMG 0x3101
#define EGL_CONTEXT_PRIORITY_MEDIUM_IMG 0x3102
#define EGL_CONTEXT_PRIORITY_LOW_IMG 0x3103
#endif /* EGL_IMG_context_priority */
#ifndef EGL_MESA_drm_image
#define EGL_MESA_drm_image 1
#define EGL_DRM_BUFFER_FORMAT_MESA 0x31D0
#define EGL_DRM_BUFFER_USE_MESA 0x31D1
#define EGL_DRM_BUFFER_FORMAT_ARGB32_MESA 0x31D2
#define EGL_DRM_BUFFER_MESA 0x31D3
#define EGL_DRM_BUFFER_STRIDE_MESA 0x31D4
#define EGL_DRM_BUFFER_USE_SCANOUT_MESA 0x00000001
#define EGL_DRM_BUFFER_USE_SHARE_MESA 0x00000002
typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEDRMIMAGEMESAPROC) (EGLDisplay dpy, const EGLint *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDRMIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLImageKHR EGLAPIENTRY eglCreateDRMImageMESA (EGLDisplay dpy, const EGLint *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglExportDRMImageMESA (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride);
#endif
#endif /* EGL_MESA_drm_image */
#ifndef EGL_MESA_platform_gbm
#define EGL_MESA_platform_gbm 1
#define EGL_PLATFORM_GBM_MESA 0x31D7
#endif /* EGL_MESA_platform_gbm */
#ifndef EGL_NOK_swap_region
#define EGL_NOK_swap_region 1
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOKPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegionNOK (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects);
#endif
#endif /* EGL_NOK_swap_region */
#ifndef EGL_NOK_swap_region2
#define EGL_NOK_swap_region2 1
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGION2NOKPROC) (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersRegion2NOK (EGLDisplay dpy, EGLSurface surface, EGLint numRects, const EGLint *rects);
#endif
#endif /* EGL_NOK_swap_region2 */
#ifndef EGL_NOK_texture_from_pixmap
#define EGL_NOK_texture_from_pixmap 1
#define EGL_Y_INVERTED_NOK 0x307F
#endif /* EGL_NOK_texture_from_pixmap */
#ifndef EGL_NV_3dvision_surface
#define EGL_NV_3dvision_surface 1
#define EGL_AUTO_STEREO_NV 0x3136
#endif /* EGL_NV_3dvision_surface */
#ifndef EGL_NV_coverage_sample
#define EGL_NV_coverage_sample 1
#define EGL_COVERAGE_BUFFERS_NV 0x30E0
#define EGL_COVERAGE_SAMPLES_NV 0x30E1
#endif /* EGL_NV_coverage_sample */
#ifndef EGL_NV_coverage_sample_resolve
#define EGL_NV_coverage_sample_resolve 1
#define EGL_COVERAGE_SAMPLE_RESOLVE_NV 0x3131
#define EGL_COVERAGE_SAMPLE_RESOLVE_DEFAULT_NV 0x3132
#define EGL_COVERAGE_SAMPLE_RESOLVE_NONE_NV 0x3133
#endif /* EGL_NV_coverage_sample_resolve */
#ifndef EGL_NV_cuda_event
#define EGL_NV_cuda_event 1
#define EGL_CUDA_EVENT_HANDLE_NV 0x323B
#define EGL_SYNC_CUDA_EVENT_NV 0x323C
#define EGL_SYNC_CUDA_EVENT_COMPLETE_NV 0x323D
#endif /* EGL_NV_cuda_event */
#ifndef EGL_NV_depth_nonlinear
#define EGL_NV_depth_nonlinear 1
#define EGL_DEPTH_ENCODING_NV 0x30E2
#define EGL_DEPTH_ENCODING_NONE_NV 0
#define EGL_DEPTH_ENCODING_NONLINEAR_NV 0x30E3
#endif /* EGL_NV_depth_nonlinear */
#ifndef EGL_NV_device_cuda
#define EGL_NV_device_cuda 1
#define EGL_CUDA_DEVICE_NV 0x323A
#endif /* EGL_NV_device_cuda */
#ifndef EGL_NV_native_query
#define EGL_NV_native_query 1
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEDISPLAYNVPROC) (EGLDisplay dpy, EGLNativeDisplayType *display_id);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEWINDOWNVPROC) (EGLDisplay dpy, EGLSurface surf, EGLNativeWindowType *window);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYNATIVEPIXMAPNVPROC) (EGLDisplay dpy, EGLSurface surf, EGLNativePixmapType *pixmap);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativeDisplayNV (EGLDisplay dpy, EGLNativeDisplayType *display_id);
EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativeWindowNV (EGLDisplay dpy, EGLSurface surf, EGLNativeWindowType *window);
EGLAPI EGLBoolean EGLAPIENTRY eglQueryNativePixmapNV (EGLDisplay dpy, EGLSurface surf, EGLNativePixmapType *pixmap);
#endif
#endif /* EGL_NV_native_query */
#ifndef EGL_NV_post_convert_rounding
#define EGL_NV_post_convert_rounding 1
#endif /* EGL_NV_post_convert_rounding */
#ifndef EGL_NV_post_sub_buffer
#define EGL_NV_post_sub_buffer 1
#define EGL_POST_SUB_BUFFER_SUPPORTED_NV 0x30BE
typedef EGLBoolean (EGLAPIENTRYP PFNEGLPOSTSUBBUFFERNVPROC) (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglPostSubBufferNV (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height);
#endif
#endif /* EGL_NV_post_sub_buffer */
#ifndef EGL_NV_stream_sync
#define EGL_NV_stream_sync 1
#define EGL_SYNC_NEW_FRAME_NV 0x321F
typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESTREAMSYNCNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum type, const EGLint *attrib_list);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateStreamSyncNV (EGLDisplay dpy, EGLStreamKHR stream, EGLenum type, const EGLint *attrib_list);
#endif
#endif /* EGL_NV_stream_sync */
#ifndef EGL_NV_sync
#define EGL_NV_sync 1
typedef void *EGLSyncNV;
typedef khronos_utime_nanoseconds_t EGLTimeNV;
#ifdef KHRONOS_SUPPORT_INT64
#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_NV 0x30E6
#define EGL_SYNC_STATUS_NV 0x30E7
#define EGL_SIGNALED_NV 0x30E8
#define EGL_UNSIGNALED_NV 0x30E9
#define EGL_SYNC_FLUSH_COMMANDS_BIT_NV 0x0001
#define EGL_FOREVER_NV 0xFFFFFFFFFFFFFFFFull
#define EGL_ALREADY_SIGNALED_NV 0x30EA
#define EGL_TIMEOUT_EXPIRED_NV 0x30EB
#define EGL_CONDITION_SATISFIED_NV 0x30EC
#define EGL_SYNC_TYPE_NV 0x30ED
#define EGL_SYNC_CONDITION_NV 0x30EE
#define EGL_SYNC_FENCE_NV 0x30EF
#define EGL_NO_SYNC_NV ((EGLSyncNV)0)
typedef EGLSyncNV (EGLAPIENTRYP PFNEGLCREATEFENCESYNCNVPROC) (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCNVPROC) (EGLSyncNV sync);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLFENCENVPROC) (EGLSyncNV sync);
typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCNVPROC) (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCNVPROC) (EGLSyncNV sync, EGLenum mode);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBNVPROC) (EGLSyncNV sync, EGLint attribute, EGLint *value);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLSyncNV EGLAPIENTRY eglCreateFenceSyncNV (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncNV (EGLSyncNV sync);
EGLAPI EGLBoolean EGLAPIENTRY eglFenceNV (EGLSyncNV sync);
EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncNV (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncNV (EGLSyncNV sync, EGLenum mode);
EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribNV (EGLSyncNV sync, EGLint attribute, EGLint *value);
#endif
#endif /* KHRONOS_SUPPORT_INT64 */
#endif /* EGL_NV_sync */
#ifndef EGL_NV_system_time
#define EGL_NV_system_time 1
typedef khronos_utime_nanoseconds_t EGLuint64NV;
#ifdef KHRONOS_SUPPORT_INT64
typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC) (void);
typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMENVPROC) (void);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeFrequencyNV (void);
EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV (void);
#endif
#endif /* KHRONOS_SUPPORT_INT64 */
#endif /* EGL_NV_system_time */
#ifndef EGL_TIZEN_image_native_buffer
#define EGL_TIZEN_image_native_buffer 1
#define EGL_NATIVE_BUFFER_TIZEN 0x32A0
#endif /* EGL_TIZEN_image_native_buffer */
#ifndef EGL_TIZEN_image_native_surface
#define EGL_TIZEN_image_native_surface 1
#define EGL_NATIVE_SURFACE_TIZEN 0x32A1
#endif /* EGL_TIZEN_image_native_surface */
#ifdef __cplusplus
}
#endif
#endif

View 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 */

View 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 */

View 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_ */

View 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

View 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

View 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;
}

View 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;
}

View file

@ -0,0 +1,307 @@
/*
** 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();
*/
}
}
//===========================================================================
//
// 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);
}
else
{
//glBindBufferRange(mUseType, mBindingPoint, mBufferId, start, length);
}
}
void GLDataBuffer::BindBase()
{
//glBindBufferBase(mUseType, mBindingPoint, mBufferId);
}
GLVertexBuffer::GLVertexBuffer() : GLBuffer(GL_ARRAY_BUFFER) {}
GLIndexBuffer::GLIndexBuffer() : GLBuffer(GL_ELEMENT_ARRAY_BUFFER) {}
GLDataBuffer::GLDataBuffer(int bindingpoint, bool is_ssbo) : GLBuffer(0), mBindingPoint(bindingpoint) {}
}

View file

@ -0,0 +1,78 @@
#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;
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;
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();
};
}

View file

@ -0,0 +1,494 @@
/*
** 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();
FPSLimit();
SwapBuffers();
mVertexData->NextPipelineBuffer();
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;
}
}

View 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

View file

@ -0,0 +1,299 @@
/*
** 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;
/*
if (forcenocompression)
{
texformat = GL_RGBA8;
}
*/
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
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;
}
//===========================================================================
//
// Destroys the texture
//
//===========================================================================
FHardwareTexture::~FHardwareTexture()
{
if (glTexID != 0) glDeleteTextures(1, &glTexID);
}
//===========================================================================
//
// 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;
}
}

View file

@ -0,0 +1,79 @@
#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
int glTextureBytes;
bool mipmapped = false;
int GetDepthBuffer(int w, int h);
public:
FHardwareTexture(int numchannels = 4, bool disablefilter = false)
{
forcenofilter = disablefilter;
glTextureBytes = numchannels;
}
~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) {} // Not used
uint8_t* MapBuffer() { return 0; } // Not used
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; }
};
}

View file

@ -0,0 +1,225 @@
/*
** 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 (int 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;
}
}
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);
}
}

View 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, &currentProgram);
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);
}
}

View 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

View 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

View 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;
};
}

View 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);
}
}

View 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

View file

@ -0,0 +1,727 @@
//
//---------------------------------------------------------------------------
//
// 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 "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 };
// Need to calc light data now in order to select correct shader
float* lightPtr = NULL;
int modLights = 0;
int subLights = 0;
int addLights = 0;
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 > gles.maxlights)
modLights = gles.maxlights;
if (modLights + subLights > gles.maxlights)
subLights = gles.maxlights - modLights;
if (modLights + subLights + addLights > gles.maxlights)
addLights = gles.maxlights - modLights - subLights;
// Skip passed the first 4 floats so the upload below only contains light data
lightPtr += 4;
}
ShaderFlavourData flavour;
flavour.textureMode = (mTextureMode == TM_NORMAL && mTempTM == TM_OPAQUE ? TM_OPAQUE : mTextureMode);
if (flavour.textureMode == -1)
flavour.textureMode = 0;
flavour.texFlags = mTextureModeFlags; if (!mBrightmapEnabled) flavour.texFlags &= ~(TEXF_Brightmap | TEXF_Glowmap);
flavour.texFlags >>= 16; //Move flags to start of word
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)
{
//matrixToGL(mHwUniforms->mProjectionMatrix, activeShader->cur->ProjectionMatrix_index);
activeShader->cur->muProjectionMatrix.Set(&mHwUniforms->mProjectionMatrix);
activeShader->cur->muViewMatrix.Set(&mHwUniforms->mViewMatrix);
activeShader->cur->muNormalViewMatrix.Set(&mHwUniforms->mNormalViewMatrix);
//matrixToGL(mHwUniforms->mViewMatrix, activeShader->cur->ViewMatrix_index);
//matrixToGL(mHwUniforms->mNormalViewMatrix, activeShader->cur->NormalViewMatrix_index);
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);
int f = mTextureModeFlags;
if (!mBrightmapEnabled) f &= ~(TEXF_Brightmap | TEXF_Glowmap);
//activeShader->cur->muTextureMode.Set((mTextureMode == TM_NORMAL && mTempTM == TM_OPAQUE ? TM_OPAQUE : mTextureMode) | f);
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)
{
int totalLights = modLights + subLights + addLights;
// Calculate the total number of vec4s we need
int totalVectors = totalLights * LIGHT_VEC4_NUM;
// TODO!!! If there are too many lights we need to remove some of the lights and modify the data
// At the moment the shader will just try to read off the end of the array...
if (totalVectors > 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));
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 (!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));
}
}

View 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

View file

@ -0,0 +1,178 @@
/*
** 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:
case CLAMP_NOFILTER_X:
case CLAMP_NOFILTER_Y:
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]);
}
*/
}
}

View 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

View file

@ -0,0 +1,952 @@
//
//---------------------------------------------------------------------------
//
// 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()
{
/*
glDeleteProgram(hShader);
if (hVertProg != 0)
glDeleteShader(hVertProg);
if (hFragProg != 0)
glDeleteShader(hFragProg);
*/
}
//==========================================================================
//
//
//
//==========================================================================
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
// Printf("Shader: %s, %08x %s", mFragProg2.GetChars(), tag, variantConfig.GetChars());
Load(mName.GetChars(), mVertProg, mFragProg, mFragProg2, mLightProg, mDefinesBase + variantConfig);
if (variants.insert(std::make_pair(tag, cur)).second == false)
{
Printf("ERROR INSERTING");
}
}
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
}
}

View file

@ -0,0 +1,484 @@
//
//---------------------------------------------------------------------------
//
// 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
};
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
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

View 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 (int 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();
}
}

View 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;
};
}

View file

@ -0,0 +1,188 @@
#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);
}
}
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);
}
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("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");
#else
gles.depthStencilAvailable = true;
gles.npotAvailable = true;
gles.useMappedBuffers = true;
#endif
gles.numlightvectors = (gles.maxlights * LIGHT_VEC4_NUM);
}
}

View file

@ -0,0 +1,91 @@
#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
#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;
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

View file

@ -5,6 +5,14 @@
class FRenderState;
#ifdef __ANDROID__
#define HW_MAX_PIPELINE_BUFFERS 8
#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

View file

@ -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;
}

View file

@ -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

View file

@ -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;

View file

@ -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)

View file

@ -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);

View file

@ -226,6 +226,10 @@ protected:
float mAlphaThreshold;
float mClipSplit[2];
int mColorMapSpecial;
float mColorMapFlash;
StreamData mStreamData = {};
PalEntry mFogColor;
@ -278,6 +282,9 @@ public:
mBias.Reset();
mPassType = NORMAL_PASS;
mColorMapSpecial = 0;
mColorMapFlash = 1;
mVertexBuffer = nullptr;
mVertexOffsets[0] = mVertexOffsets[1] = 0;
mIndexBuffer = nullptr;
@ -342,7 +349,7 @@ public:
mTextureMode = mode;
}
void SetTextureMode(FRenderStyle style)
void SetTextureMode(FRenderStyle style, bool clampy = false)
{
if (style.Flags & STYLEF_RedIsAlpha)
{
@ -356,6 +363,7 @@ public:
{
SetTextureMode(TM_INVERSE);
}
if (clampy) mTextureMode |= TM_CLAMPY;
}
int GetTextureMode()
@ -676,6 +684,12 @@ public:
return mPassType;
}
void SetSpecialColormap(int cm, float flash)
{
mColorMapSpecial = cm;
mColorMapFlash = flash;
}
// API-dependent render interface
// Draw commands

View file

@ -33,13 +33,19 @@
static const int INITIAL_BUFFER_SIZE = 100; // 100 viewpoints per frame should nearly always be enough
HWViewpointBuffer::HWViewpointBuffer()
HWViewpointBuffer::HWViewpointBuffer(int pipelineNbr):
mPipelineNbr(pipelineNbr)
{
mBufferSize = INITIAL_BUFFER_SIZE;
mBlockAlign = ((sizeof(HWViewpointUniforms) / screen->uniformblockalignment) + 1) * screen->uniformblockalignment;
mByteSize = mBufferSize * mBlockAlign;
mBuffer = screen->CreateDataBuffer(VIEWPOINT_BINDINGPOINT, false, true);
mBuffer->SetData(mByteSize, nullptr, false);
for (int n = 0; n < mPipelineNbr; n++)
{
mBufferPipeline[n] = screen->CreateDataBuffer(VIEWPOINT_BINDINGPOINT, false, true);
mBufferPipeline[n]->SetData(mByteSize, nullptr, false);
}
Clear();
mLastMappedIndex = UINT_MAX;
mClipPlaneInfo.Push(0);
@ -57,7 +63,10 @@ void HWViewpointBuffer::CheckSize()
{
mBufferSize *= 2;
mByteSize *= 2;
mBuffer->Resize(mByteSize);
for (int n = 0; n < mPipelineNbr; n++)
{
mBufferPipeline[n]->Resize(mByteSize);
}
m2DHeight = m2DWidth = -1;
}
}
@ -89,9 +98,14 @@ void HWViewpointBuffer::Set2D(FRenderState &di, int width, int height, int pll)
matrices.mProjectionMatrix.ortho(0, (float)width, (float)height, 0, -1.0f, 1.0f);
matrices.CalcDependencies();
mBuffer->Map();
memcpy(mBuffer->Memory(), &matrices, sizeof(matrices));
mBuffer->Unmap();
for (int n = 0; n < mPipelineNbr; n++)
{
mBufferPipeline[n]->Map();
memcpy(mBufferPipeline[n]->Memory(), &matrices, sizeof(matrices));
mBufferPipeline[n]->Unmap();
}
m2DWidth = width;
m2DHeight = height;
mLastMappedIndex = -1;
@ -115,5 +129,10 @@ void HWViewpointBuffer::Clear()
// Index 0 is reserved for the 2D projection.
mUploadIndex = 1;
mClipPlaneInfo.Resize(1);
mPipelinePos++;
mPipelinePos %= mPipelineNbr;
mBuffer = mBufferPipeline[mPipelinePos];
}

View file

@ -8,6 +8,9 @@ class FRenderState;
class HWViewpointBuffer
{
IDataBuffer *mBuffer;
IDataBuffer* mBufferPipeline[HW_MAX_PIPELINE_BUFFERS];
int mPipelineNbr;
int mPipelinePos = 0;
unsigned int mBufferSize;
unsigned int mBlockAlign;
@ -24,7 +27,7 @@ class HWViewpointBuffer
public:
HWViewpointBuffer();
HWViewpointBuffer(int pipelineNbr = 1);
~HWViewpointBuffer();
void Clear();
int Bind(FRenderState &di, unsigned int index);

View file

@ -72,6 +72,13 @@ CVAR(Int, win_w, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
CVAR(Int, win_h, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
CVAR(Bool, win_maximized, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
// 0 means 'no pipelining' for non GLES2 and 4 elements for GLES2
CUSTOM_CVAR(Int, gl_pipeline_depth, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
{
if (self < 0 || self >= HW_MAX_PIPELINE_BUFFERS) self = 0;
Printf("Changing the pipeline depth requires a restart for " GAMENAME ".\n");
}
CUSTOM_CVAR(Int, vid_maxfps, 200, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
{
if (self < GameTicRate && self != 0)
@ -92,6 +99,11 @@ CUSTOM_CVAR(Int, vid_preferbackend, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_N
switch(self)
{
#ifdef HAVE_GLES2
case 3:
Printf("Selecting OpenGLES 2.0 backend...\n");
break;
#endif
case 2:
Printf("Selecting SoftPoly backend...\n");
break;

View file

@ -43,6 +43,7 @@
#include "v_2ddrawer.h"
#include "intrect.h"
#include "hw_shadowmap.h"
#include "buffers.h"
struct FPortalSceneState;
@ -148,6 +149,9 @@ public:
IntRect mOutputLetterbox;
float mSceneClearColor[4]{ 0,0,0,255 };
int mPipelineNbr = 1; // Number of HW buffers to pipeline
int mPipelineType = 0;
public:
DFrameBuffer (int width=1, int height=1);
virtual ~DFrameBuffer();
@ -158,6 +162,14 @@ public:
{
mShadowMap.SetAABBTree(tree);
}
bool allowSSBO()
{
#ifndef HW_BLOCK_SSBO
return true;
#else
return mPipelineType == 0;
#endif
}
virtual DCanvas* GetCanvas() { return nullptr; }

View file

@ -209,15 +209,21 @@ void VulkanFrameBuffer::Update()
Super::Update();
}
void VulkanFrameBuffer::DeleteFrameObjects()
void VulkanFrameBuffer::DeleteFrameObjects(bool uploadOnly)
{
FrameDeleteList.Images.clear();
FrameDeleteList.ImageViews.clear();
FrameDeleteList.Framebuffers.clear();
FrameDeleteList.Buffers.clear();
FrameDeleteList.Descriptors.clear();
FrameDeleteList.DescriptorPools.clear();
FrameDeleteList.CommandBuffers.clear();
FrameTextureUpload.Buffers.clear();
FrameTextureUpload.TotalSize = 0;
if (!uploadOnly)
{
FrameDeleteList.Images.clear();
FrameDeleteList.ImageViews.clear();
FrameDeleteList.Framebuffers.clear();
FrameDeleteList.Buffers.clear();
FrameDeleteList.Descriptors.clear();
FrameDeleteList.DescriptorPools.clear();
FrameDeleteList.CommandBuffers.clear();
}
}
void VulkanFrameBuffer::FlushCommands(VulkanCommandBuffer **commands, size_t count, bool finish, bool lastsubmit)
@ -251,11 +257,12 @@ void VulkanFrameBuffer::FlushCommands(VulkanCommandBuffer **commands, size_t cou
mNextSubmit++;
}
void VulkanFrameBuffer::FlushCommands(bool finish, bool lastsubmit)
void VulkanFrameBuffer::FlushCommands(bool finish, bool lastsubmit, bool uploadOnly)
{
mRenderState->EndRenderPass();
if (!uploadOnly)
mRenderState->EndRenderPass();
if (mDrawCommands || mTransferCommands)
if ((!uploadOnly && mDrawCommands) || mTransferCommands)
{
VulkanCommandBuffer *commands[2];
size_t count = 0;
@ -267,7 +274,7 @@ void VulkanFrameBuffer::FlushCommands(bool finish, bool lastsubmit)
FrameDeleteList.CommandBuffers.push_back(std::move(mTransferCommands));
}
if (mDrawCommands)
if (!uploadOnly && mDrawCommands)
{
mDrawCommands->end();
commands[count++] = mDrawCommands.get();
@ -280,7 +287,7 @@ void VulkanFrameBuffer::FlushCommands(bool finish, bool lastsubmit)
}
}
void VulkanFrameBuffer::WaitForCommands(bool finish)
void VulkanFrameBuffer::WaitForCommands(bool finish, bool uploadOnly)
{
if (finish)
{
@ -292,7 +299,7 @@ void VulkanFrameBuffer::WaitForCommands(bool finish)
mPostprocess->DrawPresentTexture(mOutputLetterbox, true, false);
}
FlushCommands(finish, true);
FlushCommands(finish, true, uploadOnly);
if (finish)
{
@ -310,7 +317,7 @@ void VulkanFrameBuffer::WaitForCommands(bool finish)
vkResetFences(device->device, numWaitFences, mSubmitWaitFences);
}
DeleteFrameObjects();
DeleteFrameObjects(uploadOnly);
mNextSubmit = 0;
if (finish)

View file

@ -37,7 +37,7 @@ public:
VkRenderBuffers *GetBuffers() { return mActiveRenderBuffers; }
FRenderState* RenderState() override;
void FlushCommands(bool finish, bool lastsubmit = false);
void FlushCommands(bool finish, bool lastsubmit = false, bool uploadOnly = false);
unsigned int GetLightBufferBlockSize() const;
@ -64,6 +64,12 @@ public:
std::vector<std::unique_ptr<VulkanCommandBuffer>> CommandBuffers;
} FrameDeleteList;
struct
{
std::vector<std::unique_ptr<VulkanBuffer>> Buffers;
size_t TotalSize = 0;
} FrameTextureUpload;
VulkanFrameBuffer(void *hMonitor, bool fullscreen, VulkanDevice *dev);
~VulkanFrameBuffer();
bool IsVulkan() override { return true; }
@ -103,7 +109,8 @@ public:
void Draw2D() override;
void WaitForCommands(bool finish) override;
void WaitForCommands(bool finish) override { WaitForCommands(finish, false); }
void WaitForCommands(bool finish, bool uploadOnly);
void PushGroup(const FString &name);
void PopGroup();
@ -116,7 +123,7 @@ private:
void PrintStartupLog();
void CreateFanToTrisIndexBuffer();
void CopyScreenToBuffer(int w, int h, uint8_t *data) override;
void DeleteFrameObjects();
void DeleteFrameObjects(bool uploadOnly = false);
void FlushCommands(VulkanCommandBuffer **commands, size_t count, bool finish, bool lastsubmit);
std::unique_ptr<VkShaderManager> mShaderManager;

View file

@ -203,9 +203,14 @@ void VkHardwareTexture::CreateTexture(int w, int h, int pixelsize, VkFormat form
region.imageExtent.height = h;
cmdbuffer->copyBufferToImage(stagingBuffer->buffer, mImage.Image->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
fb->FrameDeleteList.Buffers.push_back(std::move(stagingBuffer));
fb->FrameTextureUpload.Buffers.push_back(std::move(stagingBuffer));
if (mipmap) mImage.GenerateMipmaps(cmdbuffer);
// If we queued more than 64 MB of data already: wait until the uploads finish before continuing
fb->FrameTextureUpload.TotalSize += totalSize;
if (fb->FrameTextureUpload.TotalSize > 64 * 1024 * 1024)
fb->WaitForCommands(false, true);
}
int VkHardwareTexture::GetMipLevels(int w, int h)

View file

@ -29,6 +29,10 @@
#include "c_cvars.h"
#include "v_video.h"
CVAR(Bool, gl_customshader, true, 0);
static IHardwareTexture* (*layercallback)(int layer, int translation);
TArray<UserShaderDesc> usershaders;
@ -124,17 +128,20 @@ FMaterial::FMaterial(FGameTexture * tx, int scaleflags)
}
auto index = tx->GetShaderIndex();
if (index >= FIRST_USER_SHADER)
if (gl_customshader)
{
const UserShaderDesc &usershader = usershaders[index - FIRST_USER_SHADER];
if (usershader.shaderType == mShaderIndex) // Only apply user shader if it matches the expected material
if (index >= FIRST_USER_SHADER)
{
for (auto &texture : tx->CustomShaderTextures)
const UserShaderDesc& usershader = usershaders[index - FIRST_USER_SHADER];
if (usershader.shaderType == mShaderIndex) // Only apply user shader if it matches the expected material
{
if (texture == nullptr) continue;
mTextureLayers.Push({ texture.get(), 0 }); // scalability should be user-definable.
for (auto& texture : tx->CustomShaderTextures)
{
if (texture == nullptr) continue;
mTextureLayers.Push({ texture.get(), 0 }); // scalability should be user-definable.
}
mShaderIndex = index;
}
mShaderIndex = index;
}
}
}

View file

@ -161,10 +161,11 @@ const int Tex_Blend_Hardlight = 4;
vec4 getTexel(vec2 st)
{
vec4 texel = texture(tex, st);
//
// Apply texture modes
//
switch (uTextureMode & 0xffff)
switch (uTextureMode & 0xfff)
{
case 1: // TM_STENCIL
texel.rgb = vec3(1.0,1.0,1.0);
@ -185,13 +186,6 @@ vec4 getTexel(vec2 st)
break;
}
case 5: // TM_CLAMPY
if (st.t < 0.0 || st.t > 1.0)
{
texel.a = 0.0;
}
break;
case 6: // TM_OPAQUEINVERSE
texel = vec4(1.0-texel.r, 1.0-texel.b, 1.0-texel.g, 1.0);
break;
@ -200,10 +194,17 @@ vec4 getTexel(vec2 st)
return texel;
}
if ((uTextureMode & 0x1000) != 0) // TM_CLAMPY
{
if (st.t < 0.0 || st.t > 1.0)
{
texel.a = 0.0;
}
}
// Apply the texture modification colors.
int blendflags = int(uTextureAddColor.a); // this alpha is unused otherwise
if ((blendflags & 0x3fff) != 0) // keep the upper flags for other things.
if (blendflags != 0)
{
// only apply the texture manipulation if it contains something.
texel = ApplyTextureManipulation(texel, blendflags);
@ -567,7 +568,7 @@ void SetMaterialProps(inout Material material, vec2 texCoord)
// OpenGL doesn't care, but Vulkan pukes all over the place if these texture samplings are included in no-texture shaders, even though never called.
#ifndef NO_LAYERS
if ((uTextureMode & TEXF_Brightmap) != 0)
material.Bright = texture(brighttexture, texCoord.st);
material.Bright = desaturate(texture(brighttexture, texCoord.st));
if ((uTextureMode & TEXF_Detailmap) != 0)
{
@ -576,7 +577,7 @@ void SetMaterialProps(inout Material material, vec2 texCoord)
}
if ((uTextureMode & TEXF_Glowmap) != 0)
material.Glow = texture(glowtexture, texCoord.st);
material.Glow = desaturate(texture(glowtexture, texCoord.st));
#endif
}
@ -631,7 +632,7 @@ vec4 getLightColor(Material material, float fogdist, float fogfactor)
color = min(color, 1.0);
// these cannot be safely applied by the legacy format where the implementation cannot guarantee that the values are set.
#ifndef LEGACY_USER_SHADER
#if !defined LEGACY_USER_SHADER && !defined NO_LAYERS
//
// apply glow
//

View file

@ -80,13 +80,13 @@ void main()
#ifdef HAS_UNIFORM_VERTEX_DATA
if ((useVertexData & 2) == 0)
vWorldNormal = NormalModelMatrix * vec4(uVertexNormal.xyz, 1.0);
vWorldNormal = NormalModelMatrix * vec4(normalize(uVertexNormal.xyz), 1.0);
else
vWorldNormal = NormalModelMatrix * vec4(normalize(mix(aNormal.xyz, aNormal2.xyz, uInterpolationFactor)), 1.0);
#else
vWorldNormal = NormalModelMatrix * vec4(normalize(mix(aNormal.xyz, aNormal2.xyz, uInterpolationFactor)), 1.0);
#endif
vEyeNormal = NormalViewMatrix * vWorldNormal;
vEyeNormal = NormalViewMatrix * vec4(normalize(vWorldNormal.xyz), 1.0);
#endif
#ifdef SPHEREMAP

View file

@ -31,7 +31,7 @@ vec4 Dither(vec4 c)
vec4 sRGBtoLinear(vec4 c)
{
return vec4(mix(pow((c.rgb + 0.055) / 1.055, vec3(2.4)), c.rgb / 12.92, step(c.rgb, vec3(0.04045))), c.a);
return vec4(mix(c.rgb / 12.92, pow((c.rgb + 0.055) / 1.055, vec3(2.4)), step(c.rgb, vec3(0.04045))), c.a);
}
vec4 ApplyHdrMode(vec4 c)

View file

@ -31,7 +31,8 @@ class os_Menu : OptionMenu
addSearchField(text);
bool found = listOptions(mDesc, "MainMenu", query, "", isAnyTermMatches);
Dictionary searchedMenus = Dictionary.Create();
bool found = listOptions(mDesc, "MainMenu", query, "", isAnyTermMatches, searchedMenus);
if (!found) { addNoResultsItem(mDesc); }
@ -54,21 +55,29 @@ class os_Menu : OptionMenu
string menuName,
os_Query query,
string path,
bool isAnyTermMatches)
bool isAnyTermMatches,
Dictionary searchedMenus)
{
if (searchedMenus.At(menuName).length() > 0)
{
return false;
}
searchedMenus.Insert(menuName, "1");
let desc = MenuDescriptor.GetDescriptor(menuName);
let listMenuDesc = ListMenuDescriptor(desc);
if (listMenuDesc)
{
return listOptionsListMenu(listMenuDesc, targetDesc, query, path, isAnyTermMatches);
return listOptionsListMenu(listMenuDesc, targetDesc, query, path, isAnyTermMatches, searchedMenus);
}
let optionMenuDesc = OptionMenuDescriptor(desc);
if (optionMenuDesc)
{
return listOptionsOptionMenu(optionMenuDesc, targetDesc, query, path, isAnyTermMatches);
return listOptionsOptionMenu(optionMenuDesc, targetDesc, query, path, isAnyTermMatches, searchedMenus);
}
return false;
@ -78,7 +87,8 @@ class os_Menu : OptionMenu
OptionMenuDescriptor targetDesc,
os_Query query,
string path,
bool isAnyTermMatches)
bool isAnyTermMatches,
Dictionary searchedMenus)
{
int nItems = sourceDesc.mItems.size();
bool found = false;
@ -92,7 +102,7 @@ class os_Menu : OptionMenu
? makePath(path, StringTable.Localize(textItem.mText))
: path;
found |= listOptions(targetDesc, actionN, query, newPath, isAnyTermMatches);
found |= listOptions(targetDesc, actionN, query, newPath, isAnyTermMatches, searchedMenus);
}
return found;
@ -102,7 +112,8 @@ class os_Menu : OptionMenu
OptionMenuDescriptor targetDesc,
os_Query query,
string path,
bool isAnyTermMatches)
bool isAnyTermMatches,
Dictionary searchedMenus)
{
if (sourceDesc == targetDesc) { return false; }
@ -152,7 +163,7 @@ class os_Menu : OptionMenu
{
string newPath = makePath(path, label);
found |= listOptions(targetDesc, item.GetAction(), query, newPath, isAnyTermMatches);
found |= listOptions(targetDesc, item.GetAction(), query, newPath, isAnyTermMatches, searchedMenus);
}
}

View file

@ -365,7 +365,7 @@ class TextEnterMenu : Menu
else if (ch == 8 || ch == 0)
{
// Draw the backspace and end "characters".
String str = ch == 8 ? "BS" : "ED";
String str = ch == 8 ? "←" : "↲";
screen.DrawText(displayFont, colr,
xx + cell_width/2 - displayFont.StringWidth(str)*CleanXfac_1/2,
yy + top_padding, str, DTA_CleanNoMove_1, true);