Base Template

Supports MacOS (ARM)
Windows is Untested
Linux is Untested
This commit is contained in:
Colton Staiduhar
2026-02-05 15:14:03 -05:00
parent d55a0dff9a
commit 96b71da74b
8 changed files with 610 additions and 0 deletions

9
.gitignore vendored Normal file
View File

@@ -0,0 +1,9 @@
*.DS_Store
.vscode/
build/
thirdparty/
CMakeFiles/
CmakeCache.txt
cmake_install.cmake
Makefile
GSM_TEMPLATE

113
CMakeLists.txt Executable file
View File

@@ -0,0 +1,113 @@
# This cmake configuration was originally created by meemknight on github
# https://github.com/meemknight/cmakeSetup
# It has been modified for use in this repository by Colton Staiduhar
cmake_minimum_required(VERSION 3.16)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Release>:Release>")
# Declare Project where "GSM_TEMPLATE" is the project name
project(GSM_TEMPLATE LANGUAGES C CXX)
# Allow cmake to fetch web repositories
include(FetchContent)
# Set the location for downloaded libraries
set(THIRDPARTY_DIR "${CMAKE_CURRENT_SOURCE_DIR}/thirdparty")
set(FETCHCONTENT_BASE_DIR "${THIRDPARTY_DIR}")
# Fetch the miniaudio Repository and install it
FetchContent_Declare(
miniaudio
GIT_REPOSITORY git@github.com:mackron/miniaudio.git
GIT_TAG "master"
GIT_SHALLOW TRUE
GIT_PROGRESS ON
SYSTEM
)
FetchContent_MakeAvailable(miniaudio)
# Fetch the STB-Image Repository and install it
FetchContent_Declare(
stb_image
GIT_REPOSITORY git@github.com:arizotaz/cmake_stb_image
GIT_TAG "master"
GIT_SHALLOW TRUE
GIT_PROGRESS ON
SYSTEM
)
FetchContent_MakeAvailable(stb_image)
# Tell Cmake to find the locations of libraries
find_package(OpenGL REQUIRED)
find_package(GLUT REQUIRED)
# Define MY_SOURCES to be a list of all the source files for my game
file(GLOB_RECURSE MY_SOURCES CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")
add_executable("${CMAKE_PROJECT_NAME}")
# Set the C++ standard to 17
set_property(TARGET "${CMAKE_PROJECT_NAME}" PROPERTY CXX_STANDARD 17)
#========================================================================================
# CHANGE RESOURCES DEFINITION
#========================================================================================
# You will change which line is commented depending
# on if the compiled binary is for development or
# production.
#
# Uncomment the line below when in development, this uses the resources folder
# in the CMake project for the RESOURCES_PATH definition
target_compile_definitions("${CMAKE_PROJECT_NAME}" PUBLIC RESOURCES_PATH="${CMAKE_CURRENT_SOURCE_DIR}/resources/")
#
# Uncomment the line below when in production, this uses a folder in the same working
# directory of the binary called "resources". Effectively RESOURCES_PATH
# becomes ./resources/. You would copy the resources folder of the cmake project
# and ship it will the compiled binary
#target_compile_definitions("${CMAKE_PROJECT_NAME}" PUBLIC RESOURCES_PATH="./resources/")
#
# Add our sources
target_sources("${CMAKE_PROJECT_NAME}" PRIVATE ${MY_SOURCES} )
# If using the VS compiler
if(MSVC)
target_compile_definitions("${CMAKE_PROJECT_NAME}" PUBLIC _CRT_SECURE_NO_WARNINGS)
#remove console
#set_target_properties("${CMAKE_PROJECT_NAME}" PROPERTIES LINK_FLAGS "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")
set_property(TARGET "${CMAKE_PROJECT_NAME}" PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreadedDebug<$<CONFIG:Debug>:Debug>")
set_property(TARGET "${CMAKE_PROJECT_NAME}" PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Release>:Release>")
endif()
# Add our include files
target_include_directories("${CMAKE_PROJECT_NAME}" PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include/")
# Disable different warning (Glut is really old, we already know that)
target_compile_options("${CMAKE_PROJECT_NAME}"
PRIVATE
-Wno-deprecated-declarations
-Wdelete-incomplete
$<$<CXX_COMPILER_ID:Clang>:-Wno-pedantic -Wno-macro-redefined>
)
# Include the libraries loaded earlier
target_link_libraries("${CMAKE_PROJECT_NAME}"
PRIVATE
OpenGL::GL
"-framework GLUT"
"-lpthread"
"-lm"
stb_image
miniaudio
)

View File

@@ -1,2 +1,6 @@
# GlutSTBMiniAudio-Template # GlutSTBMiniAudio-Template
To compile the project
```
cmake .; make; ./GSM_TEMPLATE
```

37
include/texture.h Normal file
View File

@@ -0,0 +1,37 @@
//#############################################################################
//# texture.h
//#############################################################################
//# Written by Colton Staiduhar
//# Date Created: 02/05/2025
//# Last Modification: 02/05/2025
//#############################################################################
//# This file serves as simple, yet functional example of how to use the
//# include directory of this project
//#############################################################################
//# This header exposses the LoadTexture function of this project.
//# Usage:
//# unsigned int textureID = LoadTexture(fileURL);
//#
//# Where textureID is the returned OpenGL texture ID that can be bounded
//#
//#############################################################################
#ifndef TEXTURES_H
#define TEXTRUES_H
/**
* Loads a texture for use in OpenGL with STB
*
* Usage:
* unsigned int textureID = LoadTexture(fileURL)
*
* textureID - the generated OpenGL Texture ID
*
* Bind texture with
* glBindTexture(GL_TEXTURE_2D, textureID);
*/
unsigned int LoadTexture(char *location);
#endif

Binary file not shown.

BIN
resources/container.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

377
src/main.cpp Executable file
View File

@@ -0,0 +1,377 @@
//#############################################################################
//# main.cpp
//#############################################################################
//# Written by Colton Staiduhar
//# Date Created: 02/03/2025
//# Last Modification: 02/05/2025
//#############################################################################
//# Main Entry point for Cmake project, declare by the int main() function
//#############################################################################
//#
//# This is a simple demonstration of GLUT functioning using STB_Image.H for
//# loading images and MiniAudio.h for playing audio. The repositories for
//# these libraries can be found below.
//#
//# Miniaudio
//# https://github.com/mackron/miniaudio
//#
//# STB_Image.h
//# https://github.com/arizotaz/cmake_stb_image
//#
//#############################################################################
//#
//# For GLUT/OpenGL, the operating system should have GLUT in some form already
//# installed. However, freeglut exists as the modern implementation of GLUT.
//#
//# GLUT
//# You're on your own for this, but here are some helpful implementation docs
//# MacOS: https://developer.apple.com/library/archive/documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide/opengl_drawing/opengl_drawing.html
//# Windows & Linux: https://www.opengl.org/resources/libraries/glut/glut_downloads.php
//#
//# FreeGLUT:
//# https://freeglut.sourceforge.net/docs/api.php
//#
//#############################################################################
//#
//# This file will setup much of GLUT. Getting some output to the screen
//# The following is executed:
//# Create a windows with GLUT's API
//# Create a display update timer
//# Create Keyboard Interrupts
//# Load textures the included Texture.H file
//# Setup the audio engine from MiniAudio
//# Declare the Main Loop funcitons
//# Draw a sprite to the screen
//# Texture said sprite with an image
//# Rotate, move, and scale the sprite
//# Apply translations via user keyboard input
//#
//#############################################################################
// Libraries
#include <GLUT/glut.h>
#include <miniaudio.h>
// STD
#include <math.h>
#include <iostream>
#include <stdio.h>
// Custom includes
#include <texture.h>
/**
* Function Prototypes
*/
// Basic Glut
void ProcessKeys(unsigned char, int, int);
void ProcessSpecialKeys(int, int, int);
void MainLoop();
void GlutLoopTimer(int);
// Extended Functionality
void UpdateViewPort();
void DrawSprite();
void LoadUserTextures();
// Miniaudio Engine Declaration
void CreateAudioEngine();
ma_engine engine; // Miniaudio engine
// Demo Program Variables
float rotX, rotY, rotZ;
float moveX, moveY;
float scale = 1;
bool rotPressed, movePressed, scalePressed;
unsigned int texID;
ma_sound musicSound; // Miniaudio sound object
int lastWinW = 0, lastWinH = 0;
/**
* Main entry point of the application
*/
int main(int argc, char **argv)
{
int winW = 1280;
int winH = 720;
// Initialize GLUT
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB); // RGB mode
// Setup then create the window
glutInitWindowSize(winW, winH); // window size
glutInitWindowPosition(0, 0);
glutCreateWindow("Transform Example");
// Clear screen
glClearColor(0.0, 0.0, 0.0, 1.0); // clear the window screen
// Sets up the viewport
UpdateViewPort();
// Calls the texture load method
LoadUserTextures();
// Setup Audio Engine
CreateAudioEngine();
// Play the music
ma_sound_start(&musicSound);
// Deplare the Main Loop Function
// (Will be executed when glutPostRedisplay() is called in the timer)
glutDisplayFunc(MainLoop);
// Declare Keyboard Interupts
glutKeyboardFunc(ProcessKeys);
// Declare Special Keys Keyboard Interrupt
glutSpecialFunc(ProcessSpecialKeys);
// Setup a timer to run the main loop at an interval
// (This call will call the GlutLoopTimer() function immediately)
glutTimerFunc(0, GlutLoopTimer, 0);
// Start the Glut Loop (Calls the funtions above repeatedly)
glutMainLoop();
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
*/
void UpdateViewPort()
{
// Gets the window size
int winW = glutGet(GLUT_WINDOW_WIDTH);
int winH = glutGet(GLUT_WINDOW_HEIGHT);
// Sets up OpenGL Matrix Mode
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Create projection type (Orthographic with size of window)
glOrtho(-winW / 2, winW / 2, winH / 2, -winH / 2, -1000.0f, 1000.0f); // Clipping plane is set to 1000 behind camera and 1000 infront, this works because ortho is cool
// Set last size to the new size
lastWinW = winW;
lastWinH = winH;
}
/**
* The function set as the Keyboard Interrupt of GLUT
* This function will be called whenever a keystrke is pressed by the user
* This function suffers from key repeat
*/
void ProcessSpecialKeys(int key, int x, int y)
{
if (key == GLUT_KEY_LEFT)
{
moveX = -10;
movePressed = true;
}
if (key == GLUT_KEY_RIGHT)
{
moveX = 10;
movePressed = true;
}
if (key == GLUT_KEY_UP)
{
moveY = 10;
movePressed = true;
}
if (key == GLUT_KEY_DOWN)
{
moveY = -10;
movePressed = true;
}
}
/**
* Processes Keys as characters instead of keys
* IE when a is pressed, "key" is set to "a" instead of 65
*/
void ProcessKeys(unsigned char key, int x, int y)
{
switch (key)
{
case 'q':
rotX += 1;
break;
case 'w':
rotY += 1;
break;
case 'e':
rotZ += 1;
break;
case 'a':
rotX -= 1;
break;
case 's':
rotY -= 1;
break;
case 'd':
rotZ -= 1;
break;
case 'p':
scale += .1;
break;
case 'l':
scale -= .1;
break;
case 27: // escape
exit(0);
}
rotPressed = true;
scalePressed = true;
}
/**
* Creates the miniaudio engine
* (Bare minimum to play a sound)
*/
void CreateAudioEngine()
{
ma_result result = ma_engine_init(NULL, &engine);
if (result != MA_SUCCESS)
{
std::cout << "Failed to setup the miniaudio engine\n";
fflush(stdout);
}
// Play Test Sound
ma_sound_init_from_file(
&engine,
RESOURCES_PATH "audio/CrazyLaPaint.mp3",
0,
NULL,
NULL,
&musicSound
);
}
/**
* This is the main loop functions that was declared during window creation
*/
void MainLoop()
{
// Get the window size
int winW = glutGet(GLUT_WINDOW_WIDTH);
int winH = glutGet(GLUT_WINDOW_HEIGHT);
// If Changed, update the view port
if (winW != lastWinW || winH != lastWinH)
{
UpdateViewPort();
}
// Clear the screen
glClear(GL_COLOR_BUFFER_BIT);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
// If scale oneshot is set, scale the image
if (scalePressed)
{
glScalef(scale, scale, scale);
scalePressed = false;
scale = 1;
}
// If rotation oneshot is set, rotate the image
if (rotPressed)
{
glRotatef((GLfloat)rotX, 1.0, 0.0, 0.0);
glRotatef((GLfloat)rotY, 0.0, 1.0, 0.0);
glRotatef((GLfloat)rotZ, 0.0, 0.0, 1.0);
rotPressed = false;
rotX = rotY = rotZ = 0;
}
// If move oneshot is set, move the image and set move back to 0
if (movePressed)
{
glTranslatef(moveX, moveY, 0);
movePressed = false;
moveX = moveY = 0;
}
// Draws the image
DrawSprite();
glFlush();
// Swap buffers to display the new frame
glutSwapBuffers();
}
/**
* Our function to draw the image
*/
void DrawSprite()
{
// Set texture enviorment
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
// Enable textures so OpenGL will apply the textures to the created object
glEnable(GL_TEXTURE_2D);
// Bind our texture
glBindTexture(GL_TEXTURE_2D, texID); // Which texture
// Create a polygon and apply textures to it
glBegin(GL_POLYGON);
{
glTexCoord2f(0.0, 0.0);
glVertex3f(-50, -50, 0);
glTexCoord2f(1.0, 0.0);
glVertex3f(50, -50, 0);
glTexCoord2f(1.0, 1.0);
glVertex3f(50, 50, 0);
glTexCoord2f(0.0, 1.0);
glVertex3f(-50, 50, 0);
}
glEnd();
// Disable textures so you dont continue adding textures to other objects
glDisable(GL_TEXTURE_2D); // Turn texturing off
}
/**
* Just loads a bunch of textures
*/
void LoadUserTextures()
{
/*
We add RESOURCES_PATH to the front of the filename
RESOURCES_PATH is the absolute path of the resources folder on the computer
when the application is build for production it turns into a relative path
*/
texID = LoadTexture(RESOURCES_PATH "container.jpg");
}

70
src/texture.cpp Normal file
View File

@@ -0,0 +1,70 @@
//#############################################################################
//# texture.cpp
//#############################################################################
//# Written by Colton Staiduhar
//# Date Created: 02/05/2025
//# Last Modification: 02/05/2025
//#############################################################################
//# Super simple OpenGL texture loading using the stb_image.h library
//#############################################################################
//# This file provides sources of the functions listed in Texture.h
//#############################################################################
// Include STB
#include <GLUT/glut.h>
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image/stb_image.h>
// Header file for functions defined here
#include <texture.h>
/**
* Loads a texture for use in OpenGL with STB
*/
unsigned int LoadTexture(char *location)
{
// These will be filled with attributes of the file once loaded
int w, // Width of image
h, // Height of image
bpp; // Number of color channels in the image
// Load the image and save raw pixel data as unsigned bytes
unsigned char *pixels = stbi_load(location, &w, &h, &bpp, 3);
// Declare our texture, this will be filled with the texture ID
unsigned int texture;
// Tell OpenGL to generate a texture slot and bind it to the current texture
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
// These are option values, but they are nice to set
{
// Set OpenGL texture Wrapping
// I prefer CLAMP_TO_EDGE but GL_REPEAT works too, look up the different OpenGL Texture Wrap Types
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// Set the type of Texture Filtering
// "GL_LINEAR" is default, I like GL_NEAREST. Again, look up all the options
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
// If the loaded pixel data is value
if (pixels)
{
// Load the texture data into the currently bound texture slot
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
// Generate the mipmap cause why not
glGenerateMipmap(GL_TEXTURE_2D);
}
// Frees the image data stored in ram from stb
stbi_image_free(pixels);
// Return the texture ID
return texture;
}