From 26f953e608c57414593e6c1168b8340751d41f91 Mon Sep 17 00:00:00 2001 From: fgsfds Date: Mon, 10 Feb 2020 21:52:57 +0300 Subject: [PATCH] properly check for FBO support; add OES_framebuffer_object to noGL --- src/engine/e_graphics.pas | 10 +--- src/game/sdl/g_system.pas | 16 +++--- src/game/sdl2/g_system.pas | 16 +++--- src/nogl/noGL.pas | 46 +++++++++++++++++ src/nogl/noGLES1.inc | 102 +++++++++++++++++++++++++++++++++++++ src/nogl/noGLSTUB.inc | 46 +++++++++++++++++ 6 files changed, 210 insertions(+), 26 deletions(-) diff --git a/src/engine/e_graphics.pas b/src/engine/e_graphics.pas index 236e069..744be79 100644 --- a/src/engine/e_graphics.pas +++ b/src/engine/e_graphics.pas @@ -199,13 +199,11 @@ var e_TextureFonts: array of TTextureFont = nil; e_CharFonts: array of TCharFont; //e_SavedTextures: array of TSavedTexture; -{$IF NOT DEFINED(HEADLESS) AND NOT DEFINED(USE_GLES1)} e_FBO: GLuint = 0; e_RBO: GLuint = 0; e_Frame: GLuint = 0; e_FrameW: Integer = -1; e_FrameH: Integer = -1; -{$ENDIF} //function e_getTextGLId (ID: DWORD): GLuint; begin result := e_Textures[ID].tx.id; end; @@ -383,7 +381,6 @@ end; procedure e_ResizeFramebuffer(Width, Height: Integer); begin -{$IF NOT DEFINED(HEADLESS) AND NOT DEFINED(USE_GLES1)} if e_NoGraphics then Exit; glBindTexture(GL_TEXTURE_2D, 0); @@ -421,12 +418,11 @@ begin glGenRenderbuffers(1, @e_RBO); glBindRenderbuffer(GL_RENDERBUFFER, e_RBO); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, Width, Height); + glRenderbufferStorage(GL_RENDERBUFFER, {$IFNDEF USE_GLES1}GL_DEPTH24_STENCIL8{$ELSE}GL_DEPTH_COMPONENT16{$ENDIF}, Width, Height); glBindFramebuffer(GL_FRAMEBUFFER, e_FBO); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, e_Frame, 0); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, e_RBO); -{$ENDIF} + glFramebufferRenderbuffer(GL_FRAMEBUFFER, {$IFNDEF USE_GLES1}GL_DEPTH_STENCIL_ATTACHMENT{$ELSE}GL_DEPTH_ATTACHMENT{$ENDIF}, GL_RENDERBUFFER, e_RBO); end; procedure e_ResizeWindow(Width, Height: Integer); @@ -459,7 +455,6 @@ end; procedure e_BlitFramebuffer(WinWidth, WinHeight: Integer); begin -{$IF NOT DEFINED(HEADLESS) AND NOT DEFINED(USE_GLES1)} if (e_FBO = 0) or (e_Frame = 0) or e_NoGraphics then exit; glDisable(GL_BLEND); glEnable(GL_TEXTURE_2D); @@ -472,7 +467,6 @@ begin glEnd(); glBindFramebuffer(GL_FRAMEBUFFER, e_FBO); e_SetViewPort(0, 0, e_FrameW, e_FrameH); -{$ENDIF} end; procedure e_Draw(ID: DWORD; X, Y: Integer; Alpha: Byte; AlphaChannel: Boolean; diff --git a/src/game/sdl/g_system.pas b/src/game/sdl/g_system.pas index e5f6275..bba2cae 100644 --- a/src/game/sdl/g_system.pas +++ b/src/game/sdl/g_system.pas @@ -126,17 +126,15 @@ implementation if screen <> nil then begin {$IFDEF NOGL_INIT} - nogl_Init; - glRenderToFBO := False; // TODO: check for GL_OES_framebuffer_object + nogl_Init; + if glRenderToFBO and (not nogl_ExtensionSupported('GL_OES_framebuffer_object')) then {$ELSE} - if glRenderToFBO then - if not Load_GL_ARB_framebuffer_object() then - if not Load_GL_EXT_framebuffer_object() then - begin - e_LogWriteln('SDL: no framebuffer support detected'); - glRenderToFBO := False - end; + if glRenderToFBO and (not Load_GL_ARB_framebuffer_object()) then {$ENDIF} + begin + e_LogWriteln('SDL: no framebuffer object support detected'); + glRenderToFBO := False + end; SDL_WM_SetCaption(GetTitle(), nil); gFullScreen := fullscreen; gRC_FullScreen := fullscreen; diff --git a/src/game/sdl2/g_system.pas b/src/game/sdl2/g_system.pas index 89cebaf..6fff48b 100644 --- a/src/game/sdl2/g_system.pas +++ b/src/game/sdl2/g_system.pas @@ -157,17 +157,15 @@ implementation if context <> nil then begin {$IFDEF NOGL_INIT} - nogl_Init; - glRenderToFBO := False; // TODO: check for GL_OES_framebuffer_object + nogl_Init; + if glRenderToFBO and (not nogl_ExtensionSupported('GL_OES_framebuffer_object')) then {$ELSE} - if glRenderToFBO then - if not Load_GL_ARB_framebuffer_object() then - if not Load_GL_EXT_framebuffer_object() then - begin - e_LogWriteln('SDL: no framebuffer support detected'); - glRenderToFBO := False - end; + if glRenderToFBO and (not Load_GL_ARB_framebuffer_object()) then {$ENDIF} + begin + e_LogWriteln('SDL: no framebuffer object support detected'); + glRenderToFBO := False + end; if (fullscreen = false) and (maximized = false) and (wc = false) then begin SDL_GetWindowPosition(window, @x, @y); diff --git a/src/nogl/noGL.pas b/src/nogl/noGL.pas index 7f7ab2e..68c74ad 100644 --- a/src/nogl/noGL.pas +++ b/src/nogl/noGL.pas @@ -86,6 +86,39 @@ interface GL_TEXTURE_ENV_MODE = $2200; GL_MODULATE = $2100; + GL_INVALID_FRAMEBUFFER_OPERATION = $0506; + GL_FRAMEBUFFER_DEFAULT = $8218; + GL_FRAMEBUFFER_UNDEFINED = $8219; + GL_DEPTH_STENCIL_ATTACHMENT = $821A; + GL_MAX_RENDERBUFFER_SIZE = $84E8; + GL_DEPTH_STENCIL = $84F9; + GL_DEPTH_COMPONENT16 = $81A5; + GL_DEPTH24_STENCIL8 = $88F0; + GL_FRAMEBUFFER_BINDING = $8CA6; + GL_DRAW_FRAMEBUFFER_BINDING = GL_FRAMEBUFFER_BINDING; + GL_RENDERBUFFER_BINDING = $8CA7; + GL_READ_FRAMEBUFFER = $8CA8; + GL_DRAW_FRAMEBUFFER = $8CA9; + GL_READ_FRAMEBUFFER_BINDING = $8CAA; + GL_RENDERBUFFER_SAMPLES = $8CAB; + GL_FRAMEBUFFER_COMPLETE = $8CD5; + GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT = $8CD6; + GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = $8CD7; + GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER = $8CDB; + GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER = $8CDC; + GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE = $8D56; + GL_FRAMEBUFFER_UNSUPPORTED = $8CDD; + GL_MAX_COLOR_ATTACHMENTS = $8CDF; + GL_COLOR_ATTACHMENT0 = $8CE0; + GL_DEPTH_ATTACHMENT = $8D00; + GL_STENCIL_ATTACHMENT = $8D20; + GL_FRAMEBUFFER = $8D40; + GL_RENDERBUFFER = $8D41; + GL_STENCIL_INDEX1 = $8D46; + GL_STENCIL_INDEX4 = $8D47; + GL_STENCIL_INDEX8 = $8D48; + GL_MAX_SAMPLES = $8D57; + GL_VENDOR = $1F00; GL_RENDERER = $1F01; GL_VERSION = $1F02; @@ -162,6 +195,18 @@ interface procedure glTexSubImage2D(target: GLenum; level, xoffset, yoffset: GLint; width, height: GLsizei; format, atype: GLenum; const pixels: Pointer); procedure glDeleteTextures(n: GLsizei; const textures: PGLuint); + procedure glGenFramebuffers(n: GLsizei; framebuffers: PGLuint); + procedure glBindFramebuffer(target: GLenum; framebuffer: GLuint); + procedure glFramebufferTexture2D(target, attachment, textarget: GLenum; texture: GLuint; level: GLint); + procedure glFramebufferRenderbuffer(target, attachment, rbotarget: GLenum; rbo: GLuint); + function glCheckFramebufferStatus(framebuffer: GLuint): GLenum; + procedure glDeleteFramebuffers(n: GLsizei; const framebuffers: PGLuint); + + procedure glGenRenderbuffers(n: GLsizei; renderbuffers: PGLuint); + procedure glBindRenderbuffer(target: GLenum; renderbuffer: GLuint); + procedure glRenderbufferStorage(target, internalformat: GLenum; w, h: GLsizei); + procedure glDeleteRenderbuffers(n: GLsizei; const renderbuffers: PGLuint); + // procedure glVertexPointer(size: GLint; atype: GLenum; stride: GLsizei; const pointer: Pointer); // procedure glEnableClientState(aarray: GLenum); // procedure glDisableClientState(aarray: GLenum); @@ -174,6 +219,7 @@ interface procedure nogl_Init; procedure nogl_Quit; + function nogl_ExtensionSupported(ext: string): Boolean; {$IFDEF USE_GLES1} {$I noGLES1.inc} diff --git a/src/nogl/noGLES1.inc b/src/nogl/noGLES1.inc index 1f4f67a..9aa8783 100644 --- a/src/nogl/noGLES1.inc +++ b/src/nogl/noGLES1.inc @@ -28,6 +28,9 @@ implementation var cmds: TCmds; + var + extList: string = ''; + var es_glVertexPointer: procedure (size: GLint; _type: GLenum; stride: GLsizei; pointer: PGLvoid); cdecl; es_glColorPointer: procedure (size: GLint; _type: GLenum; stride: GLsizei; pointer: PGLvoid); cdecl; @@ -80,6 +83,18 @@ implementation es_glTexSubImage2D: procedure (target: GLenum; level: GLint; xoffset, yoffset: GLint; width, height: GLsizei; format, _type: GLenum; pixels: PGLvoid); cdecl; es_glDeleteTextures: procedure (n: GLsizei; textures: PGLuint); cdecl; + es_glGenFramebuffers: procedure (n: GLsizei; framebuffers: PGLuint); cdecl; + es_glBindFramebuffer: procedure (target: GLenum; framebuffer: GLuint); cdecl; + es_glFramebufferTexture2D: procedure (target, attachment, textarget: GLenum; texture: GLuint; level: GLint); cdecl; + es_glFramebufferRenderbuffer: procedure (target, attachment, rbotarget: GLenum; rbo: GLuint); cdecl; + es_glCheckFramebufferStatus: function (framebuffer: GLuint): GLenum; cdecl; + es_glDeleteFramebuffers: procedure (n: GLsizei; const framebuffers: PGLuint); cdecl; + + es_glGenRenderbuffers: procedure (n: GLsizei; framebuffers: PGLuint); cdecl; + es_glBindRenderbuffer: procedure (target: GLenum; renderbuffer: GLuint); cdecl; + es_glRenderbufferStorage: procedure (target, internalformat: GLenum; w, h: GLsizei); cdecl; + es_glDeleteRenderbuffers: procedure (n: GLsizei; const renderbuffers: PGLuint); cdecl; + procedure glEnable(cap: GLenum); begin es_glEnable(cap); @@ -405,6 +420,62 @@ implementation + + procedure glGenFramebuffers(n: GLsizei; framebuffers: PGLuint); + begin + es_glGenFramebuffers(n, framebuffers); + end; + + procedure glBindFramebuffer(target: GLenum; framebuffer: GLuint); + begin + es_glBindFramebuffer(target, framebuffer); + end; + + procedure glFramebufferTexture2D(target, attachment, textarget: GLenum; texture: GLuint; level: GLint); + begin + es_glFramebufferTexture2D(target, attachment, textarget, texture, level); + end; + + procedure glFramebufferRenderbuffer(target, attachment, rbotarget: GLenum; rbo: GLuint); + begin + es_glFramebufferRenderbuffer(target, attachment, rbotarget, rbo); + end; + + function glCheckFramebufferStatus(framebuffer: GLuint): GLenum; + begin + result := es_glCheckFramebufferStatus(framebuffer); + end; + + procedure glDeleteFramebuffers(n: GLsizei; const framebuffers: PGLuint); + begin + es_glDeleteFramebuffers(n, framebuffers); + end; + + procedure glGenRenderbuffers(n: GLsizei; renderbuffers: PGLuint); + begin + es_glGenRenderbuffers(n, renderbuffers); + end; + + procedure glBindRenderbuffer(target: GLenum; renderbuffer: GLuint); + begin + es_glBindRenderbuffer(target, renderbuffer); + end; + + procedure glRenderbufferStorage(target, internalformat: GLenum; w, h: GLsizei); + begin + es_glRenderbufferStorage(target, internalformat, w, h); + end; + + procedure glDeleteRenderbuffers(n: GLsizei; const renderbuffers: PGLuint); + begin + es_glDeleteRenderbuffers(n, renderbuffers); + end; + + + + + + procedure nogl_Init; begin es_glVertexPointer := SDL_GL_GetProcAddress('glVertexPointer'); @@ -458,6 +529,18 @@ implementation es_glTexSubImage2D := SDL_GL_GetProcAddress('glTexSubImage2D'); es_glDeleteTextures := SDL_GL_GetProcAddress('glDeleteTextures'); + es_glGenFramebuffers := SDL_GL_GetProcAddress('glGenFramebuffersOES'); + es_glBindFramebuffer := SDL_GL_GetProcAddress('glBindFramebufferOES'); + es_glFramebufferTexture2D := SDL_GL_GetProcAddress('glFramebufferTexture2DOES');; + es_glFramebufferRenderbuffer := SDL_GL_GetProcAddress('glFramebufferRenderbufferOES'); + es_glCheckFramebufferStatus := SDL_GL_GetProcAddress('glCheckFramebufferStatusOES'); + es_glDeleteFramebuffers := SDL_GL_GetProcAddress('glDeleteFramebuffersOES'); + + es_glGenRenderbuffers := SDL_GL_GetProcAddress('glGenRenderbuffersOES'); + es_glBindRenderbuffer := SDL_GL_GetProcAddress('glBindRenderbufferOES'); + es_glRenderbufferStorage := SDL_GL_GetProcAddress('glRenderbufferStorageOES'); + es_glDeleteRenderbuffers := SDL_GL_GetProcAddress('glDeleteRenderbuffersOES'); + cmds.mode := GL_INVALID_ENUM end; @@ -513,6 +596,25 @@ implementation es_glTexImage2D := nil; es_glTexSubImage2D := nil; es_glDeleteTextures := nil; + + es_glGenFramebuffers := nil; + es_glBindFramebuffer := nil; + es_glFramebufferTexture2D := nil; + es_glFramebufferRenderbuffer := nil; + es_glCheckFramebufferStatus := nil; + es_glDeleteFramebuffers := nil; + + es_glGenRenderbuffers := nil; + es_glBindRenderbuffer := nil; + es_glRenderbufferStorage := nil; + es_glDeleteRenderbuffers := nil; + end; + + function nogl_ExtensionSupported(ext: string): Boolean; + begin + if (extList = '') and Assigned(es_glGetString) then + extList := glGetString(GL_EXTENSIONS); + result := pos(ext, extList) <> 0; end; initialization diff --git a/src/nogl/noGLSTUB.inc b/src/nogl/noGLSTUB.inc index dc01c71..e0150b6 100644 --- a/src/nogl/noGLSTUB.inc +++ b/src/nogl/noGLSTUB.inc @@ -182,6 +182,47 @@ implementation begin end; + procedure glGenFramebuffers(n: GLsizei; framebuffers: PGLuint); + begin + end; + + procedure glBindFramebuffer(target: GLenum; framebuffer: GLuint); + begin + end; + + procedure glFramebufferTexture2D(target, attachment, textarget: GLenum; texture: GLuint; level: GLint); + begin + end; + + procedure glFramebufferRenderbuffer(target, attachment, rbotarget: GLenum; rbo: GLuint); + begin + end; + + function glCheckFramebufferStatus(framebuffer: GLuint): GLenum; + begin + result := GL_FRAMEBUFFER_UNSUPPORTED + end; + + procedure glDeleteFramebuffers(n: GLsizei; const framebuffers: PGLuint); + begin + end; + + procedure glGenRenderbuffers(n: GLsizei; renderbuffers: PGLuint); + begin + end; + + procedure glBindRenderbuffer(target: GLenum; renderbuffer: GLuint); + begin + end; + + procedure glRenderbufferStorage(target, internalformat: GLenum; w, h: GLsizei); + begin + end; + + procedure glDeleteRenderbuffers(n: GLsizei; const renderbuffers: PGLuint); + begin + end; + procedure nogl_Init; begin end; @@ -190,4 +231,9 @@ implementation begin end; + function nogl_ExtensionSupported(ext: string): Boolean; + begin + result := false; + end; + initialization -- 2.29.2