Add support for externally provided GL3

This commit is contained in:
Emmanuel Boutin 2023-01-05 19:42:46 +01:00
parent 25e735048f
commit 681d137cd9
10 changed files with 229 additions and 26 deletions

View File

@ -38,7 +38,7 @@ if(NOT LIBRW_PLATFORM IN_LIST LIBRW_PLATFORMS)
message(FATAL_ERROR "Illegal LIBRW_PLATFORM=${LIBRW_PLATFORM}")
endif()
set(LIBRW_GL3_GFXLIBS "GLFW" "SDL2")
set(LIBRW_GL3_GFXLIBS "GLFW" "SDL2" "EXTGL3")
set(LIBRW_GL3_GFXLIB "GLFW" CACHE STRING "gfxlib for gl3")
set_property(CACHE LIBRW_GL3_GFXLIB PROPERTY STRINGS ${LIBRW_GL3_GFXLIBS})
if(LIBRW_PLATFORM_GL3)
@ -124,6 +124,8 @@ if(LIBRW_INSTALL)
elseif(LIBRW_PLATFORM_GL3)
if(LIBRW_GL3_GFXLIB STREQUAL "GLFW")
set(platform "-gl3-glfw")
elseif(LIBRW_GL3_GFXLIB STREQUAL "EXTGL3")
set(platform "-gl3-extgl3")
else()
set(platform "-gl3-sdl2")
endif()

View File

@ -13,7 +13,7 @@ class LibrwConan(ConanFile):
generators = "cmake", "cmake_find_package"
options = {
"platform": ["null", "gl3", "d3d9", "ps2"],
"gl3_gfxlib": ["glfw", "sdl2"],
"gl3_gfxlib": ["glfw", "sdl2", "extgl3"],
}
default_options = {
"platform": "gl3",
@ -124,7 +124,11 @@ class LibrwConan(ConanFile):
self.cpp_info.defines.append("RW_NULL")
elif self.options.platform == "gl3":
self.cpp_info.defines.append("RW_GL3")
if self.options.gl3_gfxlib == "sdl2":
if self.options.gl3_gfxlib == "glfw":
self.cpp_info.defines.append("LIBRW_GLFW")
elif self.options.gl3_gfxlib == "extgl3":
self.cpp_info.defines.append("LIBRW_EXTGL3")
elif self.options.gl3_gfxlib == "sdl2":
self.cpp_info.defines.append("LIBRW_SDL2")
elif self.options.platform == "d3d9":
self.cpp_info.defines.append("RW_D3D9")

View File

@ -6,6 +6,7 @@ newoption {
allowed = {
{ "glfw", "GLFW" },
{ "sdl2", "SDL2" },
{ "extgl3", "EXTGL3" },
},
}
@ -62,8 +63,12 @@ workspace "librw"
defines { "RW_NULL" }
filter { "platforms:*gl3" }
defines { "RW_GL3" }
if _OPTIONS["gfxlib"] == "sdl2" then
if _OPTIONS["gfxlib"] == "glfw" then
defines { "LIBRW_GLFW" }
elseif _OPTIONS["gfxlib"] == "sdl2" then
defines { "LIBRW_SDL2" }
elseif _OPTIONS["gfxlib"] == "extgl3" then
defines { "LIBRW_EXTGL3" }
end
filter { "platforms:*d3d9" }
defines { "RW_D3D9" }
@ -131,7 +136,7 @@ function findlibs()
links { "GL" }
if _OPTIONS["gfxlib"] == "glfw" then
links { "glfw" }
else
elseif _OPTIONS["gfxlib"] == "sdl2" then
links { "SDL2" }
end
filter { "platforms:win-amd64-gl3" }
@ -144,7 +149,7 @@ function findlibs()
links { "opengl32" }
if _OPTIONS["gfxlib"] == "glfw" then
links { "glfw3" }
else
elseif _OPTIONS["gfxlib"] == "sdl2" then
links { "SDL2" }
end
filter { "platforms:*d3d9" }

View File

@ -1,4 +1,4 @@
#ifndef LIBRW_SDL2
#ifdef LIBRW_GLFW
#include <rw.h>
#include "skeleton.h"

View File

@ -291,7 +291,7 @@ SetMousePosition(int x, int y)
#endif
#ifdef RW_OPENGL
#if defined(RW_OPENGL) && !defined(LIBRW_EXTGL3)
int main(int argc, char *argv[]);
int WINAPI

View File

@ -153,10 +153,13 @@ if(LIBRW_PLATFORM_GL3)
if (NOT TARGET glfw)
find_package(glfw3 REQUIRED)
endif()
target_compile_definitions(librw PUBLIC LIBRW_GLFW)
target_link_libraries(librw
PUBLIC
glfw
)
elseif (LIBRW_GL3_GFXLIB STREQUAL "EXTGL3")
target_compile_definitions(librw PUBLIC LIBRW_EXTGL3)
elseif (LIBRW_GL3_GFXLIB STREQUAL "SDL2")
if (NOT TARGET SDL2::SDL2)
find_package(SDL2 REQUIRED)

View File

@ -1244,10 +1244,13 @@ getFramebufferRect(Raster *frameBuffer)
Rect r;
Raster *fb = frameBuffer->parent;
if(fb->type == Raster::CAMERA){
#ifdef LIBRW_SDL2
#if defined(LIBRW_SDL2)
SDL_GetWindowSize(glGlobals.window, &r.w, &r.h);
#else
#elif defined(LIBRW_GLFW)
glfwGetFramebufferSize(glGlobals.window, &r.w, &r.h);
#elif defined(LIBRW_EXTGL3)
r.w = fb->width;
r.h = fb->height;
#endif
}else{
r.w = fb->width;
@ -1406,18 +1409,20 @@ showRaster(Raster *raster, uint32 flags)
// glViewport(raster->offsetX, raster->offsetY,
// raster->width, raster->height);
#ifdef LIBRW_SDL2
#if defined(LIBRW_SDL2)
if(flags & Raster::FLIPWAITVSYNCH)
SDL_GL_SetSwapInterval(1);
else
SDL_GL_SetSwapInterval(0);
SDL_GL_SwapWindow(glGlobals.window);
#else
#elif defined(LIBRW_GLFW)
if(flags & Raster::FLIPWAITVSYNCH)
glfwSwapInterval(1);
else
glfwSwapInterval(0);
glfwSwapBuffers(glGlobals.window);
#elif defined(LIBRW_EXTGL3)
// Do nothing
#endif
}
@ -1447,7 +1452,7 @@ rasterRenderFast(Raster *raster, int32 x, int32 y)
return 0;
}
#ifdef LIBRW_SDL2
#if defined(LIBRW_SDL2)
static void
addVideoMode(int displayIndex, int modeIndex)
@ -1600,7 +1605,8 @@ stopSDL2(void)
SDL_DestroyWindow(glGlobals.window);
return 1;
}
#else
#elif defined(LIBRW_GLFW)
static void
addVideoMode(const GLFWvidmode *mode)
@ -1764,6 +1770,113 @@ stopGLFW(void)
glfwDestroyWindow(glGlobals.window);
return 1;
}
#elif defined(LIBRW_EXTGL3)
// Apple defines everything on his own
#ifndef __APPLE__
#if defined(_WIN32) || defined(__WIN32__)
#ifndef WIN32_LEAN_AND_MEAN
// Reduce a bit header VC++ compilation time
#define WIN32_LEAN_AND_MEAN 1
#define LE_ME_ISDEF
#endif
// APIENTRY is defined in glad.h as well as by windows.h.
// Undefine it to prevent a macro redefinition warning.
#undef APIENTRY
#include <windows.h> //For wglGetProcAddress
#ifdef LE_ME_ISDEF
#undef WIN32_LEAN_AND_MEAN
#undef LE_ME_ISDEF
#endif
void* __defaultGetProcAddress(const char* name)
{
void* p = (void*)wglGetProcAddress(name);
if (p == 0 || (p == (void*)0x1) || (p == (void*)0x2) || (p == (void*)0x3) || (p == (void*)-1))
{
HMODULE module = LoadLibraryA("opengl32.dll");
p = (void*)GetProcAddress(module, name);
}
return p;
}
#else // Linux
// GLX_ARB_get_proc_address
// glXGetProcAddressARB is statically exported by all libGL implementations,
// while glXGetProcAddress may be not available.
#ifdef __cplusplus
extern "C" {
#endif
extern void (*glXGetProcAddressARB(const GLubyte *procName))();
#ifdef __cplusplus
}
#endif
#define __defaultGetProcAddress(name) (*glXGetProcAddressARB)((const GLubyte*)name)
#endif
#endif // __APPLE__
void* defaultGetProcAddress(const char* fname)
{
void* pret = (void*) __defaultGetProcAddress(fname);
// Some drivers return values from 0, -1, 1, 2 or 3
if ( pret == (void*)-1 || pret == (void*)1 || pret == (void*)2 || pret == (void*)3 )
pret = (void*)0;
return pret;
}
static int
openEXTGL3(EngineOpenParams *openparams)
{
glGlobals.winWidth = openparams->width;
glGlobals.winHeight = openparams->height;
glGlobals.winTitle = openparams->windowtitle;
glGlobals.modes = NULL;
glGlobals.numModes = 0;
glGlobals.currentMode = -1;
memset(&gl3Caps, 0, sizeof(gl3Caps));
gl3Caps.gles = openparams->gles;
gl3Caps.glversion = openparams->glversion;
gl3Caps.loadproc = openparams->loadproc ? openparams->loadproc : defaultGetProcAddress;
return 1;
}
static int
closeEXTGL3(void)
{
return 1;
}
static int
startEXTGL3(void)
{
if (!((gl3Caps.gles ? gladLoadGLES2Loader : gladLoadGLLoader) (gl3Caps.loadproc, gl3Caps.glversion)) ) {
RWERROR((ERR_GENERAL, "gladLoadGLLoader failed"));
return 0;
}
printf("OpenGL version: %s\n", glGetString(GL_VERSION));
glGlobals.presentWidth = 0;
glGlobals.presentHeight = 0;
glGlobals.presentOffX = 0;
glGlobals.presentOffY = 0;
return 1;
}
static int
stopEXTGL3(void)
{
return 1;
}
#endif
static int
@ -1920,7 +2033,7 @@ finalizeOpenGL(void)
return 1;
}
#ifdef LIBRW_SDL2
#if defined(LIBRW_SDL2)
static int
deviceSystemSDL2(DeviceReq req, void *arg, int32 n)
{
@ -1984,7 +2097,7 @@ deviceSystemSDL2(DeviceReq req, void *arg, int32 n)
return 1;
}
#else
#elif defined(LIBRW_GLFW)
static int
deviceSystemGLFW(DeviceReq req, void *arg, int32 n)
@ -2071,6 +2184,66 @@ deviceSystemGLFW(DeviceReq req, void *arg, int32 n)
return 1;
}
#elif defined(LIBRW_EXTGL3)
static int
deviceSystemEXTGL3(DeviceReq req, void *arg, int32 n)
{
VideoMode *rwmode;
switch(req){
case DEVICEOPEN:
return openEXTGL3((EngineOpenParams*)arg);
case DEVICECLOSE:
return closeEXTGL3();
case DEVICEINIT:
return startEXTGL3() && initOpenGL();
case DEVICETERM:
return termOpenGL() && stopEXTGL3();
case DEVICEFINALIZE:
return finalizeOpenGL();
// no sub-systems
case DEVICEGETNUMVIDEOMODES:
return glGlobals.numModes;
case DEVICEGETCURRENTVIDEOMODE:
return glGlobals.currentMode;
case DEVICESETVIDEOMODE:
if(n >= glGlobals.numModes)
return 0;
glGlobals.currentMode = n;
return 1;
case DEVICEGETVIDEOMODEINFO:
return 0;
case DEVICEGETMAXMULTISAMPLINGLEVELS:
{
GLint maxSamples;
glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
if(maxSamples == 0)
return 1;
return maxSamples;
}
case DEVICEGETMULTISAMPLINGLEVELS:
if(glGlobals.numSamples == 0)
return 1;
return glGlobals.numSamples;
case DEVICESETMULTISAMPLINGLEVELS:
glGlobals.numSamples = (uint32)n;
return 1;
default:
assert(0 && "not implemented");
return 0;
}
return 1;
}
#endif
Device renderdevice = {
@ -2090,10 +2263,12 @@ Device renderdevice = {
gl3::im3DRenderPrimitive,
gl3::im3DRenderIndexedPrimitive,
gl3::im3DEnd,
#ifdef LIBRW_SDL2
#if defined(LIBRW_SDL2)
gl3::deviceSystemSDL2
#else
#elif defined(LIBRW_GLFW)
gl3::deviceSystemGLFW
#elif defined(LIBRW_EXTGL3)
gl3::deviceSystemEXTGL3
#endif
};

View File

@ -1,8 +1,8 @@
#ifdef RW_GL3
#include "glad/glad.h"
#ifdef LIBRW_SDL2
#if defined(LIBRW_SDL2)
#include <SDL.h>
#else
#elif defined(LIBRW_GLFW)
#include <GLFW/glfw3.h>
#endif
#endif
@ -12,11 +12,15 @@ namespace rw {
#ifdef RW_GL3
struct EngineOpenParams
{
#ifdef LIBRW_SDL2
#if defined(LIBRW_SDL2)
SDL_Window **window;
bool32 fullscreen;
#else
#elif defined(LIBRW_GLFW)
GLFWwindow **window;
#elif defined(LIBRW_EXTGL3)
int gles;
int glversion;
GLADloadproc loadproc;
#endif
int width, height;
const char *windowtitle;
@ -274,6 +278,9 @@ struct Gl3Caps
{
int gles;
int glversion;
#ifdef LIBRW_EXTGL3
GLADloadproc loadproc;
#endif
bool dxtSupported;
bool astcSupported; // not used yet
float maxAnisotropy;

View File

@ -24,9 +24,9 @@ void im3DEnd(void);
struct DisplayMode
{
#ifdef LIBRW_SDL2
#if defined(LIBRW_SDL2)
SDL_DisplayMode mode;
#else
#elif defined(LIBRW_GLFW)
GLFWvidmode mode;
#endif
int32 depth;
@ -35,11 +35,11 @@ struct DisplayMode
struct GlGlobals
{
#ifdef LIBRW_SDL2
#if defined(LIBRW_SDL2)
SDL_Window **pWindow;
SDL_Window *window;
SDL_GLContext glcontext;
#else
#elif defined(LIBRW_GLFW)
GLFWwindow **pWindow;
GLFWwindow *window;

View File

@ -11,6 +11,13 @@ void skinInstanceCB(Geometry *geo, InstanceDataHeader *header, bool32 reinstance
void skinRenderCB(Atomic *atomic, InstanceDataHeader *header);
void uploadSkinMatrices(Atomic *atomic);
#ifdef LIBRW_EXTGL3
namespace extgl3 {
void init(void);
}
#endif
}
}