Files
minceraft/src/main.cpp

241 lines
5.1 KiB
C++

/*
Minceraft
By CobaltXII
*/
#include "main.hpp"
// The entry point.
int main(int argc, char** argv)
{
// Initialize SDL.
if (SDL_Init(SDL_INIT_EVERYTHING))
{
std::cout << "Could not initialize SDL." << std::endl;
exit(1);
}
// The dimensions of the SDL_Window*.
int sdl_x_res = 840;
int sdl_y_res = 525;
// Create the SDL_Window*.
SDL_Window* sdl_window = SDL_CreateWindow
(
"Minceraft 0.0.0",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
sdl_x_res,
sdl_y_res,
SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_OPENGL
);
// Make sure the SDL_Window* was created successfully.
if (!sdl_window)
{
std::cout << "Could not create the SDL_Window*." << std::endl;
exit(2);
}
// Request OpenGL 3.3 (core profile).
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
// Request double-buffering.
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
// Request a 24-bit depth buffer. 24-bit depth buffers are supported on
// most modern hardware. Having a floating-point precision of lower than
// 24-bits will cause graphical issues.
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
// Enable vertical retrace synchronization. If this is not enabled, a
// phenomenon known as tearing occurs, which causes half of the screen to
// retain the contents of the last frame instead of the entire screen
// updating immediately.
SDL_GL_SetSwapInterval(1);
// Create the SDL_GLContext.
SDL_GLContext gl_context = SDL_GL_CreateContext(sdl_window);
if (!gl_context)
{
std::cout << "Could not create the SDL_GLContext." << std::endl;
exit(3);
}
// Load all OpenGL 3.3 (core profile) functions using GLAD.
if (!gladLoadGLLoader(SDL_GL_GetProcAddress))
{
std::cout << "Could not load OpenGL functions using GLAD." << std::endl;
exit(4);
}
// Make sure the OpenGL version that was provided is greater than or equal
// to OpenGL 3.3.
if (GLVersion.major * 10 + GLVersion.minor < 33)
{
std::cout << "Could not load OpenGL 3.3 using GLAD. Received OpenGL " << GLVersion.major << "." << GLVersion.minor << " instead." << std::endl;
exit(5);
}
// Load the block texture array.
GLuint block_texture_array = mc_load_block_texture_array();
// Load the block shader program.
GLuint block_shader_program = mc_load_program("../glsl/block_vertex.glsl", "../glsl/block_fragment.glsl");
// Create variables to represent the position of the mouse pointer, and
// state of the mouse buttons.
int sdl_mouse_x = 0;
int sdl_mouse_y = 0;
bool sdl_mouse_l = false;
bool sdl_mouse_r = false;
// Enter the main loop.
bool sdl_running = true;
unsigned long long sdl_iteration = 0;
while (sdl_running)
{
// Remember the time at the start of the frame. At the end of the
// frame, this timestamp will be used to cap the framerate.
auto frame_start_time = std::chrono::high_resolution_clock::now();
// Poll events.
SDL_Event e;
while (SDL_PollEvent(&e))
{
if (e.type == SDL_QUIT)
{
// The application was quit.
sdl_running = false;
}
else if (e.type == SDL_MOUSEMOTION)
{
// The mouse moved.
sdl_mouse_x = e.motion.x;
sdl_mouse_y = e.motion.y;
}
else if (e.type == SDL_MOUSEBUTTONDOWN)
{
// A mouse button was pressed.
if (e.button.button == SDL_BUTTON_LEFT)
{
sdl_mouse_l = true;
}
else if (e.button.button == SDL_BUTTON_RIGHT)
{
sdl_mouse_r = true;
}
}
else if (e.type == SDL_MOUSEBUTTONUP)
{
// A mouse button was released.
if (e.button.button == SDL_BUTTON_LEFT)
{
sdl_mouse_l = false;
}
else if (e.button.button == SDL_BUTTON_RIGHT)
{
sdl_mouse_r = false;
}
}
else if (e.type == SDL_KEYDOWN)
{
// A key was pressed.
SDL_Keycode key = e.key.keysym.sym;
if (key == SDLK_ESCAPE)
{
sdl_running = false;
}
}
}
// Clear the OpenGL context.
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Swap the back buffer to the front, so that the last frame will
// appear on the screen.
SDL_GL_SwapWindow(sdl_window);
// Cap the framerate to 60 Hz.
float frame_elapsed_time = std::chrono::duration<float, std::milli>(std::chrono::high_resolution_clock::now() - frame_start_time).count();
if (frame_elapsed_time < 1000.0f / 60.0f)
{
int frame_sleep_time = round(1000.0f / 60.0f - frame_elapsed_time);
std::this_thread::sleep_for(std::chrono::milliseconds(frame_sleep_time));
}
// Increment the iteration counter. Do not use the iteration counter
// as a precise time measurement!
sdl_iteration++;
if (sdl_iteration % 60 == 0)
{
std::cout << "Running at " << 1000.0f / frame_elapsed_time << " Hz" << std::endl;
}
}
// Destroy all OpenGL related objects.
SDL_GL_DeleteContext(gl_context);
// Destroy all SDL related objects.
SDL_DestroyWindow(sdl_window);
SDL_Quit();
// Exit cleanly.
exit(EXIT_SUCCESS);
}