FreeGlut MacOS Support
This commit is contained in:
@@ -10,6 +10,9 @@ set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
|||||||
# Declare Project where "GSM_TEMPLATE" is the project name
|
# Declare Project where "GSM_TEMPLATE" is the project name
|
||||||
project(GSM_TEMPLATE LANGUAGES C CXX)
|
project(GSM_TEMPLATE LANGUAGES C CXX)
|
||||||
|
|
||||||
|
# Use FreeGlut on Macos (Requires X11 to be installed, but doesn't use it)
|
||||||
|
option(USE_FREEGLUT "Use FreeGLUT on Mac (ignored on Windows)" ON)
|
||||||
|
|
||||||
# Allow cmake to fetch web repositories
|
# Allow cmake to fetch web repositories
|
||||||
include(FetchContent)
|
include(FetchContent)
|
||||||
|
|
||||||
@@ -41,13 +44,28 @@ FetchContent_MakeAvailable(stb_image)
|
|||||||
|
|
||||||
|
|
||||||
# If using the Windows compiler
|
# If using the Windows compiler
|
||||||
if (MSVC)
|
if (MSVC OR USE_FREEGLUT)
|
||||||
|
|
||||||
|
if (APPLE)
|
||||||
|
|
||||||
|
find_path(XQUARTZ_INCLUDE_DIR X11/Xlib.h
|
||||||
|
PATHS /opt/X11/include
|
||||||
|
NO_DEFAULT_PATH
|
||||||
|
)
|
||||||
|
|
||||||
|
if(NOT XQUARTZ_INCLUDE_DIR)
|
||||||
|
message(FATAL_ERROR "To use FreeGLUT on Mac, you need XQuartz installed. Please install it from https://www.xquartz.org/ or set the USE_FREEGLUT cache option to OFF")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_POLICY_VERSION_MINIMUM 3.16)
|
||||||
|
|
||||||
# Download freeglut
|
# Download freeglut
|
||||||
FetchContent_Declare(
|
FetchContent_Declare(
|
||||||
freeglut
|
freeglut
|
||||||
GIT_REPOSITORY https://github.com/freeglut/freeglut.git
|
GIT_REPOSITORY https://github.com/freeglut/freeglut.git
|
||||||
GIT_TAG "master"
|
GIT_TAG "v3.8.0"
|
||||||
GIT_SHALLOW TRUE
|
GIT_SHALLOW TRUE
|
||||||
GIT_PROGRESS ON
|
GIT_PROGRESS ON
|
||||||
)
|
)
|
||||||
@@ -56,6 +74,11 @@ if (MSVC)
|
|||||||
set(FREEGLUT_BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
|
set(FREEGLUT_BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
|
||||||
set(FREEGLUT_BUILD_STATIC_LIBS ON CACHE BOOL "" FORCE)
|
set(FREEGLUT_BUILD_STATIC_LIBS ON CACHE BOOL "" FORCE)
|
||||||
|
|
||||||
|
# Force Cocca on Mac
|
||||||
|
if(APPLE)
|
||||||
|
set(FREEGLUT_USE_X11 OFF CACHE BOOL "" FORCE)
|
||||||
|
set(FREEGLUT_COCOA ON CACHE BOOL "" FORCE)
|
||||||
|
endif()
|
||||||
|
|
||||||
FetchContent_MakeAvailable(freeglut)
|
FetchContent_MakeAvailable(freeglut)
|
||||||
|
|
||||||
@@ -76,8 +99,8 @@ endif()
|
|||||||
# Tell Cmake to find the locations of libraries
|
# Tell Cmake to find the locations of libraries
|
||||||
find_package(OpenGL REQUIRED)
|
find_package(OpenGL REQUIRED)
|
||||||
|
|
||||||
# Only require glut if on macos
|
# Only require glut if on macos and not using freeglut
|
||||||
if (APPLE)
|
if (APPLE AND NOT USE_FREEGLUT)
|
||||||
find_package(GLUT REQUIRED)
|
find_package(GLUT REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
# Define MY_SOURCES to be a list of all the source files for my game
|
# Define MY_SOURCES to be a list of all the source files for my game
|
||||||
@@ -117,6 +140,37 @@ target_sources("${CMAKE_PROJECT_NAME}" PRIVATE ${MY_SOURCES})
|
|||||||
# If on mac
|
# If on mac
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
|
|
||||||
|
# FreeGlut for mac
|
||||||
|
if (USE_FREEGLUT)
|
||||||
|
|
||||||
|
|
||||||
|
target_sources("${CMAKE_PROJECT_NAME}" PRIVATE "${glad_SOURCE_DIR}/src/glad.c")
|
||||||
|
target_include_directories("${CMAKE_PROJECT_NAME}" PUBLIC "${glad_SOURCE_DIR}/include")
|
||||||
|
|
||||||
|
# Add our include files
|
||||||
|
target_include_directories("${CMAKE_PROJECT_NAME}" PUBLIC
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/include/"
|
||||||
|
"${freeglut_SOURCE_DIR}/include"
|
||||||
|
"${glad_SOURCE_DIR}/include"
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_definitions("${CMAKE_PROJECT_NAME}" PUBLIC use_freeglut=TRUE)
|
||||||
|
|
||||||
|
target_link_libraries("${CMAKE_PROJECT_NAME}"
|
||||||
|
PRIVATE
|
||||||
|
OpenGL::GL
|
||||||
|
freeglut_static
|
||||||
|
"-framework Cocoa"
|
||||||
|
"-framework IOKit"
|
||||||
|
"-framework CoreVideo"
|
||||||
|
"-lpthread"
|
||||||
|
stb_image
|
||||||
|
miniaudio
|
||||||
|
)
|
||||||
|
|
||||||
|
# Native GLUT for Mac
|
||||||
|
else()
|
||||||
|
|
||||||
# Add our include files
|
# Add our include files
|
||||||
target_include_directories("${CMAKE_PROJECT_NAME}" PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include/")
|
target_include_directories("${CMAKE_PROJECT_NAME}" PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include/")
|
||||||
|
|
||||||
@@ -138,6 +192,7 @@ target_link_libraries("${CMAKE_PROJECT_NAME}"
|
|||||||
stb_image
|
stb_image
|
||||||
miniaudio
|
miniaudio
|
||||||
)
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
# If on windows
|
# If on windows
|
||||||
|
|||||||
106
src/main.cpp
106
src/main.cpp
@@ -48,8 +48,6 @@
|
|||||||
// #
|
// #
|
||||||
// #############################################################################
|
// #############################################################################
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Libraries
|
// Libraries
|
||||||
#if defined(use_freeglut)
|
#if defined(use_freeglut)
|
||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
@@ -61,8 +59,8 @@
|
|||||||
#include <miniaudio.h>
|
#include <miniaudio.h>
|
||||||
|
|
||||||
// STD
|
// STD
|
||||||
#include <math.h>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <math.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
// Custom includes
|
// Custom includes
|
||||||
@@ -76,14 +74,12 @@
|
|||||||
void ProcessKeys(unsigned char, int, int);
|
void ProcessKeys(unsigned char, int, int);
|
||||||
void ProcessSpecialKeys(int, int, int);
|
void ProcessSpecialKeys(int, int, int);
|
||||||
void MainLoop();
|
void MainLoop();
|
||||||
void GlutLoopTimer(int);
|
|
||||||
|
|
||||||
// Extended Functionality
|
// Extended Functionality
|
||||||
void UpdateViewPort();
|
void UpdateViewPort();
|
||||||
void DrawSprite();
|
void DrawSprite();
|
||||||
void LoadUserTextures();
|
void LoadUserTextures();
|
||||||
|
|
||||||
|
|
||||||
// Miniaudio Engine Declaration
|
// Miniaudio Engine Declaration
|
||||||
void CreateAudioEngine();
|
void CreateAudioEngine();
|
||||||
ma_engine engine; // Miniaudio engine
|
ma_engine engine; // Miniaudio engine
|
||||||
@@ -97,6 +93,25 @@ unsigned int texID;
|
|||||||
ma_sound musicSound; // Miniaudio sound object
|
ma_sound musicSound; // Miniaudio sound object
|
||||||
int lastWinW = 0, lastWinH = 0;
|
int lastWinW = 0, lastWinH = 0;
|
||||||
|
|
||||||
|
bool running = true;
|
||||||
|
void CloseCallBack()
|
||||||
|
{
|
||||||
|
running = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main Loop Timer
|
||||||
|
* Wait 16.7ms then generate next frame (~60FPS)
|
||||||
|
*/
|
||||||
|
void GlutLoopTimer(int v)
|
||||||
|
{
|
||||||
|
// Runs the function specified in glutDisplayFunc
|
||||||
|
glutPostRedisplay();
|
||||||
|
|
||||||
|
// Call the timer again in 16.7 seconds ~ 60 times per second
|
||||||
|
glutTimerFunc(16.7, GlutLoopTimer, v); // Creates a frame delay that is counted in miliseconds
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main entry point of the application
|
* Main entry point of the application
|
||||||
*/
|
*/
|
||||||
@@ -115,10 +130,11 @@ int main(int argc, char **argv)
|
|||||||
// Setup then create the window
|
// Setup then create the window
|
||||||
glutInitWindowSize(winW, winH); // window size
|
glutInitWindowSize(winW, winH); // window size
|
||||||
glutInitWindowPosition(0, 0);
|
glutInitWindowPosition(0, 0);
|
||||||
glutCreateWindow("Transform Example");
|
glutCreateWindow("Transform Example - Using Native Glut");
|
||||||
|
|
||||||
// This line only needs to run when glad is in use
|
// This line only needs to run when glad is in use
|
||||||
#if defined(use_freeglut)
|
#if defined(use_freeglut)
|
||||||
|
glutSetWindowTitle("Transform Example - using FreeGLUT");
|
||||||
if (!gladLoadGL()) { }
|
if (!gladLoadGL()) { }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -147,33 +163,40 @@ int main(int argc, char **argv)
|
|||||||
// Declare Special Keys Keyboard Interrupt
|
// Declare Special Keys Keyboard Interrupt
|
||||||
glutSpecialFunc(ProcessSpecialKeys);
|
glutSpecialFunc(ProcessSpecialKeys);
|
||||||
|
|
||||||
|
#ifndef use_freeglut
|
||||||
// Setup a timer to run the main loop at an interval
|
// Setup a timer to run the main loop at an interval
|
||||||
// (This call will call the GlutLoopTimer() function immediately)
|
// (This call will call the GlutLoopTimer() function immediately)
|
||||||
glutTimerFunc(0, GlutLoopTimer, 0);
|
glutTimerFunc(0, GlutLoopTimer, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
std::cout << "Started";
|
std::cout << "Started" << std::endl;
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
// Start the Glut Loop (Calls the funtions above repeatedly)
|
// Start the Glut Loop (Calls the funtions above repeatedly)
|
||||||
glutMainLoop();
|
|
||||||
|
|
||||||
std::cout << "exited";
|
#if defined(use_freeglut)
|
||||||
|
// FreeGlut allows for manual updating of the main loop
|
||||||
|
// So we can call the main loop in a while loop and tell the loop when to stop
|
||||||
|
|
||||||
|
// Tell FreeGlut to do nothing on window X press
|
||||||
|
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
|
||||||
|
|
||||||
|
// Run callback when window X is pressed
|
||||||
|
glutCloseFunc(CloseCallBack);
|
||||||
|
|
||||||
|
// Our loop, calls the funtion in glutDisplayFunc repeatedly until running = false
|
||||||
|
while (running)
|
||||||
|
glutMainLoopEvent();
|
||||||
|
|
||||||
|
#else
|
||||||
|
// Start the Glut Loop (Calls the funtions above repeatedly)
|
||||||
|
glutMainLoop();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::cout << "exited" << std::endl;
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Main Loop Timer
|
|
||||||
* Wait 16.7ms then generate next frame (~60FPS)
|
|
||||||
*/
|
|
||||||
void GlutLoopTimer(int v)
|
|
||||||
{
|
|
||||||
// Runs the function specified in glutDisplayFunc
|
|
||||||
glutPostRedisplay();
|
|
||||||
|
|
||||||
// Call the timer again in 16.7 seconds ~ 60 times per second
|
|
||||||
glutTimerFunc(16.7, GlutLoopTimer, v); // Creates a frame delay that is counted in miliseconds
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to update the viewport to the size of the window
|
* Function to update the viewport to the size of the window
|
||||||
*/
|
*/
|
||||||
@@ -202,26 +225,22 @@ void UpdateViewPort()
|
|||||||
*/
|
*/
|
||||||
void ProcessSpecialKeys(int key, int x, int y)
|
void ProcessSpecialKeys(int key, int x, int y)
|
||||||
{
|
{
|
||||||
if (key == GLUT_KEY_LEFT)
|
if (key == GLUT_KEY_LEFT) {
|
||||||
{
|
|
||||||
moveX = -10;
|
moveX = -10;
|
||||||
movePressed = true;
|
movePressed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key == GLUT_KEY_RIGHT)
|
if (key == GLUT_KEY_RIGHT) {
|
||||||
{
|
|
||||||
moveX = 10;
|
moveX = 10;
|
||||||
movePressed = true;
|
movePressed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key == GLUT_KEY_UP)
|
if (key == GLUT_KEY_UP) {
|
||||||
{
|
|
||||||
moveY = 10;
|
moveY = 10;
|
||||||
movePressed = true;
|
movePressed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key == GLUT_KEY_DOWN)
|
if (key == GLUT_KEY_DOWN) {
|
||||||
{
|
|
||||||
moveY = -10;
|
moveY = -10;
|
||||||
movePressed = true;
|
movePressed = true;
|
||||||
}
|
}
|
||||||
@@ -233,8 +252,7 @@ void ProcessSpecialKeys(int key, int x, int y)
|
|||||||
*/
|
*/
|
||||||
void ProcessKeys(unsigned char key, int x, int y)
|
void ProcessKeys(unsigned char key, int x, int y)
|
||||||
{
|
{
|
||||||
switch (key)
|
switch (key) {
|
||||||
{
|
|
||||||
case 'q':
|
case 'q':
|
||||||
rotX += 1;
|
rotX += 1;
|
||||||
break;
|
break;
|
||||||
@@ -274,8 +292,7 @@ void ProcessKeys(unsigned char key, int x, int y)
|
|||||||
void CreateAudioEngine()
|
void CreateAudioEngine()
|
||||||
{
|
{
|
||||||
ma_result result = ma_engine_init(NULL, &engine);
|
ma_result result = ma_engine_init(NULL, &engine);
|
||||||
if (result != MA_SUCCESS)
|
if (result != MA_SUCCESS) {
|
||||||
{
|
|
||||||
std::cout << "Failed to setup the miniaudio engine\n";
|
std::cout << "Failed to setup the miniaudio engine\n";
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
@@ -287,8 +304,7 @@ void CreateAudioEngine()
|
|||||||
0,
|
0,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
&musicSound
|
&musicSound);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -302,8 +318,7 @@ void MainLoop()
|
|||||||
int winH = glutGet(GLUT_WINDOW_HEIGHT);
|
int winH = glutGet(GLUT_WINDOW_HEIGHT);
|
||||||
|
|
||||||
// If Changed, update the view port
|
// If Changed, update the view port
|
||||||
if (winW != lastWinW || winH != lastWinH)
|
if (winW != lastWinW || winH != lastWinH) {
|
||||||
{
|
|
||||||
UpdateViewPort();
|
UpdateViewPort();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -313,16 +328,14 @@ void MainLoop()
|
|||||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||||
|
|
||||||
// If scale oneshot is set, scale the image
|
// If scale oneshot is set, scale the image
|
||||||
if (scalePressed)
|
if (scalePressed) {
|
||||||
{
|
|
||||||
glScalef(scale, scale, scale);
|
glScalef(scale, scale, scale);
|
||||||
scalePressed = false;
|
scalePressed = false;
|
||||||
scale = 1;
|
scale = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If rotation oneshot is set, rotate the image
|
// If rotation oneshot is set, rotate the image
|
||||||
if (rotPressed)
|
if (rotPressed) {
|
||||||
{
|
|
||||||
glRotatef((GLfloat)rotX, 1.0, 0.0, 0.0);
|
glRotatef((GLfloat)rotX, 1.0, 0.0, 0.0);
|
||||||
glRotatef((GLfloat)rotY, 0.0, 1.0, 0.0);
|
glRotatef((GLfloat)rotY, 0.0, 1.0, 0.0);
|
||||||
glRotatef((GLfloat)rotZ, 0.0, 0.0, 1.0);
|
glRotatef((GLfloat)rotZ, 0.0, 0.0, 1.0);
|
||||||
@@ -330,8 +343,7 @@ void MainLoop()
|
|||||||
rotX = rotY = rotZ = 0;
|
rotX = rotY = rotZ = 0;
|
||||||
}
|
}
|
||||||
// If move oneshot is set, move the image and set move back to 0
|
// If move oneshot is set, move the image and set move back to 0
|
||||||
if (movePressed)
|
if (movePressed) {
|
||||||
{
|
|
||||||
glTranslatef(moveX, moveY, 0);
|
glTranslatef(moveX, moveY, 0);
|
||||||
movePressed = false;
|
movePressed = false;
|
||||||
moveX = moveY = 0;
|
moveX = moveY = 0;
|
||||||
@@ -344,6 +356,11 @@ void MainLoop()
|
|||||||
|
|
||||||
// Swap buffers to display the new frame
|
// Swap buffers to display the new frame
|
||||||
glutSwapBuffers();
|
glutSwapBuffers();
|
||||||
|
|
||||||
|
// With freeglut, we can trigger screen update right after we are done
|
||||||
|
#if defined(use_freeglut)
|
||||||
|
glutPostRedisplay();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -364,7 +381,6 @@ void DrawSprite()
|
|||||||
glBegin(GL_POLYGON);
|
glBegin(GL_POLYGON);
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
glTexCoord2f(0.0, 0.0);
|
glTexCoord2f(0.0, 0.0);
|
||||||
glVertex3f(-50, -50, 0);
|
glVertex3f(-50, -50, 0);
|
||||||
glTexCoord2f(1.0, 0.0);
|
glTexCoord2f(1.0, 0.0);
|
||||||
|
|||||||
Reference in New Issue
Block a user