Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

stef

Treue Seele

  • »stef« ist der Autor dieses Themas

Beiträge: 246

Wohnort: Kassel

Beruf: Softwareentwickler

  • Private Nachricht senden

1

09.10.2012, 17:17

[OpenGL] Rendern in eine Textur

Hallo Forum

Ich möchte mit einem FBO einen rotierenden Torus als Textur auf einem Würfel zeichnen.
Eigentlich sollte das gemähte Wiese sein, aber auf dem Würfel erscheint nix.

In Zeile 302 meines Programms (siehe Code unten) kommt folgender Fehler ...

C-/C++-Quelltext

1
2
3
4
                GLenum FBO_Attach[] = {GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT};
                GL::glDrawBuffers(2, FBO_Attach);
                glErr = glGetError();
                // ???????????  Hier kommt GL_INVALID_ENUM ???????????




Hier mein Code:
(2/3 davon sind für das Problem irrelevant)

Siehe verkürzte Fassung im nächsten Post ...


Hier noch der Fragment Shader ...

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#version 330

uniform sampler2D u_s2dColorMap;

in vec3 v3Vertex_;
in vec3 v3Normal_;
in vec2 v2Texture_;
in vec3 v3VertexToLight_;
in vec4 v4SecondaryColor_;

out vec4 _v4FragColor;

void main (void) 
{
    float diff;
    float fTexColSum;
    float fSecColSum;
    
    diff = max(0.01, dot(v3Normal_, v3VertexToLight_)); 
    _v4FragColor = diff * texture(u_s2dColorMap, v2Texture_) + v4SecondaryColor_ + 0.0f;
    
    fTexColSum = max( 1.0, texture(u_s2dColorMap, v2Texture_).r + texture(u_s2dColorMap, v2Texture_).g + texture(u_s2dColorMap, v2Texture_).b );
    fSecColSum = v4SecondaryColor_.r + v4SecondaryColor_.g + v4SecondaryColor_.b;    
    _v4FragColor.a = max(fSecColSum/3.0, fTexColSum/3.0) + 0.2;
}


Danke !
"In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." — Bjarne Stroustrup.

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »stef« (10.10.2012, 13:39)


stef

Treue Seele

  • »stef« ist der Autor dieses Themas

Beiträge: 246

Wohnort: Kassel

Beruf: Softwareentwickler

  • Private Nachricht senden

2

10.10.2012, 01:44

Ich sehe schon an der Fülle der Antworten dass es wohl etwas zu viel Code gewesen ist :D

Hier eine etwas verkürzte Version von main() ...

siehe ganz unten die Lösung !!!
"In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." — Bjarne Stroustrup.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »stef« (10.10.2012, 22:39)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

3

10.10.2012, 10:00

WTF? Du weißt schon, dass es das Konstrukt "Methode" und "Funktion" gibt? Das da ist ja quasi eine Art Reliquie an das Fliegende Spaghetti Monster!
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

DeKugelschieber

Community-Fossil

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

4

10.10.2012, 10:06

Beim Shadowmapping benutze ich auch ein FBO (natürlich). Ich denke mal das Hilft dir weiter:

Renderfunktion
ShadowMap.h (enthält das FBO)
ShadowMap.cpp hier siehst du vor allem wie das FBO aufgesetzt wird

Natürlich musst du die Parameter überall noch anpassen wenn du keine depthmap rendern willst.

5

10.10.2012, 10:36

http://developer.amd.com/tools/hc/gDEBug…es/default.aspx

Super OpenGL Debugger. Zeigt die sämtliche Fehlermeldungen an, gibt Performancetipps und du kannst dir deine Texturen angucken, d.h. sehen was in den Framebuffer gerendert wird, ohne per Ogl dessen Textur anzeigen zu müssen (wobei ja auch noch so einiges schief gehen kann).

Damit kannst du deinen Fehler eingrenzen und so vielleicht konkretere Fragen stellen.
Lieber dumm fragen, als dumm bleiben!

stef

Treue Seele

  • »stef« ist der Autor dieses Themas

Beiträge: 246

Wohnort: Kassel

Beruf: Softwareentwickler

  • Private Nachricht senden

6

10.10.2012, 13:27

WTF? Du weißt schon, dass es das Konstrukt "Methode" und "Funktion" gibt? Das da ist ja quasi eine Art Reliquie an das Fliegende Spaghetti Monster!


Ich bin halt 64'er Generation ... die 500 goto's hatte ich schon entfernt :D
Nein, das ist experimenteller Code und wenn ich FBO versatnden habe (was jetzt noch nicht der Fall ist) mach ich alles schön.


@Jonathan_Klein: Die AMD Variante von gDEBugger geht bei mir nicht (nVidia WinXP). Hab mir aber die von Graphic Remedy gesaugt.
Mein Problem mit dem GL_INVALID_ENUM habe ich damit gelöst. Leider war das nicht die Ursache das der Würfel keine Textur zeigt.


Damit kannst du deinen Fehler eingrenzen und so vielleicht konkretere Fragen stellen.


Also ganz konkret:

Ich will FBO's verstehen und programmiere dazu einfache Beispiele.
Als erstes habe ich mit Hilfe von einem FBO in einen RBO gerendert und den Inhalt dann mit glBlitFramebuffer in meinen Windows Buffer kopiert und angezeigt. Hat ohne Probleme funktioniert.
Jetzt will ich ganz simpel in eine Textur rendern und diese dann auf einen Würfel zeichnen.

Hier die einzelnen Schritte ...

1. Erzeugen des FBO, RBO (für Depth Buffer) und der Textur

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    // frame buffer
    GLuint FBO = 0;

    // render buffer
    GLuint RBO_Tex = 0;
    GLuint RBO_Depth = 0;
    GLint RBO_X=512;
    GLint RBO_Y=512;

    // create framebuffer
    GL::glGenFramebuffers(1, &FBO);
        
    // create renderbuffer
    glGenTextures(1, &RBO_Tex);
    GL::glGenRenderbuffers(1, &RBO_Depth);


2. Allokieren von Speicher für RBO und Textur
Binden von Textur an GL_COLOR_ATTACHMENT0
Binden von RBO an GL_DEPTH_ATTACHMENT

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
        GL::glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FBO);
        {
            // bind / setup renderbuffer texture
            glBindTexture(GL_TEXTURE_2D, RBO_Tex);
            {
                // set texture parameter
                GL::glGenerateMipmap(GL_TEXTURE_2D);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
                
                // allocate mem for texture
                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, RBO_X, RBO_Y, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, NULL);
                                
                // attach texture to framebuffer
                GL::glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, RBO_Tex, 0);
            }
            glBindTexture(GL_TEXTURE_2D, 0);

            // bind / setup renderbuffer depth
            GL::glBindRenderbuffer(GL_RENDERBUFFER, RBO_Depth);
            {
                // allocate mem for RBO
                GL::glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, RBO_X, RBO_Y);
                                
                // attach renderbuffer to framebuffer
                GL::glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, RBO_Depth);
            }
            GL::glBindRenderbuffer(GL_RENDERBUFFER, 0);

            // check status of FBO
            GLenum FBO_Status = GL::glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
            if(FBO_Status != GL_FRAMEBUFFER_COMPLETE)
            {
                ssErr.str("");
                ssErr << "FBO status not OK !!!";
                throw ssErr.str();
            }
        }
        GL::glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);  



3. Rendern
Torus in den FBO bzw. die Textur
Cuboid in den Fensterbuffer

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
            // render to FBO
            GL::glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FBO);
            glBindTexture(GL_TEXTURE_2D, 0);
            {
                glViewport(0,0,RBO_X,RBO_Y);
                GLenum FBO_Attach[] = {GL_COLOR_ATTACHMENT0};
                GL::glDrawBuffers(1, FBO_Attach);

                // Clear buffer (color and depth)
                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

                Shader.Use();
                {
                    v3Angle_Torus += v3Speed_Torus * g_fTimeDiff;
                    m4MVM = Camera.GetCameraMatrix() * CMatrix44::Build_RotationMatrix(v3Angle_Torus);
                    Shader.SetUniform("u_m4MVM", m4MVM);
                    m3NM = m4MVM.ConvertToNormalMat();
                    Shader.SetUniform("u_m3NM", m3NM);
                    Torus.Draw();
                }
                Shader.Unuse();
            }

            // render to window
            GL::glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
            {
                // set viewport
                glViewport(0,0,g_nWidth,g_nHight);

                // Clear buffer (color and depth)
                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

                Cuboid.m_unTexture2D = RBO_Tex;
                Shader.Use();
                {
                    v3Angle_Cuboid += v3Speed_Cuboid * g_fTimeDiff;
                    m4MVM = Camera.GetCameraMatrix() * CMatrix44::Build_RotationMatrix(v3Angle_Cuboid);
                    Shader.SetUniform("u_m4MVM", m4MVM);
                    m3NM = m4MVM.ConvertToNormalMat();
                    Shader.SetUniform("u_m3NM", m3NM);
                    Cuboid.Draw();
                }
                Shader.Unuse();             
                
            }



Sieht im großen und Ganzen aus wie bei DeKugelschieber. (zumindest sehe ich keinen Unterschied)
Trotzdem wird der Würfel ohne Torus gezeichnet.
Habe mit gDEBugger durchgestept und mir dabei die Textur angesehen die am FBO hängt.
Die Verbindung mit dem FBO wird im debugger angezeigt, die Textur bleibt aber leer.


Warum ???????
"In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." — Bjarne Stroustrup.

7

10.10.2012, 15:14

Bei so Fehlern ist oft viel rumprobieren im Spiel. Du könntest das aktivieren des FBOs auskommentieren, dann müsstest du ja die Scene am Bildschirm sehen, statt sie in der Textur zu haben. So kannst du sichergehen, dass zumindest das Rendern stimmt.
Der nächste Schritt ist dann, das FBO korrekt zu erstellen und zu binden, so dass das Ergebnis in der Textur landet. Zur Not kann man sich irgendein FBO Tutorial als Referenz schnappen und gucken, welche Funktionen dort wann aufgerufen werden. Dann sollte es eigentlich bei dir korrekt landen.
Du kannst die auch in gDebugger die tausend States von OpenGL anschauen und dort nach Fehlern suchen. Vielleicht ist etwas aktiviert, was es nicht sein sollte, oder umgekehrt.

Übrigens funktioniert die AMD Version mit meiner nVidia Karte ganz ausgezeichnet. Es kommt zwar immer eine Meldung, dass ein bestimmtes Debugfeature nur auf AMD Karten geht, aber das ist irgendwas mit OpenCL Kernel Debugging und mir egal. Funktionieren tut es trotzdem super.
Lieber dumm fragen, als dumm bleiben!

stef

Treue Seele

  • »stef« ist der Autor dieses Themas

Beiträge: 246

Wohnort: Kassel

Beruf: Softwareentwickler

  • Private Nachricht senden

8

10.10.2012, 17:28

Fehler gefunden !

Nach dem Rendern in die Textur MipMaps neu erzeugen !!!


C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
    // frame buffer
    GLuint FBO = 0;

    // render buffer
    GLuint RBO_Tex = 0;
    GLuint RBO_Depth = 0;
    GLint RBO_X=1024;
    GLint RBO_Y=1024;

        // create framebuffer
        GL::glGenFramebuffers(1, &FBO);

        RBO_Tex = texGreen.GetTexture();
        GL::glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FBO);
        {
            // create renderbuffer
            glGenTextures(1, &RBO_Tex);
            glErr = glGetError();
            GL::glGenRenderbuffers(1, &RBO_Depth);
            glErr = glGetError();

            // bind / setup renderbuffer texture
            glBindTexture(GL_TEXTURE_2D, RBO_Tex);
            glErr = glGetError();
            {               
                // allocate mem for texture
                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, RBO_X, RBO_Y, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, NULL);
                glErr = glGetError();
            
                // set texture parameter
                GL::glGenerateMipmap(GL_TEXTURE_2D);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

                // attach texture to framebuffer
                GL::glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, RBO_Tex, 0);
                glErr = glGetError();
            }
            glBindTexture(GL_TEXTURE_2D, 0);

            // bind / setup renderbuffer depth
            GL::glBindRenderbuffer(GL_RENDERBUFFER, RBO_Depth);
            glErr = glGetError();
            {
                // allocate mem for RBO
                GL::glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, RBO_X, RBO_Y);
                glErr = glGetError();
                                
                // attach renderbuffer to framebuffer
                GL::glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, RBO_Depth);
                glErr = glGetError();
            }
            GL::glBindRenderbuffer(GL_RENDERBUFFER, 0);

            // check status of FBO
            GLenum FBO_Status = GL::glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
            if(FBO_Status != GL_FRAMEBUFFER_COMPLETE)
            {
                ssErr.str("");
                ssErr << "FBO status not OK !!!";
                throw ssErr.str();
            }
        }
        GL::glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

            // render to FBO
            GL::glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FBO);
            glBindTexture(GL_TEXTURE_2D, 0);
            {
                glViewport(0,0,RBO_X,RBO_Y);
                glErr = glGetError();
                GLenum FBO_Attach[] = {GL_COLOR_ATTACHMENT0};
                GL::glDrawBuffers(1, FBO_Attach);
                glErr = glGetError();

                // check status of FBO
                GLenum FBO_Status = GL::glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
                if(FBO_Status != GL_FRAMEBUFFER_COMPLETE)
                {
                    ssErr.str("");
                    ssErr << "FBO status not OK !!!";
                    throw ssErr.str();
                }

                // Clear buffer (color and depth)
                glClearColor( 0.2f, 0.2f, 0.2f, 0.0f ); 
                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

                Shader.Use();
                {
                    v3Angle_Torus += v3Speed_Torus * g_fTimeDiff;
                    m4MVM = Camera.GetCameraMatrix() * CMatrix44::Build_RotationMatrix(v3Angle_Torus);
                    Shader.SetUniform("u_m4MVM", m4MVM);
                    m3NM = m4MVM.ConvertToNormalMat();
                    Shader.SetUniform("u_m3NM", m3NM);
                    Torus.Draw();
                }
                Shader.Unuse();
            }
            
            // Generate MipMaps !!!!!!!!!!!!!!!
            glBindTexture(GL_TEXTURE_2D, RBO_Tex);
            GL::glGenerateMipmap(GL_TEXTURE_2D);
            glBindTexture(GL_TEXTURE_2D, 0);

            // render to window
            GL::glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
            {
                // set viewport
                glViewport(0,0,g_nWidth,g_nHight);

                // Clear buffer (color and depth)
                glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); 
                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

                Cuboid.m_unTexture2D = RBO_Tex;
                Shader.Use();
                {
                    v3Angle_Cuboid += v3Speed_Cuboid * g_fTimeDiff;
                    m4MVM = Camera.GetCameraMatrix() * CMatrix44::Build_RotationMatrix(v3Angle_Cuboid);
                    Shader.SetUniform("u_m4MVM", m4MVM);
                    m3NM = m4MVM.ConvertToNormalMat();
                    Shader.SetUniform("u_m3NM", m3NM);
                    Cuboid.Draw();
                }
                Shader.Unuse();                             
            }



Danke an alle die versucht haben zu helfen.
"In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." — Bjarne Stroustrup.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »stef« (10.10.2012, 22:37)


Werbeanzeige