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

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");
}