mirror of
https://github.com/raysan5/raylib.git
synced 2025-12-25 10:22:33 -05:00
Compare commits
2 Commits
6d9e17594b
...
43c81d216c
| Author | SHA1 | Date | |
|---|---|---|---|
| 43c81d216c | |||
| 584bc14929 |
@ -8,7 +8,7 @@ if(EMSCRIPTEN)
|
||||
endif()
|
||||
enum_option(PLATFORM "Desktop;Web;Android;Raspberry Pi;DRM;SDL" "Platform to build for.")
|
||||
|
||||
enum_option(OPENGL_VERSION "OFF;4.3;3.3;2.1;1.1;ES 2.0;ES 3.0" "Force a specific OpenGL Version?")
|
||||
enum_option(OPENGL_VERSION "OFF;4.3;3.3;2.1;1.1;ES 2.0;ES 3.0;Software" "Force a specific OpenGL Version?")
|
||||
|
||||
# Configuration options
|
||||
option(BUILD_EXAMPLES "Build the examples." ${PROJECT_IS_TOP_LEVEL})
|
||||
|
||||
@ -158,6 +158,8 @@ if (NOT ${OPENGL_VERSION} MATCHES "OFF")
|
||||
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
||||
elseif (${OPENGL_VERSION} MATCHES "ES 3.0")
|
||||
set(GRAPHICS "GRAPHICS_API_OPENGL_ES3")
|
||||
elseif (${OPENGL_VERSION} MATCHES "Software")
|
||||
set(GRAPHICS "GRAPHICS_API_OPENGL_11_SOFTWARE")
|
||||
endif ()
|
||||
if (NOT "${SUGGESTED_GRAPHICS}" STREQUAL "" AND NOT "${SUGGESTED_GRAPHICS}" STREQUAL "${GRAPHICS}")
|
||||
message(WARNING "You are overriding the suggested GRAPHICS=${SUGGESTED_GRAPHICS} with ${GRAPHICS}! This may fail.")
|
||||
|
||||
@ -105,6 +105,10 @@ elseif ("${PLATFORM}" STREQUAL "DRM")
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/rlgl_standalone.c)
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/raylib_opengl_interop.c)
|
||||
|
||||
elseif ("${OPENGL_VERSION}" STREQUAL "Software")
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/rlgl_standalone.c)
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/others/raylib_opengl_interop.c)
|
||||
|
||||
elseif (NOT SUPPORT_GESTURES_SYSTEM)
|
||||
# Items requiring gestures system
|
||||
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/textures/textures_mouse_painting.c)
|
||||
|
||||
@ -51,7 +51,7 @@
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{6B1A933E-71B8-4C1F-9E79-02D98830E671}</ProjectGuid>
|
||||
<ProjectGuid>{718FCBD0-591D-448C-B7D5-9F1CA8544E7B}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>core_input_actions</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
|
||||
@ -345,7 +345,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_inline_styling", "exam
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_undo_redo", "examples\core_undo_redo.vcxproj", "{3B27F358-2679-4F38-B297-17B536F580BB}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_input_actions", "examples\core_input_actions.vcxproj", "{6B1A933E-71B8-4C1F-9E79-02D98830E671}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_input_actions", "examples\core_input_actions.vcxproj", "{718FCBD0-591D-448C-B7D5-9F1CA8544E7B}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@ -4249,30 +4249,30 @@ Global
|
||||
{3B27F358-2679-4F38-B297-17B536F580BB}.Release|x64.Build.0 = Release|x64
|
||||
{3B27F358-2679-4F38-B297-17B536F580BB}.Release|x86.ActiveCfg = Release|Win32
|
||||
{3B27F358-2679-4F38-B297-17B536F580BB}.Release|x86.Build.0 = Release|Win32
|
||||
{6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
|
||||
{6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
|
||||
{6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
|
||||
{6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
|
||||
{6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
|
||||
{6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
|
||||
{6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x64.Build.0 = Debug|x64
|
||||
{6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x86.Build.0 = Debug|Win32
|
||||
{6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
|
||||
{6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
|
||||
{6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
|
||||
{6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x64.Build.0 = Release.DLL|x64
|
||||
{6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
|
||||
{6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x86.Build.0 = Release.DLL|Win32
|
||||
{6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x64.ActiveCfg = Release|x64
|
||||
{6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x64.Build.0 = Release|x64
|
||||
{6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x86.ActiveCfg = Release|Win32
|
||||
{6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x86.Build.0 = Release|Win32
|
||||
{718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64
|
||||
{718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64
|
||||
{718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64
|
||||
{718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug.DLL|x64.Build.0 = Debug.DLL|x64
|
||||
{718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32
|
||||
{718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32
|
||||
{718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug|x64.Build.0 = Debug|x64
|
||||
{718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Debug|x86.Build.0 = Debug|Win32
|
||||
{718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64
|
||||
{718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64
|
||||
{718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release.DLL|x64.ActiveCfg = Release.DLL|x64
|
||||
{718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release.DLL|x64.Build.0 = Release.DLL|x64
|
||||
{718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32
|
||||
{718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release.DLL|x86.Build.0 = Release.DLL|Win32
|
||||
{718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release|x64.ActiveCfg = Release|x64
|
||||
{718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release|x64.Build.0 = Release|x64
|
||||
{718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release|x86.ActiveCfg = Release|Win32
|
||||
{718FCBD0-591D-448C-B7D5-9F1CA8544E7B}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@ -4447,7 +4447,7 @@ Global
|
||||
{49C67F03-1A56-4F96-B278-39B66EC93678} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
|
||||
{D496308F-3C3C-40B3-A3ED-EA327D244B3E} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A}
|
||||
{3B27F358-2679-4F38-B297-17B536F580BB} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
|
||||
{6B1A933E-71B8-4C1F-9E79-02D98830E671} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
|
||||
{718FCBD0-591D-448C-B7D5-9F1CA8544E7B} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29}
|
||||
|
||||
18
src/Makefile
18
src/Makefile
@ -235,20 +235,22 @@ endif
|
||||
# NOTE: By default use OpenGL 3.3 on desktop platforms
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_GLFW)
|
||||
GRAPHICS ?= GRAPHICS_API_OPENGL_33
|
||||
#GRAPHICS = GRAPHICS_API_OPENGL_11 # Uncomment to use OpenGL 1.1
|
||||
#GRAPHICS = GRAPHICS_API_OPENGL_21 # Uncomment to use OpenGL 2.1
|
||||
#GRAPHICS = GRAPHICS_API_OPENGL_43 # Uncomment to use OpenGL 4.3
|
||||
#GRAPHICS = GRAPHICS_API_OPENGL_ES2 # Uncomment to use OpenGL ES 2.0 (ANGLE)
|
||||
#GRAPHICS = GRAPHICS_API_OPENGL_11_SOFTWARE # Uncomment to use software rendering
|
||||
#GRAPHICS = GRAPHICS_API_OPENGL_11 # Uncomment to use OpenGL 1.1
|
||||
#GRAPHICS = GRAPHICS_API_OPENGL_21 # Uncomment to use OpenGL 2.1
|
||||
#GRAPHICS = GRAPHICS_API_OPENGL_43 # Uncomment to use OpenGL 4.3
|
||||
#GRAPHICS = GRAPHICS_API_OPENGL_ES2 # Uncomment to use OpenGL ES 2.0 (ANGLE)
|
||||
endif
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_SDL)
|
||||
GRAPHICS ?= GRAPHICS_API_OPENGL_33
|
||||
endif
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DESKTOP_RGFW)
|
||||
GRAPHICS ?= GRAPHICS_API_OPENGL_33
|
||||
#GRAPHICS = GRAPHICS_API_OPENGL_11 # Uncomment to use OpenGL 1.1
|
||||
#GRAPHICS = GRAPHICS_API_OPENGL_21 # Uncomment to use OpenGL 2.1
|
||||
#GRAPHICS = GRAPHICS_API_OPENGL_43 # Uncomment to use OpenGL 4.3
|
||||
#GRAPHICS = GRAPHICS_API_OPENGL_ES2 # Uncomment to use OpenGL ES 2.0 (ANGLE)
|
||||
#GRAPHICS = GRAPHICS_API_OPENGL_11_SOFTWARE # Uncomment to use software rendering
|
||||
#GRAPHICS = GRAPHICS_API_OPENGL_11 # Uncomment to use OpenGL 1.1
|
||||
#GRAPHICS = GRAPHICS_API_OPENGL_21 # Uncomment to use OpenGL 2.1
|
||||
#GRAPHICS = GRAPHICS_API_OPENGL_43 # Uncomment to use OpenGL 4.3
|
||||
#GRAPHICS = GRAPHICS_API_OPENGL_ES2 # Uncomment to use OpenGL ES 2.0 (ANGLE)
|
||||
endif
|
||||
ifeq ($(TARGET_PLATFORM),PLATFORM_DRM)
|
||||
# On DRM OpenGL ES 2.0 must be used
|
||||
|
||||
5230
src/external/rlsw.h
vendored
Normal file
5230
src/external/rlsw.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@ -63,18 +63,20 @@
|
||||
#include "SDL.h"
|
||||
#endif
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||
// It seems it does not need to be included to work
|
||||
//#include "SDL_opengles2.h"
|
||||
#else
|
||||
// SDL OpenGL functionality (if required, instead of internal renderer)
|
||||
#ifdef USING_SDL3_PROJECT
|
||||
#include "SDL3/SDL_opengl.h"
|
||||
#elif USING_SDL2_PROJECT
|
||||
#include "SDL2/SDL_opengl.h"
|
||||
#else
|
||||
#include "SDL_opengl.h"
|
||||
#endif
|
||||
#if !defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
|
||||
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||
// It seems it does not need to be included to work
|
||||
//#include "SDL_opengles2.h"
|
||||
#else
|
||||
// SDL OpenGL functionality (if required, instead of internal renderer)
|
||||
#ifdef USING_SDL3_PROJECT
|
||||
#include "SDL3/SDL_opengl.h"
|
||||
#elif USING_SDL2_PROJECT
|
||||
#include "SDL2/SDL_opengl.h"
|
||||
#else
|
||||
#include "SDL_opengl.h"
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
@ -1229,7 +1231,14 @@ void DisableCursor(void)
|
||||
// Swap back buffer with front buffer (screen drawing)
|
||||
void SwapScreenBuffer(void)
|
||||
{
|
||||
#if defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
|
||||
// NOTE: We use a preprocessor condition here because `rlCopyFramebuffer` is only declared for software rendering
|
||||
SDL_Surface* surface = SDL_GetWindowSurface(platform.window);
|
||||
rlCopyFramebuffer(0, 0, CORE.Window.render.width, CORE.Window.render.height, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, surface->pixels);
|
||||
SDL_UpdateWindowSurface(platform.window);
|
||||
#else
|
||||
SDL_GL_SwapWindow(platform.window);
|
||||
#endif
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
@ -1577,13 +1586,15 @@ void PollInputEvents(void)
|
||||
if (CORE.Input.Keyboard.charPressedQueueCount < MAX_CHAR_PRESSED_QUEUE)
|
||||
{
|
||||
// Add character (codepoint) to the queue
|
||||
#if defined(USING_VERSION_SDL3)
|
||||
|
||||
#if defined(USING_VERSION_SDL3)
|
||||
size_t textLen = strlen(event.text.text);
|
||||
unsigned int codepoint = (unsigned int)SDL_StepUTF8(&event.text.text, &textLen);
|
||||
#else
|
||||
#else
|
||||
int codepointSize = 0;
|
||||
int codepoint = GetCodepointNextSDL(event.text.text, &codepointSize);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
CORE.Input.Keyboard.charPressedQueue[CORE.Input.Keyboard.charPressedQueueCount] = codepoint;
|
||||
CORE.Input.Keyboard.charPressedQueueCount++;
|
||||
}
|
||||
@ -1887,7 +1898,6 @@ int InitPlatform(void)
|
||||
//----------------------------------------------------------------------------
|
||||
unsigned int flags = 0;
|
||||
flags |= SDL_WINDOW_SHOWN;
|
||||
flags |= SDL_WINDOW_OPENGL;
|
||||
flags |= SDL_WINDOW_INPUT_FOCUS;
|
||||
flags |= SDL_WINDOW_MOUSE_FOCUS;
|
||||
flags |= SDL_WINDOW_MOUSE_CAPTURE; // Window has mouse captured
|
||||
@ -1922,44 +1932,50 @@ int InitPlatform(void)
|
||||
|
||||
// NOTE: Some OpenGL context attributes must be set before window creation
|
||||
|
||||
// Check selection OpenGL version
|
||||
if (rlGetVersion() == RL_OPENGL_21)
|
||||
if (rlGetVersion() != RL_OPENGL_11_SOFTWARE)
|
||||
{
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
|
||||
}
|
||||
else if (rlGetVersion() == RL_OPENGL_33)
|
||||
{
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
}
|
||||
else if (rlGetVersion() == RL_OPENGL_43)
|
||||
{
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
#if defined(RLGL_ENABLE_OPENGL_DEBUG_CONTEXT)
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG); // Enable OpenGL Debug Context
|
||||
#endif
|
||||
}
|
||||
else if (rlGetVersion() == RL_OPENGL_ES_20) // Request OpenGL ES 2.0 context
|
||||
{
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
||||
}
|
||||
else if (rlGetVersion() == RL_OPENGL_ES_30) // Request OpenGL ES 3.0 context
|
||||
{
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
||||
}
|
||||
// Add the flag telling the window to use an OpenGL context
|
||||
flags |= SDL_WINDOW_OPENGL;
|
||||
|
||||
if (CORE.Window.flags & FLAG_MSAA_4X_HINT)
|
||||
{
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
|
||||
// Check selection OpenGL version
|
||||
if (rlGetVersion() == RL_OPENGL_21)
|
||||
{
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
|
||||
}
|
||||
else if (rlGetVersion() == RL_OPENGL_33)
|
||||
{
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
}
|
||||
else if (rlGetVersion() == RL_OPENGL_43)
|
||||
{
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
#if defined(RLGL_ENABLE_OPENGL_DEBUG_CONTEXT)
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG); // Enable OpenGL Debug Context
|
||||
#endif
|
||||
}
|
||||
else if (rlGetVersion() == RL_OPENGL_ES_20) // Request OpenGL ES 2.0 context
|
||||
{
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
||||
}
|
||||
else if (rlGetVersion() == RL_OPENGL_ES_30) // Request OpenGL ES 3.0 context
|
||||
{
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
||||
}
|
||||
|
||||
if (CORE.Window.flags & FLAG_MSAA_4X_HINT)
|
||||
{
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
|
||||
}
|
||||
}
|
||||
|
||||
// Init window
|
||||
@ -1970,10 +1986,12 @@ int InitPlatform(void)
|
||||
#endif
|
||||
|
||||
// Init OpenGL context
|
||||
platform.glContext = SDL_GL_CreateContext(platform.window);
|
||||
if (rlGetVersion() != RL_OPENGL_11_SOFTWARE)
|
||||
{
|
||||
platform.glContext = SDL_GL_CreateContext(platform.window);
|
||||
}
|
||||
|
||||
// Check window and glContext have been initialized successfully
|
||||
if ((platform.window != NULL) && (platform.glContext != NULL))
|
||||
if ((platform.window != NULL) && ((rlGetVersion() == RL_OPENGL_11_SOFTWARE) || (platform.glContext != NULL)))
|
||||
{
|
||||
CORE.Window.ready = true;
|
||||
|
||||
@ -1994,8 +2012,14 @@ int InitPlatform(void)
|
||||
TRACELOG(LOG_INFO, " > Render size: %i x %i", CORE.Window.render.width, CORE.Window.render.height);
|
||||
TRACELOG(LOG_INFO, " > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y);
|
||||
|
||||
if (CORE.Window.flags & FLAG_VSYNC_HINT) SDL_GL_SetSwapInterval(1);
|
||||
else SDL_GL_SetSwapInterval(0);
|
||||
if (platform.glContext != NULL)
|
||||
{
|
||||
SDL_GL_SetSwapInterval((CORE.Window.flags & FLAG_VSYNC_HINT)? 1 : 0);
|
||||
|
||||
// Load OpenGL extensions
|
||||
// NOTE: GL procedures address loader is required to load extensions
|
||||
rlLoadExtensions(SDL_GL_GetProcAddress);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2003,9 +2027,6 @@ int InitPlatform(void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Load OpenGL extensions
|
||||
// NOTE: GL procedures address loader is required to load extensions
|
||||
rlLoadExtensions(SDL_GL_GetProcAddress);
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// Initialize input events system
|
||||
@ -2077,7 +2098,7 @@ int InitPlatform(void)
|
||||
void ClosePlatform(void)
|
||||
{
|
||||
SDL_FreeCursor(platform.cursor); // Free cursor
|
||||
SDL_GL_DeleteContext(platform.glContext); // Deinitialize OpenGL context
|
||||
if (platform.glContext != NULL) SDL_GL_DeleteContext(platform.glContext); // Deinitialize OpenGL context
|
||||
SDL_DestroyWindow(platform.window);
|
||||
SDL_Quit(); // Deinitialize SDL internal global state
|
||||
}
|
||||
|
||||
@ -65,12 +65,17 @@
|
||||
// so the enum KEY_F12 from raylib is used
|
||||
#undef KEY_F12
|
||||
|
||||
#include <gbm.h> // Generic Buffer Management (native platform for EGL on DRM)
|
||||
#include <xf86drm.h> // Direct Rendering Manager user-level library interface
|
||||
#include <xf86drmMode.h> // Direct Rendering Manager mode setting (KMS) interface
|
||||
|
||||
#include "EGL/egl.h" // Native platform windowing system interface
|
||||
#include "EGL/eglext.h" // EGL extensions
|
||||
#if !defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
|
||||
#include <gbm.h> // Generic Buffer Management (native platform for EGL on DRM)
|
||||
#include "EGL/egl.h" // Native platform windowing system interface
|
||||
#include "EGL/eglext.h" // EGL extensions
|
||||
#else
|
||||
#include <sys/mman.h> // For mmap when copying to the dumb buffer
|
||||
#include <errno.h> // For the conversion of certain error messages
|
||||
#endif
|
||||
|
||||
// NOTE: DRM cache enables triple buffered DRM caching
|
||||
#if defined(SUPPORT_DRM_CACHE)
|
||||
@ -103,15 +108,19 @@ typedef struct {
|
||||
drmModeConnector *connector; // Direct Rendering Manager (DRM) mode connector
|
||||
drmModeCrtc *crtc; // CRT Controller
|
||||
int modeIndex; // Index of the used mode of connector->modes
|
||||
uint32_t prevFB; // Previous DRM framebufer (during frame swapping)
|
||||
|
||||
#if !defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
|
||||
struct gbm_device *gbmDevice; // GBM device
|
||||
struct gbm_surface *gbmSurface; // GBM surface
|
||||
struct gbm_bo *prevBO; // Previous GBM buffer object (during frame swapping)
|
||||
uint32_t prevFB; // Previous GBM framebufer (during frame swapping)
|
||||
|
||||
EGLDisplay device; // Native display device (physical screen connection)
|
||||
EGLSurface surface; // Surface to draw on, framebuffers (connected to context)
|
||||
EGLContext context; // Graphic context, mode in which drawing can be done
|
||||
EGLConfig config; // Graphic config
|
||||
#else
|
||||
uint32_t prevDumbHandle; // Handle to the previous dumb buffer (during frame swapping)
|
||||
#endif
|
||||
|
||||
// Keyboard data
|
||||
int defaultKeyboardMode; // Default keyboard mode
|
||||
@ -780,6 +789,8 @@ void SwapScreenBuffer()
|
||||
// Swap back buffer with front buffer (screen drawing)
|
||||
void SwapScreenBuffer(void)
|
||||
{
|
||||
#if !defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
|
||||
// Hardware rendering buffer swap with EGL
|
||||
eglSwapBuffers(platform.device, platform.surface);
|
||||
|
||||
if (!platform.gbmSurface || (-1 == platform.fd) || !platform.connector || !platform.crtc) TRACELOG(LOG_ERROR, "DISPLAY: DRM initialization failed to swap");
|
||||
@ -805,6 +816,209 @@ void SwapScreenBuffer(void)
|
||||
if (platform.prevBO) gbm_surface_release_buffer(platform.gbmSurface, platform.prevBO);
|
||||
|
||||
platform.prevBO = bo;
|
||||
#else
|
||||
// Software rendering buffer swap
|
||||
if ((-1 == platform.fd) || !platform.connector || (platform.modeIndex < 0))
|
||||
{
|
||||
TRACELOG(LOG_ERROR, "DISPLAY: DRM initialization failed to swap");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the software rendered color buffer
|
||||
int bufferWidth, bufferHeight;
|
||||
void *colorBuffer = swGetColorBuffer(&bufferWidth, &bufferHeight);
|
||||
if (!colorBuffer)
|
||||
{
|
||||
TRACELOG(LOG_ERROR, "DISPLAY: Failed to get software color buffer");
|
||||
return;
|
||||
}
|
||||
|
||||
// Retrieving the dimensions of the display mode used
|
||||
drmModeModeInfo *mode = &platform.connector->modes[platform.modeIndex];
|
||||
uint32_t width = mode->hdisplay;
|
||||
uint32_t height = mode->vdisplay;
|
||||
|
||||
// Dumb buffers use a fixed format based on bpp
|
||||
#if SW_COLOR_BUFFER_BITS == 24
|
||||
const uint32_t bpp = 32; // 32 bits per pixel (XRGB8888 format)
|
||||
const uint32_t depth = 24; // Color depth, here only 24 bits, alpha is not used
|
||||
#else
|
||||
// REVIEW: Not sure how it will be interpreted (RGB or RGBA?)
|
||||
const uint32_t bpp = SW_COLOR_BUFFER_BITS;
|
||||
const uint32_t depth = SW_COLOR_BUFFER_BITS;
|
||||
#endif
|
||||
|
||||
// Create a dumb buffer for software rendering
|
||||
struct drm_mode_create_dumb creq = {0};
|
||||
creq.width = width;
|
||||
creq.height = height;
|
||||
creq.bpp = bpp;
|
||||
|
||||
int result = drmIoctl(platform.fd, DRM_IOCTL_MODE_CREATE_DUMB, &creq);
|
||||
if (result < 0)
|
||||
{
|
||||
TRACELOG(LOG_ERROR, "DISPLAY: Failed to create dumb buffer: %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
// Create framebuffer with the correct format
|
||||
uint32_t fb = 0;
|
||||
result = drmModeAddFB(platform.fd,
|
||||
width, height,
|
||||
depth, bpp, creq.pitch,
|
||||
creq.handle, &fb);
|
||||
if (result != 0)
|
||||
{
|
||||
TRACELOG(LOG_ERROR, "DISPLAY: drmModeAddFB() failed with result: %d (%s)", result, strerror(errno));
|
||||
struct drm_mode_destroy_dumb dreq = {0};
|
||||
dreq.handle = creq.handle;
|
||||
drmIoctl(platform.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq);
|
||||
return;
|
||||
}
|
||||
|
||||
// Map the dumb buffer to copy our software rendered buffer
|
||||
struct drm_mode_map_dumb mreq = {0};
|
||||
mreq.handle = creq.handle;
|
||||
result = drmIoctl(platform.fd, DRM_IOCTL_MODE_MAP_DUMB, &mreq);
|
||||
if (result != 0)
|
||||
{
|
||||
TRACELOG(LOG_ERROR, "DISPLAY: Failed to map dumb buffer: %s", strerror(errno));
|
||||
drmModeRmFB(platform.fd, fb);
|
||||
struct drm_mode_destroy_dumb dreq = {0};
|
||||
dreq.handle = creq.handle;
|
||||
drmIoctl(platform.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq);
|
||||
return;
|
||||
}
|
||||
|
||||
// Map the buffer into userspace
|
||||
void *dumbBuffer = mmap(0, creq.size, PROT_READ | PROT_WRITE, MAP_SHARED, platform.fd, mreq.offset);
|
||||
if (dumbBuffer == MAP_FAILED)
|
||||
{
|
||||
TRACELOG(LOG_ERROR, "DISPLAY: Failed to mmap dumb buffer: %s", strerror(errno));
|
||||
drmModeRmFB(platform.fd, fb);
|
||||
struct drm_mode_destroy_dumb dreq = {0};
|
||||
dreq.handle = creq.handle;
|
||||
drmIoctl(platform.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq);
|
||||
return;
|
||||
}
|
||||
|
||||
// Copy the software rendered buffer to the dumb buffer with scaling if needed
|
||||
if (bufferWidth == width && bufferHeight == height)
|
||||
{
|
||||
// Direct copy if sizes match
|
||||
swCopyFramebuffer(0, 0, bufferWidth, bufferHeight, SW_RGBA, SW_UNSIGNED_BYTE, dumbBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Scale the software buffer to match the display mode
|
||||
swBlitFramebuffer(0, 0, width, height, 0, 0, bufferWidth, bufferHeight, SW_RGBA, SW_UNSIGNED_BYTE, dumbBuffer);
|
||||
}
|
||||
|
||||
// Unmap the buffer
|
||||
munmap(dumbBuffer, creq.size);
|
||||
|
||||
// Find a CRTC compatible with the connector
|
||||
uint32_t crtcId = 0;
|
||||
if (platform.crtc)
|
||||
{
|
||||
crtcId = platform.crtc->crtc_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Find a CRTC that's compatible with this connector
|
||||
drmModeRes *res = drmModeGetResources(platform.fd);
|
||||
if (!res)
|
||||
{
|
||||
TRACELOG(LOG_ERROR, "DISPLAY: Failed to get DRM resources");
|
||||
drmModeRmFB(platform.fd, fb);
|
||||
struct drm_mode_destroy_dumb dreq = {0};
|
||||
dreq.handle = creq.handle;
|
||||
drmIoctl(platform.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check which CRTCs are compatible with this connector
|
||||
drmModeEncoder *encoder = NULL;
|
||||
if (platform.connector->encoder_id)
|
||||
{
|
||||
encoder = drmModeGetEncoder(platform.fd, platform.connector->encoder_id);
|
||||
}
|
||||
|
||||
if (encoder && encoder->crtc_id)
|
||||
{
|
||||
crtcId = encoder->crtc_id;
|
||||
platform.crtc = drmModeGetCrtc(platform.fd, crtcId);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Find a free CRTC
|
||||
for (int i = 0; i < res->count_crtcs; i++)
|
||||
{
|
||||
drmModeCrtc *crtc = drmModeGetCrtc(platform.fd, res->crtcs[i]);
|
||||
if (crtc && !crtc->buffer_id) // CRTC is free
|
||||
{
|
||||
crtcId = res->crtcs[i];
|
||||
if (platform.crtc) drmModeFreeCrtc(platform.crtc);
|
||||
platform.crtc = crtc;
|
||||
break;
|
||||
}
|
||||
if (crtc) drmModeFreeCrtc(crtc);
|
||||
}
|
||||
}
|
||||
|
||||
if (encoder) drmModeFreeEncoder(encoder);
|
||||
drmModeFreeResources(res);
|
||||
|
||||
if (!crtcId)
|
||||
{
|
||||
TRACELOG(LOG_ERROR, "DISPLAY: No compatible CRTC found");
|
||||
drmModeRmFB(platform.fd, fb);
|
||||
struct drm_mode_destroy_dumb dreq = {0};
|
||||
dreq.handle = creq.handle;
|
||||
drmIoctl(platform.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Set CRTC with better error handling
|
||||
result = drmModeSetCrtc(platform.fd, crtcId, fb, 0, 0,
|
||||
&platform.connector->connector_id, 1,
|
||||
mode);
|
||||
if (result != 0)
|
||||
{
|
||||
TRACELOG(LOG_ERROR, "DISPLAY: drmModeSetCrtc() failed with result: %d (%s)", result, strerror(errno));
|
||||
TRACELOG(LOG_ERROR, "DISPLAY: CRTC ID: %u, FB ID: %u, Connector ID: %u", crtcId, fb, platform.connector->connector_id);
|
||||
TRACELOG(LOG_ERROR, "DISPLAY: Mode: %dx%d@%d", mode->hdisplay, mode->vdisplay, mode->vrefresh);
|
||||
|
||||
drmModeRmFB(platform.fd, fb);
|
||||
struct drm_mode_destroy_dumb dreq = {0};
|
||||
dreq.handle = creq.handle;
|
||||
drmIoctl(platform.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq);
|
||||
return;
|
||||
}
|
||||
|
||||
// Clean up previous framebuffer
|
||||
if (platform.prevFB)
|
||||
{
|
||||
result = drmModeRmFB(platform.fd, platform.prevFB);
|
||||
if (result != 0)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: drmModeRmFB() failed with result: %d", result);
|
||||
}
|
||||
}
|
||||
|
||||
platform.prevFB = fb;
|
||||
|
||||
// Clean up previous dumb buffer
|
||||
if (platform.prevDumbHandle)
|
||||
{
|
||||
struct drm_mode_destroy_dumb dreq = {0};
|
||||
dreq.handle = platform.prevDumbHandle;
|
||||
drmIoctl(platform.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq);
|
||||
}
|
||||
|
||||
platform.prevDumbHandle = creq.handle;
|
||||
#endif
|
||||
}
|
||||
#endif // SUPPORT_DRM_CACHE
|
||||
|
||||
@ -950,10 +1164,15 @@ int InitPlatform(void)
|
||||
platform.connector = NULL;
|
||||
platform.modeIndex = -1;
|
||||
platform.crtc = NULL;
|
||||
platform.prevFB = 0;
|
||||
|
||||
#if !defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
|
||||
platform.gbmDevice = NULL;
|
||||
platform.gbmSurface = NULL;
|
||||
platform.prevBO = NULL;
|
||||
platform.prevFB = 0;
|
||||
#else
|
||||
platform.prevDumbHandle = 0;
|
||||
#endif
|
||||
|
||||
// Initialize graphic device: display/window and graphic context
|
||||
//----------------------------------------------------------------------------
|
||||
@ -965,11 +1184,12 @@ int InitPlatform(void)
|
||||
if (platform.fd != -1) TRACELOG(LOG_INFO, "DISPLAY: Default graphic device DRM opened successfully");
|
||||
#else
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: No graphic card set, trying platform-gpu-card");
|
||||
platform.fd = open("/dev/dri/by-path/platform-gpu-card", O_RDWR); // VideoCore VI (Raspberry Pi 4)
|
||||
platform.fd = open("/dev/dri/by-path/platform-gpu-card", O_RDWR); // VideoCore VI (Raspberry Pi 4)
|
||||
if (platform.fd != -1) TRACELOG(LOG_INFO, "DISPLAY: platform-gpu-card opened successfully");
|
||||
|
||||
if ((platform.fd == -1) || (drmModeGetResources(platform.fd) == NULL))
|
||||
{
|
||||
if (platform.fd != -1) close(platform.fd);
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to open platform-gpu-card, trying card1");
|
||||
platform.fd = open("/dev/dri/card1", O_RDWR); // Other Embedded
|
||||
if (platform.fd != -1) TRACELOG(LOG_INFO, "DISPLAY: card1 opened successfully");
|
||||
@ -977,10 +1197,19 @@ int InitPlatform(void)
|
||||
|
||||
if ((platform.fd == -1) || (drmModeGetResources(platform.fd) == NULL))
|
||||
{
|
||||
if (platform.fd != -1) close(platform.fd);
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to open graphic card1, trying card0");
|
||||
platform.fd = open("/dev/dri/card0", O_RDWR); // VideoCore IV (Raspberry Pi 1-3)
|
||||
if (platform.fd != -1) TRACELOG(LOG_INFO, "DISPLAY: card0 opened successfully");
|
||||
}
|
||||
|
||||
if ((platform.fd == -1) || (drmModeGetResources(platform.fd) == NULL))
|
||||
{
|
||||
if (platform.fd != -1) close(platform.fd);
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to open graphic card0, trying card2");
|
||||
platform.fd = open("/dev/dri/card2", O_RDWR);
|
||||
if (platform.fd != -1) TRACELOG(LOG_INFO, "DISPLAY: card2 opened successfully");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (platform.fd == -1)
|
||||
@ -993,29 +1222,58 @@ int InitPlatform(void)
|
||||
if (!res)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed get DRM resources");
|
||||
close(platform.fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: Connectors found: %i", res->count_connectors);
|
||||
|
||||
// Connector detection
|
||||
for (size_t i = 0; i < res->count_connectors; i++)
|
||||
{
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: Connector index %i", i);
|
||||
|
||||
drmModeConnector *con = drmModeGetConnector(platform.fd, res->connectors[i]);
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: Connector modes detected: %i", con->count_modes);
|
||||
if (!con)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to get connector %i", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: Connector %i modes detected: %i", i, con->count_modes);
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: Connector %i status: %s", i,
|
||||
(con->connection == DRM_MODE_CONNECTED) ? "CONNECTED" :
|
||||
(con->connection == DRM_MODE_DISCONNECTED) ? "DISCONNECTED" :
|
||||
(con->connection == DRM_MODE_UNKNOWNCONNECTION) ? "UNKNOWN" : "OTHER");
|
||||
|
||||
// In certain cases the status of the conneciton is reported as UKNOWN, but it is still connected
|
||||
// This might be a hardware or software limitation like on Raspberry Pi Zero with composite output
|
||||
if (((con->connection == DRM_MODE_CONNECTED) || (con->connection == DRM_MODE_UNKNOWNCONNECTION)) && (con->encoder_id))
|
||||
// WARNING: Accept CONNECTED, UNKNOWN and even those without encoder_id connectors for software mode
|
||||
if (((con->connection == DRM_MODE_CONNECTED) || (con->connection == DRM_MODE_UNKNOWNCONNECTION)) && (con->count_modes > 0)//(con->encoder_id))
|
||||
{
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: DRM mode connected");
|
||||
#if !defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
|
||||
// For hardware rendering, we need an encoder_id
|
||||
if (con->encoder_id)
|
||||
{
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: DRM connector %i connected with encoder", i);
|
||||
platform.connector = con;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: DRM connector %i connected but no encoder", i);
|
||||
}
|
||||
#else
|
||||
// For software rendering, we can accept even without encoder_id
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: DRM connector %i suitable for software rendering", i);
|
||||
platform.connector = con;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
|
||||
if (!platform.connector)
|
||||
{
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: DRM mode NOT connected (deleting)");
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: DRM connector %i NOT suitable (deleting)", i);
|
||||
drmModeFreeConnector(con);
|
||||
}
|
||||
}
|
||||
@ -1024,14 +1282,18 @@ int InitPlatform(void)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: No suitable DRM connector found");
|
||||
drmModeFreeResources(res);
|
||||
close(platform.fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if !defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
|
||||
drmModeEncoder *enc = drmModeGetEncoder(platform.fd, platform.connector->encoder_id);
|
||||
if (!enc)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to get DRM mode encoder");
|
||||
drmModeFreeConnector(platform.connector);
|
||||
drmModeFreeResources(res);
|
||||
close(platform.fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1040,7 +1302,9 @@ int InitPlatform(void)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to get DRM mode crtc");
|
||||
drmModeFreeEncoder(enc);
|
||||
drmModeFreeConnector(platform.connector);
|
||||
drmModeFreeResources(res);
|
||||
close(platform.fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1055,7 +1319,9 @@ int InitPlatform(void)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: No matching DRM connector mode found");
|
||||
drmModeFreeEncoder(enc);
|
||||
drmModeFreeConnector(platform.connector);
|
||||
drmModeFreeResources(res);
|
||||
close(platform.fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1064,7 +1330,7 @@ int InitPlatform(void)
|
||||
}
|
||||
|
||||
const bool allowInterlaced = CORE.Window.flags & FLAG_INTERLACED_HINT;
|
||||
const int fps = (CORE.Time.target > 0)? (1.0/CORE.Time.target) : 60;
|
||||
const int fps = (CORE.Time.target > 0) ? (1.0/CORE.Time.target) : 60;
|
||||
|
||||
// Try to find an exact matching mode
|
||||
platform.modeIndex = FindExactConnectorMode(platform.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, allowInterlaced);
|
||||
@ -1083,7 +1349,9 @@ int InitPlatform(void)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to find a suitable DRM connector mode");
|
||||
drmModeFreeEncoder(enc);
|
||||
drmModeFreeConnector(platform.connector);
|
||||
drmModeFreeResources(res);
|
||||
close(platform.fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1092,19 +1360,45 @@ int InitPlatform(void)
|
||||
|
||||
TRACELOG(LOG_INFO, "DISPLAY: Selected DRM connector mode %s (%ux%u%c@%u)", platform.connector->modes[platform.modeIndex].name,
|
||||
platform.connector->modes[platform.modeIndex].hdisplay, platform.connector->modes[platform.modeIndex].vdisplay,
|
||||
(platform.connector->modes[platform.modeIndex].flags & DRM_MODE_FLAG_INTERLACE)? 'i' : 'p',
|
||||
(platform.connector->modes[platform.modeIndex].flags & DRM_MODE_FLAG_INTERLACE) ? 'i' : 'p',
|
||||
platform.connector->modes[platform.modeIndex].vrefresh);
|
||||
|
||||
drmModeFreeEncoder(enc);
|
||||
enc = NULL;
|
||||
#else
|
||||
// For software rendering, the first available mode can be used
|
||||
if (platform.connector->count_modes > 0)
|
||||
{
|
||||
platform.modeIndex = 0;
|
||||
CORE.Window.display.width = platform.connector->modes[0].hdisplay;
|
||||
CORE.Window.display.height = platform.connector->modes[0].vdisplay;
|
||||
|
||||
TRACELOG(LOG_INFO, "DISPLAY: Selected DRM connector mode %s (%ux%u%c@%u) for software rendering",
|
||||
platform.connector->modes[0].name,
|
||||
platform.connector->modes[0].hdisplay,
|
||||
platform.connector->modes[0].vdisplay,
|
||||
(platform.connector->modes[0].flags & DRM_MODE_FLAG_INTERLACE) ? 'i' : 'p',
|
||||
platform.connector->modes[0].vrefresh);
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: No modes available for connector");
|
||||
drmModeFreeConnector(platform.connector);
|
||||
drmModeFreeResources(res);
|
||||
close(platform.fd);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Use the width and height of the surface for render
|
||||
CORE.Window.render.width = CORE.Window.screen.width;
|
||||
CORE.Window.render.height = CORE.Window.screen.height;
|
||||
|
||||
drmModeFreeEncoder(enc);
|
||||
enc = NULL;
|
||||
|
||||
drmModeFreeResources(res);
|
||||
res = NULL;
|
||||
|
||||
#if !defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
|
||||
// Hardware rendering initialization with EGL
|
||||
platform.gbmDevice = gbm_create_device(platform.fd);
|
||||
if (!platform.gbmDevice)
|
||||
{
|
||||
@ -1273,6 +1567,32 @@ int InitPlatform(void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Load OpenGL extensions
|
||||
// NOTE: GL procedures address loader is required to load extensions
|
||||
rlLoadExtensions(eglGetProcAddress);
|
||||
#else
|
||||
// At this point we need to manage render size vs screen size
|
||||
// NOTE: This function use and modify global module variables:
|
||||
// -> CORE.Window.screen.width/CORE.Window.screen.height
|
||||
// -> CORE.Window.render.width/CORE.Window.render.height
|
||||
// -> CORE.Window.screenScale
|
||||
SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height);
|
||||
|
||||
// Setup window ready state for software rendering
|
||||
CORE.Window.ready = true;
|
||||
|
||||
CORE.Window.render.width = CORE.Window.screen.width;
|
||||
CORE.Window.render.height = CORE.Window.screen.height;
|
||||
CORE.Window.currentFbo.width = CORE.Window.render.width;
|
||||
CORE.Window.currentFbo.height = CORE.Window.render.height;
|
||||
|
||||
TRACELOG(LOG_INFO, "DISPLAY: Device initialized successfully (Software Rendering)");
|
||||
TRACELOG(LOG_INFO, " > Display size: %i x %i", CORE.Window.display.width, CORE.Window.display.height);
|
||||
TRACELOG(LOG_INFO, " > Screen size: %i x %i", CORE.Window.screen.width, CORE.Window.screen.height);
|
||||
TRACELOG(LOG_INFO, " > Render size: %i x %i", CORE.Window.render.width, CORE.Window.render.height);
|
||||
TRACELOG(LOG_INFO, " > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y);
|
||||
#endif
|
||||
|
||||
if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow();
|
||||
|
||||
// If graphic device is no properly initialized, we end program
|
||||
@ -1285,12 +1605,8 @@ int InitPlatform(void)
|
||||
CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED; // true
|
||||
CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED; // false
|
||||
|
||||
// Load OpenGL extensions
|
||||
// NOTE: GL procedures address loader is required to load extensions
|
||||
rlLoadExtensions(eglGetProcAddress);
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// Initialize timming system
|
||||
// Initialize timing system
|
||||
//----------------------------------------------------------------------------
|
||||
// NOTE: timming system must be initialized before the input events system
|
||||
InitTimer();
|
||||
@ -1336,6 +1652,7 @@ void ClosePlatform(void)
|
||||
platform.prevFB = 0;
|
||||
}
|
||||
|
||||
#if !defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
|
||||
if (platform.prevBO)
|
||||
{
|
||||
gbm_surface_release_buffer(platform.gbmSurface, platform.prevBO);
|
||||
@ -1353,6 +1670,7 @@ void ClosePlatform(void)
|
||||
gbm_device_destroy(platform.gbmDevice);
|
||||
platform.gbmDevice = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (platform.crtc)
|
||||
{
|
||||
@ -1374,6 +1692,7 @@ void ClosePlatform(void)
|
||||
platform.fd = -1;
|
||||
}
|
||||
|
||||
#if !defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
|
||||
// Close surface, context and display
|
||||
if (platform.device != EGL_NO_DISPLAY)
|
||||
{
|
||||
@ -1392,6 +1711,7 @@ void ClosePlatform(void)
|
||||
eglTerminate(platform.device);
|
||||
platform.device = EGL_NO_DISPLAY;
|
||||
}
|
||||
#endif
|
||||
|
||||
CORE.Window.shouldClose = true; // Added to force threads to exit when the close window is called
|
||||
|
||||
|
||||
87
src/rlgl.h
87
src/rlgl.h
@ -149,7 +149,8 @@
|
||||
#endif
|
||||
|
||||
// Security check in case no GRAPHICS_API_OPENGL_* defined
|
||||
#if !defined(GRAPHICS_API_OPENGL_11) && \
|
||||
#if !defined(GRAPHICS_API_OPENGL_11_SOFTWARE) && \
|
||||
!defined(GRAPHICS_API_OPENGL_11) && \
|
||||
!defined(GRAPHICS_API_OPENGL_21) && \
|
||||
!defined(GRAPHICS_API_OPENGL_33) && \
|
||||
!defined(GRAPHICS_API_OPENGL_43) && \
|
||||
@ -159,7 +160,7 @@
|
||||
#endif
|
||||
|
||||
// Security check in case multiple GRAPHICS_API_OPENGL_* defined
|
||||
#if defined(GRAPHICS_API_OPENGL_11)
|
||||
#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
|
||||
#if defined(GRAPHICS_API_OPENGL_21)
|
||||
#undef GRAPHICS_API_OPENGL_21
|
||||
#endif
|
||||
@ -174,6 +175,11 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Software implementation uses OpenGL 1.1 functionality
|
||||
#if defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
|
||||
#define GRAPHICS_API_OPENGL_11
|
||||
#endif
|
||||
|
||||
// OpenGL 2.1 uses most of OpenGL 3.3 Core functionality
|
||||
// WARNING: Specific parts are checked with #if defines
|
||||
#if defined(GRAPHICS_API_OPENGL_21)
|
||||
@ -427,7 +433,8 @@ typedef struct rlRenderBatch {
|
||||
|
||||
// OpenGL version
|
||||
typedef enum {
|
||||
RL_OPENGL_11 = 1, // OpenGL 1.1
|
||||
RL_OPENGL_11_SOFTWARE = 0, // Software rendering
|
||||
RL_OPENGL_11, // OpenGL 1.1
|
||||
RL_OPENGL_21, // OpenGL 2.1 (GLSL 120)
|
||||
RL_OPENGL_33, // OpenGL 3.3 (GLSL 330)
|
||||
RL_OPENGL_43, // OpenGL 4.3 (using GLSL 330)
|
||||
@ -768,6 +775,10 @@ RLAPI unsigned int rlLoadFramebuffer(void); // Loa
|
||||
RLAPI void rlFramebufferAttach(unsigned int fboId, unsigned int texId, int attachType, int texType, int mipLevel); // Attach texture/renderbuffer to a framebuffer
|
||||
RLAPI bool rlFramebufferComplete(unsigned int id); // Verify framebuffer is complete
|
||||
RLAPI void rlUnloadFramebuffer(unsigned int id); // Delete framebuffer from GPU
|
||||
#if defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
|
||||
RLAPI void rlCopyFramebuffer(int x, int y, int w, int h, int format, void* pixels);
|
||||
RLAPI void rlResizeFramebuffer(int width, int height);
|
||||
#endif
|
||||
|
||||
// Shaders management
|
||||
RLAPI unsigned int rlLoadShaderCode(const char *vsCode, const char *fsCode); // Load shader from code strings
|
||||
@ -834,24 +845,32 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad
|
||||
#endif
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_11)
|
||||
#if defined(__APPLE__)
|
||||
#include <OpenGL/gl.h> // OpenGL 1.1 library for OSX
|
||||
#include <OpenGL/glext.h> // OpenGL extensions library
|
||||
#if defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
|
||||
#define RLSW_IMPL
|
||||
#define SW_MALLOC(sz) RL_MALLOC(sz)
|
||||
#define SW_REALLOC(ptr, newSz) RL_REALLOC(ptr, newSz)
|
||||
#define SW_FREE(ptr) RL_FREE(ptr)
|
||||
#include "external/rlsw.h" // OpenGL 1.1 software implementation
|
||||
#else
|
||||
// APIENTRY for OpenGL function pointer declarations is required
|
||||
#if !defined(APIENTRY)
|
||||
#if defined(_WIN32)
|
||||
#define APIENTRY __stdcall
|
||||
#else
|
||||
#define APIENTRY
|
||||
#if defined(__APPLE__)
|
||||
#include <OpenGL/gl.h> // OpenGL 1.1 library for OSX
|
||||
#include <OpenGL/glext.h> // OpenGL extensions library
|
||||
#else
|
||||
// APIENTRY for OpenGL function pointer declarations is required
|
||||
#if !defined(APIENTRY)
|
||||
#if defined(_WIN32)
|
||||
#define APIENTRY __stdcall
|
||||
#else
|
||||
#define APIENTRY
|
||||
#endif
|
||||
#endif
|
||||
// WINGDIAPI definition. Some Windows OpenGL headers need it
|
||||
#if !defined(WINGDIAPI) && defined(_WIN32)
|
||||
#define WINGDIAPI __declspec(dllimport)
|
||||
#endif
|
||||
#endif
|
||||
// WINGDIAPI definition. Some Windows OpenGL headers need it
|
||||
#if !defined(WINGDIAPI) && defined(_WIN32)
|
||||
#define WINGDIAPI __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
#include <GL/gl.h> // OpenGL 1.1 library
|
||||
#include <GL/gl.h> // OpenGL 1.1 library
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -2337,6 +2356,14 @@ void rlglInit(int width, int height)
|
||||
glShadeModel(GL_SMOOTH); // Smooth shading between vertex (vertex colors interpolation)
|
||||
#endif
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
|
||||
if (!swInit(width, height))
|
||||
{
|
||||
TRACELOG(RL_LOG_ERROR, "RLGL: Software renderer initialization failed!");
|
||||
exit(-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
// Store screen size into global variables
|
||||
RLGL.State.framebufferWidth = width;
|
||||
@ -2363,6 +2390,10 @@ void rlglClose(void)
|
||||
glDeleteTextures(1, &RLGL.State.defaultTextureId); // Unload default texture
|
||||
TRACELOG(RL_LOG_INFO, "TEXTURE: [ID %i] Default texture unloaded successfully", RLGL.State.defaultTextureId);
|
||||
#endif
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
|
||||
swClose();
|
||||
#endif
|
||||
}
|
||||
|
||||
// Load OpenGL extensions
|
||||
@ -2672,7 +2703,9 @@ void *rlGetProcAddress(const char *procName)
|
||||
int rlGetVersion(void)
|
||||
{
|
||||
int glVersion = 0;
|
||||
#if defined(GRAPHICS_API_OPENGL_11)
|
||||
#if defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
|
||||
glVersion = RL_OPENGL_11_SOFTWARE;
|
||||
#elif defined(GRAPHICS_API_OPENGL_11)
|
||||
glVersion = RL_OPENGL_11;
|
||||
#endif
|
||||
#if defined(GRAPHICS_API_OPENGL_21)
|
||||
@ -3713,6 +3746,20 @@ void *rlReadTexturePixels(unsigned int id, int width, int height, int format)
|
||||
return pixels;
|
||||
}
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
|
||||
void rlCopyFramebuffer(int x, int y, int w, int h, int format, void* pixels)
|
||||
{
|
||||
unsigned int glInternalFormat, glFormat, glType;
|
||||
rlGetGlTextureFormats(format, &glInternalFormat, &glFormat, &glType);
|
||||
swCopyFramebuffer(x, y, w, h, glFormat, glType, pixels);
|
||||
}
|
||||
|
||||
void rlResizeFramebuffer(int width, int height)
|
||||
{
|
||||
swResizeFramebuffer(width, height);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Read screen pixel data (color buffer)
|
||||
unsigned char *rlReadScreenPixels(int width, int height)
|
||||
{
|
||||
@ -5313,4 +5360,4 @@ static Matrix rlMatrixInvert(Matrix mat)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // RLGL_IMPLEMENTATION
|
||||
#endif // RLGL_IMPLEMENTATION
|
||||
@ -1429,7 +1429,7 @@ void UpdateMeshBuffer(Mesh mesh, int index, const void *data, int dataSize, int
|
||||
// Draw a 3d mesh with material and transform
|
||||
void DrawMesh(Mesh mesh, Material material, Matrix transform)
|
||||
{
|
||||
#if defined(GRAPHICS_API_OPENGL_11)
|
||||
#if defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_11_SOFTWARE)
|
||||
#define GL_VERTEX_ARRAY 0x8074
|
||||
#define GL_NORMAL_ARRAY 0x8075
|
||||
#define GL_COLOR_ARRAY 0x8076
|
||||
|
||||
Reference in New Issue
Block a user