diff --git a/.gitignore b/.gitignore index 35030d4..3d363ed 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ link/ .vscode/ -earn/ +run/ *.swp *.swo diff --git a/command/linux/rebuild.sh b/command/linux/rebuild.sh index db9af49..2f78ec6 100755 --- a/command/linux/rebuild.sh +++ b/command/linux/rebuild.sh @@ -3,7 +3,7 @@ F_ROOT=$(readlink -f "$0") D_ROOT=$(dirname "${F_ROOT}")/../../. D_COMPILE=${D_ROOT}/compile D_LINK=${D_ROOT}/link -D_EARN=${D_ROOT}/earn +D_RUN=${D_ROOT}/run F_COMPILE_LIST=${D_COMPILE}/project_files.txt F_LINK_LIST=${D_LINK}/project_files.txt echo "" > ${F_LINK_LIST} @@ -37,12 +37,12 @@ do break fi LINE=$((LINE+1)) - LIBRARY="-l$(head -n ${LINE} ${F_LIBRARY_LIST}) " + LIBRARY="-l$(head -n ${LINE} ${F_LIBRARY_LIST} | tail -n 1)" echo $LIBRARY >> ${F_LIBRARY_OPTIONS} done # Link. I_LINK=$(cat ${F_LINK_LIST}) I_LIBRARIES=$(cat ${F_LIBRARY_OPTIONS}) -O_LINK=${D_EARN}/executable +O_LINK=${D_RUN}/executable clang++ ${I_LIBRARIES} ${I_LINK} -o ${O_LINK} diff --git a/command/linux/rebuild_android.sh b/command/linux/rebuild_android.sh new file mode 100644 index 0000000..a9bf588 --- /dev/null +++ b/command/linux/rebuild_android.sh @@ -0,0 +1 @@ +#!/bin/bash diff --git a/command/linux/setup.sh b/command/linux/setup.sh index 3ea6af6..2dc57db 100755 --- a/command/linux/setup.sh +++ b/command/linux/setup.sh @@ -1 +1,5 @@ -apt install -y libx11-dev +#!/bin/bash +apt install -y \ + libx11-dev \ + libglew-dev glew-utils libglew2.1 \ + libglx-dev libglx-mesa0 libglx0 diff --git a/command/linux/setup_android.sh b/command/linux/setup_android.sh new file mode 100755 index 0000000..7b6fda1 --- /dev/null +++ b/command/linux/setup_android.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +# Make sure we are running this script as root. +[[ $EUID -ne 0 ]] && echo "This script must be run as root." && exit 1 + +ANDROID_CLI_TOOLS_FILE=commandlinetools-linux-7583922_latest.zip +ANDROID_CLI_TOOLS_LINK=https://dl.google.com/android/repository/${ANDROID_CLI_TOOLS_FILE} +ANDROID_CLI_TOOLS_DIR=cmdline-tools +ANDROID_SDK_DIR=/opt/android_sdk + +wget $ANDROID_CLI_TOOLS_LINK +unzip $ANDROID_CLI_TOOLS_FILE +rm $ANDROID_CLI_TOOLS_FILE +mkdir $ANDROID_SDK_DIR +mv $ANDROID_CLI_TOOLS_DIR /opt/android_sdk/ + +${ANDROID_SDK_DIR}/bin/sdkmanager --sdk_root=${ANDROID_SDK_DIR} --install \ + "platforms;android-21" \ + "sources;android-21" \ + "platform-tools" \ + "build-tools;21.1.2" \ + "ndk;21.4.7075529" diff --git a/compile/act/controller.h b/compile/act/controller.h index c3b47d0..2dcdf6c 100644 --- a/compile/act/controller.h +++ b/compile/act/controller.h @@ -1,15 +1,16 @@ #ifndef ACT_CONTROLLER #define ACT_CONTROLLER +#include "code/return.h" class controller_t { public: + enum error_t { + none, + unknown + }; enum event_t { start, stop }; - enum status_t { - ok, - error - }; - virtual status_t on_event(event_t event_p) = 0; + virtual void_t on_event(event_t event_p) = 0; }; #endif diff --git a/compile/act/root.cpp b/compile/act/root.cpp index 2ad23fc..12b5e3e 100644 --- a/compile/act/root.cpp +++ b/compile/act/root.cpp @@ -1,28 +1,46 @@ +#include "act/controller.h" #include "act/root.h" #include "allocate/factory.h" -#include "draw/window.h" -root_controller_t::root_controller_t(root_controller_t::configuration_t* configuration_p) { - mode_m = configuration_p->mode_m; +#include "code/return.h" +#include "draw/window_service.h" + +root_controller_t::root_controller_t( + root_controller_t::configuration_t* configuration_p +) { + configuration_m = configuration_p; } -controller_t::status_t root_controller_t::on_event(controller_t::event_t event_p) { - window_service_t* window_service = new window_service_t(); - window_service_t::status_t window_status = window_service->create_window(); - controller_t::status_t controller_status; - switch (window_status) { - case window_service_t::status_t::ok: - controller_status = controller_t::status_t::ok; - break; - case window_service_t::status_t::error: - default: - controller_status = controller_t::status_t::error; - break; - } - return controller_status; + +void_t root_controller_t::on_event( + controller_t::event_t event_p +) { + text_service_t* text_service_l = configuration_m->provider_m->configuration_m->text_service_m; + text_service_l->initialize( + ); + std::string window_title = text_service_l->get_text( + text_service_t::text_t::window_title + ).value_m; + configuration_m->provider_m->configuration_m->window_service_m->create_window( + &window_title + ); + void_t void_l; + void_l.error_m = controller_t::error_t::none; + return void_l; } -root_controller_t* root_controller_factory_t::create(root_controller_t::configuration_t* configuration_p) { - return new root_controller_t(configuration_p); + +return_t root_controller_factory_t::create( + root_controller_t::configuration_t* configuration_p +) { + return_t return_l; + return_l.error_m = root_controller_t::error_t::none; + return_l.value_m = new root_controller_t(configuration_p); + return return_l; } -factory_t::status_t root_controller_factory_t::dispose(root_controller_t* root_controller_p) { + +void_t root_controller_factory_t::dispose( + root_controller_t* root_controller_p +) { delete root_controller_p; - return factory_t::status_t::ok; + void_t return_l; + return_l.error_m = root_controller_t::error_t::none; + return return_l; } diff --git a/compile/act/root.h b/compile/act/root.h index 96e37eb..d737fcb 100644 --- a/compile/act/root.h +++ b/compile/act/root.h @@ -2,24 +2,33 @@ #define ACT_ROOT #include "act/controller.h" #include "allocate/factory.h" +#include "code/provider.h" #include class root_controller_t : public controller_t { public: - enum mode_t { - cli, - app, - game + enum error_t { + none, + unknown }; struct configuration_t { - mode_t mode_m; + provider_t* provider_m; }; - root_controller_t(configuration_t* configuration_p); - controller_t::status_t on_event(event_t event_p) override; + root_controller_t( + configuration_t* configuration_p + ); + void_t on_event( + controller_t::event_t event_p + ); private: - mode_t mode_m; + configuration_t* configuration_m; }; -class root_controller_factory_t : public factory_t { - root_controller_t* create(root_controller_t::configuration_t* configuration_p) override; - factory_t::status_t dispose(root_controller_t* root_controller_p) override; +class root_controller_factory_t : public factory_t { + public: + return_t create( + root_controller_t::configuration_t* configuration_p + ); + void_t dispose( + root_controller_t* root_controller_p + ); }; #endif diff --git a/compile/allocate/factory.h b/compile/allocate/factory.h index 40d6325..0099f0e 100644 --- a/compile/allocate/factory.h +++ b/compile/allocate/factory.h @@ -1,13 +1,13 @@ #ifndef ALLOCATE_FACTORY #define ALLOCATE_FACTORY -template class factory_t { +#include "code/return.h" +template class factory_t { public: - enum status_t { - ok, - error - }; - private: - virtual O* create(I* i) = 0; - virtual status_t dispose(O* o) = 0; + virtual return_t create( + I* i + ) = 0; + virtual void_t dispose( + O* o + ) = 0; }; #endif diff --git a/compile/code/observable.cpp b/compile/code/observable.cpp new file mode 100644 index 0000000..8b4be96 --- /dev/null +++ b/compile/code/observable.cpp @@ -0,0 +1,61 @@ +#include "code/observable.h" +#include "code/return.h" + +template observable_t::observable_t( + observable_t::configuration_t* configuration_p +) { + configuration_m = configuration_p; +} + +template void observable_t::observe( + observer_t* observer_p +) { + observer_p->on_change(configuration_m->value_m); + observers_m.push_back(observer_p); +} + +template void_t observable_t::unobserve( + observer_t* observer_p +) { + observable_t::error_t error_l = observable_t::error_t::not_observing; + for (int i = 0; i < observers_m.size(); i++) { + if (observers_m[i] == observer_p) { + observers_m.erase(i); + error_l = observable_t::error_t::none; + break; + } + } + void_t void_l; + void_l.error_m = error_l; + return void_l; +} + +template V observable_t::get_value( +) { + return value_m; +} + +template void_t observable_t::change( + V* value_p +) { + configuration_m->value_m = value_p; + for (int i = 0; i < observers_m.size(); i++) { + observer_m = observers_m[i]; + observer_m->on_change(configuration_m->value_m); + } + void_t void_l; + void_l.error_m = observable_t::error_t::none; + return void_l; +} + +template return_t observable_factory_t::create( + observable_t::configuration_t* configuration_p +) { + observable_t* observable_l = new observable_t( + configuration_p + ); + return_t return_l; + return_l.error_m = observable_t::error_t::none; + return_l.value_m = observable_l; + return return_l; +} diff --git a/compile/code/observable.h b/compile/code/observable.h new file mode 100644 index 0000000..c4a4c50 --- /dev/null +++ b/compile/code/observable.h @@ -0,0 +1,88 @@ +#ifndef CODE_OBSERVABLE +#define CODE_OBSERVABLE +#include "code/return.h" +#include +template class observer_t { + public: + virtual void on_change( + V* value_p + ) = 0; +}; +template class observable_t { + public: + enum class error_t { + none, + unknown, + not_observing + }; + struct configuration_t { + V* value_m; + }; + observable_t( + configuration_t* configuration_p + ) { + configuration_m = configuration_p; + } + void_t observe( + observer_t* observer_p + ) { + observer_p->on_change(configuration_m->value_m); + observers_m.push_back(observer_p); + } + void_t unobserve( + observer_t* observer_p + ) { + observable_t::error_t error_l = observable_t::error_t::not_observing; + for (int i = 0; i < observers_m.size(); i++) { + if (observers_m[i] == observer_p) { + observers_m.erase(i); + error_l = observable_t::error_t::none; + break; + } + } + void_t void_l; + void_l.error_m = error_l; + return void_l; + } + V* get_value() { + return value_m; + } + void_t change( + V* value_p + ) { + configuration_m->value_m = value_p; + for (int i = 0; i < observers_m.size(); i++) { + observer_m = observers_m[i]; + observer_m->on_change(configuration_m->value_m); + } + void_t void_l; + void_l.error_m = observable_t::error_t::none; + return void_l; + } + private: + std::vector*> observers_m; + configuration_t* configuration_m; +}; +template class observable_factory_t : public observable_t { + public: + return_t *> create( + observable_t::configuration_t configuration_p + ) { + observable_t* observable_l = new observable_t( + configuration_p + ); + return_t return_l; + return_l.error_m = observable_t::error_t::none; + return_l.value_m = observable_l; + return return_l; + } + void_t dispose( + observable_t* observable_p + ) { + delete observable_p; + void_t void_l; + void_l.error_m = observable_t::error_t::none; + return void_l; + } +}; +#endif diff --git a/compile/code/provider.cpp b/compile/code/provider.cpp new file mode 100644 index 0000000..4d51670 --- /dev/null +++ b/compile/code/provider.cpp @@ -0,0 +1,29 @@ +#include "code/provider.h" +#include "inform/text_service.h" +#include "draw/window_service.h" + +provider_t::provider_t( + provider_t::configuration_t* configuration_p +) { + configuration_m = configuration_p; +} + +return_t provider_factory_t::create( + provider_t::configuration_t* configuration_p +) { + return_t return_l; + return_l.error_m = provider_t::error_t::none; + return_l.value_m = new provider_t( + configuration_p + ); + return return_l; +} + +void_t provider_factory_t::dispose( + provider_t* provider_p +) { + delete provider_p; + void_t void_l; + void_l.error_m = provider_t::error_t::none; + return void_l; +} diff --git a/compile/code/provider.h b/compile/code/provider.h new file mode 100644 index 0000000..d8f5b0a --- /dev/null +++ b/compile/code/provider.h @@ -0,0 +1,33 @@ +#ifndef CODE_PROVIDER +#define CODE_PROVIDER +#include "allocate/factory.h" +#include "code/return.h" +#include "inform/text_service.h" +#include "draw/window_service.h" +class provider_t { + friend class provider_factory_t; + public: + enum error_t { + none, + unknown + }; + struct configuration_t { + text_service_t* text_service_m; + window_service_t* window_service_m; + }; + configuration_t* configuration_m; + private: + provider_t( + configuration_t* configuration_p + ); +}; +class provider_factory_t : public factory_t { + public: + return_t create( + provider_t::configuration_t* configuration_p + ); + void_t dispose( + provider_t* root_controller_p + ); +}; +#endif diff --git a/compile/code/return.h b/compile/code/return.h new file mode 100644 index 0000000..b1fa567 --- /dev/null +++ b/compile/code/return.h @@ -0,0 +1,16 @@ +#ifndef CODE_RETURN +#define CODE_RETURN +class empty_t { +}; +template class return_t { + public: + enum component_t { + render + }; + component_t component_m; + E error_m; + D value_m; +}; +template class void_t : public return_t { +}; +#endif diff --git a/compile/draw/opengl_service.cpp b/compile/draw/opengl_service.cpp new file mode 100644 index 0000000..bafd31e --- /dev/null +++ b/compile/draw/opengl_service.cpp @@ -0,0 +1,81 @@ +#include "allocate/factory.h" +#include "code/return.h" +#include "draw/opengl_service.h" + +opengl_service_t::opengl_service_t( + opengl_service_t::configuration_t* configuration_p +) { + configuration_m = configuration_p; +} + +void_t opengl_service_t::draw_quad( +) { + glClearColor(1.0, 1.0, 1.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-1., 1., -1., 1., 1., 20.); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + gluLookAt(0., 0., 10., 0., 0., 0., 0., 1., 0.); + + glBegin(GL_QUADS); + glColor3f(1., 0., 0.); glVertex3f(-.75, -.75, 0.); + glColor3f(0., 1., 0.); glVertex3f( .75, -.75, 0.); + glColor3f(0., 0., 1.); glVertex3f( .75, .75, 0.); + glColor3f(1., 1., 0.); glVertex3f(-.75, .75, 0.); + glEnd(); + void_t void_l; + void_l.error_m = opengl_service_t::error_t::none; + return void_l; +} + +void_t opengl_service_t::enable_depth_test( +) { + glEnable( + GL_DEPTH_TEST + ); + void_t void_l; + void_l.error_m = opengl_service_t::error_t::none; + return void_l; +} + +void_t opengl_service_t::resize_viewport( + int x, + int y, + int width, + int height +) { + void_t void_l; + void_l.error_m = opengl_service_t::error_t::none; + glViewport( + 0, + 0, + width, + height + ); + return void_l; +} + +return_t opengl_service_factory_t::create( + opengl_service_t::configuration_t* configuration_p +) { + opengl_service_t* opengl_service_l = new opengl_service_t( + configuration_p + ); + return_t return_l; + return_l.error_m = opengl_service_t::error_t::none; + return_l.value_m = opengl_service_l; + return return_l; +} + +void_t opengl_service_factory_t::dispose( + opengl_service_t* opengl_service_p +) { + delete opengl_service_p; + void_t void_l; + void_l.error_m = opengl_service_t::error_t::none; + return void_l; +} diff --git a/compile/draw/opengl_service.h b/compile/draw/opengl_service.h new file mode 100644 index 0000000..ebaeede --- /dev/null +++ b/compile/draw/opengl_service.h @@ -0,0 +1,48 @@ +#ifndef SERVICE_RENDER +#define SERVICE_RENDER +#include "allocate/factory.h" +#include "code/return.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +class opengl_service_t { + friend class opengl_service_factory_t; + public: + enum error_t { + none, + unknown + }; + struct configuration_t { + }; + void_t draw_quad( + ); + void_t enable_depth_test( + ); + void_t resize_viewport( + int x, + int y, + int width, + int height + ); + private: + opengl_service_t( + configuration_t* configuration_p + ); + configuration_t* configuration_m; +}; +class opengl_service_factory_t : public factory_t { + public: + return_t create( + opengl_service_t::configuration_t* configuration_p + ); + void_t dispose( + opengl_service_t* opengl_service_p + ); +}; +#endif diff --git a/compile/draw/window.h b/compile/draw/window.h deleted file mode 100644 index c603d95..0000000 --- a/compile/draw/window.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef SERVICE_WINDOW -#define SERVICE_WINDOW -class window_service_t { - public: - enum status_t { - ok, - error - }; - status_t create_window(); -}; -#endif diff --git a/compile/draw/window_service.h b/compile/draw/window_service.h new file mode 100644 index 0000000..72d0145 --- /dev/null +++ b/compile/draw/window_service.h @@ -0,0 +1,35 @@ +#ifndef SERVICE_WINDOW +#define SERVICE_WINDOW +#include "allocate/factory.h" +#include "code/return.h" +#include "inform/text_service.h" +#include +class window_service_t { + friend class window_service_factory_t; + public: + enum error_t { + none, + unknown, + x_server_connection_failure + }; + struct configuration_t { + }; + void_t create_window( + std::string* window_title + ); + private: + window_service_t( + configuration_t* configuration_p + ); + configuration_t* configuration_m; +}; +class window_service_factory_t : public factory_t { + public: + return_t create( + window_service_t::configuration_t* configuration_p + ); + void_t dispose( + window_service_t* window_service_p + ); +}; +#endif diff --git a/compile/inform/text_service.cpp b/compile/inform/text_service.cpp new file mode 100644 index 0000000..39e691e --- /dev/null +++ b/compile/inform/text_service.cpp @@ -0,0 +1,60 @@ +#include "inform/text_service.h" +#include "code/return.h" +#include + +text_service_t::text_service_t( + text_service_t::configuration_t* configuration_p +) { + configuration_m = configuration_p; +} + +void text_service_t::update( + text_service_t::text_t text_p, + std::string string_p +) { + text_to_string[text_p] = string_p; +} + +void_t text_service_t::initialize( +) { + text_service_t::language_t language_l = configuration_m->language_m; + switch (language_l) { + case text_service_t::language_t::english: + update(text_service_t::text_t::window_title, "Fortuitous Frogs"); + break; + } + void_t void_l; + void_l.error_m = text_service_t::error_t::none; + return void_l; +} + +return_t text_service_t::get_text( + text_service_t::text_t text_p +) { + std::string string_l = text_to_string[text_p]; + return_t return_l; + return_l.error_m = text_service_t::error_t::none; + return_l.value_m = string_l; + return return_l; +} + +return_t text_service_factory_t::create( + text_service_t::configuration_t* configuration_p +) { + text_service_t* text_service_l = new text_service_t( + configuration_p + ); + return_t return_l; + return_l.error_m = text_service_t::error_t::none; + return_l.value_m = text_service_l; + return return_l; +} + +void_t text_service_factory_t::dispose( + text_service_t* text_service_p +) { + delete text_service_p; + void_t void_l; + void_l.error_m = text_service_t::error_t::none; + return void_l; +} diff --git a/compile/inform/text_service.h b/compile/inform/text_service.h new file mode 100644 index 0000000..36a968f --- /dev/null +++ b/compile/inform/text_service.h @@ -0,0 +1,52 @@ +#ifndef INTEGRATE_TEXT_SERVICE +#define INTEGRATE_TEXT_SERVICE +#include "allocate/factory.h" +#include "code/return.h" +#include +#include +class text_service_t { + friend class text_service_factory_t; + public: + enum status_t { + ok, + error + }; + enum error_t { + none, + unknown + }; + enum language_t { + english + }; + enum text_t { + window_title + }; + struct configuration_t { + language_t language_m; + }; + return_t get_text( + text_t text_p + ); + void_t initialize( + ); + private: + text_service_t( + configuration_t* configuration_p + ); + configuration_t* configuration_m; + std::map text_to_string; + void update( + text_t text_p, + std::string string_p + ); +}; +class text_service_factory_t : public factory_t { + public: + return_t create( + text_service_t::configuration_t* configuration_p + ); + void_t dispose( + text_service_t* text_service_p + ); +}; +#endif diff --git a/compile/libraries.txt b/compile/libraries.txt index 08d2b99..952f7c5 100644 --- a/compile/libraries.txt +++ b/compile/libraries.txt @@ -1 +1,3 @@ X11 +GL +GLU diff --git a/compile/main.cpp b/compile/main.cpp index 76890fb..d09f92c 100644 --- a/compile/main.cpp +++ b/compile/main.cpp @@ -1,11 +1,60 @@ #include "act/controller.h" #include "act/root.h" +#include "code/provider.h" #include int main(int argc, char *argv[]) { - root_controller_t::configuration_t configuration_l; - configuration_l.mode_m = root_controller_t::mode_t::app; - root_controller_t* controller_l = new root_controller_t(&configuration_l); - controller_t::status_t status_l = controller_l->on_event(controller_t::event_t::start); - delete controller_l; - return status_l; + // Create text service. + text_service_factory_t text_service_factory_l; + text_service_t::configuration_t text_service_configuration_l; + text_service_configuration_l.language_m = text_service_t::language_t::english; + text_service_t* text_service_l = text_service_factory_l.create( + &text_service_configuration_l + ).value_m; + + // Create window service. + window_service_factory_t window_service_factory_l; + window_service_t::configuration_t window_service_configuration_l; + window_service_t* window_service_l = window_service_factory_l.create( + &window_service_configuration_l + ).value_m; + + // Create provider. + provider_factory_t provider_factory_l; + provider_t::configuration_t provider_configuration_l; + provider_configuration_l.text_service_m = text_service_l; + provider_configuration_l.window_service_m = window_service_l; + provider_t* provider_l = provider_factory_l.create( + &provider_configuration_l + ).value_m; + + // Create root controller. + root_controller_factory_t root_controller_factory_l; + root_controller_t::configuration_t root_controller_configuration_l; + root_controller_configuration_l.provider_m = provider_l; + root_controller_t* root_controller_l = root_controller_factory_l.create( + &root_controller_configuration_l + ).value_m; + + // Start root controller. + controller_t::error_t root_controller_event_l = root_controller_l->on_event( + controller_t::event_t::start + ).error_m; + + // Clean up + root_controller_factory_l.dispose( + root_controller_l + ); + provider_factory_l.dispose( + provider_l + ); + window_service_factory_l.dispose( + window_service_l + ); + text_service_factory_l.dispose( + text_service_l + ); + if (root_controller_event_l == controller_t::error_t::none) { + return 0; + } + return 1; } diff --git a/compile/project_files.txt b/compile/project_files.txt index 4ff57a3..19ff17b 100644 --- a/compile/project_files.txt +++ b/compile/project_files.txt @@ -1,3 +1,7 @@ main.cpp act/root.cpp -target/linux/draw/window.cpp +code/provider.cpp +draw/opengl_service.cpp +inform/text_service.cpp +target/linux/draw/window_service.cpp +target/linux/draw/opengl_x11_service.cpp diff --git a/compile/target/linux/draw/opengl_x11_service.cpp b/compile/target/linux/draw/opengl_x11_service.cpp new file mode 100644 index 0000000..ccb1f81 --- /dev/null +++ b/compile/target/linux/draw/opengl_x11_service.cpp @@ -0,0 +1,115 @@ +#include "allocate/factory.h" +#include "code/return.h" +#include "target/linux/draw/opengl_x11_service.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +opengl_x11_service_t::opengl_x11_service_t( + opengl_x11_service_t::configuration_t* configuration_p +) { + configuration_m = configuration_p; +} + +return_t opengl_x11_service_t::get_visual_info( + Display* display_p +) { + return_t return_l; + return_l.error_m = opengl_x11_service_t::error_t::none; + GLint attributes_l[] = { + GLX_RGBA, + GLX_DEPTH_SIZE, + 24, + GLX_DOUBLEBUFFER, + None + }; + XVisualInfo *visual_info_l = glXChooseVisual( + display_p, + 0, + attributes_l + ); + if (visual_info_l == NULL) { + return_l.error_m = opengl_x11_service_t::error_t::no_visual_found; + } + return_l.value_m = visual_info_l; + return return_l; +} + +void_t opengl_x11_service_t::initialize_context( + Display* display_p, + XVisualInfo* visual_info_p, + Window window_p +){ + void_t void_l; + configuration_m->glx_context_m = glXCreateContext( + display_p, + visual_info_p, + NULL, + GL_TRUE + ); + glXMakeCurrent( + display_p, + window_p, + configuration_m->glx_context_m + ); + void_l.error_m = opengl_x11_service_t::error_t::none; + return void_l; +} + +void_t opengl_x11_service_t::swap_buffers( + Display* display_p, + Window window_p +) { + void_t void_l; + void_l.error_m = opengl_x11_service_t::error_t::none; + glXSwapBuffers( + display_p, + window_p + ); + return void_l; +} + +void_t opengl_x11_service_t::dispose( + Display* display_p +) { + void_t void_l; + void_l.error_m = opengl_x11_service_t::error_t::none; + glXMakeCurrent( + display_p, + None, + NULL + ); + glXDestroyContext( + display_p, + configuration_m->glx_context_m + ); + return void_l; +} + +return_t opengl_x11_service_factory_t::create( + opengl_x11_service_t::configuration_t* configuration_p +) { + opengl_x11_service_t* opengl_x11_service_l = new opengl_x11_service_t( + configuration_p + ); + return_t return_l; + return_l.error_m = opengl_x11_service_t::error_t::none; + return_l.value_m = opengl_x11_service_l; + return return_l; +} + +void_t opengl_x11_service_factory_t::dispose( + opengl_x11_service_t* opengl_x11_service_p +) { + delete opengl_x11_service_p; + void_t void_l; + void_l.error_m = opengl_x11_service_t::error_t::none; + return void_l; +} + diff --git a/compile/target/linux/draw/opengl_x11_service.h b/compile/target/linux/draw/opengl_x11_service.h new file mode 100644 index 0000000..540448c --- /dev/null +++ b/compile/target/linux/draw/opengl_x11_service.h @@ -0,0 +1,55 @@ +#ifndef DRAW_OPENGL_X11_SERVICE +#define DRAW_OPENGL_X11_SERVICE +#include "allocate/factory.h" +#include "code/return.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +class opengl_x11_service_t { + friend class opengl_x11_service_factory_t; + public: + enum error_t { + none, + unknown, + no_visual_found + }; + struct configuration_t { + GLXContext glx_context_m; + }; + return_t get_visual_info( + Display* display_p + ); + void_t initialize_context( + Display* display_p, + XVisualInfo* visual_info_p, + Window window_p + ); + void_t swap_buffers( + Display* display_p, + Window window_p + ); + void_t dispose( + Display* display_p + ); + private: + opengl_x11_service_t( + configuration_t* configuration_p + ); + configuration_t* configuration_m; +}; +class opengl_x11_service_factory_t : public factory_t { + public: + return_t create( + opengl_x11_service_t::configuration_t* configuration_p + ); + void_t dispose( + opengl_x11_service_t* opengl_x11_service_p + ); +}; +#endif diff --git a/compile/target/linux/draw/window.cpp b/compile/target/linux/draw/window.cpp deleted file mode 100644 index 169fdf9..0000000 --- a/compile/target/linux/draw/window.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "draw/window.h" -#include -#include -#include -#include -window_service_t::status_t window_service_t::create_window() { - Display *d; - Window w; - XEvent e; - const char *msg = "Hello, World!"; - int s; - d = XOpenDisplay(NULL); - if (d == NULL) { - return window_service_t::status_t::error; - } - s = DefaultScreen(d); - w = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 100, 100, 1, BlackPixel(d, s), WhitePixel(d, s)); - XSelectInput(d, w, ExposureMask | KeyPressMask); - XMapWindow(d, w); - while (true) { - XNextEvent(d, &e); - if (e.type == Expose) { - XFillRectangle(d, w, DefaultGC(d, s), 20, 20, 10, 10); - XDrawString(d, w, DefaultGC(d, s), 10, 50, msg, strlen(msg)); - } - if (e.type == KeyPress) - break; - } - XCloseDisplay(d); - return window_service_t::status_t::ok; -} diff --git a/compile/target/linux/draw/window_service.cpp b/compile/target/linux/draw/window_service.cpp new file mode 100644 index 0000000..1eea0d9 --- /dev/null +++ b/compile/target/linux/draw/window_service.cpp @@ -0,0 +1,158 @@ +#include "draw/opengl_service.h" +#include "draw/window_service.h" +#include "inform/text_service.h" +#include "target/linux/draw/opengl_x11_service.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +window_service_t::window_service_t( + window_service_t::configuration_t* configuration_p +) { + configuration_m = configuration_p; +} + +void_t window_service_t::create_window( + std::string* window_title +) { + void_t void_l; + void_l.error_m = window_service_t::error_t::unknown; + Display* display_l = XOpenDisplay( + NULL + ); + if (display_l == NULL) { + void_l.error_m = window_service_t::error_t::x_server_connection_failure; + return void_l; + } + Window root_window_l = DefaultRootWindow( + display_l + ); + + // Create OpenGL X11 Service for binding + opengl_x11_service_t::configuration_t opengl_x11_service_configuration_l; + opengl_x11_service_factory_t opengl_x11_service_factory_l; + opengl_x11_service_t* opengl_x11_service_l = opengl_x11_service_factory_l.create( + &opengl_x11_service_configuration_l + ).value_m; + + XVisualInfo* visual_info_l = opengl_x11_service_l->get_visual_info( + display_l + ).value_m; + Colormap colormap_l = XCreateColormap( + display_l, + root_window_l, + visual_info_l->visual, + AllocNone + ); + XSetWindowAttributes set_window_attributes_l; + set_window_attributes_l.colormap = colormap_l; + set_window_attributes_l.event_mask = ExposureMask | KeyPressMask; + Window window_l = XCreateWindow( + display_l, + root_window_l, + 0, + 0, + 320, + 240, + 0, + visual_info_l->depth, + InputOutput, + visual_info_l->visual, + CWColormap | CWEventMask, + &set_window_attributes_l + ); + XMapWindow( + display_l, + window_l + ); + XStoreName( + display_l, + window_l, + window_title->data() + ); + + opengl_x11_service_l->initialize_context( + display_l, + visual_info_l, + window_l + ); + + // Create OpenGL Service for rendering + opengl_service_t::configuration_t opengl_service_configuration_l; + opengl_service_factory_t opengl_service_factory_l; + opengl_service_t* opengl_service_l = opengl_service_factory_l.create( + &opengl_service_configuration_l + ).value_m; + + opengl_service_l->enable_depth_test( + ); + + XEvent event_l; + XWindowAttributes window_attributes_l; + while(true) { + XNextEvent( + display_l, + &event_l + ); + if (event_l.type == Expose) { + XGetWindowAttributes( + display_l, + window_l, + &window_attributes_l + ); + opengl_service_l->resize_viewport( + 0, + 0, + window_attributes_l.width, + window_attributes_l.height + ); + opengl_service_l->draw_quad( + ); + opengl_x11_service_l->swap_buffers( + display_l, + window_l + ); + } else if (event_l.type == KeyPress) { + opengl_x11_service_l->dispose( + display_l + ); + XDestroyWindow( + display_l, + window_l + ); + XCloseDisplay( + display_l + ); + break; + } + } + void_l.error_m = window_service_t::error_t::none; + return void_l; +} + +return_t window_service_factory_t::create( + window_service_t::configuration_t* configuration_p +) { + return_t return_l; + return_l.error_m = window_service_t::error_t::none; + window_service_t* window_service_l = new window_service_t( + configuration_p + ); + return_l.value_m = window_service_l; + return return_l; +} + +void_t window_service_factory_t::dispose( + window_service_t* window_service_p +) { + delete window_service_p; + void_t void_l; + void_l.error_m = window_service_t::error_t::none; + return void_l; +}