forked from Redacted/Re3D
initial commit
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/cmake-build-debug
|
||||
/.idea
|
21
CMakeLists.txt
Normal file
21
CMakeLists.txt
Normal file
@@ -0,0 +1,21 @@
|
||||
cmake_minimum_required(VERSION 3.18)
|
||||
project(SDL3D)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
||||
add_executable(SDL3D src/main.cpp
|
||||
src/types/entity.h
|
||||
src/types/camera.h
|
||||
src/types/world.h
|
||||
src/engine/engine.h
|
||||
src/types/vector3.h
|
||||
src/types/player.h
|
||||
src/types/entityList.h
|
||||
src/engine/render.h
|
||||
src/engine/tick.h
|
||||
src/types/vertex.h
|
||||
src/types/skybox.h
|
||||
src/types/geometry.h)
|
||||
|
||||
find_package(OpenGL)
|
||||
target_link_libraries(SDL3D SDL2 freeimage ${OPENGL_LIBRARIES})
|
24
LICENSE
Normal file
24
LICENSE
Normal file
@@ -0,0 +1,24 @@
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to <https://unlicense.org>
|
2
run.sh
Executable file
2
run.sh
Executable file
@@ -0,0 +1,2 @@
|
||||
sleep 0.5
|
||||
vblank_mode=0 mangohud --dlsym /home/william/Documents/GitHub/SDL3D/cmake-build-debug/SDL3D
|
152
src/engine/engine.h
Normal file
152
src/engine/engine.h
Normal file
@@ -0,0 +1,152 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_opengl.h>
|
||||
#include <GL/glu.h>
|
||||
#include <FreeImage.h>
|
||||
|
||||
enum class gamestate: uint8_t {
|
||||
NORMAL = 0, //Gameplay.
|
||||
IN_MAIN_MENU = 1,
|
||||
IN_PAUSE_MENU = 2,
|
||||
IN_LEVEL_ANIMATION = 3, //A cutscene which moves entities in the world and cannot be interrupted.
|
||||
IN_QUIT = 4, //The game should close.
|
||||
NULL_ = 7
|
||||
};
|
||||
|
||||
class Engine {
|
||||
public:
|
||||
gamestate gameState = gamestate::NULL_;
|
||||
bool debug = true;
|
||||
bool takingScreenshot = false; //Because
|
||||
SDL_Window *window = nullptr;
|
||||
uint16_t windowWidth = 1152;
|
||||
uint16_t windowHeight = 864;
|
||||
ulong tickCount = 0;
|
||||
float tickDelta = NULL;
|
||||
ulong frameCount = 0;
|
||||
float frameDelta = NULL;
|
||||
uint16_t minimumTickDelta = 15625;
|
||||
GLenum glError = GL_NO_ERROR;
|
||||
SDL_GLContext glContext = nullptr;
|
||||
float nearPlane = 0.01f;
|
||||
float farPlane = 100.0f;
|
||||
float fov = 70.0f;
|
||||
SDL_Event event;
|
||||
|
||||
|
||||
[[nodiscard]] float framerate() const {
|
||||
return 1.f / this->frameDelta;
|
||||
}
|
||||
|
||||
void takeScreenshot() {
|
||||
if (!this->takingScreenshot)
|
||||
return;
|
||||
FreeImage_Initialise();
|
||||
auto* fbData = new GLubyte[this->windowWidth * this->windowHeight * 3];
|
||||
glReadPixels(0, 0, this->windowWidth, this->windowHeight, GL_RGB, GL_UNSIGNED_BYTE, fbData);
|
||||
FIBITMAP* image = FreeImage_ConvertFromRawBits(fbData, this->windowWidth, this->windowHeight, this->windowWidth * 3, 24, 0xFF0000, 0x00FF00, 0x0000FF, false);
|
||||
FreeImage_Save(FIF_BMP, image, std::to_string(this->frameCount).c_str(), 0);
|
||||
FreeImage_Unload(image);
|
||||
delete[] fbData;
|
||||
FreeImage_DeInitialise();
|
||||
this->takingScreenshot = false;
|
||||
}
|
||||
|
||||
void takeScreenshot(const char* filename) {
|
||||
if (!this->takingScreenshot)
|
||||
return;
|
||||
FreeImage_Initialise();
|
||||
auto* fbData = new GLubyte[this->windowWidth * this->windowHeight * 3];
|
||||
glReadPixels(0, 0, this->windowWidth, this->windowHeight, GL_RGB, GL_UNSIGNED_BYTE, fbData);
|
||||
FIBITMAP* image = FreeImage_ConvertFromRawBits(fbData, this->windowWidth, this->windowHeight, this->windowWidth * 3, 24, 0xFF0000, 0x00FF00, 0x0000FF, false);
|
||||
FreeImage_Save(FIF_BMP, image, filename, 0);
|
||||
FreeImage_Unload(image);
|
||||
delete[] fbData;
|
||||
FreeImage_DeInitialise();
|
||||
this->takingScreenshot = false;
|
||||
}
|
||||
|
||||
void quit() {
|
||||
SDL_DestroyWindow(this->window);
|
||||
SDL_Quit();
|
||||
exit(0);
|
||||
}
|
||||
static float getGLVersion() {
|
||||
std::string str = reinterpret_cast<const char *>(glGetString(GL_VERSION));
|
||||
str.erase(str.begin()+3,str.end());
|
||||
return std::stof(str);
|
||||
}
|
||||
|
||||
void initGL() {
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
//glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -0.5f, 0.5f);
|
||||
gluPerspective(this->fov, this->windowWidth / this->windowHeight, this->nearPlane, this->farPlane);
|
||||
this->glError = glGetError();
|
||||
|
||||
if (glError != GL_NO_ERROR) {
|
||||
std::cerr << "OpenGL: " << gluErrorString(glError);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
if (glError != GL_NO_ERROR) {
|
||||
std::cerr << "OpenGL: " << gluErrorString(glError);
|
||||
exit (1);
|
||||
}
|
||||
glClearColor(0.f, 0.f, 0.f, 1.f);
|
||||
glViewport(0,0,this->windowWidth,this->windowHeight);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LESS);
|
||||
glDepthMask(GL_TRUE);
|
||||
glClearDepth(1.0f);
|
||||
glDisable(GL_CULL_FACE);
|
||||
//glDepthRange(-0.5f,0.5f);
|
||||
}
|
||||
|
||||
void initVideo() {
|
||||
|
||||
Uint32 sdl_initializer_flags = SDL_INIT_VIDEO;// | SDL_INIT_AUDIO;
|
||||
|
||||
// Start SDL, check for errors
|
||||
if (SDL_Init(sdl_initializer_flags) < 0) {
|
||||
std::cerr << "SDL_Error: " << SDL_GetError() << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Create the window, set resizable, check for errors
|
||||
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 1);
|
||||
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 4);
|
||||
SDL_GL_SetSwapInterval(0);
|
||||
this->window = SDL_CreateWindow("SDL3D", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, this->windowWidth, this->windowHeight, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
|
||||
SDL_SetWindowResizable(this->window,SDL_FALSE);
|
||||
this->glContext = SDL_GL_CreateContext(window);
|
||||
|
||||
if (isless(this->getGLVersion(),1.4f)) {
|
||||
std::cerr << "Driver OpenGL version: " << this->getGLVersion() << std::endl;
|
||||
std::cerr << "OpenGL >= 1.4 is required." << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (this->window == nullptr) {
|
||||
std::cerr << "SDL_Error: " << SDL_GetError() << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void debugInfo() {
|
||||
if (this->debug) {
|
||||
std::cout << "Last tick completed in: " << (tickDelta / 1000) << "ms, " << "sleeping " << ((minimumTickDelta - tickDelta) / 1000) << "ms." << std::endl;
|
||||
std::cout << "Last frame dT: " << this->frameDelta << std::endl;
|
||||
std::cout << "Framerate: " << framerate() << std::endl;;
|
||||
//std::cout << "EntityCount: " << entityList.list.size() << std::endl;
|
||||
//std::cout << "Camera Position: " << "X " << entityList.getCamera()->position.x << " Y " << entityList.getCamera()->position.y << " Z " << entityList.getCamera()->position.z << std::endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
auto* engine = new(Engine);
|
129
src/engine/render.h
Normal file
129
src/engine/render.h
Normal file
@@ -0,0 +1,129 @@
|
||||
#pragma once
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include "engine.h"
|
||||
#include "../types/camera.h"
|
||||
#include "../types/entityList.h"
|
||||
|
||||
|
||||
void process_sdl_events() {
|
||||
while (SDL_PollEvent(&engine->event)) {
|
||||
// TODO: Consider switch statements as opposed to ifs
|
||||
// This adds control flow in the form of "break" statement.
|
||||
// Which will save checking every single event type unnecessarily
|
||||
|
||||
if (engine->event.type == SDL_QUIT) {engine->quit();}
|
||||
if (engine->event.type == SDL_DROPFILE) {}
|
||||
|
||||
// Window Events
|
||||
if (engine->event.type == SDL_WINDOWEVENT) {
|
||||
auto window_ev = engine->event.window;
|
||||
auto ev_type = window_ev.event;
|
||||
if (ev_type == SDL_WINDOWEVENT_FOCUS_LOST) {}
|
||||
if (ev_type == SDL_WINDOWEVENT_FOCUS_GAINED) {}
|
||||
if (ev_type == SDL_WINDOWEVENT_CLOSE) {}
|
||||
if (ev_type == SDL_WINDOWEVENT_SHOWN) {}
|
||||
if (ev_type == SDL_WINDOWEVENT_HIDDEN) {}
|
||||
if (ev_type == SDL_WINDOWEVENT_EXPOSED) {}
|
||||
if (ev_type == SDL_WINDOWEVENT_MOVED) {}
|
||||
if (ev_type == SDL_WINDOWEVENT_RESIZED) {}
|
||||
if (ev_type == SDL_WINDOWEVENT_SIZE_CHANGED) {}
|
||||
if (ev_type == SDL_WINDOWEVENT_MINIMIZED) {}
|
||||
if (ev_type == SDL_WINDOWEVENT_MAXIMIZED) {}
|
||||
if (ev_type == SDL_WINDOWEVENT_RESTORED) {}
|
||||
if (ev_type == SDL_WINDOWEVENT_ENTER) {}
|
||||
if (ev_type == SDL_WINDOWEVENT_LEAVE) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pre_render() {
|
||||
if(engine->frameCount == 0) {
|
||||
engine->initVideo();
|
||||
engine->initGL();
|
||||
auto camera = new(Camera);
|
||||
entityList.storeEntity(camera);
|
||||
entityList.getCamera()->position.set(0.0f,0.0f,5.0f);
|
||||
}
|
||||
|
||||
process_sdl_events();
|
||||
engine->frameCount++;
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
entityList.getCamera()->render();
|
||||
}
|
||||
|
||||
void render() {
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glColor3f(1,0.5,1);
|
||||
// Front face
|
||||
glVertex3f(-0.5f, -0.5f, 0.5f);
|
||||
glVertex3f(0.5f, -0.5f, 0.5f);
|
||||
glVertex3f(0.5f, 0.5f, 0.5f);
|
||||
glVertex3f(-0.5f, 0.5f, 0.5f);
|
||||
|
||||
// Back face
|
||||
glVertex3f(-0.5f, -0.5f, -0.5f);
|
||||
glVertex3f(0.5f, -0.5f, -0.5f);
|
||||
glVertex3f(0.5f, 0.5f, -0.5f);
|
||||
glVertex3f(-0.5f, 0.5f, -0.5f);
|
||||
|
||||
// Left face
|
||||
glVertex3f(-0.5f, -0.5f, -0.5f);
|
||||
glVertex3f(-0.5f, -0.5f, 0.5f);
|
||||
glVertex3f(-0.5f, 0.5f, 0.5f);
|
||||
glVertex3f(-0.5f, 0.5f, -0.5f);
|
||||
|
||||
// Right face
|
||||
glVertex3f(0.5f, -0.5f, -0.5f);
|
||||
glVertex3f(0.5f, -0.5f, 0.5f);
|
||||
glVertex3f(0.5f, 0.5f, 0.5f);
|
||||
glVertex3f(0.5f, 0.5f, -0.5f);
|
||||
|
||||
// Top face
|
||||
glVertex3f(-0.5f, 0.5f, -0.5f);
|
||||
glVertex3f(0.5f, 0.5f, -0.5f);
|
||||
glVertex3f(0.5f, 0.5f, 0.5f);
|
||||
glVertex3f(-0.5f, 0.5f, 0.5f);
|
||||
|
||||
// Bottom face
|
||||
glVertex3f(-0.5f, -0.5f, -0.5f);
|
||||
glVertex3f(0.5f, -0.5f, -0.5f);
|
||||
glVertex3f(0.5f, -0.5f, 0.5f);
|
||||
glVertex3f(-0.5f, -0.5f, 0.5f);
|
||||
glEnd();
|
||||
|
||||
glPopMatrix();
|
||||
glPushMatrix();
|
||||
|
||||
|
||||
//glBegin(GL_QUADS);
|
||||
//glColor3f(0,1,0);
|
||||
//glVertex3f(-0.25f, -0.75f,0.0);
|
||||
//glVertex3f(0.25f, -0.75f,0.0);
|
||||
//glVertex3f(0.25f, 0.75f,0.0);
|
||||
//glVertex3f(-0.25f, 0.75f,0.0);
|
||||
//glEnd();
|
||||
}
|
||||
|
||||
void post_render() {
|
||||
SDL_GL_SwapWindow(engine->window);
|
||||
engine->takeScreenshot();
|
||||
|
||||
//Resets all of the transformations for the next frame.
|
||||
glPopMatrix();
|
||||
glPushMatrix();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
|
||||
[[noreturn]] void render_loop() {
|
||||
while (true) {
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
pre_render();
|
||||
render();
|
||||
post_render();
|
||||
auto stop = std::chrono::high_resolution_clock::now();
|
||||
float dT = (std::chrono::duration_cast<std::chrono::microseconds>(stop - start).count());
|
||||
engine->frameDelta = dT / 1000000;
|
||||
}
|
||||
}
|
39
src/engine/tick.h
Normal file
39
src/engine/tick.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include "engine.h"
|
||||
#include "../types/entityList.h"
|
||||
|
||||
[[noreturn]] void gameTick() {
|
||||
while (true) {
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
//do stuff
|
||||
|
||||
engine->tickCount++;
|
||||
switch (engine->gameState) {
|
||||
case gamestate::NORMAL:
|
||||
break;
|
||||
case gamestate::IN_MAIN_MENU:
|
||||
break;
|
||||
case gamestate::IN_PAUSE_MENU:
|
||||
break;
|
||||
case gamestate::IN_LEVEL_ANIMATION:
|
||||
break;
|
||||
case gamestate::IN_QUIT:
|
||||
engine->quit();
|
||||
break;
|
||||
}
|
||||
|
||||
if (engine->tickCount % 64 == 0)
|
||||
engine->debugInfo();
|
||||
if(engine->frameCount > 0)
|
||||
entityList.getCamera()->update();
|
||||
auto stop = std::chrono::high_resolution_clock::now();
|
||||
//limit to 64 ticks per second.
|
||||
if ((int) engine->tickDelta < engine->minimumTickDelta)
|
||||
std::this_thread::sleep_for(
|
||||
std::chrono::microseconds(engine->minimumTickDelta - (uint16_t) engine->tickDelta));
|
||||
//Pause without potential deSync issues.
|
||||
engine->tickDelta = std::chrono::duration_cast<std::chrono::microseconds>(stop - start).count();
|
||||
}
|
||||
}
|
10
src/main.cpp
Normal file
10
src/main.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
#include <thread>
|
||||
#include "engine/tick.h"
|
||||
#include "engine/render.h"
|
||||
int main() {
|
||||
std::thread renderThread(render_loop);
|
||||
std::thread tickThread (gameTick);
|
||||
renderThread.join();
|
||||
tickThread.join();
|
||||
return 0;
|
||||
}
|
85
src/types/camera.h
Normal file
85
src/types/camera.h
Normal file
@@ -0,0 +1,85 @@
|
||||
#pragma once
|
||||
#include "entity.h"
|
||||
#include "../engine/engine.h"
|
||||
|
||||
enum class cameramode: uint8_t {
|
||||
FREECAM = 0,
|
||||
FOLLOW_PLAYER = 1
|
||||
};
|
||||
class Camera : public entity {
|
||||
public:
|
||||
uint8_t mode = 0;
|
||||
void move(vector3 offset) {
|
||||
position.x += offset.x;
|
||||
position.y += offset.y;
|
||||
position.z += offset.z;
|
||||
}
|
||||
|
||||
void move(float x, float y, float z) {
|
||||
position.x += x;
|
||||
position.y += y;
|
||||
position.z += z;
|
||||
}
|
||||
|
||||
void update() {
|
||||
if (mode == 0) {
|
||||
const Uint8* keyState = SDL_GetKeyboardState(nullptr);
|
||||
//TODO: Make the direction that is considered "forward" not a set axis direction
|
||||
//But instead determined by the yaw.
|
||||
if (keyState[SDL_SCANCODE_S] == 1) {
|
||||
this->position.z = this->position.z+0.1f;
|
||||
}
|
||||
if (keyState[SDL_SCANCODE_W] == 1) {
|
||||
this->position.z = this->position.z-0.1f;
|
||||
}
|
||||
if (keyState[SDL_SCANCODE_A] == 1) {
|
||||
this->position.x = this->position.x-0.025f;;
|
||||
}
|
||||
if (keyState[SDL_SCANCODE_D] == 1) {
|
||||
this->position.x = this->position.x+0.025f;
|
||||
}
|
||||
|
||||
if (keyState[SDL_SCANCODE_SPACE] == 1) {
|
||||
this->position.y -= 0.025;
|
||||
}
|
||||
|
||||
if (keyState[SDL_SCANCODE_LSHIFT] == 1) {
|
||||
this->position.y += 0.025;
|
||||
}
|
||||
|
||||
if (keyState[SDL_SCANCODE_LEFT] == 1) {
|
||||
this->angles.y +=2.0f;
|
||||
}
|
||||
if (keyState[SDL_SCANCODE_RIGHT] == 1) {
|
||||
this->angles.y -=2.0f;
|
||||
//std::cout << this->angles.y << std::endl;
|
||||
}
|
||||
if (keyState[SDL_SCANCODE_UP] == 1) {
|
||||
this->angles.x +=2.0f;
|
||||
//std::cout << this->angles.x << std::endl;
|
||||
}
|
||||
if (keyState[SDL_SCANCODE_DOWN] == 1) {
|
||||
this->angles.x -=2.0f;
|
||||
//std::cout << this->angles.x << std::endl;
|
||||
}
|
||||
}
|
||||
this->angles.clamp();
|
||||
}
|
||||
|
||||
void render() {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
//glTranslatef(-position.x, -position.y, -position.z);
|
||||
// up vector
|
||||
glRotatef(-angles.x,1.0f, 0.0f, 0.0f);
|
||||
glRotatef(-angles.y,0.0f, 1.0f, 0.0f);
|
||||
|
||||
glTranslatef(0.0f, 0.0f, 0.0f);
|
||||
gluLookAt(position.x, position.y, position.z, // camera position
|
||||
position.x, position.y, -engine->farPlane+position.z, // target position, We're always *looking at* the far plane straight ahead so the camera never turns around.
|
||||
0.0f, 1.0f, 0.0f);
|
||||
std::cout << "Camera:" << std::endl;
|
||||
std::cout << "X: " << position.x << " Y: " << position.y << " Z: " << position.z << std::endl;
|
||||
std::cout << "Pitch: " << angles.x << " Yaw: " << angles.y << " Roll: " << angles.z << std::endl;
|
||||
}
|
||||
};
|
19
src/types/entity.h
Normal file
19
src/types/entity.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
#include "vector3.h"
|
||||
|
||||
class entity {
|
||||
public:
|
||||
bool draw;
|
||||
bool collidable;
|
||||
uint32_t ticksAlive; //At 64tps it'd take 776 days to overflow.
|
||||
Position position; //X Y Z
|
||||
angle angles = {0,0,0}; //Pitch Yaw Roll, The orientation of the entity in the world,
|
||||
angle velAngles = {0,0,0}; //The angle of an entities velocity.
|
||||
void destruct() {
|
||||
//TODO: Search entity list for this entity and remove it to avoid use-after-free.
|
||||
delete this;
|
||||
}
|
||||
|
||||
virtual ~entity() {}
|
||||
};
|
28
src/types/entityList.h
Normal file
28
src/types/entityList.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include "entity.h"
|
||||
#include "player.h"
|
||||
#include "camera.h"
|
||||
class entitylist {
|
||||
public:
|
||||
std::vector<entity*> list;
|
||||
|
||||
inline player* getPlayer() {
|
||||
for (auto& e : this->list)
|
||||
if (auto* p = dynamic_cast<player*>(e) )
|
||||
return dynamic_cast<player *>(e);
|
||||
}
|
||||
|
||||
inline Camera* getCamera() {
|
||||
for (auto& e : this->list)
|
||||
if (auto* p = dynamic_cast<Camera*>(e) )
|
||||
return dynamic_cast<Camera *>(e);
|
||||
}
|
||||
|
||||
inline void storeEntity(entity* e) {
|
||||
this->list.push_back(e);
|
||||
}
|
||||
};
|
||||
|
||||
//the primary entity list.
|
||||
entitylist entityList;
|
10
src/types/geometry.h
Normal file
10
src/types/geometry.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include <SDL2/SDL_opengl.h>
|
||||
#include <vector>
|
||||
class Geometry {
|
||||
public:
|
||||
//I would use array for this, But from what I've read array of unknown size
|
||||
//as a member of class was removed after c++99.
|
||||
std::vector<GLfloat> vertices;
|
||||
std::vector<GLuint> indices;
|
||||
};
|
21
src/types/player.h
Normal file
21
src/types/player.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
#include "entity.h"
|
||||
|
||||
class player : public entity {
|
||||
public:
|
||||
bool alive;
|
||||
uint8_t health;
|
||||
uint8_t state;
|
||||
Position cameraTarget; //The point where the 3rd-person camera will want to look at.
|
||||
|
||||
//Each type of entity will have an "update" function and a "render" function.
|
||||
//These will be declared in each type of entity and not in the base entity because
|
||||
//It'll be different for each one.
|
||||
void update() {
|
||||
|
||||
}
|
||||
|
||||
void render() {
|
||||
|
||||
}
|
||||
};
|
48
src/types/skybox.h
Normal file
48
src/types/skybox.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include <SDL2/SDL_opengl.h>
|
||||
#include "entity.h"
|
||||
#include "geometry.h"
|
||||
class skybox : public entity {
|
||||
public:
|
||||
const Geometry geometry = {
|
||||
{0.000f, 1.000f, 0.000f,
|
||||
0.894f, 0.2235f, 0.000f,
|
||||
0.276f, 0.2235f, -0.4255f,
|
||||
-0.724f, 0.2235f, -0.263f,
|
||||
-0.724f, 0.2235f, 0.263f,
|
||||
0.276f, 0.2235f, 0.4255f,
|
||||
0.724f, -0.2235f, -0.263f,
|
||||
-0.276f, -0.2235f, -0.4255f,
|
||||
-0.894f, -0.2235f, 0.000f,
|
||||
-0.276f, -0.2235f, 0.4255f,
|
||||
0.724f, -0.2235f, 0.263f,
|
||||
0.000f, -1.000f, 0.000f},
|
||||
|
||||
{0, 1, 2,
|
||||
0, 2, 3,
|
||||
0, 3, 4,
|
||||
0, 4, 5,
|
||||
0, 5, 1,
|
||||
1, 6, 2,
|
||||
2, 7, 3,
|
||||
3, 8, 4,
|
||||
4, 9, 5,
|
||||
5, 10, 1,
|
||||
11, 6, 1,
|
||||
11, 7, 2,
|
||||
11, 8, 3,
|
||||
11, 9, 4,
|
||||
11, 10, 5,
|
||||
6, 7, 2,
|
||||
7, 8, 3,
|
||||
8, 9, 4,
|
||||
9, 10, 5,
|
||||
10, 6, 1}
|
||||
};
|
||||
|
||||
void render() {
|
||||
//TODO: Teleport the sphere such that the center of the sphere is the cameras position every frame.
|
||||
}
|
||||
|
||||
};
|
69
src/types/vector3.h
Normal file
69
src/types/vector3.h
Normal file
@@ -0,0 +1,69 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
|
||||
class vector3{
|
||||
public:
|
||||
float x = 0; //pitch
|
||||
float y = 0; //yaw
|
||||
float z = 0; //roll
|
||||
};
|
||||
|
||||
class angle : public vector3 {
|
||||
public:
|
||||
void clamp() {
|
||||
if (this->x > 89.0f)
|
||||
this->x = 89.0f;
|
||||
if (this->x <= -89.0f)
|
||||
this->x = -89.0f;
|
||||
|
||||
//TODO: Make this seamless by getting the amount they rotated passed -180 and +180 by.
|
||||
if (this->y <= -180.0f)
|
||||
this->y = 180.0f;
|
||||
if (this->y >= 180.01f)
|
||||
this->y = -179.9f;
|
||||
|
||||
if (this->z >= 360.0f)
|
||||
this->z = 0.0;
|
||||
if(this->z <= -360.0f)
|
||||
this->z = 0.0;
|
||||
}
|
||||
};
|
||||
|
||||
class Position : public vector3 {
|
||||
public:
|
||||
|
||||
Position* get() {
|
||||
return this;
|
||||
}
|
||||
|
||||
void set(Position p) {
|
||||
this->x = p.x;
|
||||
this->y = p.y;
|
||||
this->z = p.z;
|
||||
}
|
||||
|
||||
void set(Position* p) {
|
||||
this->x = p->x;
|
||||
this->y = p->y;
|
||||
this->z = p->z;
|
||||
}
|
||||
|
||||
void set(vector3 v) {
|
||||
this->x = v.x;
|
||||
this->y = v.y;
|
||||
this->z = v.z;
|
||||
}
|
||||
|
||||
void set(vector3* v) {
|
||||
this->x = v->x;
|
||||
this->y = v->y;
|
||||
this->z = v->z;
|
||||
}
|
||||
void set(float x, float y, float z) {
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
this->z = z;
|
||||
}
|
||||
};
|
45
src/types/vertex.h
Normal file
45
src/types/vertex.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
#include <SDL2/SDL_opengl.h>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <SDL2/SDL_opengl.h>
|
||||
#include <GL/glu.h>
|
||||
#include <GL/gl.h>
|
||||
|
||||
struct vertex {
|
||||
GLfloat x, y, z;
|
||||
};
|
||||
|
||||
class vertexarray {
|
||||
public:
|
||||
std::vector<vertex> vertices;
|
||||
std::vector<GLint> indices;
|
||||
|
||||
void load(const char* file) {
|
||||
//This will take a .obj
|
||||
std::ifstream f(file);
|
||||
std::string line;
|
||||
while (std::getline(f, line)) {
|
||||
std::istringstream iss(line);
|
||||
std::string prefix;
|
||||
iss >> prefix;
|
||||
|
||||
if (prefix == "v") {
|
||||
vertex v;
|
||||
iss >> v.x >> v.y >> v.z;
|
||||
this->vertices.push_back(v);
|
||||
}
|
||||
else if (prefix == "f") {
|
||||
unsigned int v1, v2, v3;
|
||||
char slash;
|
||||
iss >> v1 >> slash >> slash >> v2 >> slash >> slash >> v3;
|
||||
this->indices.push_back(v1 - 1);
|
||||
this->indices.push_back(v2 - 1);
|
||||
this->indices.push_back(v3 - 1);
|
||||
}
|
||||
}
|
||||
f.close();
|
||||
}
|
||||
};
|
0
src/types/world.h
Normal file
0
src/types/world.h
Normal file
Reference in New Issue
Block a user