mirror of
https://github.com/bulletphysics/bullet3
synced 2024-12-16 06:30:05 +00:00
ab8f16961e
Apply clang-format-all.sh using the _clang-format file through all the cpp/.h files. make sure not to apply it to certain serialization structures, since some parser expects the * as part of the name, instead of type. This commit contains no other changes aside from adding and applying clang-format-all.sh
594 lines
12 KiB
C++
594 lines
12 KiB
C++
|
|
#ifdef B3_USE_GLFW
|
|
#include "GLFWOpenGLWindow.h"
|
|
|
|
#include <glad/gl.h>
|
|
#include <GLFW/glfw3.h>
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include "LinearMath/btScalar.h"
|
|
|
|
struct GLFWOpenGLWindowInternalData
|
|
{
|
|
bool m_requestedExit;
|
|
bool m_hasCursorPos;
|
|
bool m_altPressed;
|
|
bool m_shiftPressed;
|
|
bool m_ctrlPressed;
|
|
float m_cursorXPos;
|
|
float m_cursorYPos;
|
|
b3MouseMoveCallback m_mouseMoveCallback;
|
|
b3MouseButtonCallback m_mouseButtonCallback;
|
|
b3ResizeCallback m_resizeCallback;
|
|
b3WheelCallback m_wheelCallback;
|
|
b3KeyboardCallback m_keyboardCallback;
|
|
b3RenderCallback m_renderCallback;
|
|
int m_width;
|
|
int m_height;
|
|
float m_retinaScaleFactor;
|
|
|
|
GLFWwindow* m_glfwWindow;
|
|
|
|
GLFWOpenGLWindowInternalData()
|
|
: m_requestedExit(false),
|
|
m_hasCursorPos(false),
|
|
m_altPressed(false),
|
|
m_shiftPressed(false),
|
|
m_ctrlPressed(false),
|
|
m_cursorXPos(0),
|
|
m_cursorYPos(0),
|
|
m_mouseMoveCallback(0),
|
|
m_mouseButtonCallback(0),
|
|
m_resizeCallback(0),
|
|
m_wheelCallback(0),
|
|
m_keyboardCallback(0),
|
|
m_renderCallback(0),
|
|
m_width(0),
|
|
m_height(0),
|
|
m_retinaScaleFactor(1),
|
|
m_glfwWindow(0)
|
|
{
|
|
}
|
|
};
|
|
|
|
static void GLFWErrorCallback(int error, const char* description)
|
|
{
|
|
fprintf(stderr, "Error: %s\n", description);
|
|
}
|
|
|
|
static void GLFWMouseButtonCallback(GLFWwindow* window, int button, int glfwState, int)
|
|
{
|
|
GLFWOpenGLWindow* wnd = (GLFWOpenGLWindow*)glfwGetWindowUserPointer(window);
|
|
if (wnd && wnd->getMouseButtonCallback())
|
|
{
|
|
int state = (glfwState == GLFW_PRESS) ? 1 : 0;
|
|
wnd->mouseButtonCallbackInternal(button, state);
|
|
}
|
|
}
|
|
|
|
static void GLFWScrollCallback(GLFWwindow* window, double deltaX, double deltaY)
|
|
{
|
|
GLFWOpenGLWindow* wnd = (GLFWOpenGLWindow*)glfwGetWindowUserPointer(window);
|
|
if (wnd && wnd->getWheelCallback())
|
|
{
|
|
wnd->getWheelCallback()(deltaX * 100, deltaY * 100);
|
|
}
|
|
}
|
|
|
|
static void GLFWCursorPosCallback(GLFWwindow* window, double xPos, double yPos)
|
|
{
|
|
GLFWOpenGLWindow* wnd = (GLFWOpenGLWindow*)glfwGetWindowUserPointer(window);
|
|
if (wnd && wnd->getMouseMoveCallback())
|
|
{
|
|
wnd->mouseCursorCallbackInternal(xPos, yPos);
|
|
}
|
|
}
|
|
|
|
static void GLFWKeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
|
|
{
|
|
GLFWOpenGLWindow* wnd = (GLFWOpenGLWindow*)glfwGetWindowUserPointer(window);
|
|
if (wnd)
|
|
{
|
|
wnd->keyboardCallbackInternal(key, action);
|
|
}
|
|
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
|
|
{
|
|
glfwSetWindowShouldClose(window, GLFW_TRUE);
|
|
}
|
|
}
|
|
|
|
static void GLFWSizeCallback(GLFWwindow* window, int width, int height)
|
|
{
|
|
GLFWOpenGLWindow* wnd = (GLFWOpenGLWindow*)glfwGetWindowUserPointer(window);
|
|
{
|
|
wnd->resizeInternal(width, height);
|
|
}
|
|
}
|
|
|
|
GLFWOpenGLWindow::GLFWOpenGLWindow()
|
|
{
|
|
m_data = new GLFWOpenGLWindowInternalData();
|
|
}
|
|
|
|
GLFWOpenGLWindow::~GLFWOpenGLWindow()
|
|
{
|
|
if (m_data->m_glfwWindow)
|
|
{
|
|
closeWindow();
|
|
}
|
|
delete m_data;
|
|
}
|
|
|
|
int getBulletKeyFromGLFWKeycode(int glfwKeyCode)
|
|
{
|
|
int keycode = -1;
|
|
if (glfwKeyCode >= 'A' && glfwKeyCode <= 'Z')
|
|
{
|
|
return glfwKeyCode + 32; //todo: fix the ascii A vs a input
|
|
}
|
|
if (glfwKeyCode >= '0' && glfwKeyCode <= '9')
|
|
{
|
|
return glfwKeyCode;
|
|
}
|
|
|
|
switch (glfwKeyCode)
|
|
{
|
|
case GLFW_KEY_ENTER:
|
|
{
|
|
keycode = B3G_RETURN;
|
|
break;
|
|
};
|
|
case GLFW_KEY_ESCAPE:
|
|
{
|
|
keycode = B3G_ESCAPE;
|
|
break;
|
|
};
|
|
case GLFW_KEY_F1:
|
|
{
|
|
keycode = B3G_F1;
|
|
break;
|
|
}
|
|
case GLFW_KEY_F2:
|
|
{
|
|
keycode = B3G_F2;
|
|
break;
|
|
}
|
|
case GLFW_KEY_F3:
|
|
{
|
|
keycode = B3G_F3;
|
|
break;
|
|
}
|
|
case GLFW_KEY_F4:
|
|
{
|
|
keycode = B3G_F4;
|
|
break;
|
|
}
|
|
case GLFW_KEY_F5:
|
|
{
|
|
keycode = B3G_F5;
|
|
break;
|
|
}
|
|
case GLFW_KEY_F6:
|
|
{
|
|
keycode = B3G_F6;
|
|
break;
|
|
}
|
|
case GLFW_KEY_F7:
|
|
{
|
|
keycode = B3G_F7;
|
|
break;
|
|
}
|
|
case GLFW_KEY_F8:
|
|
{
|
|
keycode = B3G_F8;
|
|
break;
|
|
}
|
|
case GLFW_KEY_F9:
|
|
{
|
|
keycode = B3G_F9;
|
|
break;
|
|
}
|
|
case GLFW_KEY_F10:
|
|
{
|
|
keycode = B3G_F10;
|
|
break;
|
|
}
|
|
|
|
//case GLFW_KEY_SPACE: {keycode= ' '; break;}
|
|
|
|
case GLFW_KEY_PAGE_DOWN:
|
|
{
|
|
keycode = B3G_PAGE_DOWN;
|
|
break;
|
|
}
|
|
case GLFW_KEY_PAGE_UP:
|
|
{
|
|
keycode = B3G_PAGE_UP;
|
|
break;
|
|
}
|
|
|
|
case GLFW_KEY_INSERT:
|
|
{
|
|
keycode = B3G_INSERT;
|
|
break;
|
|
}
|
|
case GLFW_KEY_BACKSPACE:
|
|
{
|
|
keycode = B3G_BACKSPACE;
|
|
break;
|
|
}
|
|
case GLFW_KEY_DELETE:
|
|
{
|
|
keycode = B3G_DELETE;
|
|
break;
|
|
}
|
|
|
|
case GLFW_KEY_END:
|
|
{
|
|
keycode = B3G_END;
|
|
break;
|
|
}
|
|
case GLFW_KEY_HOME:
|
|
{
|
|
keycode = B3G_HOME;
|
|
break;
|
|
}
|
|
case GLFW_KEY_LEFT:
|
|
{
|
|
keycode = B3G_LEFT_ARROW;
|
|
break;
|
|
}
|
|
case GLFW_KEY_UP:
|
|
{
|
|
keycode = B3G_UP_ARROW;
|
|
break;
|
|
}
|
|
case GLFW_KEY_RIGHT:
|
|
{
|
|
keycode = B3G_RIGHT_ARROW;
|
|
break;
|
|
}
|
|
case GLFW_KEY_DOWN:
|
|
{
|
|
keycode = B3G_DOWN_ARROW;
|
|
break;
|
|
}
|
|
case GLFW_KEY_RIGHT_SHIFT:
|
|
{
|
|
keycode = B3G_SHIFT;
|
|
break;
|
|
}
|
|
case GLFW_KEY_LEFT_SHIFT:
|
|
{
|
|
keycode = B3G_SHIFT;
|
|
break;
|
|
}
|
|
case GLFW_KEY_MENU:
|
|
{
|
|
keycode = B3G_ALT;
|
|
break;
|
|
}
|
|
case GLFW_KEY_RIGHT_CONTROL:
|
|
{
|
|
keycode = B3G_CONTROL;
|
|
break;
|
|
}
|
|
case GLFW_KEY_LEFT_CONTROL:
|
|
{
|
|
keycode = B3G_CONTROL;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
//keycode = MapVirtualKey( virtualKeyCode, MAPGLFW_KEY_GLFW_KEY_TO_CHAR ) & 0x0000FFFF;
|
|
}
|
|
};
|
|
|
|
return keycode;
|
|
}
|
|
|
|
void GLFWOpenGLWindow::keyboardCallbackInternal(int key, int state)
|
|
{
|
|
if (getKeyboardCallback())
|
|
{
|
|
//convert keyboard codes from glfw to bullet
|
|
int btcode = getBulletKeyFromGLFWKeycode(key);
|
|
int btstate = (state == GLFW_RELEASE) ? 0 : 1;
|
|
|
|
switch (btcode)
|
|
{
|
|
case B3G_SHIFT:
|
|
{
|
|
m_data->m_shiftPressed = state != 0;
|
|
break;
|
|
}
|
|
case B3G_ALT:
|
|
{
|
|
m_data->m_altPressed = state != 0;
|
|
break;
|
|
}
|
|
case B3G_CONTROL:
|
|
{
|
|
m_data->m_ctrlPressed = state != 0;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
}
|
|
}
|
|
|
|
getKeyboardCallback()(btcode, btstate);
|
|
}
|
|
}
|
|
|
|
void GLFWOpenGLWindow::mouseButtonCallbackInternal(int button, int state)
|
|
{
|
|
if (getMouseButtonCallback() && m_data->m_hasCursorPos)
|
|
{
|
|
getMouseButtonCallback()(button, state, m_data->m_cursorXPos, m_data->m_cursorYPos);
|
|
}
|
|
}
|
|
|
|
void GLFWOpenGLWindow::mouseCursorCallbackInternal(double xPos, double yPos)
|
|
{
|
|
if (getMouseMoveCallback())
|
|
{
|
|
m_data->m_hasCursorPos = true;
|
|
m_data->m_cursorXPos = xPos;
|
|
m_data->m_cursorYPos = yPos;
|
|
getMouseMoveCallback()(xPos, yPos);
|
|
}
|
|
}
|
|
|
|
void GLFWOpenGLWindow::resizeInternal(int width, int height)
|
|
{
|
|
glfwGetFramebufferSize(m_data->m_glfwWindow, &m_data->m_width, &m_data->m_height);
|
|
glViewport(0, 0, m_data->m_width, m_data->m_height);
|
|
|
|
if (getResizeCallback())
|
|
{
|
|
getResizeCallback()(m_data->m_width / m_data->m_retinaScaleFactor, m_data->m_height / m_data->m_retinaScaleFactor);
|
|
}
|
|
}
|
|
|
|
void GLFWOpenGLWindow::createDefaultWindow(int width, int height, const char* title)
|
|
{
|
|
b3gWindowConstructionInfo ci;
|
|
ci.m_width = width;
|
|
ci.m_height = height;
|
|
ci.m_title = title;
|
|
|
|
createWindow(ci);
|
|
}
|
|
|
|
void GLFWOpenGLWindow::createWindow(const b3gWindowConstructionInfo& ci)
|
|
{
|
|
btAssert(m_data->m_glfwWindow == 0);
|
|
if (m_data->m_glfwWindow == 0)
|
|
{
|
|
glfwSetErrorCallback(GLFWErrorCallback);
|
|
|
|
if (!glfwInit())
|
|
exit(EXIT_FAILURE);
|
|
|
|
if (ci.m_openglVersion == 2)
|
|
{
|
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
|
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
|
|
}
|
|
else
|
|
{
|
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
|
|
}
|
|
|
|
m_data->m_glfwWindow = glfwCreateWindow(ci.m_width, ci.m_height, ci.m_title, NULL, NULL);
|
|
|
|
if (!m_data->m_glfwWindow)
|
|
{
|
|
glfwTerminate();
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
glfwSetKeyCallback(m_data->m_glfwWindow, GLFWKeyCallback);
|
|
glfwSetMouseButtonCallback(m_data->m_glfwWindow, GLFWMouseButtonCallback);
|
|
|
|
glfwSetCursorPosCallback(m_data->m_glfwWindow, GLFWCursorPosCallback);
|
|
glfwSetScrollCallback(m_data->m_glfwWindow, GLFWScrollCallback);
|
|
|
|
glfwSetWindowSizeCallback(m_data->m_glfwWindow, GLFWSizeCallback);
|
|
glfwSetWindowUserPointer(m_data->m_glfwWindow, this);
|
|
|
|
glfwMakeContextCurrent(m_data->m_glfwWindow);
|
|
gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
|
|
glfwSwapInterval(0); //1);
|
|
glfwGetFramebufferSize(m_data->m_glfwWindow, &m_data->m_width, &m_data->m_height);
|
|
int windowWidth, windowHeight;
|
|
glfwGetWindowSize(m_data->m_glfwWindow, &windowWidth, &windowHeight);
|
|
m_data->m_retinaScaleFactor = float(m_data->m_width) / float(windowWidth);
|
|
glViewport(0, 0, m_data->m_width, m_data->m_height);
|
|
}
|
|
}
|
|
|
|
void GLFWOpenGLWindow::closeWindow()
|
|
{
|
|
if (m_data->m_glfwWindow)
|
|
{
|
|
glfwDestroyWindow(m_data->m_glfwWindow);
|
|
|
|
glfwTerminate();
|
|
m_data->m_glfwWindow = 0;
|
|
}
|
|
}
|
|
|
|
void GLFWOpenGLWindow::runMainLoop()
|
|
{
|
|
}
|
|
|
|
float GLFWOpenGLWindow::getTimeInSeconds()
|
|
{
|
|
return 0.f;
|
|
}
|
|
|
|
bool GLFWOpenGLWindow::requestedExit() const
|
|
{
|
|
bool shouldClose = m_data->m_requestedExit;
|
|
|
|
if (m_data->m_glfwWindow)
|
|
{
|
|
shouldClose = shouldClose || glfwWindowShouldClose(m_data->m_glfwWindow);
|
|
}
|
|
return shouldClose;
|
|
}
|
|
|
|
void GLFWOpenGLWindow::setRequestExit()
|
|
{
|
|
if (m_data->m_glfwWindow)
|
|
{
|
|
glfwSetWindowShouldClose(m_data->m_glfwWindow, GLFW_TRUE);
|
|
}
|
|
m_data->m_requestedExit = true;
|
|
}
|
|
|
|
void GLFWOpenGLWindow::startRendering()
|
|
{
|
|
if (m_data->m_glfwWindow)
|
|
{
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
|
}
|
|
}
|
|
|
|
void GLFWOpenGLWindow::endRendering()
|
|
{
|
|
glfwPollEvents();
|
|
glfwSwapBuffers(m_data->m_glfwWindow);
|
|
}
|
|
|
|
bool GLFWOpenGLWindow::isModifierKeyPressed(int key)
|
|
{
|
|
bool result = false;
|
|
|
|
switch (key)
|
|
{
|
|
case B3G_SHIFT:
|
|
{
|
|
result = m_data->m_shiftPressed;
|
|
break;
|
|
}
|
|
case B3G_ALT:
|
|
{
|
|
result = m_data->m_altPressed;
|
|
break;
|
|
}
|
|
case B3G_CONTROL:
|
|
{
|
|
result = m_data->m_ctrlPressed;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void GLFWOpenGLWindow::setMouseMoveCallback(b3MouseMoveCallback mouseCallback)
|
|
{
|
|
m_data->m_mouseMoveCallback = mouseCallback;
|
|
}
|
|
|
|
b3MouseMoveCallback GLFWOpenGLWindow::getMouseMoveCallback()
|
|
{
|
|
return m_data->m_mouseMoveCallback;
|
|
}
|
|
|
|
void GLFWOpenGLWindow::setMouseButtonCallback(b3MouseButtonCallback mouseCallback)
|
|
{
|
|
m_data->m_mouseButtonCallback = mouseCallback;
|
|
}
|
|
|
|
b3MouseButtonCallback GLFWOpenGLWindow::getMouseButtonCallback()
|
|
{
|
|
return m_data->m_mouseButtonCallback;
|
|
}
|
|
|
|
void GLFWOpenGLWindow::setResizeCallback(b3ResizeCallback resizeCallback)
|
|
{
|
|
m_data->m_resizeCallback = resizeCallback;
|
|
getResizeCallback()(m_data->m_width / getRetinaScale(), m_data->m_height / getRetinaScale());
|
|
}
|
|
|
|
b3ResizeCallback GLFWOpenGLWindow::getResizeCallback()
|
|
{
|
|
return m_data->m_resizeCallback;
|
|
}
|
|
|
|
void GLFWOpenGLWindow::setWheelCallback(b3WheelCallback wheelCallback)
|
|
{
|
|
m_data->m_wheelCallback = wheelCallback;
|
|
}
|
|
|
|
b3WheelCallback GLFWOpenGLWindow::getWheelCallback()
|
|
{
|
|
return m_data->m_wheelCallback;
|
|
}
|
|
|
|
void GLFWOpenGLWindow::setKeyboardCallback(b3KeyboardCallback keyboardCallback)
|
|
{
|
|
m_data->m_keyboardCallback = keyboardCallback;
|
|
}
|
|
|
|
b3KeyboardCallback GLFWOpenGLWindow::getKeyboardCallback()
|
|
{
|
|
return m_data->m_keyboardCallback;
|
|
}
|
|
|
|
void GLFWOpenGLWindow::setRenderCallback(b3RenderCallback renderCallback)
|
|
{
|
|
m_data->m_renderCallback = renderCallback;
|
|
}
|
|
|
|
void GLFWOpenGLWindow::setWindowTitle(const char* title)
|
|
{
|
|
if (m_data->m_glfwWindow)
|
|
{
|
|
glfwSetWindowTitle(m_data->m_glfwWindow, title);
|
|
}
|
|
}
|
|
|
|
float GLFWOpenGLWindow::getRetinaScale() const
|
|
{
|
|
return m_data->m_retinaScaleFactor;
|
|
}
|
|
void GLFWOpenGLWindow::setAllowRetina(bool allow)
|
|
{
|
|
}
|
|
|
|
int GLFWOpenGLWindow::getWidth() const
|
|
{
|
|
if (m_data->m_glfwWindow)
|
|
{
|
|
glfwGetFramebufferSize(m_data->m_glfwWindow, &m_data->m_width, &m_data->m_height);
|
|
}
|
|
int width = m_data->m_width / m_data->m_retinaScaleFactor;
|
|
return width;
|
|
}
|
|
int GLFWOpenGLWindow::getHeight() const
|
|
{
|
|
if (m_data->m_glfwWindow)
|
|
{
|
|
glfwGetFramebufferSize(m_data->m_glfwWindow, &m_data->m_width, &m_data->m_height);
|
|
}
|
|
return m_data->m_height / m_data->m_retinaScaleFactor;
|
|
}
|
|
|
|
int GLFWOpenGLWindow::fileOpenDialog(char* fileName, int maxFileNameLength)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
#endif //B3_USE_GLFW
|