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

Schwarzefee

Treue Seele

  • »Schwarzefee« ist der Autor dieses Themas

Beiträge: 155

Wohnort: Ost-Sachsen

Beruf: Programmierer

  • Private Nachricht senden

1

13.03.2014, 19:59

OpenGL - SOIL - wxWidgets

Hi,

da mir letztes Mal super geholfen wurde, jetz das nächste Problem.

Ich versuche mit SOIL Texturen zu rendern. Leider bekomme ich nur ein schwarzes Rechteck.
Beim googlen haben ich unter Anderem gelesen, dass es Probleme geben kann, wenn verschiedene Threads laufen.
Könnte das Problem dann wxWidgets sein?

Ich sitze jetz schon wieder seit ein paar Stunden dran und finde keine Fehler.

Hier mal die Methode, wie im Moment Texturen geladen werden:

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
bool Grafics::Texture::LoadImageFromFile(std::string filename)
{
    this->Loaded = false;
    this->Filename = filename;

    this->Renderer->MakeCurrent();

    int width, height;
    unsigned char* data = SOIL_load_image(filename.c_str(), &width, &height, 0, SOIL_LOAD_RGBA);

    if (data == NULL)
    {
        return false;
    }
 
    glActiveTexture(GL_TEXTURE0);
    glGenTextures(1, &this->TextureID);
    glBindTexture(GL_TEXTURE_2D, this->TextureID); 
        
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

    glTexImage2D(GL_TEXTURE_2D, 0,  GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
    
    //Unbind
    glBindTexture(GL_TEXTURE_2D,0);

    this->Width = (float)width;
    this->Height = (float)height;
    
    this->Loaded = true;
    return true;
}


Das funktioniert soweit fehlerflei, Width und Height werden u.A. richtig erkannt.
Setsamer Weise funktioniert die Funktion SOIL_load_OGL_texture() nicht, da bekomme ich eine Exception.
Ich habe gelesen, dass das passieren kann, wenn kein richtiger Device angelegt ist.

So lege ich den Device an, läuft auch ohne Fehler bis zum Ende durch.

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
this->DeviceContext = GetDC(this->WindowHandle);

    PIXELFORMATDESCRIPTOR pfd;
    memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); // Clear our  PFD  
    pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
    pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; // Enable double buffering, opengl support and drawing to a window
    pfd.iPixelType = PFD_TYPE_RGBA; // Set our application to use RGBA pixels  
    pfd.cColorBits = 32; // Give us 32 bits of color information (the higher, the more colors)  
    pfd.cDepthBits = 32; // Give us 32 bits of depth information (the higher, the more depth levels)  
    pfd.iLayerType = PFD_MAIN_PLANE; // Set the layer of the PFD  

    int nPixelFormat = ChoosePixelFormat(this->DeviceContext, &pfd); // Check if our PFD is valid and get a pixel format back  
    if (nPixelFormat == 0)
    {
        return false;  
    }
    
    BOOL bResult = SetPixelFormat(this->DeviceContext, nPixelFormat, &pfd); // Try and set the pixel format based on our PFD  
    if (!bResult)
    {
        return false;
    }

    HGLRC tempOpenGLContext = wglCreateContext(this->DeviceContext); // Create an OpenGL 2.1 context for our device context  
    wglMakeCurrent(this->DeviceContext, tempOpenGLContext); // Make the OpenGL 2.1 context current and active  

    //Init Glew
    GLenum error = glewInit(); // Enable GLEW  
    if (error != GLEW_OK) // If GLEW fails  
    {
        return false;
    }

    int attributes[] = {  
        WGL_CONTEXT_MAJOR_VERSION_ARB, 3, // Set the MAJOR version of OpenGL to 3  
        WGL_CONTEXT_MINOR_VERSION_ARB, 2, // Set the MINOR version of OpenGL to 2  
        WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, // Set our OpenGL context to be forward compatible  
        0
    };

    if (wglewIsSupported("WGL_ARB_create_context") == 1) 
    {
        this->RenderContext = wglCreateContextAttribsARB(this->DeviceContext, NULL, attributes); // Create and OpenGL 3.x context based on the given attributes  
        wglMakeCurrent(NULL, NULL); // Remove the temporary context from being active  
        wglDeleteContext(tempOpenGLContext); // Delete the temporary OpenGL 2.1 context  
        wglMakeCurrent(this->DeviceContext, this->RenderContext); // Make our OpenGL 3.0 context current  
    }
    else 
    {  
        this->RenderContext = tempOpenGLContext; // If we didn't have support for OpenGL 3.x and up, use the OpenGL 2.1 context  
    }




Ich hatte es schon testweise mit DevIL versucht, aber da hatte ich auch nur ein schwarzes Rechteck.




C-/C++-Quelltext

1
glEnable(GL_TEXTURE_2D);

ist gesetzt.

Die Texture-Uniform wird in jeder Frame gesetzt:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, this->CurrentTexture->GetTextureID());
        // Set the texture in the pixel shader to use the data from the first texture unit.
        location = glGetUniformLocation(this->ShaderProgram, "ShaderTexture");
        if(location == -1)
        {
            return;
        }
        glUniform1i(location, 0);
        glBindTexture(GL_TEXTURE_2D,0);



Kann das Problem mit wxWidgets zusammenhängen?


Gruß

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

2

13.03.2014, 21:16

Zitat von »Schwarzefee«

Kann das Problem mit wxWidgets zusammenhängen?

Können schon, ist aber sehr unwahrscheinlich.

Zitat von »Schwarzefee«

glBindTexture(GL_TEXTURE_2D,0);

Ist falsch.
Siehe zum Beispiel hier: glBindTexture
2. Parameter ist die ID der Textur.

Schwarzefee

Treue Seele

  • »Schwarzefee« ist der Autor dieses Themas

Beiträge: 155

Wohnort: Ost-Sachsen

Beruf: Programmierer

  • Private Nachricht senden

3

13.03.2014, 21:19

Hi,

Zitat

Ist falsch.
Siehe zum Beispiel hier: glBindTexture
2. Parameter ist die ID der Textur.


Jap ist mir bekannt. Allerdings hab ich in einem Tutorial mal gelesen, wenn man die Texture nichtmehr benutzt soll man sie "unbind"en



Gruß

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

4

13.03.2014, 21:47

Nein, das wäre Quatsch. Ich nehme an, du bindest eh wieder eine Textur. Welchen Vorteil soll es haben, zwischen drin auch noch auf 0 umzuschalten?
Außerdem willst du doch mit dem Code eine Textur rendern. Dann muss die Textur auch gebunden sein.
Das die Texturuniform in jede Frame neu gesetzt wird ist genau genommen auch Unsinn.

Schwarzefee

Treue Seele

  • »Schwarzefee« ist der Autor dieses Themas

Beiträge: 155

Wohnort: Ost-Sachsen

Beruf: Programmierer

  • Private Nachricht senden

5

13.03.2014, 22:05

Hi,

also ich lade beim starten zuerst mal alle Texturen die ich benötige.
Beim rendern aktiviere ich dann immer die Texture, die ich benötige.

Aber das hilft mir bei meinem Problem auch nicht weiter, die Optimierung kommt dann, wenn es erstmal läuft ;)

Das komische ist halt, dass ich mit SOIL_load_OGL_texture() eine Exception bekommen, ohne dass ich irgendwas an dem Code ändere.


Gruß

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Schwarzefee« (13.03.2014, 22:16)


6

13.03.2014, 22:09

Auch ich lade Texturen mit SOIL benutze aber nciht die SOIL_load_OGL_xxx-Funktionen, sondern SOIL_load_image, und erzeuge die OpenGL-Texture dann selbst. Vielleicht macht ja auch SOIL etwas falsch.

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

7

13.03.2014, 22:10

Ja, da hast du recht.
Allerdings würde ich sagen, steht der Code damit einfach Grundsätztzlich an der ersten Stelle.

Zitat von »Schwarzefee«

Beim rendern aktiviere ich dann immer die Texture, die ich benötige.

Genau das solltest du auch machen.
Momentan bindest du die Textur vollkommen sinnlos einmal beim setzen Des Uniform-Textureunit-Indices, entfernst sie dann wieder und willst danach mit einer ungebundenen Textur rendern?

Schwarzefee

Treue Seele

  • »Schwarzefee« ist der Autor dieses Themas

Beiträge: 155

Wohnort: Ost-Sachsen

Beruf: Programmierer

  • Private Nachricht senden

8

13.03.2014, 22:23

Hi,

wieder mal typisch, an solchen Kleinigkeiten hängts...

Ich hab eben gedacht, dass die Texture nur solange gebunden sein muss, bis glUniform1i(location, 0); aufgerufen wurde.


Trotzdem nochmal vielen dank, dass hier einem Noob wie mir immer weitergeholfen wird ;)


Gruß

Sc4v

Alter Hase

Beiträge: 376

Beruf: Student

  • Private Nachricht senden

9

14.03.2014, 12:21

Hi,

solche Fehler passieren einem in OpenGL eigentlich recht schnell (mir zumindest :thumbsup: )
Wenn du mit OpenGL <= 3.2 arbeitest, dann empfehle ich dir einen Debugger wie z.B. gDEBugger (OT: Kennt jemand einen für OGL >=4 ?). Das Teil wird zwar nicht mehr weiterentwickelt ist aber ein Traum und deckt Fehler sehr schnell auf.

Greets

Werbeanzeige