/** * paradiso - Paradigmen der Softwareentwicklung * * (c) Copyright 2023 Hartmut Seichter * */ #include #include #include #include #include #include #include #include #include void setup_shaders(paradiso::Shader& shader) { const auto unlit_v = R"( #version 330 core layout (location = 0) in vec3 vertices; layout (location = 1) in vec3 normals; layout (location = 2) in vec2 texture_coords; uniform vec4 pivot = vec4( 0.5, 0.5, 0.0, 1.0 ); out vec2 tex_c; void main() { tex_c = texture_coords; gl_Position = vec4(vertices, 1.0) + pivot; } )"; const auto unlit_f = R"( #version 330 core uniform vec4 color = vec4(1.0, 0.0, 0.0, 1.0); uniform sampler2D tex_color; in vec2 tex_c; out vec4 frag_color; void main() { frag_color = texture(tex_color,tex_c); // * color; })"; shader.set_source(paradiso::Shader::Type::Vertex, unlit_v); shader.set_source(paradiso::Shader::Type::Fragment, unlit_f); shader.build(); } auto main() -> int { // Ausgabefenster ... sieht aus als wäre es auf dem Stack auto window = paradiso::Window(); // wir bauen ein Fenster ... window .set_size(paradiso::Size{.width = 1280, .height = 720}) // ... Grösse .set_position(paradiso::Point{.x = 100, .y = 100}) // ... Position .set_title("PardiSO") // ... Titel .set_visible(true); // ... und jetzt anzeigen! // der Fenster Kontext auto ctx = paradiso::Context{}; // als Beispiel eine Sprite mit farbiger Textur auto sprite = paradiso::Sprite{ .bitmap = paradiso::Bitmap::from_data( paradiso::Size{2, 2}, paradiso::RGBA::from_rgba(0x00, 0xFF, 0x00, 0x80), // G paradiso::RGBA::from_rgba(0xFF, 0x00, 0x00, 0x80), // R paradiso::RGBA::from_rgba(0x00, 0x00, 0xFF, 0x80), // B paradiso::RGBA::from_rgba(0xFF, 0x00, 0xFF, 0x80)) // C }; // das eigentliche 2D rendering sub-system auto renderer = paradiso::Renderer{}; // ein Shader (Schattierungsprogramm) auto shader = paradiso::Shader{}; // hier werden die Shader Programme geladen, kompiliert usw. setup_shaders(shader); // kein schönes Design: dies sind globale Variablen ... uint8_t slider_value = 0xFF; bool want_close{false}; // eine sehr rudimentäre Eingabebehandlung. Bei vorhandenen // Eingaben landen diese hier. Wer sich am Design beteiligen // möchte, kann hier einen eleganteren Vorschlag machen window.set_keyboardcallback( [&](auto& w, int key, int scancode, int action, int mods) { if (key == 'Q' || key == 256) want_close = true; else if (key == 'A') { slider_value += 10; } }); // das update führt den hier mitgegebnen Ausdruck innerhalb der internen // Updates des Fensters auf. Es wird hier auch explizit ein bool gefordert // damit das update auch zu jederzeit unterbrochen werden kann while (window.update([&](auto& w) -> bool { // Context behandelt den sogenannten viewport - Hintergrund löschen, // grösse usw. werden hier behandelt ctx.set_clearcolor( paradiso::RGBA::from_rgb(slider_value, slider_value, slider_value)); // ein viewport stellt die Sicht der Kamera dar, d.h. bei quadratischen // Pixeln sollte hier auch eine dementsprechende Grösse eingestellt // werden ctx.set_viewport(paradiso::Rectangle{ .size = w.client_size().minimal_extent() // wir wollen das // Seitenverhältnis beibehalten }); // hier wird das eigentliche löschen des vorherigen Inhalts ausgelöst ctx.clear(); // Ein `renderer` kann nur mit einer Sprite verwendet werden! // Aber ein Shader kann man für mehrere Sprite-Renderer Kombis verwenden renderer.draw(sprite, shader); // ... signalisiere ob wir weitermachen wollen ... return !want_close; })) { }; return 0; }