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



## DarkMo (23. Juli 2012)

huhu, durch unseren Cymes bin ich mal wieder in Schwung gekommen... gott, ich nutz sogar schon shift >< nene, das verbrauch zuviel saft.

also jedenfalls hab ich bei mir jetz mal ne maussteuerung versucht. bedienung soll wie folgt funtzen: rechtsklicke ich mit der maus, kann ich durch die mausbewegung den blickwinkel ändern. durch rollen am mausrad fährt er vor und zurück.

ausgangssituation: ich mach nen kleines array (soviele tasten hat ne maus ja ned ^^) mit erstma 5 plätzen. lmb ist id 0, rmb is die 2 und mausrad vor/zurück is 3 und 4. die 1 is warscheinlich ne mittlere mausstaste - leider geht mausrad klick ned :/ wurscht erstma ^^

hab das ganze jetz so gebaut, dass ich mir den status (geklickt oder aufgehört zu klicken) merke - was beim mausrad schlauerweise ned geht, da es immer den status "aufgehört zu drücken" hat, also sonderlösung >< - sowie die mausposition und die veränderung der mausposition von frame zu frame. joa, und mittels der veränderung der position lass ich dann die ansicht halt rumrotieren (hab da nen cameraFrame vorschlag aus meinem dollen buch da drin). hier mal der code:


```
// Globals
// maus einstellungen
#define MOUSE_BUTTONS    5
int                    mouseX = 0, mouseY = 0;        // mausposition
int                    mChangeX = 0, mChangeY = 0;    // änderung der mausposition
int                    mouseKey = -1;                // maustaste
long                mouseMove = 0;                // bewegt sich die maus? (0 = nein, alles andere = letzter zeitpunkt der bewegung als timestamp)
int                    mouseTresh = 50;            // in ms - zeit bevor mausbewegung negiert wird

GLFrame                cameraFrame;                // global camera instance

struct keyState {
    int key;
    int status;
    int x;
    int y;

    void init(int k, int ks, int kx, int ky) {
        this->key = k;
        this->status = ks;
        this->x = kx;
        this->y = ky;
    }
};
keyState            pressedMouse[MOUSE_BUTTONS];        // platzhalter für maustasten

...

// ----------- Callback functions ----------- //
void mouseClick(int key, int status, int x, int y)
{
    if(key < MOUSE_BUTTONS) {
        if(key == 3 || key == 4) status = 0;
        pressedMouse[key].init(key, status, x, y);
    }
    /*
    0: lmb
    2: rmb
    3: mr hoch
    4: mr runter
    */
}

void mouseActive(int x, int y)
{
    mChangeX = x - mouseX;
    mChangeY = y - mouseY;
    mouseX = x;
    mouseY = y;
    mouseMove = GetTickCount();
}

void mousePassive(int x, int y)
{
    mChangeX = x - mouseX;
    mChangeY = y - mouseY;
    mouseX = x;
    mouseY = y;
    mouseMove = GetTickCount();
}
// ----------- Callback functions ----------- //

void SetupRC(void) {
    for(int i=0; i<MOUSE_BUTTONS; i++) pressedMouse[i].init(i, 1, 0, 0);
    ...
}

void RenderScene(void) {
    long elapsedTime = GetTickCount() - FrameTickCount;
    long FrameTickCount = GetTickCount();

    float linear = 0.2f;
    float angular = float(m3dDegToRad(1.0f));

    if(pressedMouse[3].status == 0) cameraFrame.MoveForward(linear);
    if(pressedMouse[4].status == 0) cameraFrame.MoveForward(-linear);
    if(pressedMouse[2].status == 0) {
        cameraFrame.RotateWorld(-angular, 0.f, (float)(elapsedTime * mChangeX), 0.f);
        cameraFrame.RotateWorld(-angular, (float)(elapsedTime * mChangeY), 0.f, 0.f);
    }

    ...

    long timePassed;
    if(mouseMove == 0) {
        mChangeX = 0;
        mChangeY = 0;
    } else {
        timePassed = FrameTickCount - mouseMove;
        if(timePassed > mouseTresh) mouseMove = 0;
    }
}
```
so, das sollten alle schnipsel sein. ich hatte erst das problem, dass ohne mausbewegung auch keine berechnung der variablen mChangeX und Y erfolgte, die diese auf 0 setzen. also wenn man RMB gedrückt hatte, die maus bewegte und dann aufhörte, wurden die werte der letzten bewegung immer weiter genutzt. also anstatt anzuhalten, weil auch die maus still steht, hat sichs immer weiter und weiter gedreht ^^ deswegen hab ich das mit mouseMove und mouseTresh eingebaut. bei jeder bewegung bekommt mouseMove den zeitstempel als wert und der wird dann später mit mouseTresh verglichen. nach 50 milisekunden (hatte nachm rumtesten mit werten ganz gut gefunzt) wird dann mChangeX und Y auf 0 resettet. ohne das war die bewegen total ruckhaft und kaum vorhanden. scheinbar fragt der ned so sehr oft bei der maus nach oder so >< ohne diesen treshold wollts jedenfalls garnich so recht klappen (entweder er bewegt und bewegt sich - oder es zuckelt langsam vor sich hin ^^).

gut, also soweit so gut, das funzt. jetz hab ich nur noch ein problem: wenn ich die maus diagonal beweg, also er x UND y drehen muss, dann zuckelts wieder :/ also das bild springt blöde umher, wie wenn er erst eine drehung rendert und dann die nächste >< pausen dazwischen sind ned, is also nen andres ruckeln wie ohne das treshold gedöhns (da bewegt er sich nur alle sekunde ca nen bissl, hier aber is die bewegung stetig, aber zuckelnd).

wie ichs jetz hab is schon die 2. version.

```
if(pressedMouse[2].status == 0) cameraFrame.RotateWorld(-angular, (float)(elapsedTime * mChangeY), (float)(elapsedTime * mChangeX), 0.f);
```
also beide drehungen in einem befehl - brachte auch kein andres ergebnis. hat irgendwer ne idee, woran das liegt oder sogar, wie ichs lösen könnt? ^^


----------



## fadade (24. Juli 2012)

*AW: Maussteuerung bei meinem Projekt*

Hi,

also ich habe mich jetzt nicht sehr eingedacht, da Zeitmangel, aber bei mir mache ich es so (jetzt nur auf die Maus bezogen):

1) Pre-Update-Call
 - Mausstatus abrufen (nicht per Callback, sondern jedes Frame immer wieder)
...

2) Update-Call
 - Mausdaten berechnen (wo befindet sich gerade der Cursor im aktuellen Window, wo zeigt er im 3-dimensionalen hin etc.
 - Szenenkamera mit den berechneten Daten aktualisieren (z.B. rotationsmatrizen anwenden, wie in deinem Code beschrieben)
...
 - Alle im Pre-Update-Call erhaltenen Werte resetten (bzw. sicherstellen, dass sie in jedem Call neu überschrieben werden)

3) Render-Call
 - Rendern halt^^

________________________________________________
Die Reihenfolge spielt bei solchen Sachen eine große Rolle!
Ggf. kann es sein, dass deine rotate-funktionen mit den werten nicht klarkommt -> zu groß/klein und liefert deshalb immer nur 0,000....000234 oder sowas zurück


----------



## DarkMo (24. Juli 2012)

*AW: Maussteuerung bei meinem Projekt*



fadade schrieb:


> 1) Pre-Update-Call
> - Mausstatus abrufen (nicht per Callback, sondern jedes Frame immer wieder)


 genau den gedanken hatte ich auch schon, also dass die callback funke das garnich jeden frame testet. ohne meinen treshhold wert da würde ers ja nur alle - tjoa muss wohl was unter 50ms sein ^^ - updaten. da die anwendung grad noch sehr spartanisch is, läuftse aber mit 1000+fps, ergo er macht lange zeit garnix ><

nun DIE frage: wie stelle ich das denn ohne die callback funktion fest? ^^ ich war schon froh, diese methode erfahren zu haben 

und wegen deinem satz am ende: wenn ich die maus nur in x oder y richtung bewege, funzt es schön flüssig/weich, wie ich mir das vorstelle. nur wenn er beide gleichzeitig rotieren soll, macht er hick hack ><

oho: http://nehe.gamedev.net/tutorial/picking_alpha_blending_alpha_testing_sorting/16005/ *les* ^^


----------



## joffal (24. Juli 2012)

*AW: Maussteuerung bei meinem Projekt*

hier vllt mal was: OpenGL Mouse, how it works.. | DaniWeb

ginge es nicht sonst auch, dass du den Mausstatus irgendwo speicherst und die callback-funktion den mausstatus einfach immer wieder überschreibt. und in deinem update oder render-call kannst du dann ja den mausstatus nutzen, der gerade gespeichert ist ...


----------



## DarkMo (24. Juli 2012)

*AW: Maussteuerung bei meinem Projekt*

so mach ichs doch grad, das is ja jetz au ned das prob. das zuckelige drehen der kamera nervt mich xD


----------



## joffal (24. Juli 2012)

*AW: Maussteuerung bei meinem Projekt*

aso, dann hab ich da was verhibbelt 

Vielleicht kannst du dir ja einen kleinen "Buffer" bauen, in den du die Mausdaten reinspeicherst und für das jeweilige Update nimmst du dann den *Durchschnittswert *für x und y aus dem Buffer. Würde dort aber erstmal nicht über die Länge 5 hinausgehen, da er dann halt noch 5 Callback-Aufrufe etwas nachruckelt!
Ansonsten ..... kp  
Möglicherweise kannst du ja mal AMD fragen wie er das in seiner 3D-Anwendung gemacht hat ...


----------



## Skysnake (28. Juli 2012)

*AW: Maussteuerung bei meinem Projekt*

Ähm unter OpenGL gibts für die Maustasten schon fertige Macros. Die sollte man verwenden. Insbesondere für drücken und loslassen der Maustasten gibt es diese Macros schon. Wenn du die Mouse-Callback-Function verwendest, dann brauchst du auch nichts besonderes machen, so lange eben eine Maustaste als Trigger verwendet wird. Nur wenn man sich umsehen will ohne Tastendruck muss ein bischen überlegen.

Also die Sache ist eigentlich ziemlich simpel. Eventuell schaff ich es ja mal meinen Code dazu raus zu suchen.

PS: Du musst natürlich aufpassen, wie du mit den Daten umgehst. Wenn du nur die 2D Daten für eine 2D Bewegung in 3D nutzt über entsprechende Transformationen, dann bekommst du eine Invariante, wenn du dich zu weit drehst. Das ist ein bischen eklig, weil dann plötzlich rechts und links vertauscht, oder oben und unten. Dazu hatte ich auch mal Code, der das eleminiert, aber keine Ahnung wo das grad ist.


----------



## DarkMo (13. August 2012)

*AW: [update] Framebuffer bei meinem Projekt*

huhu, ich mal wieder >< diesmal zu einem anderen problem (daher das update im namen):

ich habe vor 1 2 wochen versucht das ganze von direkter-fenster-bemalung ^^ auf framebuffer-bemalung umzustellen. sprich, ich bau nen framebuffer und klatsche dem nen depthbuffer renderbuffer dran und einen für ne textur. die textur wird am ende als bildschirmfüllendes rechteck ausgegeben. funzt soweit auch ganz gut, nur führt er keine tiefenberechnung aus :/ sieht schrecklich aus ><

habt ihr irgendeinen plan, woran das liegen könnte? ich hab meines erachtens nach scho alles rumprobiert und es wollt ned klappen. bei den beispielen aus meinem buch funzt das einwandfrei, bei mir macht ers einfach ned. hab den code verglichen und geschaut ob da was anders is, ich find nix -.- im endeffekt handelt es sich um diesen code, is ja im endeffekt überall gleich. nur dass ich bei mir all das EXT zeug ned hab *hmm* is das ogl1.0 zeugs oder wieso stand das ned so bei meinem buch (ogl3+) mit bei? ^^

OpenGL Frame Buffer Object 101 - OpenGL - Articles - Articles - GameDev.net


----------



## Skysnake (13. August 2012)

*AW: [update] Framebuffer bei meinem Projekt*

Hast du dran gedacht, dass du glEnable(GL_DEPTH_TEST) machen musst? 

Es macht natürlich sinn, das nur da ein zu schalten, wo dus auch wirklich brauchst und danach eben wieder aus zu schalten.

Ich glaub glEnable(GL_BLEND) brauchst du auch noch, bin ich mir aber gerade nicht sicher.


----------



## DarkMo (13. August 2012)

*AW: [update] Framebuffer bei meinem Projekt*

jop, habs auch schon direkt davor explizit nochmal angemacht und alles :/ is alles korrekt gebunden zu den zeitpunkt. wenn ich heut abend wieder an meinen rechner komm, kann ichs ja nochmal reinstellen. aber soweit ich das vergleichen konnte, gibts da keine unterschiede und es geht dennoch nich. das hatte mich dann so demotiviert, das ich erstmal pausiert hatte. aber es beschäftigt mich seitdem laufend und ich will ja auch mal vorran kommen ><


----------



## Skysnake (13. August 2012)

*AW: [update] Framebuffer bei meinem Projekt*

Reihenfolge der zu zeichnenden Objekte bedacht?


----------



## DarkMo (13. August 2012)

*AW: [update] Framebuffer bei meinem Projekt*

bisher hab ich da keine regel für, das kommt noch irgendwann ^^ aber mE is ja genau dazu der depth buffer gut und ohne fbo (bzw ned in ne textur rendern, in fbo un dann per blitting aufs fenster kopiert funzt auch tadellos) klappt das ja auch wies soll. nur sobald ich in ne textur render, macht er plötzlich fehler.

hier mal fix der code noch:

```
// Globals
int                    screenX = 1440, screenY = 900;    // fenster-maße
GLuint                mainFBO;                    // globaler framebuffer
GLuint                mainRBOdepth;                // globaler tiefenpuffer für frambuffer
GLuint                screenTexture;                // globale textur, in die der framebuffer rendert
GLenum                mainFBObuff[] = { GL_COLOR_ATTACHMENT0 | GL_DEPTH_ATTACHMENT }; // eigentlich nur das erste, aber ich wollts halt mal testen
GLenum                windowBuff[] = { GL_BACK_LEFT };

void checkFBO(GLuint FBO) {
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mainFBO);
    GLuint status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if(status == GL_FRAMEBUFFER_COMPLETE) cout << "Framebuffer erfolgreich erstellt." << endl;
    else cout << "Framebuffer konnte nicht erstellt werden! Status: " << status << endl;
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
}
```

innerhalb des großen (immernoch falsch texturierten ^^) raumschiff dings bumses da is ja noch meine erde mit mond und sonne. die atmosphäre (wolken, transparenz bla) wird ganz am ende gezeichnet - was man ja auch sieht ^^ die is eigentlich innerhalb des raumschiffs wird aber eben dennoch gezeichnet, da kein depthtest gemacht wird. genauso die ganzen kleinen anbauten an der schiffskugel - scheint alles durch :/


```
void SetupRC(void) {
    // FBO erstellen
    glGenFramebuffers(1, &mainFBO);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mainFBO);
    // tiefen renderbuffer erstellen
    glGenRenderbuffers(1, &mainRBOdepth);
    glBindRenderbuffer(GL_RENDERBUFFER, mainRBOdepth);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, screenX, screenY);
    // screenTexture erstellen
    glGenTextures(1, &screenTexture);
    glBindTexture(GL_TEXTURE_2D, screenTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, screenX, screenY, 0, GL_RGBA, GL_FLOAT, NULL);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, screenX, screenY);
    // (tiefen)renderbuffer und textur an fbo hängen
    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, screenTexture, 0);
    glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mainRBOdepth);
    glClearColor(0.f, 0.f, 0.f, 1.f);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

    checkFBO(mainFBO);
    ...
}

void RenderScene(void) {
    ...
    glEnable(GL_DEPTH_TEST);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mainFBO);
    glDrawBuffers(2, mainFBObuff);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    DrawSpace(elapsedTime);
        
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    DrawScreenTexture();
    DrawHud();   // disabled depth test zum bsp

    glutSwapBuffers();
    glutPostRedisplay();
}

void ShutDownRC(void) {
    ...
    // fbo kram löschen
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
    glBindRenderbuffer(GL_RENDERBUFFER, 0);
    glDeleteFramebuffers(1, &mainFBO);
    glDeleteRenderbuffers(1, &mainRBOdepth);
    glDeleteTextures(1, &screenTexture);
}
```


----------



## Skysnake (13. August 2012)

*AW: [update] Framebuffer bei meinem Projekt*

kannst du mal zeigen, wies richtig aussehen soll? Kanns mir grad nicht vorstellen, was genau schief geht.


----------



## DarkMo (14. August 2012)

*AW: [update] Framebuffer bei meinem Projekt*

uff, ich such mal eben mein eines, was ich schonma gemacht hatte *such*


----------



## Skysnake (14. August 2012)

*AW: [update] Framebuffer bei meinem Projekt*

ähm kanns sein, das du nicht alles gleichzeitig in einen Frambuffer packst, sondern mehrere miteinander kombinieren willst und dabei etwas schief geht?

Sieht so aus, als ob die große Kugel nen Framebuffer wäre, welches dann praktisch wie ein Quad mit TExtur drauf gezeichnet wird und dann die anderen Objekte drum rum. Da stimmt dann ja aber die Perspektive nicht mehr, weil das eine eben 2D und in 3D ist, und die anderen Sachen 3D in 3D. Für mich siehts so aus, als ob dass das Problem wäre, aber mit Framebuffern hab ich selbst noch nicht gearbeitet, daher sind mir die Eigenheiten/typischen Fehler leider nicht geläufig


----------



## DarkMo (14. August 2012)

*AW: [update] Framebuffer bei meinem Projekt*

hm nope. ich hab EINEN framebuffer und hänge dem einen renderbuffer mit depth_attachment an und einen mit ner textur. ohne textur (einfach in nen renderbuffer gerendert und dort dann alles ins wondow kopiert) klappt das auch noch super. aber sobald ich die textur nutze isses, als hätte ich den tiefentest garnich drin >< regt mich nur auf, dass ich ned dahinterkomm wieso ^^


----------



## Skysnake (14. August 2012)

*AW: [update] Framebuffer bei meinem Projekt*

kanns sein dass du die Textur erst nochmal mit dem Tiefentestbuffer verknüpfen musst?

EDIT:
Schau dir einfach mal das Tutorial an. Ich weiß nicht, ob du die Seite schon kennst, aber die Beispiele da sind ganz gut. http://wiki.delphigl.com/index.php/Tutorial_Framebufferobject

Ich bin jetzt nur den Anfang deines Codes durchgegangen, und das scheint auch soweit zu stimmen, da steckt irgendwo der Teufel im Detail....


----------



## DarkMo (14. August 2012)

*AW: [update] Framebuffer bei meinem Projekt*

ich befürchts auch. die verknüpfung des ganzen sollte meines wissens nach das binden an den framebuffer sein. also im groben gestaltet sich das ja so:
- fbo (framebuffer) erstellen
- 2 rbo's (renderbuffer) erstellen - einen für depth und einen für farbinfos (können später natürlich auch mal mehr werden)
- rbo's an fbo binden

das wars im groben schon. in diesem falle müsste man mittels blitting dann die gerenderten daten ausm fbo ins fenster kopieren, was auch tadellos klappte und so aussah wies soll. wenn ich jetz an das farb rbo aber ne textur hänge, dann rendert er nur die farbinfos da rein, beachtet aber das depth rbo scheinbar ned. hmm, muss man vllt die textur nochma gesondert irgendwie mit dem detph ding verknüpfen? wenn hab ich dazu jedenfalls noch nirgends was gefunden ><


----------



## Skysnake (14. August 2012)

*AW: [update] Framebuffer bei meinem Projekt*

schau dir den obigen Link von mir an. Da besprechen Sie expliziet, wie man sogar mit mehreren Texturen umgeht 

Da bin ich aber nur drüber geflogen, da mir dazu zu viel Code bei dir wohl fehlt mit Init usw usw.


----------



## DarkMo (4. September 2012)

*AW: [update] Framebuffer bei meinem Projekt*



DarkMo schrieb:


> ```
> void SetupRC(void) {
> // FBO erstellen
> glGenFramebuffers(1, &mainFBO);
> ...


 AHAHAHAHHAHAHAHAHAHAHAHAHA

ich hab den sack gefunden >< die rote zeile is die wurzel allen übels. es überschreibt den depthbuffer speicher mit falschen einstellungen und schon is alles dahin -.- war immer der meinung, der textur muss man auch speicher zuweisen, aber das geht scheinbar irgendwie anders  mr durchblick is wohl noch ned mein zweiter name ^^


----------



## DarkMo (10. September 2012)

*AW: [update 2] Bloom-Effekt erzeugen*

so, ich häng auch mal wieder bissl an meinem projekt, nachdem das ja nu funzt ^^ -> daher *[update 2]*

joa, das ganze in nen framebuffer zu packen soll ja nich nur schön aussehen, sondern mir auch was bringen: posteffects. als erstes mal bloom probieren - kommt grad im buch dran ^^ joa, also die theorie sieht so aus:
- die szene "normal" rendern, über nen framebuffer in eine textur
- allerdings wird hierbei noch ne 2. textur zeitgleich erstellt, welche alle hellen bereiche der szene enthält (wie das genau funzt sieht für mich auch noch sehr magisch aus xD )
- nachdem man die beiden hat, wird diese "brightTexture" mehrmals geschrumpft (mit nem kernel und gaussfilter bla irgendwie). die schrumpfung simuliert hier immer größer werdende kernel*, welche aktuelle hardware sprengen würden (kleineres bild bei gleichem kernel geblurt und wieder auf ursprungsgröße gebastelt = annäherungsweise das selbe wie originaltextur mit größerem kernel)
-> kann man ganz gut mit ner mipmap lösen, die im grunde ja die originaltextur mit kleineren abbildern ihrer selbst is ^^
- jut, hat man nun den ganzen spaß geblurt, erfolgt im dritten durchgang die kombination der normalen farbausgabe mit dem geblurten gedöhnse und zack peng puff, is die szene schön bloomig 

jo, soweit zur theorie. nu stellt sich mir aber eine essentielle frage. wenn ich die texturen, wo reingerendert wird (im ertsen schritt), ans fbo häng, dann sag ich dabei, zu welchem colorattachment die gehören:

```
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, [B]GL_COLOR_ATTACHMENT0[/B], GL_TEXTURE_2D, this->colorTexture, 0);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, [B]GL_COLOR_ATTACHMENT1[/B], GL_TEXTURE_2D, this->bloomTexture, 0);
```
heisst also, dass alles, was ins color attachment 0 gemalt wird, in der colorTexture landet, und alles in die 1 landet in der bloomTexture. im shader baut man nun 2 output variablen:

```
out vec4 oColor;
out vec4 oBright;
```
welche dann mit farbwerten gefüttert werden. verknüpft wird die ganze chose dann beim "laden" der shader zum programmstart:

```
glBindFragDataLocation(myShader, [B]0[/B], "oColor");
glBindFragDataLocation(myShader, [B]1[/B], "oBright");
```
hier wird der shaderoutput oColor auf das attachment 0 gelenkt und oBright auf die 1.

jep, soweit sogut. nu hab ich doch aber auch texturen, die "rein gehen" in den shader. speziell bei mir haben die objekte ja (momentan) ne normale textur (attachment 0) und ne specular-map (attachment 1) - überschreibt sich das ned? oder unterscheidet ogl da? weil der output geht ja ins fbo, die input-texturen gehören aber nich zum fbo. da blick ich atm leider noch garnich durch >< und zum googlen bin ich ma wieder zu blöde. die meisten "tutorials" die ich finde, die enthalten keinen einzigen code schnipsel oder nur code fetzen ohne wirklich wichtige zusammenhänge aufzuzeigen oO


achja: *Kernel ^^ der kernel bezeichnet hier ne 5x5 matrix von werten und wichtungen. in der mitte ist der aktuell betrachtete pixel mit der höchsten wichtung und drumherum in 2 "schalen" werden die umgebenden pixel samt wertung erfasst. das sieht zum bsp so dann aus:

```
// 5x5 Gaussian kernel
// 1  4  7  4 1
// 4 16 26 16 4
// 7 26 41 26 7 / 273
// 4 16 26 16 4
// 1  4  7  4 1
```
also der eigentliche pixel wird mit der höchsten wertung erfasst und die umliegenden mit abnehmenden wertungen. alles zusammen gerechnet und durch die gesamtzahl der wertungen dividiert (hier 273) ergibt den "durchschnittswert" des pixels nach betrachtung mit seinem umfeld.


----------



## DarkMo (12. September 2012)

*AW: [update 2] Bloom-Effekt erzeugen*

himmel arsch un zwirn noch eins, ich dreh bald durch hier -.-

ich arbeite mich jetz schritt für schritt vorwärts. zuerst hab ichs mal überhaupt wieder zum laufen gebracht, das war noch der einfachere part. was ich sah, war dann auch ein sexy schwarzer bildschirm als endergebnis ^^ dann hab ich mir mal die colorTexture ausgeben lassen. wirkte irgendwie überstrahlt, aber bloomt noch ned wirklich. zudem scheint auf angeleuchteten flächen alles dahinter durch Oo "in" meinem schiffsmodellchen da is ja noch die erde mit mond usw die sich da lustig drehn (einfach weil das schiffsmodell bissl groß is): auf der schattenseite sieht mans ned durchscheinen, aber auf der "tag"seite leuchten plötzlich die sterne vom hintergrund und die erde samt wolken und mond in dunklem blau durch oO un ich hab keinen blassen wieso plötzlich ><

naja, auf später verschoben. hab jetz erstmal dann die bloomTexture angeschaut, größtenteils schwarz und ab und an weise bereiche. soweit so gut, nur irgendwie hatte das rein garnix mit den hellen stellen des bildes zu tun oO hab das ganze dann bissl modifiziert un nu hauts besser hin. und jetzt kommt meine verzweiflung ins spiel: wie zum henker kann ich denn nen mipmap level einer textur aktualisieren? egal was ich mache, es geht ums verrecken nich. das einzige was funzt, is das automatische glGenerateMipmap() nachm neuzeichnen in die textur. schön und gut, nur wird hier ja nur die textur immer halbiert/verkleinert aber der kernelfilter zum blurren wird ja freilich ned angewendet.

nu hab ich schon versucht den output des shaders auf das entsprechende miplevel zu lenken - kein erfolg. oder glCopyTexSubImage zum kopieren auf das miplevel. nix. bei dem copy ding findet man auch NIRGENDS irgendwelche infos, welche width und height angabe man verwenden muss. muss ich da jetz die base-level (also originale größe) maße nehmen und er shrinkt das selber dann runter auf die entsprechende miplevel größe, oder muss ich das selber angeben oder wie? hat sich die frage noch nie einer gestellt, das keiner drauf kommt, sowas mal zu beantworten im netz *argh* das nächste is, dass ich google hasse - oder goggle hasst mich, was weis ich. gib da ma ein "opengl updating mipmap" oder noch nen level hinten dran. was findet der hurenbock? GENERATING mipmaps. herrgott noch eins, hab ich nachm generieren oder nachm updaten versucht? 10 seiten nur gülle. und wenn man mal ein "tutorial" findet, dann fehlt jeglicher code 

also jungs: ihr wollt euer eignes flugzeug bauen? geht ganz easy, hier mein tutorial: bau nen rumpf, bau 2 flügel und ne schwanzflosse, bastel alles zusammen und kleb noch paar triebwerke und räder unten dran. wers richtig geil will, baut in den rumpf noch fenster rein!

ey, da fasst man sich an die birne... is das nen staatsgeheimnis, das KEINER ne echte anleitung zu sowas mal hergibt oder was?


----------



## fadade (12. September 2012)

*AW: [update 2] Bloom-Effekt erzeugen*

Also dass es zu einigen Sachen kaum/keine Tutorials gibt, liegt daran, dass die Techniken dazu entweder viel zu komplex sind oder dass sie auch im kommerziellen Bereich angewendet werden und wer gibt schon gerne seine "Geldeinnahmequelle" für lau Preis?
Kenn ich von der Arbeit, einige Algorithmen zur Simulation von irgendwelchen Volumenberechnungen wirst du in "freier Wildbahn" kaum finden, die gibts nur hinter verschlossenen Türen für viel Geld 

Ansonsten habe ich hier: Graphics Programming and Theory - GameDev.net oder hier: DirectX and XNA - GameDev.net vor maximal ein paar Tagen auch einen Thread zu Bloom(ing) gesehen; weiß nicht mehr genau welches Unterforum, aber kannst die beiden ja etwas durchstöbern.


----------



## DarkMo (12. September 2012)

*AW: [update 2] Bloom-Effekt erzeugen*

naja, dx nutzt mir nix. den core des ganzen hab ich ja. hab mir ja auch nen teures buch gekauft wo mir grundlagen erklärt werden - nur wird dort nich mit ner mipmap gearbeitet sondern mit 5 einzel-fbo's mit jeweils einer textur. ich werd das bald so umschreiben wie im buch he -.- aber es MUSS doch gehen. es soll ja auch nich unbedingt schritt für schritt dastehen.

ok, also schritt für schritt: im buch wirds eben auf ne etwas "grobe" tour erklärt und am ende steht dabei, das man als ne art selbstübung ja mal probieren kann, das ganze auf mipmaps umzubauen. also es muss definitiv gehen. dann fand ich im netz nen "tutorial" das quasi genau das is. das sin exakt die selben shader wie im buch, nur eben auf mipmap umgebaut. soweit so gut, hat mir shaderseitig auch nen guten einblick gegeben. nur gibt man ausserhalb des shaders an, wohin das gemalte zeugs fließt, also bringt mir der shader in der richtung recht wenig. ich weis DAS es geht, aber nich wie. das is frustrierend.

und wenn ich nun nach grundlagen google, also ned nach zusammengesetzten algorythmen, dann findet er einfach nix -.- wie kann ich den shaderoutput in ein mipmap-level einer textur umleiten? WIE? xD such mal nach update mipmap. du findest NUR was dazu, wie man se generiert. das is die härte. als ob opengl das garnich könnte lol. das komplexe algorithmen ned offiziell sin is klar, aber ne dokumentation oder suche nach einzelnen funktionen muss doch erfolgversprechend sein *grr*

ich hab jetz auch schon überlegt, jeweils in ne seperate textur zu rendern und diese dann in das miplevel zu kopieren, aber dann hab ich ja wieder die ganzen extra texturen und könnt mir das mipmap gekröse gleich ganz sparen. da fragt man sich nach dem sinn dahinter :/

ich habs jetz zum bsp schon so versucht:
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, this->bloomTexture, i+1);
also ich render jedes miplevel in ner forschleife (haupttextur und 4 miplevels). die bloomTexture geht rein und die i-te ebene (bei 0 anfangend bis 3) wird im jeweiligen durchgang als src genommen und mit der zeile wollte ich eben versuchen, das was als ergebnis rauskommt, in die "darunterliegende" eben zu lenken. aber wirklich funtzen tuts ned. er generiert beim erzeugen die miplevel und das erste gerenderte bild bleibt bestehen. danach wird nix mehr geupdatet.

glCopyTexSubImage2D(GL_TEXTURE_2D, i+1, 0, 0, 0, 0, x, y);
das soll glaube ausm back/color buffer des fbo's in die textur kopieren? also eigentlich das falsche für meine zwecke, da ich ja in ne textur render, aber ich wollts zumindest ma probiert ham ^^ klappt jedenfalls auch ned.

rein vom empfinden her, wäre das hier ne tolle anlaufstelle für sowas:
glBindFragDataLocation(this->secondPassShader, 1, "oBright");
also die out variable oBright des secondPassShaders wird hier aufs color-attachment-1 gelenkt. wenn man hier noch das miplevel angeben könnte... aber das is wohl zu einfach xD aber gut, man muss danach den shader jedesma wieder linken und das jeden frame... is sicher nich sehr performatn. naja. ich find jedenfalls absolut nix, was mir filft :/

also wie gesagt: ich brauche keinen kompletten algorithmus, ich brauche keine theorie, ich brauche nen funktionierende möglichkeit, ein bestehendes mipmap-level zu aktualisieren >< das MUSS doch irgendwie gehn.


----------



## fadade (13. September 2012)

*AW: [update 2] Bloom-Effekt erzeugen*

Achso du suchst konkret welche Methoden wie anzuwenden sind, naja gut dazu ist das DirectX-Forum dann natürlich nicht geeignet. Ggf. hier: OpenGL - GameDev.net
Mimaps updaten habe ich jetzt bisher auch noch nie gemacht ... immer nur erstellen und dann freuen dass man sie hat und sich nicht mehr um sie kümmern 
Darüber hinaus habe ich Bloom selbst noch nicht genutzt, soll aber bald auch passieren; da kann ich auf jeden Fall mal die Augen offen halten 

PS: ist ja ein bisschen wie in der höheren Mathematik: Ja es gibt mindestens eine (eindeutige) Lösung .... aber wie die aussieht?!?! Da bin ich überfragt xDD


----------



## DarkMo (12. März 2013)

*AW: [update 2] Bloom-Effekt erzeugen*

soa, ich hab seit längerem mal wieder bissl rumgeschraubt. da das mit der mipmap nich funktionieren wollte (und ich mich scheute das umzutüdeln -> lange nix gemacht ^^) hab ichs nun mal angefangen so umzubauen, dass er statt mipmaps halt extra texturen hernimmt. btw: das wird ne etwas größere "erklärerei", da ich das ganze auch nochmal für mich aufbereiten möchte. es stellt also meine "auffassung der wahrheit" dar  wäre schön, falls wer hier schon grundsatzfehler in der denke findet und mich aufklären könnte 

also mipmaps sind "bestandteil" eines bildes - einer textur besser gesagt. die textur hat meinetwegen ne auflösung von 1024x1024, dann wäre die erste mipmap das selbe bild nur in 512x512 und das nächste 256x256 usw usf. nur zur erklärung, dass man weiss, was ich machen wollt.

bloom-effekt wird wohl wie folgt realisiert: man rendert die szene ganz normal, macht in diesem durchlauf aber noch nen "bright pass" - also erstellt im gleichen atemzug eine 2. textur, die nur die hellen bereiche der ersten textur enthält. dieser bright pass wird dann mehrfach geblurt. heisst soviel wie, dass man aus der brightpass texture ein kleineres abbild erstellt - aber eben nicht nur verkleinern, sondern das ganze durch nen "kernel" jagen. man betrachtet also jedes pixel der textur und schaut sich im endeffekt die umliegenden pixel auch noch an. das eigentliche pixel erhält die höchste wichtung und je weiter weg die betrachteten pixel liegen, desto geringer fällt deren wichtung aus. ich hab da jetz nen 5x5 kernel (er betrachtet also 5x5 pixel - mit dem ausgangs pixel in der mitte -> also quasi ne "schale" von 2 pixeln dichte um das eigentlich betrachtete pixel drum herum).
joa, und das macht man eben mehrmals. ich hab bei mir jetzt 4 blur images quasi. also im endeffekt 1 color texture, eine brigth pass texture und 4 blur textures.

dadurch, dass die blur- images immer ein verkleinertes abbild ihrer ausgangstextur sind, würde sich hier mipmapping halt anbieten, da der vorgang ja verwandt ist. aber ich habs einfach ned hinbekommen >< also hab ich statt einer textur mit mipmaps eben 5 einzelne gebaut.

weiteres detail: ich rendere natürlich die meiste zeit in texturen, und nicht auf den bildschirm. das is dann nur der letzte schritt. gut, jetzt mal zum ablauf:

ich hab den ganzen textur und framebuffer krams in ne klasse gebaut. beim setup wird nun also auch nen obj der klasse initiiert. dabei werden die fbo's, der tiefenbuffer und die zig texturen angelegt und zusammengebunden ^^ ausserdem werden die shader zusammen geschraubt. hab hier mal exemplarisch den für den sternenhintergrund genommen. die bilden quasi den first-pass dann, also den ersten render durchgang:

```
screenFBO            mFBO;

...

void SetupRC(void) {
    mFBO.init(screenX, screenY);
    ...
    starFieldShader = gltLoadShaderPairWithAttributes("Shader/Star.vp", "Shader/Star.fp", 2, GLT_ATTRIBUTE_VERTEX, "vVertex", GLT_ATTRIBUTE_COLOR, "vColor");
    locSFUniforms[0] = glGetUniformLocation(starFieldShader, "mvpMatrix");
    locSFUniforms[1] = glGetUniformLocation(starFieldShader, "starImage");
    glBindFragDataLocation(starFieldShader, 0, "oColor");                        // -> in att0 rendern
    glBindFragDataLocation(starFieldShader, 1, "oBright");                        // -> in att1 rendern
    glLinkProgram(starFieldShader);
    ...
}
```
gut, hier wird nun beim shader die ausgabe durch glBindFragDataLocation() eingestellt. oColor (shader variable) wird also in die 0 (GL_COLOR_ATTACHMENT0) gerendert, und oBright in die 1 (GL_COLOR_ATTACHMENT1). man lenkt hiermit also den output des shaders. der input wird dann über glActiveTexture() geregelt. also als bsp:

```
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, screenTexture);
```
tex0 wird mit screenTexture gefüttert. mit locSFUniforms[1] = glGetUniformLocation(starFieldShader, "starImage"); als bsp hab ich die "location" der uniform-variablen starImage im shader besorgt und mit glUniform1i(locSFUniforms[1], *0*); vorm rendern geb ich über die 0 an, dass er die textur, die an tex0 (GL_TEXTURE0) gebunden ist, in den shader feuern soll -> in dem bsp also screenTexture.

gut, zurück zum thema... öh ja, was macht die init des mFBO objekts?

```
void screenFBO::init(GLuint x, GLuint y) {
    int sub_x, sub_y, i;

    this->initialized = true;
    this->screenX = x;
    this->screenY = y;

    this->exposure = 1.0f;
    this->bloomLevel = 0.5;
    this->ratio = 0.5f;

    this->mainFBObuff[0] = GL_COLOR_ATTACHMENT0;
    this->mainFBObuff[1] = GL_COLOR_ATTACHMENT1;
    this->windowBuff[0] = GL_BACK_LEFT;

    // Haupt-FBO erstellen
    glGenFramebuffers(5, this->mainFBO);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, this->mainFBO[0]);
    // tiefen renderbuffer erstellen
    glGenRenderbuffers(1, &this->mainRBOdepth);
    glBindRenderbuffer(GL_RENDERBUFFER, this->mainRBOdepth);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, this->screenX, this->screenY);
    // colorTexture erstellen
    glGenTextures(1, &this->colorTexture);
    glBindTexture(GL_TEXTURE_2D, this->colorTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, this->screenX, this->screenY, 0, GL_RGBA, GL_FLOAT, NULL);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
    glGenerateMipmap(GL_TEXTURE_2D);
    // bloomTexture erstellen
    sub_x = this->screenX;
    sub_y = this->screenY;
    glGenTextures(5, this->bloomTexture);
    for(i = 0; i < 5; i++) {
        glBindTexture(GL_TEXTURE_2D, this->bloomTexture[i]);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, sub_x, sub_y, 0, GL_RGBA, GL_FLOAT, NULL);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
        cout << "BloomTexture[" << i << "] mit Dimension " << sub_x << "x" << sub_y << " erstellt." << endl;
        sub_x = (int)(sub_x * this->ratio);
        sub_y = (int)(sub_y * this->ratio);
    }

    // (tiefen)renderbuffer und texturen an fbo hängen
    glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, this->mainRBOdepth);
    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, this->colorTexture, 0);
    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, this->bloomTexture[0], 0);
    for(i = 1; i < 5; i++) {
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, this->mainFBO[i]);
        glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, this->bloomTexture[i], 0);
    }

    // alles wieder unbinden
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
    glBindRenderbuffer(GL_RENDERBUFFER, 0);

    for(i = 0; i < 5; i++)
        this->checkFBO(this->mainFBO[i]);

    // shader initialisieren
    /* secondPassShader für den zweiten durchgang mit erstellung der geblurten sub images */
    this->secondPassShader = gltLoadShaderPairWithAttributes("Shader/screenShader.vp", "Shader/blurShader.fp", 2, 
                            GLT_ATTRIBUTE_VERTEX, "vVertex", 
                            GLT_ATTRIBUTE_TEXTURE1, "vTexCoord0");
    this->loc2PUniforms[0] = glGetUniformLocation(this->secondPassShader, "texture");            // texture
    this->loc2PUniforms[1] = glGetUniformLocation(this->secondPassShader, "tc_offset");            // offset array für kernel
    glBindFragDataLocation(this->secondPassShader, 0, "oBright");                                // -> in att0 rendern
    glLinkProgram(this->secondPassShader);

    /* thirdPassShader für den dritten durchgang zur kombinierung der colorTexture mit der geblurrten bloomTexture */
    this->thirdPassShader = gltLoadShaderPairWithAttributes("Shader/screenShader.vp", "Shader/bloomShader.fp", 2, 
                            GLT_ATTRIBUTE_VERTEX, "vVertex", 
                            GLT_ATTRIBUTE_TEXTURE0, "vTexCoord0");
    this->loc3PUniforms[0] = glGetUniformLocation(this->thirdPassShader, "origImage");            // colorTexture
    this->loc3PUniforms[1] = glGetUniformLocation(this->thirdPassShader, "brightImage0");        // bloomTexture
    this->loc3PUniforms[2] = glGetUniformLocation(this->thirdPassShader, "brightImage1");        // blurTexture1
    this->loc3PUniforms[3] = glGetUniformLocation(this->thirdPassShader, "brightImage2");        // blurTexture2
    this->loc3PUniforms[4] = glGetUniformLocation(this->thirdPassShader, "brightImage3");        // blurTexture3
    this->loc3PUniforms[5] = glGetUniformLocation(this->thirdPassShader, "brightImage4");        // blurTexture4
    this->loc3PUniforms[6] = glGetUniformLocation(this->thirdPassShader, "bloomLevel");            // bloomLevel
    this->loc3PUniforms[7] = glGetUniformLocation(this->thirdPassShader, "exposure");            // belichtung
    glBindFragDataLocation(this->thirdPassShader, 0, "oColor");                                    // -> in att0 rendern
    glLinkProgram(this->thirdPassShader);

    this->GenTexCoordOffsets(this->screenX, this->screenY);
}
```
es werden also diverse variablen gesetzt und vorallem eben auch die texturen und BO's erzeugt. auch die shader fürs bloomen werden "gebaut". zuerst baue ich also erstmal 5 framebuffer objects (fbo's) und das erste fbo[0] setz ich als aktiv. danach kommt der tiefenbuffer dran und dann die colorTexture. und dann kommen die bloomTextures, wie ich sie hier genannt habe. auch wieder 5 stück. bloomTexture[0] enthält dann den bright pass, der zusammen mit der colorTexture im 1stPass erzeugt wird, [1..4] sind dann die geblurrten subimages, die ich eingangs erwähnte. jedes bekommt sein eigenes fbo dann. joa genau, das follgt dann schon. zuerst wird mainFBO[0] fertig gebastelt, sprich, es bekommt den tiefenbuffer angehängt sowie die beiden texturen colorTexture und bloomTexture[0]. man beachte das GL_COLOR_ATTACHMENT0 bzw GL_COLOR_ATTACHMENT1 - damit wird die ausgabe dieses framebuffers auf die jeweiligen color-attachments gelegt. ergo wird die "spur" 0 auf die colorTexture gelenkt, sprich, alles was darein gerendert wird, kommt in die colorTexture, und alles auf der 1 kommt in die bloomTexture[0].


was im shader welche "spur" ist, wird durch dieses glBindFragDataLocation() gesetzt, was ich vorhin schon erklärte. also beim shader-binden usw wird angegeben, welche variable auf welche "spur" geleitet wird. gut, also haben wir ausserhalb der klasse bei sternen shader die ausgabe auf die richtige spur gesetzt und hier beim framebuffer die ausgangstexturen an diese spuren gehängt.

gut, dann wird noch bissl "aufgeräumt" und die internen shader getüdelt. der 2ndPassShader ist eben dafür zuständig, dass die bloomTexture[0] geblurrt wird und die bloomTexture[1..4] ihren krempel erhalten. der 3rdPassShader macht aus all diesen bunten texturen dann (laut theorie  ) das finale gebloomte bild ^^


ok, also weiter im text, was passiert jetzt?

```
void RenderScene(void) {
    ...
    mFBO.activate();
    DrawSpace(elapsedTime);
    mFBO.deactivate();
    ...

    // clear the screen
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    DrawScreenTexture();
    DrawHud();

    glutSwapBuffers();
    glutPostRedisplay();
}
```
tjoa, also das ist das wichtigste hier runtergebrochen. in meiner fbo klasse hab ich 2 methoden gebaut, die dann alles für den 1stPass vorbereiten, da die shader ja extern verwaltet werden (noch? kA ^^). ich kann das also ein- und wieder ausschalten (code kommt auch gleich noch). dann wird die szene ganz normal gerendert, dabei kommen shader zum einsatz, die eben auf die 2 ausgabe-"spuren" rendern und am ende wird dann die "screenTexture" auf dem bildschirm ausgegeben. diese ominöse screenTexture ist die colorTexture aus derm fbo objekt ^^ dann zum schluss wird noch bissl text ausgegeben zum debuggen bla. is ne fps anzeige, wo die maus is, wie sie sich bewegt, was gedrückt wird... an und für sich unintressant, funzt soweit wunderbar und hab ich auch nix geändert dran.

gut, jetzt nochmal fix zu dem de-activate() gelumbe:

```
void screenFBO::activate(void) {
    if(this->initialized) {
        // frame- und renderbuffer binden und drawbuffers einrichten
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, this->mainFBO[0]);
        glBindRenderbuffer(GL_RENDERBUFFER, this->mainRBOdepth);

        glDrawBuffers(2, this->mainFBObuff);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        this->checkErrors("activate()");
    }
}

void screenFBO::deactivate(void) {
    if(this->initialized) {
        // alles wieder unbinden und drawbuffers zurücksetzen
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
        glBindRenderbuffer(GL_RENDERBUFFER, 0);
        glDrawBuffers(1, this->windowBuff);
        this->checkErrors("deactivate()");
    }
}
```
nix wildes - ich "aktiviere" den "haupt" framebuffer (also der, der diese 2-spurige ausgabe beinhaltet, mit color_attachment0 und 1 für colorTexture und bloomTexture[0] bla - siehe oben) und setz die drawbuffers. beim deaktivate() genau andersrum.

SOA! hier kommen wir nun zu meinem problem 1 >< aus irgendeinem grund wird die colorTexture nicht neugemalt. geb ich die aus, steht das bild ab dem ersten frame und sieht aus, wie 20 mal übereinander gemalt. normalerweise zieht das bild dann ja schlieren quasi. es bewegt sich ja aber noch >< machts aber ned. geb ich den brightpass aus (also bloomtexture[0]) klappt das wunderbar. die szene in dunkel mit dem hellen krams hauptsächlich und in voller bewegung. also beim brightpass passt alles, nur beim normal pass quasi is irgendwas im argen :/

hier nochmal der kleine code für drawScreenTexture():

```
void DrawScreenTexture(void) {
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, mFBO.getTex());

    projectionMatrix.PushMatrix();
        projectionMatrix.LoadMatrix(orthoMatrix);
        modelViewMatrix.PushMatrix();
            modelViewMatrix.LoadIdentity();
            //mFBO.draw();
            glUseProgram(screenShader);
            glUniform1i(locSSUniforms[0], 0);                                                                            // textur
            screenQuad.Draw();
        modelViewMatrix.PopMatrix();
    projectionMatrix.PopMatrix();
}
```
er nimmt also quasi nur die textur aus dem fbo objekt und pinselt sie auf nen bildschirmfüllendes viereck. mFBO.draw() is grad noch ausgegraut, da das zu meinem nächsten problem führt. aber erstmal so weiter. wenn mFBO.getTex() die colorTexture liefert, siehts so aus:



			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        


bei bloomTexture[0] dann so:



			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        




			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        


die anderen bloomText ebenen sind einfach schwarz ^^ is ja noch nix gemalt worden.

ok, hab grad festgestellt, wenn ichs erste mal starte, dann ist colorTexture quasi uninitialisiert. da war nur schwarzer hintergrund mit vielen rosa tupfen oO. dann lies ichs mal mit der ausgabe auf die bloomtexture laufen und es kam halt das normale gerenderte bild. bewegte szene usw. danach nochmal colorTexture ausgeben lassen und schwupps hatte es ein stehendes bild ohne rosa tupfen. man, was is denn da nur im argen, was ich überseh? ich hoffe irgendwer blickt hier durch und kann helfen ><

gut, also wie gesagt, dass ist mein erstes problem: die colorTexture will einfach nich mehr so, wie ich das will :/ das 2. problem hängt mit dem mFBO.draw() zusammen. da wird das geblurre realisiert:

```
void screenFBO::draw(void) {
    if(this->initialized) {
        // die bloomTexture blurren
        glActiveTexture(GL_TEXTURE0);
        GLuint x = this->screenX;
        GLuint y = this->screenY;
        this->load2PShader();
        for(int i = 1; i < 5; i++) {
            x = (int)(x * this->ratio);
            y = (int)(y * this->ratio);
            glBindFramebuffer(GL_DRAW_FRAMEBUFFER, this->mainFBO[i]);    // output texture i bound to fbo i
            glBindTexture(GL_TEXTURE_2D, this->bloomTexture[i-1]);        // input texture is i-1
            glDrawBuffers(1, &this->mainFBObuff[0]);
            glViewport(0, 0, x, y);
            this->screenQuad.Draw();
        }
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, this->mainFBO[0]);
        glDrawBuffers(1, &this->mainFBObuff[0]);
        glViewport(0, 0, this->screenX, this->screenY);

        // colorTexture und blurredTexture kombinieren für die finale szene
        /*this->load3PShader();
        this->screenQuad.Draw();
        // anschließend wieder alle texturen unbinden
        for(int i = 0; i < 6; i++) {
            glActiveTexture(GL_TEXTURE0 + i);
            glBindTexture(GL_TEXTURE_2D, 0);
        } */
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
        glDrawBuffers(1, &this->windowBuff[0]);
        this->checkErrors("draw()");
    }
}
```
das hauptsächlichste ist erstmal die forschleife. das is quasi mein versuch den 2ndPass zu realisieren. framebuffer_ hat ja bloomTexture als output deklariert. als input will ich aber die "vorgänger" textur haben - daher binde ich hier bloomTexture[i-1]. das mach ich für alle 4 subtexturen und warte gesapnnt auf das ergebnis:

colorTexture: 


			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        



bloomTexture[0]: 


			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        



bloomTexture[1]: 


			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        


...

selbst dass wenige bischen, was bisher funktioniert hatte, wird nun völlig zerschossen >< wiesooooo?

hoffe, irgendwer weis rat ^^_


----------



## DarkMo (24. April 2013)

*AW: [update 2] Bloom-Effekt erzeugen*

ich nochmal. habs gestern geschafft, 2 fehlerchen auszumertzen. zum einen, wieso die bilder bei dem drawScreenTexture so versaubeutelt wurden. ich hatte die textur ausm fbo geladen und dann an den texturen rumgezeichnet (mFBO.draw()) und dann die davor geladene textur ausgegeben. einfach den texture-bind zeitpunkt nach der draw methode aufgerufen, und das problem war schonmal gelöst 

das 2. problem, was ich dann in angriff nahm war die nicht gezeichnete colorTexture. hab im shader die variablen vertauscht (also dass die brigtpass farbe auf die normal-farben variable gelegt wurde und umgekehrt und die attachments vertauscht - 0 erfolge. am ende hatte ich einfach mal zum schauen beim binden ans fbo die variablen vertauscht und wieder zurück (also quasi KEINERLEI änderung vorgenommen) - und es ging  als hätte es da geklemmt und man musste nur mal gegen den kasten latschen, dass es wieder ging 

nuja, nun läufts als erstmal grundsätzlich wieder. leider hab ichs noch ned hinbekommen, dass er dann bloomTexture[i-1] als vorlage nimmt und in bloomTexture_ zeichnet (also selbst erstmal einfach nen durchschleifen ohne änderungen am bild selbst). is im grunde vom grundprinzip her nix andres wie mein ausgabe-shader am ende (also das fertige bild aufn moni pinseln) - aber es will nich :/_


----------



## DarkMo (28. April 2013)

*AW: [update 2] Bloom-Effekt erzeugen*

mehehehehehhehehehehheeehe *crazy*


ICH HABS! ^^
als ich zufällig mal (das normalerweise immer gleich vom ausgabefensterchen überdeckte) konsolenfensterchen anschaute, grinste mich ein dickes "A GL ERROR OCCURED!" an. k, also irgendwas is wohl im busch ^^ hab dann rumgechekt und er sagte sehr spezifisch, dass "diese operation in diesems state nicht erlaubt sei". aha - welche der 1000 da? ^^ die lösung war zum glück recht simpel: glDrawBuffers sollte man erst nach dem binden des fbo's aufrufen - also ab damit in die schleife:

```
// die bloomTexture blurren
        glActiveTexture(GL_TEXTURE0);
        [COLOR=red]glDrawBuffers(1, this->mainFBObuff);  // hier stands zuerst - löst den error aus. mainFBObuff is nen 2er array mit {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1} - beim default window fbo geht dat nit
        GLuint x = this->screenX;
        GLuint y = this->screenY;
        for(int i = 1; i < 5; i++) {
            x = (int)(x * this->ratio);
            y = (int)(y * this->ratio);
            glBindFramebuffer(GL_DRAW_FRAMEBUFFER, this->mainFBO[i]);    // output texture i bound to fbo i
            [COLOR=green]glDrawBuffers(1, this->mainFBObuff); // hier isses korrekt. es darf auch nur das erste (GL_COLOR_ATTACHMENT0) genutzt werden, da ich hier keine 2 texturen gleichzeitig nutze wie im ersten renderdurchlauf)
            glBindTexture(GL_TEXTURE_2D, this->bloomTexture[i-1]);        // input texture is i-1
            this->load2PShader();
            glViewport(0, 0, x, y);
            this->screenQuad.Draw();
        }
```
gut, so war das schonmal vom tisch. ABER - die rotz ausgabe war immernoch tot. hab dann im shader einfach mal als outputfarbe rot gemacht (ned textur lesen) nur um zu sehn, ob wenigstens das ankommt - jop. also bekommt er keine textur rein. irgendwann siegte mein ordnungswahn... beim initialisieren der shade, also wo ich die uniform locations ermittel usw, hatte ich bei just meinem 2pass shader die eine zeile NICHT umgebrochen und die war halt so lang, dass sie ausm blickfeld verschwand. ich also gelangweilt wie bei den anderen den zeilenumbruch eingefügt und enddeckte DAS:

```
/* secondPassShader für den zweiten durchgang mit erstellung der geblurten sub images */
    this->secondPassShader = gltLoadShaderPairWithAttributes("Shader/screenShader.vp", "Shader/blurShader.fp", 2, // hier fehlte besagter zeilenumbruch übrigens
                            GLT_ATTRIBUTE_VERTEX, "vVertex", 
                            GLT_ATTRIBUTE_TEXTURE[COLOR=red][B]1[/B], "vTexCoord0");
    this->loc2PUniforms[0] = glGetUniformLocation(this->secondPassShader, "texture0");            // texture
    this->loc2PUniforms[1] = glGetUniformLocation(this->secondPassShader, "tc_offset");            // offset array für kernel
    glBindFragDataLocation(this->secondPassShader, 0, "oBright");                                // -> in att0 rendern
    glLinkProgram(this->secondPassShader);
```
GLT_ATTRIBUTE_TEXTURE1 - eins, EINS! himmel herrschaftszeiten, ich nutz doch die 0 

gut, das gelöst, passiert dennoch nix  nu hatte ich bei meinem letzten test da (letzes posting) die externe draw funktion mit in die klasse integriert. dazu brauchte ich auch nen shader (der 3. nun - der war auch mit diesem zeilenumbruch da, also 2 von 3en umgebrochen, einer ned ^^ -> ordnung schaffen *zitter*) der einfach nur ne textur auf den bildschrim ausgibt (bisher hab ich die ja in ne textur gepinselt). also im grunde nix wildes, einfach ausm hauptteil übernommen in die klasse, funzte sofort. so, nun nutze ich für alle diese shader als grundlage den selben vertex-teil (vertex-shade, fragment-shader). UUUUND? da wo besagte falsche 1 stand steht ja dahinter vTexCoord0 <- joa, bei dem neu integrierten steht da aber vTexture0...

naja, der rest ist wohl schnell zusammengereimt. das geändert, BÄM wir haben ein bild xD

tjo, nu würd ich sagen: auffi zum 3p shader xD ich freue mich schon jetzt auf neues gefluche und ewiges suchen von absoluten deppschusselfehlern. ich könnt mich manchmal selber latschen...


----------



## fadade (29. April 2013)

*AW: [update 2] Bloom-Effekt erzeugen*



DarkMo schrieb:


> "A GL ERROR OCCURED!" an. k, also irgendwas is wohl im busch ^^


 made my "morning" 



DarkMo schrieb:


> die lösung war zum glück recht simpel: glDrawBuffers sollte man erst nach dem binden des fbo's aufrufen - also ab damit in die schleife:


Das mit der Reihenfolge ist natürlich so ein typisch leicht zu übersehendes Problem! Aber in obigem Code-Schnipsel sehe ich keine Stelle, wo DrawBuffers schon vor der Bindung aufgerufen wird?! 

 Btw, wie schauen eigentlich die Shader for OGL aus? (*zu faul zum googlen sei* ^^) Auch HLSL? Dann könnt ich da jedenfalls vielleicht ein bisschen Unterstützung geben, weil für mein DirectX-Projekt werden halt auch HLSL-Shader genutzt. Ansonsten werde ich wohl Ende des aktuellen Semesters auch (zwangsweise) einen OpenGL-Renderer Programmieren müssen; momentan stecken wir noch beim kompletten Sotware-Renderer (Pixel für Pixel von Hand!) fest ...

Achja und wie schaut das fertige Resultat aus? Akzeptabel? ^^


----------



## DarkMo (29. April 2013)

*AW: [update 2] Bloom-Effekt erzeugen*

also bei ogl nennt sichs GLSL ^^

endergebnis... also ich hab gestern nochmal fix den 3rd pass shader angeworfen und wieder nen shcwarzes bild gesehn. da kam ich aber schnell druff. da ich mehrere bilder habe, die ich dem reintüdel, hab ich in ner schleife alle zugewiesen (glActiveTexture...), dann gerendert und dann in ner schleife wieder für alle textures deaktiviert ():

```
// anschließend wieder alle texturen unbinden
        for(int i = 0; i < 6; i++) {
            glActiveTexture(GL_TEXTURE0 + i);
            glBindTexture(GL_TEXTURE_2D, 0);
        }
```
glActiveTexture ist danach also GL_TEXTURE5 - un das kann dann natürlich nix werden, wenn ich der meine textur zur ausgabe binde ^^ gut, das also auch fix gelöst und wir hatten ein bild!

leider sah es ned sehr schön aus >< ok, gestern sah es besser aus 



			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        



das ist mit bloomFactor = 0.5f; je größer der wert wird (1.0 is schon grausam), desto heller wird zwar die szene, desto mehr verschmiert sie aber auch oO



			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        


junge junge, das wird ja immer schlimmer. im oberen rechten teil dieser lila "strich" zur mitte hin ist die sonne, die im bild ihre bahn zieht, statt halt einfach neugezeichnet zu werden. meine herrn, gestern sahs ja wenigstens noch ansatzweise ordentlich aus ><

naja, zumindest kann ich dir hier gleich mal als bsp die shader präsentieren, dann kannste dir vllt selber antworten, wie vergleichbar das ist. zuerst mal der vertex shader - der gibt an sich nur die daten durch (is ja nur nen bildschirm füllendes 4eck):

```
#version 330
 
in vec4 vVertex;
in vec4 vTexture0;

smooth out vec2 vTexCoords;

void main(void) {
    // Pass along the texture coordinates
    vTexCoords = vTexture0.st;

    // Pass along geometry
    gl_Position = vVertex;
}
```
(wie man sieht, steht hier eindeutig vTexture0 und nicht vTexCoord0... ^^)

der dient eigentlich für die meisten schritte (ausser dem ersten schritt halt, wo das bild an sich gemalt wird ^^). hier mal der blurring fragmentshader. also das ding, wo aus dem brightpass des ersten renderdurchgangs die kleineren subimages erstellt werden mit diesem gausian blur kernel da. ist original so ausm buch abgetippselt (oder findet man genau so auch im netz). sind halt 25 "texture lookups" was nicht unbedingt die tollste lösung ist ^^ empfohlen wird da lieber ein horizontal und ein vertical pass mit je 5 lookups. aber ich wollts erstmal so zum laufen bekommen, bevor ich hier die nächste baustelle aufmach 

```
#version 330

smooth in vec2 vTexCoords;

uniform sampler2D texture0;
uniform vec2 tc_offset[25];

out vec4 oBright;

void main(void)
{
    vec4 hdrSample[25];
    for (int i = 0; i < 25; ++i)
    {
        // Perform 25 lookups around the current texel
        hdrSample[i] = texture(texture0, vTexCoords.st + tc_offset[i]);
    }

    // 5x5 Gaussian kernel
    //   1  4  7  4 1
    //   4 16 26 16 4
    //   7 26 41 26 7 / 273
    //   4 16 26 16 4
    //   1  4  7  4 1

    // Calculate weighted color of a region
    oBright = (
                ( 1.0 * (hdrSample[ 0] + hdrSample[ 4] + hdrSample[20] + hdrSample[24])) +
                ( 4.0 * (hdrSample[ 1] + hdrSample[ 3] + hdrSample[ 5] + hdrSample[ 9] + hdrSample[15] + hdrSample[19] + hdrSample[21] + hdrSample[23])) +
                ( 7.0 * (hdrSample[ 2] + hdrSample[10] + hdrSample[14] + hdrSample[22])) +
                (16.0 * (hdrSample[ 6] + hdrSample[ 8] + hdrSample[16] + hdrSample[18])) +
                (26.0 * (hdrSample[ 7] + hdrSample[11] + hdrSample[13] + hdrSample[17])) +
                (41.0 * (hdrSample[12]))
              ) / 273.0;
}
```

und zu guter letzt noch den 3rd pass shader. also der, der die ganzen erstellten blur-bilderchen von eben zusammen matscht ^^

```
#version 330

smooth in vec2 vTexCoords;

uniform sampler2D origImage;
uniform sampler2D brightImage0;
uniform sampler2D brightImage1;
uniform sampler2D brightImage2;
uniform sampler2D brightImage3;
uniform sampler2D brightImage4;

uniform float bloomLevel;
uniform float exposure;

out vec4 oColor;

void main(void)
{
    // Fetch from HDR texture & blur textures
    vec4 baseImage  = texture(origImage,    vTexCoords);
    vec4 brightPass = texture(brightImage0, vTexCoords);
    vec4 blurColor1 = texture(brightImage1, vTexCoords);
    vec4 blurColor2 = texture(brightImage2, vTexCoords);
    vec4 blurColor3 = texture(brightImage3, vTexCoords);
    vec4 blurColor4 = texture(brightImage4, vTexCoords);

    vec4 bloom = brightPass + blurColor1 + blurColor2 + blurColor3 + blurColor4;

    vec4 color = baseImage + bloomLevel * bloom;

    // Apply the exposure to this texel
    oColor = 1.0 - exp2 (-color * exposure);
    oColor.a = 1.0;
}
```

tjoa, irgendwas is da scheinbar noch nich so ganz wies soll ^^


----------



## fadade (1. Mai 2013)

*AW: [update 2] Bloom-Effekt erzeugen*

Hmmm ... also erkennen tut man ja schon etwas!
Die ganzen Überschneidungen und Farben sehen aber merkwürdig aus. Diese Treppenstufeneffekte/Balken deuten eigentlich oft auf Schleifen hin, deren Daten nicht ordentlich zurückgesetzt wurden. 

Vielleicht hilft ja eine der folgenden Ressourcen:
- OpenGL Bloom Shader :: Dönemeier.de
- Philip Rideout :: Bloom
- Tutorial - OpenGL Bloom Effect - openFrameworks forum

Ansonsten hab ich mich an Bloom noch nicht rangewagt, sprich kenne das Vorgehen dahinter auch nicht^^


----------



## DarkMo (2. Mai 2013)

*AW: [update 2] Bloom-Effekt erzeugen*

hab jetz gradmal noch nen sinnlosschritt wieder ausgebaut. hatte das alles in ne extra textur gerendert und diese dann aufn schirm gerendert - anstatt das gerödel direkt aufn schirm zu packen ^^ hab mir jetzt mal alle einzelbestandteile anzeigen lassen: die coloTexture is mal wieder schwarz -.- die brightPass textur passt und die blur immages weissen diese fehlstellen auf *grrr*


----------



## DarkMo (12. Mai 2013)

*AW: [update 2] Bloom-Effekt erzeugen*

ho ha!




			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        




			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        



ich glaube, ich hatte eben ne intressante idee >< ich bin bisher davon ausgegangen, dass man den bright-pass (also die helligkeits textur da) blurred und diese geblurrte kleinere textur wiederrum blurrt. scheinbar bezieht sich das aber NUR auf die ausgangs textur. eben jene wird zigfach verkleinert und diese verkleinerten subimages der originalen werden geblurred und diese geblurrten farben zusammen addiert usw usf. dabei erschloss sich mir auch das mit den mipmaps.

aktuell hab ichs so umgebaut:
- rendere die szene normal und erzeuge dabei color- und brightpass.
- erzeuge vom brightpass mipmaps (4 bei mir)
- im shader geht er nun alle mip-level durch und für jedes mip-level macht er dieses kernel-abtast-gedöhns da (also 2nd pass shader ist in eine for-schleife im shader gewandert)
- diese werden dann zusammengefasst und das gerödel aus dem 3rd pass shader gleich hinterher berechnet (der 3rd pass shader passiert dann also bei der addition der einzelnen werte und nach dieser extra for schleife)
-> ausgabe aufn schirm

hat jetz ne halbe stunde umbau gedauert und lief auf anhieb xD leider sieht der bloom noch ebbes grob aus. also wenn die sonne so durchs bild wandert, schiebt sie sone pixel-bloom-wlkoe mit sich mit >< hoffe das bekomm ich noch hin. is sicherlich das hdr zeugs, mal schauen, wie ich das hinbekomm.


----------



## fadade (14. Mai 2013)

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

Servus,

schaut schonmal gut aus 
(auch wenn ich auf dem 2. Bild jetzt nicht unbedingt den Blur-Effekt erkenne ^^ )

Hast du schonmal mit mehr MipMaps probiert? Ändert sich die Optik signifikant?

Manchmal sind es die kleineren Sachen, die zum großen Fortschritt beitragen! Ist mir/meiner Gruppe heute auch in unserem Softwarerenderer passiert: Wurzel-Funktion bei der ganzen Datentransformation rausgekürzt und zagggg 1) Alles lief um Welten schneller (klar) 2) keine Interpolationsartefakte mehr übrig 

Wenn wir zum Ende des Semesters noch Zeit haben können wir auch mal versuchen Blur noch mit reinzuklatschen, mal sehen, wie das auf der CPU läuft


----------



## DarkMo (15. Mai 2013)

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

aufm 2. sah es zumindest weichgezeichneter aus ^^ hab jetzt aber mal die "originale" variante ausm buch genommen, wo wirklich nur die hellen bereiche geblurrt werden. zudem hab ich endlich ma rausgefunden, wieso sich manche bildteile (wenn man hier rauszoomed hat man ja dieses kugel-raumschiff - mit erdtextur xD - und da drückte sich halt mond und erde bla durch in sonem lila blau stich) durchdrückten. im shader wird ja die fragmentfarbe durch licht und specular gedöhnse verändert - und damit auch der alpha wert nebenher geändert. hab also einfach den alphawert vorher gesichert, dann die lichtberechnungen usw gemacht und am ende den fragment-wert wieder überschrieben. war nen test ins blaue hinein und hat gleich gefunzt xD naja, zuerst hatte ich einfach stur alpha = 1 gemacht, da war aber die atmosphäre eben ned mehr transparent - daher "herrüber retten" des originalen werts. funzt top ^^

nächster ansatz war, dass ich einfach mal für die blur-textur da die werte verzehn(hundert, 1000)fache (also beim ersten renderdurchgang, wo color und brightpass erstellt werden) und im 2. durchlauf dann im kernel (am ende teile ich ja /273) diesen wert am ende eben verzehn,hundert,1000fache (2730, 27300...). hatte allerdings 0 effekt ^^ jetzt laß ich im buch aber, dass dieser ganze part danach mit belichtung und bloom bla auch dazu genutzt wird, aus nem hdr bild nen ldr bild zur ausgabe zu machen (per clamp usw). jetz werd ich mal testen, obs was bringt, wenn ich für die brightpass textur die werte ver-zig-fache ^^ und dafür aber die 273 unberührt lasse. ma schauen ><

weitere änderungen: aufsplittung in vertikal und horizontal pass - ergo doch wieder zig einzeltexturen und fbo's bauen >< weil atm bin ich performance mäßig um den faktor 10 gefallen (~800 auf 80fps  ). und zu guter letzt soll es laut deinem einen link (den ich auch scho immer gefunden hab, als obs nix andres dazu gibt xD) auch 3 reichen. mal schauen. vllt is das tc_offset dingen (das array mit den abtastwerten) ja auch nur irgendwie ungünstig gebaut, werd ich mir wohl auch nochma anschauen müssen.

jedenfalls hätte man bei ner aufteilung statt 25 abtastwerten nur noch 10 (statt 5x5 2x5) und wenn das mit 3en auch funzt ohne verluste, wärens gar nur 6 (2x3) - also nen 4tel.

Edit: mit dem tc_offset lässt sichs wirklich verbessern:

```
void screenFBO::GenTexCoordOffsets(GLuint width, GLuint height) {
    float xInc = [B]3.0f[/B] / (GLfloat)(width);
    float yInc = [B]3.0f[/B] / (GLfloat)(height);

    for (int i = 0; i < 5; i++)    {
        for (int j = 0; j < 5; j++)    {
            this->texCoordOffsets[(((i*5)+j)*2)+0] = (-2.0f * xInc) + ((GLfloat)i * xInc);
            this->texCoordOffsets[(((i*5)+j)*2)+1] = (-2.0f * yInc) + ((GLfloat)j * yInc);
        }
    }
}
```
hier ganz oben x und yInc waren 1 - das war scheinbar zu "nah". habs jetz mal bissl probiert und 3 sieht ganz annehmbar aus. 5 war wieder zu schlimm ^^ also wenn ichs richtig deute, dann tastet er jetz nichmehr 1 oder 2 pixel um den mittleren herum ab, sondern lässt eben 2e abstand dazwischen. hmm, ich versuchs mal als bild zu verdeutlichen:



			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        




			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        


x/yInc = 1 <- beziehungsweise -> x/yInc = 3

wenn man das mal als vergrößerte pixel sieht, dann sind die roten diejenigen, die abgetastet werden.

das ergebnis schaut nun so aus (hoffe das jpg vormat hats nich allzusehr zerstört ><):



			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        




			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        


beim ersten mal die sonne aus der nahperspektive (ned so ein block-artiger bloom-hof) und beim 2. etwas aus distanz. auch hier wirkt es deutlich besser finde ich. an der linken landestütze sieht man auch noch etwas bloom des specular lights. also vorallem die ruhe des bildes wirkt sehr viel besser wie vorher (der bloom-hof/schein aussenrum is halt ned mehr so quadratisch/blockig und hüpft nicht mehr mit).


----------



## fadade (15. Mai 2013)

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

Nabend,

kann morgen vielleicht mal unseren Dozenten aus der Grafik-Veranstaltung fragen, ob er noch andere Lektüre zu Bloom(ing) kennt. Rückmeldung kommt dann 
Die Auswirkungen von Vervielfachung der Werte für die Blur-Textur kann man ja eigentlich schnell zurückverfolgen; ggf. ist da eine Formel auch nicht richtig umgesetzt (letzteres habe ich selbst öfter erfahren (müssen)).
Zur Rechnerei kann ich jetzt nicht so viel sagen ^^ aber ein *hust* negatives Performancewachstum um den Faktor 10 klingt jetzt eher nach irgendeinem Fehler im Vorgehen ... 

Die Optik der Sonne in Nahaufnahme ist ja eigentlich schon ganz ansehbar, wird m.M.n. aber vom Aussehen der Erde - oder des Erdenkonstruktes oder was das ist  - stark übertroffen: Nicht zu auffällig, aber dennoch signifikant, quasi keine "Kanten" -> Top


----------



## DarkMo (16. Mai 2013)

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

najo, es stand schon im buch, dass das viel rechenzeit kostet. also diese pixel-abfrage da (texture() befehl). und da man hier quasi für jeden pixel 25 abfragen macht, hat man also das 25fache abfrage-volumen. demgegenüber nur 10facher einbruch ist schon vorstellbar, denk ich mal. eben deswegen gibt es ja die aufsplittung in vertical und horizontal pass. weil dieser kernel da (ne matrix, wenn man so will) ergibt sich ja aus den "vektoren" (1 4 7 4 1) und das dingen um 90° gedreht ^^ wart ma...


```
/ 1 \   1  4  7  4 1
              | 4 |   4 16 26 16 4
(1 4 7 4 1) + | 7 | = 7 26 41 26 7
              | 4 |   4 16 26 16 4
              \ 1 /   1  4  7  4 1
```
so quasi. und die aufsplittung resultiert dann eben wieder in diesen einzelvektoren. das ergebnisbild sieht genauso aus, nur dass man eben nur 10 statt 25 pixelabfragen hat. gestern hatte ich auch mal ein "early bias" probiert. hatte mal was zu shadowmaps gelesen gehabt, und da kam auch son kernel vor - und da hatten sie zur verbesserung dieses dingen angemerkt. da prüft man quasi erstmal am rand 4 punkte, ob hier bedarf am blurren besteht (also irgendwas in der blurtextur steht) und nur dann, werden die 25 (also die restlichen 21) pixelabfragen komplett durchgezogen. klappte von der performance her auch super, allerdings hatte ich dann keinen ordentlichen bloom mehr, das sah eher wie ne blume aus xD also wenn ich links rechts oben unten die early abfrage mache, dann hatte die sonne usw eben in diesen richtungen nen kreisrunden blur -> blumen effekt ^^ performance also io, optik fürn hund ><

naja, ich werd mich mal an der aufsplittung versuchen irgendwann.


----------



## kühlprofi (17. Mai 2013)

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

Sehr interessantes Projekt und auch sehr interessant zum lesen, auch wenn ich meist nur Bahnhof verstehe. 
Doch du beschreibst alles sehr gut in einem humorvollen stil, (auch sehr witzig wenn du dich aufregst lol) wenn lehrbücher auch so geschrieben wären würde das lesen viel mehr spass machen


----------



## DarkMo (18. Mai 2013)

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

hehe danke ^^ ich find es sehr hilfreich für mich selber, wenn ich versuche anderen die problematik zu erklären. oft hilft mir allein schon diese formuliererei der problematik. dann durchdenk ich alles (und da ich keinen bullshit erzählen will, vertief ich mich zusätzlich nochma rein um alles möglichst richtig rüber zubringen) und komm teils allein dabei schon auf lösungen. wenn dann doch mal ab und zu einer was gescheites weis, umso besser


----------



## DarkMo (29. Mai 2013)

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

Mal eine fixe Frage der etwas anderen art in die runde: ich hab hier nen hübsches (rein von den themen her) tutorial für OGL gefunden. leider sind das scheinbar "nur" die quelltexte ohne erläuterungen. ich würd zwar versuchen, mich da erstmal so reinzufuchsen, aber nuja ^^

jedenfalls scheint es besagte erläuterungen dazu in eBook-Form zu geben: 3D-Spieleentwicklung - OpenGL - GLSL - OpenCL - OpenAL - KI - Animation - Spielephysik hier sind 2 amazon links zu den büchern, zusammen unter 10€. ALLERDINGS als "Kindle Edition" - also für diesen besichnen eBook reader da von amazon. Daher jetzt meine frage: braucht man das rotz ding unbedingt oder is das nen stink normales pfd, was ich auch einfach am rechner lesen kann?

kenn mich damit leider 0 aus ><


----------



## DarkMo (29. August 2013)

*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  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*


----------



## DarkMo (1. September 2013)

*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:



			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        


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*



			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        




			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        



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   nur am bloom hat sich noch ned wirklich was getan. warscheinlich is die schwelle zu gering. also die aufhellung nicht stark genug *grübel*



			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        




			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.


----------



## DarkMo (27. Januar 2014)

*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


----------



## DarkMo (28. Juni 2014)

*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


----------



## VikingGe (29. Juni 2014)

*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.


----------



## DarkMo (29. Juni 2014)

*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 :/


----------



## VikingGe (29. Juni 2014)

*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...


----------



## DarkMo (29. Juni 2014)

*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... ><


----------



## DarkMo (17. August 2015)

*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:

```
#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?


----------



## Ap0ll0XT (18. August 2015)

*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.


----------



## DarkMo (21. August 2015)

*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 :/


----------



## DarkMo (23. August 2015)

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:

```
#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".
> ...



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 ^^)



			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        


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


----------



## bingo88 (23. August 2015)

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


----------



## DarkMo (24. August 2015)

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


----------



## bingo88 (24. August 2015)

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


----------



## Ap0ll0XT (24. August 2015)

Na ich hoffe mal, das es denn jetzt auch mit deinem Vollbildproblem erledigt ist, weswegen du ja die Bibliothek gewechselt hast ^^


----------



## DarkMo (24. August 2015)

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.


----------



## DarkMo (28. August 2015)

so, mal wieder eine zwischenmeldung. aktueller stand:



			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        



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:

```
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:

```
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


----------



## DarkMo (30. August 2015)

und wieder ein stück geschafft:



			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        



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  (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  

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 :/


----------



## DarkMo (2. September 2015)

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  ) 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  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):



			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        



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 :/



			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        

 


			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        


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:



			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        



Passt alles ideal :/ Wieso zeigt er dann aber sonen Murks an?


----------



## -Zottel- (3. September 2015)

Die obj Datei sieht für nen Würfel ziemlich komisch aus.
Eigentlich müsstest du für einen Würfel 8 Vertices haben, in der obj sind es 4 und im Programm sind es 6.

Ich würden den Würfel in blender neu machen und schauen, dass die Datei richtig importiert wird.
(Den Würfel am besten nicht drehen/bewegen/skalieren, damit die Vertex koordinaten und die normale glatte Zahlen sind)


----------



## DarkMo (3. September 2015)

Ich hab von 2 seiten 2 dreiecke übrig gelassen damits nicht soviel ist und übersichtlich. also das hatte schon gestimmt. hast aber recht, war etwas verwirrend gesmacht ^^ die ersten bilder waren noch vom richtigen würfel. danach das war dann wie gesagt an das schriftliche bsp angepasst mit 2 dreiecken die sich ne kante teilen.

bin btw schon auf ein neues problem gestoßen: scheinbar sind die vertices auch im obj-file nicht zwingend einmalig? -.- hatte von einem TF-Modell was ich mal gebastelt hatte ein Rad exportiert um zu lunzen, was er da draus macht. ~150 verts wovon er aber nur ~90 speichert (weil der rest halt doppelt ist) und schwupps bekomm ich speicherverletzungen um die ohren gehauen -.- wenn er auf vert 100 zugreifen will wo ich nur 90 gespeichert hab - logisch. jetzt hab ich hierbei die vermutung, dass es am smoothing liegt.

kleiner blender exkurs:
in blender kann man (wie sicher auch in anderen programmen dieser art) oberflächen "smoothen" - sprich rundungen vorgaukeln. die normalen der vertices werden eben zusammen gerechnet (aus 90° und 0° wird eben 45° -> (90+0) / 2 = 45) und im shader werden die interpoliert (also von einem vertex zum nächsten stück für stück angepasst anstatt schlagartig). so sieht hüsch rund aus - aber wenn man in all den rundungen definierte eckige kanten mag, dann muss man das mesh hier auftrennen (zum bsp mit dem edgesplit modifier). das bewirkt (um bei unserem 2 dreiecksproblem zu bleiben), dass nun beide 3ecke ihre vertices NICHT mehr teilen. man könnte also das eine dreieck wegschieben ohne das das andere mit geht bzw deformiert wird, weils dran hängt.

und genau hier befürchte ich, liegt das problem :/ anstatt das nur die normalen dann getrennt werden, wird der vertex doppelt gespeichert. muss ich mal guggn, notfalls muss ich halt auf das vermeiden von doppelspeicherungen verzichten. find ich nich gerade schön, aber was will man machen.

ich probiere mal ein video anzuhängen. komme natürlich bei vimeo nich mehr rein -.- was auch sonst... wie ich diesen ganzen dreck immer hasse. wollen die schlüpfergröße von einem wissen und dann kommste nich mehr an den acc ran.

hui, hat sogar gefunzt. knapp 9mp entpackt, mp4 und 30 secs - diesmal wieder der "würfel". sieht stellenweise nichmal schlecht aus


----------



## DarkMo (26. September 2015)

wasn das jetz fürn blödsinn -.- "Testzeitraum abgelaufen"... wtf? da stand nie was von testversion. denk das teil is freeware? also das visual ^^ kotzt mich grad derbe an...


----------



## bingo88 (26. September 2015)

Welche Version ahst du denn installiert? Kostenlos nutzbar ist nur die Community Version (bzw. die alten Express Editions).


----------



## DarkMo (26. September 2015)

Ich bild mir ja ein genau die genommen zu haben. Wenn ich das ausm Startmenü picke steht da aber Visual Studio 2015 - also nix mit Community *hmm*
Mal gugn ob ich den installer noch find... Ah hier isses - siehe Anhang.


----------



## bingo88 (27. September 2015)

Offenbar muss man sich noch bei MS registrieren, um das dauerhaft freizuschalten. Quelle: https://msdn.microsoft.com/de-de/library/dn457348.aspx


----------

