Oddly Posted January 30, 2018 Share Posted January 30, 2018 Repository Link: https://gitlab.com/oddly-doddly/salem-gdk/  Discord Link, (we're community development drive): https://discordapp.com/invite/0wtBMrHuLTjsfsoH For the past 4 months I have been working on a library for developing games and game engines. I am writing this engine to develop my upcoming game project, OddlyDoddly's The InBetween. The system is very simple to how many already existing game engines work, and even though it is very young, it is becoming a very powerful tool. Salem GDK is written with raw OpenGL in C++. It uses GLFW for window and input management. Here are some features i've currently finished developing: Basic TCP Network, soon will be rewritten as a modular network supporting both TCP and UDP protocols. Will also have match making servers.  GUI ENGINE with capabilities of scripting user interfaces through JSON files. An example json script and its output  { "interface": { "fonts": [ { "id": "arial", "source": "./resource/fonts/arial.ttf" } ], "objects": [ { "type": "image", "id": "img_sanic", "textures": [ { "id": "source", "texture": "./resource/gui/images/sanic.png" } ], "text": "Exit", "position": { "x": -1.0, "y": -1.0 }, "size": { "width": 0.4, "height": 0.6 }, "shader": "ui" }, { "type": "button", "id": "btn_exit", "textures": [ { "id": "inactive", "texture": "./resource/gui/buttons/btn_exit_inactive.png" }, { "id": "hover", "texture": "./resource/gui/buttons/btn_exit_hover.png" }, { "id": "click", "texture": "./resource/gui/buttons/btn_exit_click.png" } ], "text": "Exit", "position": { "x": 0.0, "y": 0.3 }, "size": { "width": 0.4, "height": 0.2 }, "attributes": { "anchor": "left", "text-align": "center" }, "shader": "ui" }, { "type": "textbox", "id": "txt_username", "textures": [ { "id": "inactive", "texture": "./resource/gui/textboxes/textbox_inactive.png" }, { "id": "focus", "texture": "./resource/gui/textboxes/textbox_focus.png" } ], "size": { "width": 0.4, "height": 0.05 }, "position": { "x": 0.0, "y": 0.1 }, "attributes": { "font": "arial", "text-align": "left", "anchor": "center", "place-holder": "Email/Username", "font-size": 0.5, "font-color": "#ffffff" } }, { "type": "textbox", "id": "txt_password", "textures": [ { "id": "inactive", "texture": "./resource/gui/textboxes/textbox_inactive.png" }, { "id": "focus", "texture": "./resource/gui/textboxes/textbox_focus.png" } ], "size": { "width": 0.4, "height": 0.05 }, "position": { "x": 0.0, "y": 0.0 }, "attributes": { "font": "arial", "text-align": "left", "anchor": "center", "place-holder": "Password", "font-size": 0.5, "font-color": "#ffffff", "is-password": true } } ] } } Output Render:  All ui objects are interactable and can be grabbed through the gameview's ui engine auto myControl = getView()->ui()->getControl("txt_username"); returns a pinter to the textbox username myControl->value(); Will even get the value of what is in the textbox. Events can be bound to ui buttons through lambda functions. If i want to link an event to btn_exit that prints out the value of email and username to the debug console I can do so like this: // Load GUI loadGui("./resource/gui/views/MainMenu.json"); auto btnExit = gui().findUiControlById<Salem::Graphics::Controls::uiButton>("btn_exit"); auto txtUsername = gui().findUiControlById<Salem::Graphics::Controls::uiTextBox>("txt_username"); auto txtPassword = gui().findUiControlById<Salem::Graphics::Controls::uiTextBox>("txt_password"); btnExit->on_click = []() { std::string username = GAMELOOP_PTR->GetView()->gui().findUiControlById<Salem::Graphics::Controls::uiTextBox>("txt_username")->value(); std::string password = GAMELOOP_PTR->GetView()->gui().findUiControlById<Salem::Graphics::Controls::uiTextBox>("txt_password")->value(); std::cout << "Login: {" << username.c_str() << " : " << password.c_str() << "}" << std::endl; };  Here is an example of a gameview, basically a scene in your game: // // Created by ddodds on 10/24/17. // #ifndef TEST_CLIENT_MAINMENUVIEW_HPP #define TEST_CLIENT_MAINMENUVIEW_HPP #include "system/GameLoop.hpp" #include "system/interface/GameView.hpp" #include "views/controllers/MainMenuController.hpp" #include "behaviours/TestBehaviour.hpp" #include "physics/PhysicsTypes.hpp" #include "physics/types/Transform.hpp" #include <graphics/objects/Model.hpp> #include "graphics/controls/uiButton.hpp" #include "graphics/controls/uiTextBox.hpp" extern Salem::System::GameLoop *GAMELOOP_PTR; namespace TestClient::Views { class MainMenuView : public Salem::System::Interface::GameView { public: explicit MainMenuView(Controllers::MainMenuController &p_view_controller) : GameView(p_view_controller) {} void Initialize() override { // Load GUI loadGui("./resource/gui/views/MainMenu.json"); // Create and bind a Camera Salem::Physics::Types::Transform camera_transform( Salem::Physics::Vector3(0.0f, 0.0f, 0.0f), Salem::Physics::Quaternion(), Salem::Physics::Vector3(1.0f, 1.0f, 1.0f)); GameView::camera(new Salem::Graphics::Objects::Camera(camera_transform, 45.0f, GAMELOOP_PTR->vp_width(), GAMELOOP_PTR->vp_height(), 0.0f, 100.0f)); auto btnExit = gui().findUiControlById<Salem::Graphics::Controls::uiButton>("btn_exit"); auto txtUsername = gui().findUiControlById<Salem::Graphics::Controls::uiTextBox>("txt_username"); auto txtPassword = gui().findUiControlById<Salem::Graphics::Controls::uiTextBox>("txt_password"); btnExit->on_click = []() { std::string username = GAMELOOP_PTR->GetView()->gui().findUiControlById<Salem::Graphics::Controls::uiTextBox>("txt_username")->value(); std::string password = GAMELOOP_PTR->GetView()->gui().findUiControlById<Salem::Graphics::Controls::uiTextBox>("txt_password")->value(); std::cout << "Login: {" << username.c_str() << " : " << password.c_str() << "}" << std::endl; }; Salem::Physics::Types::Transform transform( Salem::Physics::Vector3(0.0f, 0.0f, 0.0f), Salem::Physics::Quaternion(), Salem::Physics::Vector3(1.0f, 1.0f, 1.0f) ); // Game Objects do not get initalized until you add them to a view now. Salem::Graphics::Objects::Model* model = new Salem::Graphics::Objects::Model(transform, "./resource/models/nanosuit/nanosuit.obj"); // Mono Behaviour Initialize Functions get called during the game object's initialization model->AddBehaviour(new Behaviours::TestBehaviour(model->transform())); // Append GameObject to the view addGameObject(model); } void Update() override { // Some Update Logic GameView::Update(); } }; } #endif //TEST_CLIENT_MAINMENUVIEW_HPP  And a script to start a scene: The main function of the game itself: We create a game loop, and instruct it to load our Main Menu View, which is defined above. // // Created by ddodds on 10/21/17. // #include <iostream> #include <boost/asio.hpp> #include <views/controllers/MainMenuController.hpp> #include "system/GameLoop.hpp" #include "views/MainMenuView.hpp" #include "views/controllers/MainMenuController.hpp" int main(int argc, char *argv[]) { TestClient::Controllers::MainMenuController mainMenuController; auto mainMenuViewPtr = std::make_unique<TestClient::Views::MainMenuView>(mainMenuController); Salem::System::GameLoop gameLoop; gameLoop.LoadView(std::move(mainMenuViewPtr)); gameLoop.Run(); return 0; } And of course, a game controller to handle user input: // // Created by ddodds on 1/22/18. // #ifndef TEST_CLIENT_MAINMENUCONTROLLER_HPP #define TEST_CLIENT_MAINMENUCONTROLLER_HPP #include <system/interface/ViewController.hpp> #include <physics/PhysicsTypes.hpp> #include "system/GameLoop.hpp" extern Salem::System::GameLoop *GAMELOOP_PTR; namespace TestClient::Controllers { class MainMenuController : public Salem::System::Interface::ViewController { public: void on_keypress(GLFWwindow *window, int key, int scancode, int action, int mods) override { if(key == GLFW_KEY_W) { Salem::Physics::Vector3 move_transform(0.0f, 0.0f, 1.0f); GAMELOOP_PTR->GetView()->camera()->transform().Translate(move_transform); } if(key == GLFW_KEY_S) { Salem::Physics::Vector3 move_transform(0.0f, 0.0f, -1.0f); GAMELOOP_PTR->GetView()->camera()->transform().Translate(move_transform); } if(key == GLFW_KEY_A) { Salem::Physics::Vector3 move_transform(1.0f, 0.0f, 0.0f); GAMELOOP_PTR->GetView()->camera()->transform().Translate( move_transform); } if(key == GLFW_KEY_D) { Salem::Physics::Vector3 move_transform(-1.0f, 0.0f, 0.0f); GAMELOOP_PTR->GetView()->camera()->transform().Translate(move_transform); } } void on_cursor_move(GLFWwindow *p_window, double p_xpos, double p_ypos) override { double x_offset = p_xpos - m_last_x; double y_offset = p_ypos - m_last_y; GAMELOOP_PTR->GetView()->camera()->transform().Rotate(0.05f*x_offset, Salem::Physics::Vector3(0.0f, 1.0f, 0.0f)); GAMELOOP_PTR->GetView()->camera()->transform().Rotate(0.05f*y_offset, Salem::Physics::Vector3(1.0f, 0.0f, 0.0f)); m_last_x = p_xpos; m_last_y = p_ypos; }; private: double m_last_x, m_last_y = 0; }; } #endif //TEST_CLIENT_MAINMENUCONTROLLER_HPP  The library supports camera views and transforms: (for this test i just converted all 2d interface objects into 3d world objects.)  Of course, 3D model loading at its very basics....  Game Object behaviours. You can bind as many scripted behaviours as you'd like to a game object, and the system runs them when necessary:  If you've ever used unity, they are very similar to MonoBehaviours, but these are not scripted or injected, they get baked into the final application compilation.  Also support GLSL shader language  Coming up in the project's todo; Audio Engine (being developed by a Salem-GDK community member) Animation Engine (will be developed by me) UDP Network (developed by me) Witchcraft Engine;World (engine used to generate 3D worlds and maps for SalemGDK, in development next, by me)  More screenshots to come. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now