mirror of
https://github.com/raysan5/raylib.git
synced 2026-10-10 19:51:55 -04:00
Compare commits
3 Commits
e18de07224
...
91d50e2938
| Author | SHA1 | Date | |
|---|---|---|---|
| 91d50e2938 | |||
| 92f1f3d5d5 | |||
| f0736f6fb5 |
@ -30,7 +30,7 @@ target_link_libraries(${PROJECT_NAME} raylib)
|
||||
# Web Configurations
|
||||
if (${PLATFORM} STREQUAL "Web")
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".html") # Tell Emscripten to build an example.html file.
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 -s ASYNCIFY -s GL_ENABLE_GET_PROC_ADDRESS=1")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 -s ASYNCIFY")
|
||||
endif()
|
||||
|
||||
# Checks if OSX and links appropriate frameworks (Only required on MacOS)
|
||||
|
||||
@ -2093,7 +2093,7 @@ static void WindowDropCallback(GLFWwindow *window, int count, const char **paths
|
||||
// GLFW3: Keyboard callback, runs on key pressed
|
||||
static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods)
|
||||
{
|
||||
if (key < 0) return; // Security check, macOS fn key generates -1
|
||||
if ((key < 0) || (key >= MAX_KEYBOARD_KEYS)) return; // Security check, macOS fn key generates -1
|
||||
|
||||
// WARNING: GLFW could return GLFW_REPEAT, it needs to be considered as 1
|
||||
// to work properly with our implementation (IsKeyDown/IsKeyUp checks)
|
||||
|
||||
@ -1401,7 +1401,23 @@ void PollInputEvents(void)
|
||||
// NOTE: Creating a dummy context first to query required extensions
|
||||
HGLRC InitOpenGL(HWND hwnd, HDC hdc)
|
||||
{
|
||||
// First, create a dummy context to get WGL extensions
|
||||
// Create an invisible window for initial dummy OpenGL context
|
||||
WNDCLASSEXW dummyWindowClass = {
|
||||
.cbSize = sizeof(WNDCLASSEXW),
|
||||
.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC,
|
||||
.lpfnWndProc = DefWindowProcW,
|
||||
.hInstance = GetModuleHandleW(NULL),
|
||||
.lpszClassName = L"wglDummy"
|
||||
};
|
||||
RegisterClassExW(&dummyWindowClass);
|
||||
|
||||
HWND dummyWindow = CreateWindowExW(
|
||||
0, dummyWindowClass.lpszClassName, L"dummyWindow",
|
||||
0, 0, 0, 1, 1, NULL, NULL, NULL, NULL);
|
||||
|
||||
HDC dummyHDC = GetDC(dummyWindow);
|
||||
|
||||
// Create a dummy OpenGL context to get WGL extensions
|
||||
PIXELFORMATDESCRIPTOR pixelFormatDesc = {
|
||||
.nSize = sizeof(PIXELFORMATDESCRIPTOR),
|
||||
.nVersion = 1,
|
||||
@ -1410,18 +1426,19 @@ HGLRC InitOpenGL(HWND hwnd, HDC hdc)
|
||||
.cColorBits = 32,
|
||||
.cAlphaBits = 8,
|
||||
.cDepthBits = 24,
|
||||
.cStencilBits = 8,
|
||||
.iLayerType = PFD_MAIN_PLANE
|
||||
};
|
||||
|
||||
int pixelFormat = ChoosePixelFormat(hdc, &pixelFormatDesc);
|
||||
SetPixelFormat(hdc, pixelFormat, &pixelFormatDesc);
|
||||
int dummyPixelFormat = ChoosePixelFormat(dummyHDC, &pixelFormatDesc);
|
||||
SetPixelFormat(dummyHDC, dummyPixelFormat, &pixelFormatDesc);
|
||||
//int pixelFormat = ChoosePixelFormat(platform.hdc, &pixelFormatDesc);
|
||||
//if (!pixelFormat) { TRACELOG(LOG_ERROR, "%s failed, error=%lu", "ChoosePixelFormat", GetLastError()); return -1; }
|
||||
//if (!SetPixelFormat(platform.hdc, pixelFormat, &pixelFormatDesc)) { TRACELOG(LOG_ERROR, "%s failed, error=%lu", "SetPixelFormat", GetLastError()); return -1; }
|
||||
|
||||
HGLRC tempContext = wglCreateContext(hdc);
|
||||
HGLRC tempContext = wglCreateContext(dummyHDC);
|
||||
//if (!tempContext) { TRACELOG(LOG_ERROR, "%s failed, error=%lu", "wglCreateContext", GetLastError()); return -1; }
|
||||
BOOL result = wglMakeCurrent(hdc, tempContext);
|
||||
BOOL result = wglMakeCurrent(dummyHDC, tempContext);
|
||||
//if (!result) { TRACELOG(LOG_ERROR, "%s failed, error=%lu", "wglMakeCurrent", GetLastError()); return -1; }
|
||||
|
||||
// Load WGL extension entry points
|
||||
@ -1431,6 +1448,7 @@ HGLRC InitOpenGL(HWND hwnd, HDC hdc)
|
||||
wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
|
||||
|
||||
// Setup modern pixel format if extension is available
|
||||
bool selectedModernPixelFormat = false;
|
||||
if (wglChoosePixelFormatARB)
|
||||
{
|
||||
int pixelFormatAttribs[] = {
|
||||
@ -1440,10 +1458,10 @@ HGLRC InitOpenGL(HWND hwnd, HDC hdc)
|
||||
WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
|
||||
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
|
||||
WGL_COLOR_BITS_ARB, 32,
|
||||
//WGL_RED_BITS_ARB, 8,
|
||||
//WGL_GREEN_BITS_ARB, 8,
|
||||
//WGL_BLUE_BITS_ARB, 8,
|
||||
//WGL_ALPHA_BITS_ARB, 8,
|
||||
WGL_RED_BITS_ARB, 8,
|
||||
WGL_GREEN_BITS_ARB, 8,
|
||||
WGL_BLUE_BITS_ARB, 8,
|
||||
WGL_ALPHA_BITS_ARB, 8,
|
||||
WGL_DEPTH_BITS_ARB, 24,
|
||||
WGL_STENCIL_BITS_ARB, 8,
|
||||
0 // Terminator
|
||||
@ -1455,10 +1473,18 @@ HGLRC InitOpenGL(HWND hwnd, HDC hdc)
|
||||
{
|
||||
PIXELFORMATDESCRIPTOR newPixelFormatDescriptor = { 0 };
|
||||
DescribePixelFormat(hdc, format, sizeof(newPixelFormatDescriptor), &newPixelFormatDescriptor);
|
||||
SetPixelFormat(hdc, format, &newPixelFormatDescriptor);
|
||||
BOOL success = SetPixelFormat(hdc, format, &newPixelFormatDescriptor);
|
||||
selectedModernPixelFormat = (success == TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
if (!selectedModernPixelFormat)
|
||||
{
|
||||
// If modern pixel format selection failed, fall back to old SetPixelFormat
|
||||
int pixelFormat = ChoosePixelFormat(hdc, &pixelFormatDesc);
|
||||
SetPixelFormat(hdc, pixelFormat, &pixelFormatDesc);
|
||||
}
|
||||
|
||||
// Create real modern OpenGL context (3.3 core)
|
||||
HGLRC realContext = NULL;
|
||||
if (wglCreateContextAttribsARB)
|
||||
@ -1521,10 +1547,18 @@ HGLRC InitOpenGL(HWND hwnd, HDC hdc)
|
||||
// ERROR_INVALID_PROFILE_ARB (0x2096)
|
||||
if (realContext == NULL) TRACELOG(LOG_ERROR, "GL: Error creating requested context: %lu", GetLastError());
|
||||
}
|
||||
else
|
||||
{
|
||||
// If modern context extension isn't available, fall back to classic context creation
|
||||
realContext = wglCreateContext(hdc);
|
||||
}
|
||||
|
||||
// Cleanup dummy temp context
|
||||
// Cleanup dummy temp context and window
|
||||
wglMakeCurrent(NULL, NULL);
|
||||
wglDeleteContext(tempContext);
|
||||
ReleaseDC(dummyWindow, dummyHDC);
|
||||
DestroyWindow(dummyWindow);
|
||||
UnregisterClassW(dummyWindowClass.lpszClassName, dummyWindowClass.hInstance);
|
||||
|
||||
// Activate real context
|
||||
if (realContext) wglMakeCurrent(hdc, realContext);
|
||||
|
||||
@ -111,6 +111,9 @@ static const char cursorLUT[11][12] = {
|
||||
int InitPlatform(void); // Initialize platform (graphics, inputs and more)
|
||||
void ClosePlatform(void); // Close platform
|
||||
|
||||
// OpenGL extensions loader
|
||||
static void *WebGLGetProcAddress(const char *procName); // Get WebGL extension procedure address, used by rlLoadExtensions()
|
||||
|
||||
// Error callback event
|
||||
static void ErrorCallback(int error, const char *description); // GLFW3 Error Callback, runs on GLFW3 error
|
||||
|
||||
@ -1442,7 +1445,7 @@ int InitPlatform(void)
|
||||
|
||||
// Load OpenGL extensions
|
||||
// NOTE: GL procedures address loader is required to load extensions
|
||||
rlLoadExtensions(glfwGetProcAddress);
|
||||
rlLoadExtensions(WebGLGetProcAddress);
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// Initialize events callbacks
|
||||
@ -1499,6 +1502,24 @@ void ClosePlatform(void)
|
||||
glfwTerminate();
|
||||
}
|
||||
|
||||
// Get WebGL extension procedure address
|
||||
// WARNING: rlGetProcAddress() uses this loader, so it only returns the functions listed below
|
||||
static void *WebGLGetProcAddress(const char *procName)
|
||||
{
|
||||
void *proc = NULL;
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||
if (strcmp(procName, "glGenVertexArraysOES") == 0) proc = (void *)glGenVertexArraysOES;
|
||||
else if (strcmp(procName, "glBindVertexArrayOES") == 0) proc = (void *)glBindVertexArrayOES;
|
||||
else if (strcmp(procName, "glDeleteVertexArraysOES") == 0) proc = (void *)glDeleteVertexArraysOES;
|
||||
else if (strcmp(procName, "glDrawArraysInstancedANGLE") == 0) proc = (void *)glDrawArraysInstancedANGLE;
|
||||
else if (strcmp(procName, "glDrawElementsInstancedANGLE") == 0) proc = (void *)glDrawElementsInstancedANGLE;
|
||||
else if (strcmp(procName, "glVertexAttribDivisorANGLE") == 0) proc = (void *)glVertexAttribDivisorANGLE;
|
||||
#endif
|
||||
|
||||
return proc;
|
||||
}
|
||||
|
||||
// GLFW3 callback functions, called on GLFW registered events
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
// GLFW3: Called on errors
|
||||
|
||||
@ -209,6 +209,9 @@ static const char cursorLUT[11][12] = {
|
||||
int InitPlatform(void); // Initialize platform (graphics, inputs and more)
|
||||
void ClosePlatform(void); // Close platform
|
||||
|
||||
// OpenGL extensions loader
|
||||
static void *WebGLGetProcAddress(const char *procName); // Get WebGL extension procedure address, used by rlLoadExtensions()
|
||||
|
||||
// Emscripten window callback events
|
||||
static EM_BOOL EmscriptenResizeCallback(int eventType, const EmscriptenUiEvent *event, void *userData);
|
||||
static EM_BOOL EmscriptenFocusCallback(int eventType, const EmscriptenFocusEvent *focusEvent, void *userData);
|
||||
@ -1387,7 +1390,7 @@ int InitPlatform(void)
|
||||
|
||||
// Load OpenGL extensions
|
||||
// NOTE: GL procedures address loader is required to load extensions
|
||||
if (platform.glContext != 0) rlLoadExtensions(emscripten_webgl_get_proc_address);
|
||||
if (platform.glContext != 0) rlLoadExtensions(WebGLGetProcAddress);
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// Initialize events callbacks
|
||||
@ -1450,6 +1453,24 @@ void ClosePlatform(void)
|
||||
if (platform.glContext != 0) emscripten_webgl_destroy_context(platform.glContext);
|
||||
}
|
||||
|
||||
// Get WebGL extension procedure address
|
||||
// WARNING: rlGetProcAddress() uses this loader, so it only returns the functions listed below
|
||||
static void *WebGLGetProcAddress(const char *procName)
|
||||
{
|
||||
void *proc = NULL;
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||
if (strcmp(procName, "glGenVertexArraysOES") == 0) proc = (void *)glGenVertexArraysOES;
|
||||
else if (strcmp(procName, "glBindVertexArrayOES") == 0) proc = (void *)glBindVertexArrayOES;
|
||||
else if (strcmp(procName, "glDeleteVertexArraysOES") == 0) proc = (void *)glDeleteVertexArraysOES;
|
||||
else if (strcmp(procName, "glDrawArraysInstancedANGLE") == 0) proc = (void *)glDrawArraysInstancedANGLE;
|
||||
else if (strcmp(procName, "glDrawElementsInstancedANGLE") == 0) proc = (void *)glDrawElementsInstancedANGLE;
|
||||
else if (strcmp(procName, "glVertexAttribDivisorANGLE") == 0) proc = (void *)glVertexAttribDivisorANGLE;
|
||||
#endif
|
||||
|
||||
return proc;
|
||||
}
|
||||
|
||||
// Emscripten callback functions, called on specific browser events
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
// Emscripten: Called on resize event
|
||||
|
||||
Reference in New Issue
Block a user