[OpenGL-Projekt] Alles auf Anfang [Update 4]

AW: [OpenGL-Projekt] Bloom-Effekt erzeugen [update 2]

kleines update mal wieder.

hab mich heute endlich mal dazu durchgerungen, wieder bissl zu basteln. endete vorläufig natürlich erstmal in nem desaster :P meine zielsetzung: die aufdröselung der 5x5 kernel matrix mit 25 pixel-abfragen in nen 1x5 und 5x1 kernel. also aufsplittung in horizontal- und vertikal-pass und somit aus 25 texturabfragen 10 machen. hatte zuerst wieder 5 bloom texturen gebaut und nen weiteren shader. wollte quasi den horizontalen pass in 5 einzelbildchen zwischenspeichern und am ende mit dem vertikalen pass alles kombinieren. allerdings war das nich grad ne intelligenzleistung >< man muss ja eigentlich das bisherige einfach nur runterbrechen. am ende baute ich also quasi alles wieder zurück, nur mit dem unterschied, dass ich den selben shader zwei mal durchlaufe, mit ner neuen uniform als flag für eben h_pass oder v_pass. statt nun bei einem durchgang diese 25er-kernel geschichte zu tüdeln, mach ich nun je nach flag entweder den 5x1 oder den 1x5er kernel. das war dann auch schon alles. gut, war halt viel gefibbel in details, aber im groben doch nich so wild, wie ichs mir erst erdachte. nunja, jedenfalls das ergebnis: kA, aber mir kommts vor, als siehts wieder minimal besichener aus (pixeliger ^^) aber die fps sind von 80-90 auf 190-210 gestiegen. also der performance zuwachs ist ok.

glaube, als nächstes werd ich mal versuchen, den objectloader zu vervollständigen. sprich: dass er die farben/texturen mit ausliest (macht er glaube schon) und beim zeichnen auch benutzt (ein unwesentliches detail, das bisher fehlt *hust* ^^). deswegen sieht dieses schiff atm auch aus, wie das zuletzt tapezierte objekt - in dem fall halt die erdmurmel. zusätzlich will noch ne alphamap einbauen. also eben leuchtende bereiche per textur angeben bla (lava planet, der auf der nachtseite glüht oder sowas). sollte recht simpel sein *denk*
 
AW: [OpenGL-Projekt] Bloom-Effekt erzeugen [update 2]

sohooo ^^

hab die letzten tage fleissig nebenher ab und zu mal getüftelt und mir eine texturverwaltungsklasse gebaut. speichert quasi global in ner vector-liste texturen mit ihren namen und der generierten id. baue ich nen objekt mit dem object loader, dann liest der das mtl file ein und holt da alle textur-namen raus. daraus kann ich dann ne string-liste bauen lassen die meiner textur klasse geschickt wird und die fügt dann alle noch nicht aufgenommenen texturen hinzu. so lad ich im notfall nich 10 ma die selbe textur ^^

jut, funzt soweit. obs nutzvoll is in dieser art und weise muss ich mal schauen ^^

hab dann also noch mein 2. vorhaben probiert. hab dazu die specular-textur angepasst. der rote kanal stellt die specular-map dar, der grüne die lumineszens map. funzt soweit auch ganz gut. hier mal ein bild:
SolarSystem 2013-09-01 21-49-39-53.jpg
das rote ding da is mein textur test blubb gewesen (sieht man auf den anderen besser). war ja früher das schiffsobjekt, habsch jetz einfach ne kugel genommen. die erde usw is also "handarbeit" und io (zumindest laut textur xD) ist rein aus dem obj file geladen. jut, man sieht - nachtseite und bei io leuchten so nen paar ausgewählte bereiche und bei der erde die stadtlichter. was man gerade bei der erde sieht: es werden keine lichter drüber gelegt, sondern einfach der untergrund erhellt. somit leuchten die gebiete nicht weis/gelb wie licht, sondern grün oder braun/gelb wie der untergrund. glaube nicht, dass mir das endgültig gefällt xD werd hier wohl also nochmal umbauen und ne seperate textur bauen. rgb für die farbe, die dann leuchtet (als überlagerung quasi) und alpha kanal als "intensität" - also wie stark es leuchtet halt.


ein weiteres prob is mir auch aufgefallen: es bloomt nur die "tagseite". ich hab bisher die sonne per trick zum leuchten gebracht (die lampe is ja eigentlich innendrin) indem ich dem shader ne flag variable mitgegeben hatte. war die 1, hat er sich die ganze renderei einfach gemacht, ansonsten hat er schön schattiert usw usf. gut, beim schattieren macht er nu eben scheinbar murks. wie man auf den bildchen sieht, hat die sonne nur auf der tagseite bloom (abgesehen davon, dass die sonne garkeine tagseite haben sollte, da sie ja an die position der lampe gesetzt wird... ätzende bugs überall ^^). jetz muss ich noch rausfinden, wieso das ned funzt *bäh*
SolarSystem 2013-09-01 21-48-57-25.jpg SolarSystem 2013-09-01 21-50-08-03.jpg

hmm, jetzt füge ich 2mal farbanteile hinzu. einmal generell und einmal, wenn schatten is >< das ganze noch gemixt mit dem schattenanteil, damit der übergang ned so scharf is - und überraschenderweise siehts ganz gut aus. aber ob das so richtig is :ka: :ugly: nur am bloom hat sich noch ned wirklich was getan. warscheinlich is die schwelle zu gering. also die aufhellung nicht stark genug *grübel*
SolarSystem 2013-09-01 22-39-42-40.jpg SolarSystem 2013-09-01 22-41-50-32.jpg
 
AW: [OpenGL-Projekt] Datenbank-Anbindung [Update 3]

soa, ich mal wieder. das dingen schläft ja nun auch schon ne weile, aber im kopf rumort es und es will nicht aufhören xD hier nunmal ein schritt, der mich schon länger intressiert: wie löst man das mit datenbanken und c++? also ich kenns bisher nur mit php, wo man halt auf ne (meinetwegen) xammp-db zugreift. wie kann ichs aber erreichen, dass der quasi eine db "integriert"? geht sowas überhaupt (kostenlos ^^)? ich mein so wie mit php auf ne externe db zuzugreifen geht ja wohl noch recht simpel. hab ich zwar auch nur absolut oberflächliches "wissen", aber nuja. jedoch direkt im programm sowas zu haben - wie löst man sowas?

also mir gehts hauptsächlich darum, meinetwegen raumschiffsparameter wie position usw zu speichern. geht sicherlich auch über irgendwelche dateien denk ich mal, aber ne db is dann doch recht flink mit der sucherei oder? daher: lohnt sich der aufwand überhaupt, oder mach ich mir falsche vorstellungen?

weiteres anwendungsbsp: ein raumschiff ist modular aufgebaut. im innern ist es szs eine aneinanderreihung von räumen, die in der schiffshülle positioniert sind und aggregate wie antriebe oder waffen/sensoren whatever müssen auch platziert werden. wäre für sowas ne db überhaupt sinnvoll, oder würdet ihr sowas anders speichern? also mir gehts grad auch eher erstmal um konzeptionelle grundlagen, weniger um detaillierte ausarbeitungen :>

würde mich über ideen/anregungen zur thematik freuen :D
 
AW: [OpenGL-Projekt] Datenbank-Anbindung [Update 3]

weis zufällig wer, wie ich schriftarten (also die dateien) auslesen kann? es scheint ja vorgefertigte funktionen dafür zu geben, aber die machen natürlich nich so ganz das, was mir so vorschwebt. hab auch schon sonen msdn dingens gefunden mit viel geschreibsel, aber so recht werd ich da (wie immer) nich schlau draus ><

The OpenType Font File


meinem verständnis nach sind das doch "vektorgrafiken". also die einzelnen buchstaben. die werden am ende genau wie 3d modelle in der gewünschten (schrift)größe rasterisiert. also müssen da drin ja für die einzelnen buchstaben die vektoren stehen. die würd ich gerne auslesen, den buchstaben quasi als spiel-objekt erstellen und daraus ein 3d objekt machen (einfach in die tiefe extrudieren? oder wie das heisst ^^), mit dem ich dann lustig arbeiten kann. bis hierhin geht das wohl auch per vorgefertigter funktion, allerdings nutzt die wohl displaylisten zum bsp, und keine vbo's bla. zudem wöllt ich da gerne mit texturen usw arbeiten, um effekte zu erreichen.

vllt kennt sich ja wer von euch damit aus :)
 
AW: [OpenGL-Projekt] Datenbank-Anbindung [Update 3]

Schau dir mal FreeType an, das ist zwar eigentlich eine Bibliothek fürs Rasterisieren von Schriften, aber gibt dir auch direkt Zugriff auf die Outline der einzelnen Glyphen.

Um jetzt (korrekt) herauszufinden, welche Zeichen welche Glyphen erzeugen, müsstest du zwar schon manuell die Font-Datei lesen, die ganzen Tabellen auswerten und dann die Strings, die du rendern willst, entsprechend in Folgen von Glyph-IDs umwandeln, aber... das braucht es dann doch eher für exotischere Sprachen, fürs Erste sollte Freetype allein reichen.
 
Zuletzt bearbeitet:
AW: [OpenGL-Projekt] Datenbank-Anbindung [Update 3]

hmmm, hab da jetzt mal bei download geschaut und kam zu dieser seite:
Index of /releases/freetype

da gibts fast ganz unten mit aktuellstem datum eine ttfautohint-1.1-win32.7z. aber da sind nur 2 exe dateien drin? dachte da is ne lib oder dll oder sowas zu finden. oder installiert mir die exe das schön fein, so das auch ich ahnungsloser mich auf einfache art und weise freuen kann? ^^ nich dass das einfach irgendein tool is, mit dem ich wenig anfangen kann :/
 
AW: [OpenGL-Projekt] Datenbank-Anbindung [Update 3]

ttfautohint ist ein Tool, mit dem du nichts anfangen kannst, freetype ist die Bibliothek - die musst du allerdings wohl selbst compilieren, den Sourcecode findest du in der freetype-2.5.3.tar.bz2. Hier stehen auch die notwendigen Schritte, wenn man das mit Visual Studio machen will, und bis auf die Klickerei dürfte das gleiche auch für mingw-gcc gelten.

Edit: Es gibt auf der Projektseite irgendwo sogar Windows-Binaries, aber das sind schon steinzeitliche Versionen.

Ich weiß schon, warum ich mich fürs Programmieren von Windows fernhalte... :ugly:
 
AW: [OpenGL-Projekt] Datenbank-Anbindung [Update 3]

oha, mit dem dingen hab sogar ich grad ne dll erstellt bekommen. nur keinen plan, ob das funzt ^^ ich hab die erstmal in mein projekt verzeichnis geschoben und werd die einfach mal dazutüdeln, wie ich das mit dem opengl zeugs gemacht hatte. langt das schon, oder muss ich dann noch mehr bauen? bin, was sowas betrifft. echt der übelste anfänger :/

edit: er faselte gerade was von nicht vorhandenen build regeln >< meine güte, ich fühl mich wie am ersten tag xD

edit2: bin jetzt mal nach http://www.freetype.org/freetype2/docs/tutorial/step1.html vorgegangen bis zum initialisieren. resultiert in "Fehler 33 error LNK2001: Nicht aufgelöstes externes Symbol "_FT_Init_FreeType". SolarSystem.obj SolarSystem" *meh*



edit3: neuer tag, neues glück: hab einfach mal die mitgelieferte lib genommen statt der dll - funzt >< darf ich hierbei gleich eine theoriefrage in den raum werfen? was ist der unterschied zw lib und dll und wann verwende/brauche ich was? was ich jetzt mitbekommen hab ist, dass lib ne statische bibo ist und dll ne dynamische - aber was das bedeuted... ><
 
Zuletzt bearbeitet:
AW: [OpenGL-Projekt] Datenbank-Anbindung [Update 3]

huhu, ich mal wieder.

dank neuem visual hab ich mal wieder bissl losgelegt. neustart eben, nachdem die alte platte abgeraucht ist. muss mir mal gedanken machen, wie ich nen backup realisieren kann ^^

nujut, nutze c++ und glut bisher. glew soll dann noch kommen, wenn ich erstmal so die gröbsten grundlagen hab. aktuell hab ich noch ogl 1.0 code mit glbegin und so ^^ muss mich da wieder langsam rantasten. der grund, wieso ich schreibe ist aber folgender:
ich habe jetzt den fullscreenmode mittels glutEnterGameMode(); umgesetzt. ebenso dass ich mit alt+enter zw windowed und fullscreen wechseln kann. so, damit das wechseln klappt, erstelle ich in der main() erstmal ein window und danach betrete ich den "gamemode" / fullscreen. ohne das window vorher kann er nicht hin und her wechseln. funzt prinzipiell auch ganz gut, mit einer kleinen macke: er erstellt das fenster, wechselt in fullscreen (bild flackert) aber bekommt ihn nicht dargestellt. er ist aber im gamemode. sobald man mit der maus reinklickt oder ne taste drückt zeigt ers plötzlich richtig an.

hat wer ne idee, wie ich diese macke lösen kann?

hier mal die main:
Code:
#include "include\main.h"
#include "include\OGLfunc.h"

int main(int argc, char **argv) {
    stringstream mode;
    mode << width << "x" << height << ":32";
    // init GLUT and create Window
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);

    glutInitWindowPosition(100, 100);
    glutInitWindowSize(800, 600);
    glutCreateWindow("DarkMo - OpenGL Game");
    init();

    // setting the game mode
    glutGameModeString(mode.str().c_str());
    // enter full screen
    if (glutGameModeGet(GLUT_GAME_MODE_POSSIBLE)) {
        glutEnterGameMode();
        init();
    } else {
        printf("The select mode is not available\nStay Window-Mode instead.\n");
    }

    // enter GLUT event processing cycle
    glutMainLoop();

    return 0;
}
das doppelte init() muss wohl sein, da fullscreen ein "eigenes"/neues fenster ist und man dafür den render context bla neu erstellen muss. oder liegt das am visual? also dass das fenster keinen fokus hat und erst beim reinklicken bekommt oder so späße?
 
AW: [OpenGL-Projekt] Datenbank-Anbindung [Update 3]

Das sieht für mich sehr stark danach aus, das laut Dokumentation leider nicht das Window in den Vordergrund gesetzt und alle Hintergrundfenster deaktiviert wurden.
Da fallen mir pauschal nur 2 Möglichkeiten ein. Du könntest nach dem Wechsel in den Gamemode mit glutSetWindow den Fensterfokus forcieren oder auf Win-API Basis das Fenster an Hand des Titels ermitteln und mit dessen Handle in den Vordergrund forcieren. Mehr wüsste ich da auch nicht. Kenne glut nicht wirklich.
 
AW: [OpenGL-Projekt] Datenbank-Anbindung [Update 3]

hmm, hab jetzt mal die integers abgegriffen, die bei den funktionen geliefert werden. also:
...
int windowHandle, windowHandleFull;
...
windowHandle = glutCreateWindow("DarkMo - OpenGL Game");
cout << windowHandle;
...
windowHandleFull = glutEnterGameMode();
glutSetWindow(windowHandleFull);
cout << " - " << glutGetWindow() << "(" << windowHandleFull << ")";

gibt als ausgabe "1 - 2(2)". also das normale fenster ist 1, das fullscreen 2. das gesetzte window ist also tatsächlich das fullscreen teil. mit dem set window scheint es nun auch so zu sein, dass ich den fullscreeninhalt IMMER im hintergrund sehe. also momentan läuft es (mit dem code hier) so ab:

start
konsolenfenster
normales gl-fenster
geflacker (fullscreen bla)
wieder normales fenster
irgendwas machen - tatsächlich fullscreen
mit alt+enter in den windowmode -> im vordergrund ist wieder das normale fenster (id 1) und im hintergrund sieht man dann noch das fullscreen fenster.



edit: habs jetzt anders probiert. direkt im fullscreen starten - funzt perfekt. allerdings fehlt ja dann eben das windowed-fenster (sind ja verschiedene, daher ja auch das mit dem 2mal init();). nun wollte ich das im nachhinein erstellen, wenn ich in den fenstermode wechsel (und das fenster noch nich erstellt wurde). mach ich das, raucht allerdings alles ab. man muss also scheinbar erst das windowed dingen erstellen und danach den gamemode. dann aber eben mit den schon gezeigten problemen.

ich weiß atm keine lösung, ausser auf den windowed mode zu verzichten :/
 
Zuletzt bearbeitet:
ich probiere mich gerade an glfw für die fenster anstelle von glut. nutze https://solarianprogrammer.com/2013/05/10/opengl-101-windows-osx-linux-getting-started/ als gröbste anleitung - und musste erstmal zig pfade anpassen >< #include <GL\glfw.h> wurde bspw zu #include <GLFW\glfw3.h> und dann die Pfade zu den libs usw usf... aber hab soweit mMn alles zusammen, alles rot unterstrichelte ist weg und er erkennt alles:
Code:
#include <GLFW/glfw3.h>
#include <cstdlib>
#include <iostream>
using namespace std;

int main() {
    GLFWwindow* window;

    // Initialize GLFW
    if (!glfwInit()) {
        cerr << "GLFW: Failed to initialize GLFW!" << endl;
        exit(-1);
    }

    // Open a window and attach an OpenGL rendering context to the window surface
    window = glfwCreateWindow(800, 600, "Modoria", NULL, NULL);
    if (!window) {
        cerr << "GLFW: Failed to open a window!" << endl;
        glfwTerminate();
        exit(-1);
    }

    // Make the window's context current
    glfwMakeContextCurrent(window);

    // Use red to clear the screen
    glClearColor(1, 0, 0, 1);

    // Create a rendering loop
    while (!glfwWindowShouldClose(window)) {
        // Render stuff
        glClear(GL_COLOR_BUFFER_BIT);

        // Swap front and back buffers
        glfwSwapBuffers(window);
    
        // Poll for and process events
        glfwPollEvents();
    }
    // Terminate GLFW
    glfwTerminate();

    return 0;
}

Nun soll ich das Projekt mit F7 bauen, aber da kommen nun folgende Fehler:
1>------ Erstellen gestartet: Projekt: Modoria, Konfiguration: Debug Win32 ------
1> main.cpp
1>LINK : warning LNK4098: Standardbibliothek "MSVCRT" steht in Konflikt mit anderen Bibliotheken; /NODEFAULTLIB:Bibliothek verwenden.
1>glfw3.lib(init.c.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__vsnprintf" in Funktion "__glfwInputError".
1>MSVCRTD.lib(vsnprintf.obj) : error LNK2001: Nicht aufgelöstes externes Symbol "__imp__vsnprintf".
1>glfw3.lib(context.c.obj) : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__sscanf" in Funktion "_parseVersionString".
1>MSVCRTD.lib(vsnprintf.obj) : error LNK2001: Nicht aufgelöstes externes Symbol "__imp___vsnprintf".
1>F:\DarkMo\Programme\Visual Studio 2015\myProjects\Modoria\Debug\Modoria.exe : fatal error LNK1120: 3 nicht aufgelöste Externe
========== Erstellen: 0 erfolgreich, 1 fehlerhaft, 0 aktuell, 0 übersprungen ==========

hab nun also nach dem fehler gegoogled und das hier gefunden:
https://msdn.microsoft.com/de-de/library/6wtdswk0(v=vs.120).aspx

meh, kann mir das jemand erklären? xD verstehe da nur bahnhof :( wieso schaff ichs objectloader und weiß der geier was zu bauen, aber solche basics sind mir ein buch mit 7 siegeln...



edit: hab nun noch das hier gefunden:
c++ - Linker Errors with glfw and MSVS 2012 - Stack Overflow
das besagt, dass man als lib die verwenden soll, die für das eigene visual gedacht ist. also wenn man visual 2010 hat, sollte man nicht die für die 2013er version nutzen. so weit so gut... nun ist dieses community dingen aber glaube 2015 und dafür gibts keine lib... un nu? was isn das fürn blödsinn, dass man für verschiedene "ide" versionen verschiedene libs brauch oO


edit2: so, man kann sich das wohl auch selber generieren aus den source-files. nur wie ist halt die frage. hab jetzt gerade das hier gefunden:
GLFW / Discussion / Using GLFW:Visual Studio 2013
mal schauen ob das klappt. ist zwar für die 13er version, aber vllt bekomm ichs ja dennoch hin...

edit3: ok, bin scheinbar zu doof dafür. cmake geladen, installiert und ausgeführt, wie gewünscht mit den daten gefüttert und er baut mir auch irgendwas (viele ordner und vc++ projekte...). nun hab ich die .sln geöffnet, auf release gestellt und F5 gedrückt - fehler :/ auch nirgends ne lib oder so zu finden. jetzt schau ich mir nochmal das an:
GLFW: Compiling GLFW

ausser so schlauen sprüchen wie "das selber zu kompilieren is ja nich schwer" findet man leider nicht viel hilfreiches -.-


edit4: k... das war auch ein schuss in den ofen. das cmake ist scheinbar so alles korrekt, aber wieso geht das projekt nich? ich öffne das, drück f5 und er schmeisst nen error (konnte ... ah lest selbst ^^)
Unbenannt.png
er erstellt zwar fleissig ordner, aber da ist entweder keine lib bzw dll drin oder aber sie sind gänzlich leer. und zum suchen bin ich scheinbar zu doof, ich find einfach keine anleitung, wie man sowas macht. auch der zuletzt genannte link höhnt mich nur an, dass ich das machen soll, "wie sonst auch"... (Go ahead and compile the actual GLFW library with these files, as you would with any other project.) - danke -.- so wie ich das sonst mache gehts nicht *durchdreh*

ich hasse sowas. wegen sonem mist geht wieder nix. hat denn keiner ne idee? hier laufen doch immer soviele gurus rum xD
 
Zuletzt bearbeitet:
IMHO kommt der LNK4098 zum Beispiel, wenn man einen Release Build in einen Debug Build packen will. Angenommen eine Lib setzt auf die MSCVRT im Release Mode und deine Anwendung wird aber im Debug Mode kompiliert - dann passen die internen Libs (Runtime) nicht zueinander. Das ist auch gleich der zweite Punkt: Die Libs hängen nicht von der Visual Studio Version ab sondern sind an die Version der MSVCRT gebunden, welche allerdings mit VS ausgeliefert werden. Und die sind untereinander nicht wirklich kompatibel. Du kannst auch mit einem 2015er Visual Studio eine ältere Runtime als Target haben, dazu musst du allerdings die entsprechenden Build Tools zusätzlich installieren.

Ich habe GLFW bisher noch nicht selbst kompiliert, aber normalerweise funktioniert F5 bei Libs generell nicht, da die ja nicht ausführbar sind. Ich kann die allerdings SFML empfehlen, das läuft unter Windows out of the box ganz gut, arbeite ich selber mit. Ohne die Fehlermeldung zu kennen kann ich dir zu deinem aktuellen Problem auch nichts weiter sagen :(
 
Zuletzt bearbeitet:
kurze zwischenmeldung: es läuft!

apollo hatte die rettende idee für diesen defaultlib konflikt: die libs sind nicht für den debug mode gemacht -> switch zu release und der fehler war weg. dann blieb noch der fehler mit den unaufgelösten symbolen (sscanf und printf irgendwas) - warscheinlich intern in glfw genutzes zeugs. dann stieß ich zufällig auf diesen link:
https://social.msdn.microsoft.com/F...et-unresolved-external-errors?forum=vcgeneral

problem gelöst ><


sicher nur ein workaround da er gemachte veränderungen/verbesserungen(?) der neuen version rückgängig macht, aber hoffentlich bringt eine neue lib von den jungs bei einem neuen glfw release endgültig abhilfe. nun muss ich mal rumtesten, ob hier ein gescheiter fullscreenmode zu realisieren ist :) sonst war das auch wieder umsonst xD
 

Anhänge

  • lüppt.png
    lüppt.png
    157,7 KB · Aufrufe: 47
  • linker-input.png
    linker-input.png
    196,1 KB · Aufrufe: 38
Hatte ich doch geschrieben mit den Libs, kenne das von libSDL, die haben auch kein Debug-Build. Aber schön dass es nun läuft :)
 
Na ich hoffe mal, das es denn jetzt auch mit deinem Vollbildproblem erledigt ist, weswegen du ja die Bibliothek gewechselt hast ^^
 
das hier
[Solved][GLFW][LWJGL3] Toggle between fullscreen and windowed mode - Java-Gaming.org
klingt recht vielversprechend.


ich glaub, ich muss nochmal ne noobfrage stellen ^^ header richtig einbinden.
ich habe jetzt meine main.cpp mit ner main.h - in maincpp includiere ich also main.h. soweit so gut. nun habe ich mir noch eine mesh-klasse gebaut mit mesh.cpp und mesh.h sowie das gleiche nochmal mit einer vertex-klasse. normalerweise includiert nun mesh.cpp ja mesh.h und vertex.cpp die vertex.h. allerdings soll ja auch meine main.cpp darauf zugreifen können - in der main.h ist aber nix includiert. tu ich dort einfach auch nochmal die 2 header includieren oder wie funzt das?

ich hatte es eben so gemacht, dass die main.h die vertex und mesh.h includiert und mesh und vertex.cpp includierten die main.h (und somit über einen umweg eben auch "ihre" header - ohne das alles doppelt includiert wird). er hatte mir dabei auch alles ordentlich angezeigt, also ich konnte auf die memberfunktionen usw zugreifen per tooltip beim schreiben und es war nix unterstrichelt - beim kompilieren aber hat ers mir angekreidet, dass er nix kennt.

wie macht mans richtig xD

ps: mesh soll später mal alle mesh-daten (vertices, die daraus gebildeten edges (erstmal optional) und die faces) beinhalten und mir vbo usw zusammen bauen. warscheinlich werd ich noch eine model-klasse bauen, welche dann "komplexe" meshes darstellt. also eine liste von mesh-objekten enthält die seperat dann bewegt werden können (stichpunkt animationen). die vertex-klasse kapselt die vertexdaten und stellt paar mathematische funktionen bereit (länge, skalar/kreuzprodukt, winkel....) mal schauen ob das später nützlich ist oder doch überflüssig ^^ mesh "filtert" auch die eingefügten vertices, so dass keine doppelten daten vorhanden sind. ob sich das später rächt, muss ich mal schauen >< wobei ich die befürchtete problematik eher bei "per-vertex-normalen" vermute - was ja nun doch wieder ein bischen was anderes ist.

naja, zukunftsmusik noch.
 
so, mal wieder eine zwischenmeldung. aktueller stand:
output.png

und nein, das soll kein getarntes hakenkreuz sein ^^ ich folge derzeit diesem tutorial in etwa:
https://solarianprogrammer.com/2013/05/13/opengl-101-drawing-primitives/

leider ist das mit ner glfw version 2.x geschrieben und zu meiner genutzten 3.1.1 ist da doch recht viel anders. aber klappt scho irgendwie. hab mich auch wieder oft reichlich dusslig angestellt ^^ zum bsp wollt ich nur ein vbo generieren - absturz mit speicherverletzung usw oO man sollte das halt erst nach der glew initialisierung aufrufen. ist schön, wenn die funktioniert, aber eben erst danach ^^ hatte ne init-funktion für die fnster callbacks usw und da war eben auch das ogl zeugs mit drin. musste ich am ende aufdröseln in 2 inits. einmal fenster - denn ohne das kein glew - und dann nochmal das ogl gerödel, was wiederrum ohne glew ned funzt. naja, hab ich das also auch.

momentaner aufbau vom code: das hauptfile und dann eine mesh-klasse, die alle meshdaten verwaltet. da sind listen für die vertices drin und ebenso listen für normalen sowie flächen und kanten (die allerdings nur mit "id" (vectorlisten-position) verweisen auf die vertices usw). mit den vertices kann ich auch lustig rechnen, also skalarproduk, kreuzprodukt, normalisierung, länge, addition, subtraktion, skalare multiplikation... all so sachen. klappt bisher ganz gut. der aufbau der figur im bild wird bspw so geregelt:
Code:
GLfloat *batch = 0;
    vertex v1, v2, v3;
    mesh m;

    v1.setVertex(0.0, 0.0);
    v2.setVertex(0.5, 0.0);
    v3.setVertex(0.5, 0.5);
    m.addFace(v1, v2, v3);

    v1.setVertex(0.0, 0.0);
    v2.setVertex(0.0, 0.5);
    v3.setVertex(-0.5, 0.5);
    m.addFace(v1, v2, v3);

    v1.setVertex(0.0, 0.0);
    v2.setVertex(-0.5, 0.0);
    v3.setVertex(-0.5, -0.5);
    m.addFace(v1, v2, v3);

    v1.setVertex(0.0, 0.0);
    v2.setVertex(0.0, -0.5);
    v3.setVertex(0.5, -0.5);
    m.addFace(v1, v2, v3);

    unsigned int count = 0;
    batch = m.generateBatch(count);
ich bastel 3 vertices (z und w werden mit der methode auf 0 und 1 initialisiert, also auch bei nur 2 koords werden 4d verts erzeugt) und erstelle damit eine fläche im mesh. diese funktion fügt die vertices in die entsprechenden listen ein, legt die ecken an (wie gesagt: bisher sind die eigentlich sinnlos, aber eventuell brauch ich die mal für schatten) und berechnet noch die flächennormale. die vertex-ids und die normalen-id werden dann als fläche gespeichert, fertig. am ende wird noch das array mit den vertex-daten geschnürt und zurück gegeben. damit kann ich dann die figur da zeichnen.

hierzu hätte ich noch eine frage... das übertragen in den vRam geschieht mittels diesen aufrufes:
glBufferData(GL_ARRAY_BUFFER, (sizeof(batch) * count), batch, GL_STATIC_DRAW);

wie man eventuell erkennt, hantiere ich hier mit dieser count variable rum. also ich erstelle sie mit 0, übergebe sie der generateBatch funktion welche dann den intern ermittelten wert darin speichert und "zurückgibt" damit ich den zu allocierenden speicher ordentlich angeben kann. weil ich habe das problem, dass ich einfach keine vernünftige angabe aus dem sizeof gezaubert bekomm :/ erstelle ich ein statisches array:
GLfloat batch[24];
dann gibt mir sizeof die korrekten 96 (byte?) zurück. 4 für elemente des typs GLfloat und 24 an der zahl -> 4*24=96. nun bastelt mir aber generateBatch ein "dynamisches" array. hier mal die funktion:
Code:
GLfloat* mesh::generateBatch(unsigned int &count) {
    unsigned int vpf = 3; // vertices per face
    unsigned int vac = 2; // vertices axis count
    count = this->fList.size() * vpf * vac; // anzahl flächen * anzahl vertices pro fläche * anzahl vertice-koordinaten
    int id;
    GLfloat *vBatchPtr = new GLfloat[count];
    vertex vt;

    for (unsigned int f = 0; f < this->fList.size(); f++) {
        //cout << "face " << f << endl;
        for (unsigned int v = 0; v < vpf; v++) {
            //cout << "  vertex " << v << endl;
            id = this->fList.at(f).getID(v);
            if (id >= 0) {
                vt = this->vList.at(id);
                for (unsigned int a = 0; a < vac; a++) {
                    vBatchPtr[(f * vpf * vac + v * vac + a)] = vt.getAxis(a);
                    //cout << "    " << (f * vpf * vac + v * vac + a) << " = " << vt.getAxis(a) << endl;
                }
            }
        }
    }

    return vBatchPtr;
}
vBatchPtr ist ein zeiger auf ein GLfloat-array mit "count" elementen. hauptsächlicher bestandteil sind natürlich die anzahl der flächen. je mehr flächen ich habe, desto mehr vertex-daten brauch ich. weiterhin fließt die anzahl der vertices pro fläche mit rein (da ich mit triangles arbeite -> 3) und als letztes die anzahl der vertex-werte. da ich fürs bsp nur mit 2 achsen (x und y) arbeite, steht hier aktuell die 2. kann man rein theoretisch gleich auf 4 setzen, da OGL das intern eh wieder auf 4er verts hochsetzt. zur besseren vergleichbarkeit der sizeof-werte hab ichs aber so eingestellt erstmal.

so, dann geht er alle gespeicherten flächen durch und hier werden für alle 3 vertices die entsprechenden id's abgeholt. bzw eben listen-positionen. id = this->fList.at(f).getID(v); macht das. fList ist die liste der flächen, at(f) die entsprechende fläche und getID liefert die entsprechende vertex-id zurück. also eben punkt/vertex 0, 1 oder 2 vom dreieck. vt ist dann das tatsächliche vertex, welches aus der vertex liste vList gepult wird mittels der id. jetzt werden noch alle gewünschten achsen ausgelesen und in der batch-variablen gespeichert. am ende wird der zeiger auf das array zurück gegeben.

jut, wenn ich nun aber sizeof auf den zeiger schmeiss, gibt er mir 4 zurück und eben nicht die gesamt-array größe. mein problem ist nun, dass ich meine sizeof * count etwas unsauber finde, da ich nicht genau weiß, wofür die 4 steht. ist das die größe der speicheradresse oder die von GLfloat? wenn beide zufällig 4byte sind mag das passen und zum richtigen ergebnis führen, aber wehe auf irgend einem system sieht das mal anders aus ^^ hmm, ich könnte natürlich statt sizeof(batch) auch sizeof(GLfloat) machen und wäre auf der sicheren seite - am liebsten hätte ich aber ein ganz simples sizeof(batch) was mir in diesem konkreten fall direkt die 96 liefert.

weiß da jemand rat?



edit: aso, das windowed/fullscreen geswitche klappt prinzipiell erstmal. also ich kann hin und her wechseln, allerdings muss ich noch rausfinden, wie ich den gl-kontext "rüberrette". wenn ich switche, dann ist dat figürsche einfach weg :heul:
 
Zuletzt bearbeitet:
und wieder ein stück geschafft:
texturen.png

texturen! ^^

was hing da nun alles dran? hab meine mesh-klasse um eine uv-liste erweitert mit allen funktionen drumherum und die face-klasse wurde auch um die uv-id's erweitert. dann eben noch die uv's als vertex-objekte erstellen und dem mesh mit übergeben und die grundlage war da. hat sich auch rausgestellt, dass es generell keine doofe idee war, mich wie früher wieder am .obj datei-aufbau zu orientieren (mit den id's). unterstützt OpenGL auch sowas :D (dx unter garantie auch, fand nur die generelle erkenntnis toll ^^). nun brauch ich nicht soviel speichern und spare speicher! optimieren wo es geht xD

mal an einem bsp erklärt:
an der figur oben sieht man ja 4 flächen. jede fläche hat 3 eckpunkte - macht in der summe also 4*3=12 vertices die ich speicher. jedes vertex besteht aus 4 float-werten wovon ich aber aktuell nur 2 speicher. float braucht wohl 4byte (bei mir). haben wir also einen speicherbedarf von 12*2 *4byte = 24*4byte = 96byte. das gleiche für die uv-koordinaten auch (und später kommen auch noch die normalen hinzu, ggf noch farbwerte... wobei ich glaube auf color verzichte und rein auf texture geh). also aktuell 192byte (mit normalen mal irgendwann 288byte).
gut, wie ich schonmal erwähnte speichert meine mesh-klasse alles nur "unique". der punkt in der mitte wird von allen 4 flächen benötigt - wird aber nur einmal in der liste gespeichert. bisher wars nun so, dass ich meine vertexdaten so zusammen gestellt hab, dass dieser punkt dann trotzdem 4mal gespeichert wurde. jetzt arbeite ich aber mit einem "element array buffer" welcher auch über die id's arbeitet. sprich: auch der gemeinsam genutze punkt wird jetzt nur einmal gespeichert. bei der figur hier ist das warscheinlich noch nicht so effizient, da eben nur ein punkt doppelt genutzt wird, aber bei ordentlichen modellen lohnt sich das sicher eher.
kann ja nochmal rechnen. jetzt werden also nur noch 9 vertices übertragen á 2 koordinaten á 4byte macht 9*2*4=72byte. mit den uv's dann 144 und mal mit normalen 216byte. jetzt kommt halt allerdings noch das id-dingen hinzu, für jede fläche 3 unsingned int werte (auch 4 byte bei mir): 4*3*4 = 48byte. bei der figur machen wir also bei reinen vertexdaten nasse: 72+48=120byte statt 96. mit den uv's sinds dann 144+48=192byte - also gleich auf. mit normalen würde man aber sogar schon bei sonem ungünstigen figürchen was sparen: 216+48=264 statt 288 byte ^^ denke also mal, dass das alles in allem keine schlechte variante ist.

zum bilder laden nutze ich jetzt erstmal freeImage. open source, cross platform, viele formate (nich nur tga oder so). und: es funzt bei mir mal auf anhieb ^^ ich hab bei sowas ja eigentlich immer so ein händchen :ugly:

zu meinen problemen des letzten posts: hab ich jetzt nochmal komplett umgemodelt. die ganze geschichte mit den dynamischen arrays und das an ogl zu übertragen hab ich jetzt alles in die mesh-funktion direkt gepackt. m.generateBatch() macht das nun also alles intern. somit brauch ich die pointer und die count-variablen nicht hin und her schubsen. einzig den shader lade ich ausserhalb und übergeb dessen handle an die funktion, damit da drin die attribute locations usw ordentlich verknüpft werden können (also wie heißen die shader-variablen, an die meine daten gesendet werden usw usf). auch vbo usw sind in die mesh-klasse gewandert, damit lässt sich auch das "aufräumen" schöner gestalten - einfach in den destruktor geknallt ^^ achja, eine draw()-methode gibts nun auch für die mesh-klasse. da das alles da reingewandert ist, löse ich das einfach so. ein einfaches m.draw() und gut is :)

einziges problem bleibt das mit dem ogl-context. da drück ich mich grade etwas vor xD hab keinen blassen, wie ich das lösen soll :/
 
So, muss jetzt doch mal meine Gedanken mit euch Teilen...

Ich hatte ja das Thema mit dem Datensparen angesprochen. Nun gibt es da ein kleines Problem mit. Hmm, wie entwickel ich euch das jetzt mal... Nehmen wir ein Dreieck. Das hat, nuja, drei Ecken ^^ Punkte, Vertices. Nennen wir sie v0, v1 und v2. Jedes Vertice hat seine Koordinaten x, y und z. Nun speichere ich ja nix doppelt. Also hätten wir ein zweites Dreieck, dass am Ersten angrenzt und auch dessen Punkte (meinetwegen v0 und v1) mitbenutzt, so würden diese NICHT doppelt gespeichert.

Hier ganz gut dargestellt:
Tutorial 9 : VBO Indexing | opengl-tutorial.org

Ich habe nun also nicht 6 gespeicherte Vertices, sondern nur 4. Gut, nun haben diese Punkte aber auch andere Charakteristika. Allen vorran die UV-Koordinaten. Macht aber in dem Falle selten etwas, da bei einem "übergangslosen Mapping" ja eigentlich die UV's auch unverändert bleiben. Sprich v0-uv von Dreieck1 wird die selbe sein wie bei Dreieck2. Also haben wir die zwei Charakteristiken Raum-Koordinaten (Vertex) und Textur-Koordinaten (UV). Fürs Shading von immenser Wichtigkeit sind nun aber noch die Normalen (Richtungsvektoren) - eine dritte Charakteristik. Und gerade HIER beginnt der Spaß. Ist Dreieck1 nicht in der selben Ebene wie Dreieck2 (also da ist ein Knick zwischen beiden), dann haben ihre Vertices auch unterschiedliche Normalen. Sieht man jetzt davon ab, dass ein weicher Kantenübergang vermieden werden soll (mittels Smoothshading) und man wirklich harte Kanten möchte, muss man das beachten. Sollen die Kanten "smooth" sein, so werden einfach alle Flächen-Normalen ge-averaged (dschinglisch 4tw :ugly: ) und alle Punkte aller Flächen haben auch wieder identische Normalen. Aber darum gehts mir ja gerade nicht ^^

Gut. Was ist nun genau das Problem. Bleiben wir bei zwei Dreiecken die in einer Ebene liegen. Ergo sind auch alle Normalen gleich. Wir haben nun also folgendes gespeichert:
v0
v1
v2
v3
uv0
uv1
uv2
uv3
n0

Nun erstellen wir unsere Arraybuffer Dingsens da. Dazu wird jedes Vorkommen nur einmal gespeichert statt für jeden Punkt (eben dass gemeinsam genutzte Punkte nicht doppelt auftauchen - Platz sparen usw). Dann hätten wir also eine Vertex-Liste mit { v0, v1, v2, v3 }, eine UV-Liste mit { uv0, uv1, uv2, uv3 } und eine Normalen-Liste mit { n0 }. Und jetzt unsere Indexe: Dreieck1 besteht aus den vertices 0, 1 und 2, Dreieck2 aus 1, 2 und 3. Also sieht unsere Index-Liste so aus: { 0, 1, 2, 1, 2, 3 }. Oder anders dargestellt:
{ 0, 1, 2, // Dreieck1
1, 2, 3 } // Dreieck2
Bei den UV's haben wir wie gesagt noch Glück, da auch die genauso indexiert werden können. Aber bei den Normalen... Wenn er da versuchen sollte auf den Index 1 zuzugreifen... wo es doch nur ein Element gibt (also Index 0)... ^^

Daher war mein Ansatzpunkt, die Definition des Punktes vom Vertex allein zu trennen. Ich habe das Intern bei mir jetzt Uniques genannt, points hätts aber sicher auch getan. Ich habe also neben den bisherigen Listen für Vertices, UV's und Normalen noch diese Uniques. Das sind auch wieder Vertices (der Einfachheit halber) die allerdings anstatt irgendwelcher x|y|z-Koordinaten die ID's speichern, die einen einmaligen Punkt charakterisieren: Vertex-ID|UV-ID|Normalen-ID.

Statt nun meine Array-Listen Dinger da so aufzubauen wie eben, gehe ich nun über die Uniques-Liste. Hmm, ich zeige erstmal, wie die Uniques bei unserem BSP hier aussehen:
Punkt1 besteht aus v0, uv0 und n0
Punkt2 besteht aus v1, uv1 und wieder n0
Punkt3 besteht aus v2, uv2 und ebenfallswieder n0

Das wäre unser erstes Dreieck. Das zweite hat ja die Punkte v0 und v1 gemeinsam mit dem ersten, und da beide in der selben Ebene liegen, haben auch die Punkte von Dreieck2 die gleichen Normalen wie die von Dreieck1 - sie sind also gleich und werden NICHT erneut gespeichert. Hinzugefügt wird nu:
Punkt4, bestehend aus v3, uv3 und n0.

In unserer Liste haben wir also nun die folgenden Werte gespeichert:
p0(0,0,0)
p1(1,1,0)
p2(2,2,0)
p3(3,3,0)

Weiter. Ich gehe nun wie gesagt über diese Uniques p0-p3. Habe also ein for(i=0 bis uniques-size-1) und in dieser Schleife fülle ich alle 3 Array-Listen parallel. In die erste für die Vertices wird nun also jeweils die x-Koordinate (erste Spalte) gespeichert -> { 0, 1, 2, 3 }. Das Gleiche kommt auch für die UV's raus und bei den Normalen erhalten wir ein { 0, 0, 0, 0 }. Und hier sehen wir schon den Unterschied: Vorhin hatte die Normalen-Liste nur den einen Eintrag, nun hat auch sie 4 wie die anderen. Ein korrektes Indexieren funzt also nun Tadellos.

Prinzipiell :ugly: Irgendwas läuft da bei mir schief. Ich habe mir in Blender einen simplen Würfel gebaut, trianguliert und mit einer simplen UV-Map ausgestattet. Dann der Gerät als .obj exportiert und das dann über meine Anwendung laden lassen (selbst geschriebener Loader, nicht wie in dem Tutorial-Link umgesetzt):
blender-cube.png

Kleine Fotomontage dass man UV-Mapping und den einen ausgewählten Punkt sieht ^^ An besagtem Punkt konnte ich feststellen, dass ich da beim Exportieren die Achsen umstellen musste. Er hatte immer aus der y-Koord die z-Koord gemacht und aus der z-Koord die -y-Koord (also auch noch negiert). Um also auch das auszuschließen, hab ichs gerichtet und ordentlich exportiert. Dann kommt aber sowas bei raus :/
my-cube1.png my-cube2.png
Einmal mit und einmal ohne Backface-Culling. Ohne sieht ja fast noch anständig aus, als würde er halt Quads rendern müssen, er aber nur Tris kann und somit immer eine Ecke und somit eine Fläche fort is ^^ Aber ohne BFC sieht man, dass doch scheinbar alle da sind - nur eben total verhunzt :/

Hat irgendwer eine Idee, was das sein könnte? Habe ich bei meinem Gedankengang da oben doch einen Fehler? Falls wer eine zündende Idee hat... ^^


Edit: Hab nochmal die gebauten Arrays ausgeben lassen:
arrays.png

Passt alles ideal :/ Wieso zeigt er dann aber sonen Murks an?
 
Zuletzt bearbeitet:
Zurück