Würfelkunstprojekt

Cube Art Project – kubischer 3D-Editor.
Sie haben die großartige Möglichkeit, sich auf der Bühne zu bewegen, Würfel mit den Tasten WSAD + E zu erstellen und zu löschen und das Mausrad zu drehen, um die Farbe des Würfels zu ändern. Derzeit werden nur 16 Farben unterstützt, für die Zukunft sind jedoch viele Verbesserungen geplant.

Webversion
https://demensdeum.com/games/CubeArtProjectWEB/

Windows
https://demensdeum.com/games/CubeArtProjectReleases/CubeArtProjectWin32.zip

macOS
https://demensdeum.com/games/CubeArtProjectReleases/CubeArtProjectMacOS.zip

Linux (x86-64)
https://demensdeum.com/games/CubeArtProjectReleases/CubeArtProjectLinux86_64.zip

Android
(Konzept, erfordert USB-Maus)
https://demensdeum.com/games/CubeArtProjectReleases/CubeArtProject.apk

Quellcode
https://gitlab.com/demensdeum/cube-art-project-bootstrap
https://gitlab.com/demensdeum/cube-art-project-server

Technologien: SDL, Emscripten, MinGW, Glew, GLM, Cpp-JSON

Auf den Kopf gestellte Welt

Um ein neues Projekt zu entwickeln, hat Cube Art Project die Test Driven Development-Methodik übernommen. Bei diesem Ansatz wird zunächst ein Test für eine bestimmte Funktionalität der Anwendung durchgeführt und anschließend die spezifische Funktionalität implementiert. Den großen Vorteil dieses Ansatzes sehe ich darin, dass die finalen Schnittstellen möglichst unbeeinflusst von Implementierungsdetails implementiert werden, bevor mit der Entwicklung der Funktionalität begonnen wird. Bei diesem Ansatz bestimmt der Test die weitere Implementierung und bietet alle Vorteile der Vertragsprogrammierung, wenn es sich bei Schnittstellen um Verträge für eine bestimmte Implementierung handelt.
Würfelkunstprojekt – Ein 3D-Editor, in dem der Benutzer Figuren aus Würfeln baut; vor nicht allzu langer Zeit war dieses Genre sehr beliebt. Da es sich um eine grafische Anwendung handelt, habe ich beschlossen, Tests mit Screenshot-Validierung hinzuzufügen.
Um Screenshots zu validieren, müssen Sie sie aus dem OpenGL-Kontext abrufen. Dies geschieht mit der glReadPixels-Funktion. Die Beschreibung der Funktionsargumente ist einfach – Startposition, Breite, Höhe, Format (RGB/RGBA/usw.), Zeiger auf Ausgabepuffer; jeder, der mit SDL gearbeitet hat oder Erfahrung mit Datenpuffern in C hat, ersetzt einfach die notwendigen Argumente. Ich halte es jedoch für notwendig, eine interessante Funktion des glReadPixels-Ausgabepuffers zu beschreiben: Pixel werden darin von unten nach oben gespeichert, während in SDL_Surface alle grundlegenden Operationen von oben nach unten erfolgen.
Das heißt, nachdem ich einen Referenz-Screenshot aus einer PNG-Datei geladen hatte, konnte ich die beiden Puffer nicht direkt vergleichen, da einer von ihnen auf dem Kopf stand.
Um den Ausgabepuffer von OpenGL umzudrehen, müssen Sie ihn füllen, indem Sie die Screenshot-Höhe von der Y-Koordinate subtrahieren. Es ist jedoch zu bedenken, dass die Möglichkeit besteht, dass die Puffergrenzen überschritten werden, wenn Sie beim Füllen nichts subtrahieren zu Speicherbeschädigungen führen.
Da ich immer versuche, das OOP-Paradigma der „Programmierung durch Schnittstellen“ anstelle des direkten C-ähnlichen Speicherzugriffs durch Zeiger zu verwenden, hat mich das Objekt beim Versuch, Daten außerhalb des Puffers zu schreiben, dank der Grenzvalidierung in der Methode darüber informiert .
Der endgültige Code für die Methode zum Erstellen eines Screenshots im Top-Down-Stil:

    auto width = params->width;
    auto height = params->height;

    auto colorComponentsCount = 3;
    GLubyte *bytes = (GLubyte *)malloc(colorComponentsCount * width * height);
    glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, bytes);

    auto screenshot = make_shared(width, height);

    for (auto y = 0; y < height; y++) {
        for (auto x = 0; x < width; x++) {
            auto byteX = x * colorComponentsCount;
            auto byteIndex = byteX + (y * (width * colorComponentsCount));
            auto redColorByte = bytes[byteIndex];
            auto greenColorByte = bytes[byteIndex + 1];
            auto blueColorByte = bytes[byteIndex + 2];
            auto color = make_shared(redColorByte, greenColorByte, blueColorByte, 255);
            screenshot->setColorAtXY(color, x, height - y - 1);
        }
    }

    free(bytes);

Quellen

https://community.khronos.org/ t/glreadpixels-fliped-image/26561
https://stackoverflow.com/questions/8346115/why-are-bmps-stored-upside-down

Quellcode

https://gitlab.com/demensdeum/cube- Kunstprojekt-Bootstrap