OpenGL 3+ - Mehrere 2D-Texturen verwenden



  • Heyho,

    ich hänge mal wieder Fest und finde nach stundenlangem recherchieren immer nur die selben Vorschläge, die bei mir nicht zum Ziel führen.

    Ich möchte auf 2 verschiedene Objekte in 2 verschiedenen Viewports, 2 verschiedene Texturen mit 2 verschiedenen ShaderProgrammen mappen.

    Code so far..

    // Alle verwendeten IDs (wie beispielsweise texture1, texUD1 usw) wurden Global mit "GLuint <IDNAME>;" initialisiert.
    
    // PRE RENDER
       ... // Shader laden um compilen
       programID_1 = getProgramID();
       ... // Vertex und UV berechnung und buffer Zeugs
    
        glGenTextures(1, &texture1);
        glBindTexture(GL_TEXTURE_2D, texture1);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, texturDaten1);  
    
        texID1 = glGetUniformLocation(programID_1, "s2D");
    
       ... // Shader laden um compilen
       programID_2 = getProgramID();
       ... // Vertex und UV berechnung und buffer Zeugs
    
        glGenTextures(1, &texture2);
        glBindTexture(GL_TEXTURE_2D, texture2);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, texturDaten2);  
    
        texID2 = glGetUniformLocation(programID_2, "s2D");
    
    // RENDER-LOOP
    	glViewport(x1, y1, width1, height1);
    	glScissor(x1, y1, width1, height1);
    
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    	// Fill viewport with backgroundcolor for new frame
    	GLfloat color[] = { this->bgColor[0], this->bgColor[1], this->bgColor[2], this->bgColor[3] };
    	glClearBufferfv(GL_COLOR, 0, color);
    
            glUseProgram(programID_1);
    
            ... //MVP berechnung usw
    
    	// 1rst attribute buffer : vertices
    	glEnableVertexAttribArray(0);
    	glBindBuffer(GL_ARRAY_BUFFER, vbo1);
    	lVertexAttribPointer(
    	   0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
    	   3,                  // size
    	   GL_FLOAT,           // type
    	   GL_FALSE,           // normalized?
    	   0,                  // stride
    	   (void*)0            // array buffer offset
    	);
    	// 2nd attribute buffer : uvs
    	glEnableVertexAttribArray(1);
    	glBindBuffer(GL_ARRAY_BUFFER, uvbo1);
    	glVertexAttribPointer(
    	   1,                  // attribute 1. No particular reason for 1, but must match the layout in the shader.
    	   2,                  // size
    	   GL_FLOAT,           // type
    	   GL_FALSE,           // normalized?
    	   0,                  // stride
    	   (void*)0            // array buffer offset
    	);
    
     	glUniform1i(texID1, 0);
    	glActiveTexture(GL_TEXTURE0);
    	glBindTexture(GL_TEXTURE_2D, texture1);
    
    	glDrawArrays(GL_TRIANGLES, 0, 2*3);
    
    	glDisableVertexAttribArray(0);
    	glDisableVertexAttribArray(1);
    
    	glViewport(x2, y2, width2, height2);
    	glScissor(x2, y2, width2, height2);
    
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    	// Fill viewport with backgroundcolor for new frame
    	GLfloat color[] = { this->bgColor[0], this->bgColor[1], this->bgColor[2], this->bgColor[3] };
    	glClearBufferfv(GL_COLOR, 0, color);
    
            glUseProgram(programID_2);
    
            ... //MVP berechnung usw
    
    	// 1rst attribute buffer : vertices
    	glEnableVertexAttribArray(0);
    	glBindBuffer(GL_ARRAY_BUFFER, vbo2);
    	lVertexAttribPointer(
    	   0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
    	   3,                  // size
    	   GL_FLOAT,           // type
    	   GL_FALSE,           // normalized?
    	   0,                  // stride
    	   (void*)0            // array buffer offset
    	);
    	// 2nd attribute buffer : uvs
    	glEnableVertexAttribArray(1);
    	glBindBuffer(GL_ARRAY_BUFFER, uvbo2);
    	glVertexAttribPointer(
    	   1,                  // attribute 1. No particular reason for 1, but must match the layout in the shader.
    	   2,                  // size
    	   GL_FLOAT,           // type
    	   GL_FALSE,           // normalized?
    	   0,                  // stride
    	   (void*)0            // array buffer offset
    	);
    
     	glUniform1i(texID2, 0);
    	glActiveTexture(GL_TEXTURE0);
    	glBindTexture(GL_TEXTURE_2D, texture2);
    
    	glDrawArrays(GL_TRIANGLES, 0, 2*3);
    
    	glDisableVertexAttribArray(0);
    	glDisableVertexAttribArray(1);
    

    Beide Fragment-Shader sehen im endeffekt gleich aus (Aus Programmtechnischen gründen sind aber 2 verschiedene Shader notwendig. Das hier ist ein minimalbeispiel)

    #version 430 core
    
    in vec2 fragment_uv;
    uniform sampler2D s2D;
    
    void main() {
    	vec4 tmp = texture2D(s2D, fragment_uv);
    	tmp[1] = tmp[0];
    	tmp[2] = tmp[0];
    	tmp[3] = 1;
    
    	gl_FragColor = tmp;
    }
    

    Angezeigt wird mir allerdings nur die Textur im ersten Viewport, der zweite Viewport bleibt leider schwarz.

    Weiß da vllt jemand Rat?

    Alle Recherechen im Internet liefen im endeffekt darauf hinaus, dass ich die aktive Textur vorm Rendern Binden muss. Aber wenn ich mit nicht komplett irre mache ich das doch mit den Zeilen "glBindTexture(GL_TEXTURE_2D, texture2);" jeweils vor "glDrawArrays".

    Vielen Dank im Voraus für die Hilfe

    Lieben Gruß



  • JangoK schrieb:

    Angezeigt wird mir allerdings nur die Textur im ersten Viewport, der zweite Viewport bleibt leider schwarz.

    Liegt das Problem denn tatsächlich an der Textur? Wird "im zweiten Viewport" überhaupt etwas gerendert? Was, wenn du deinen Fragment Shader einfach mal Weiß ausgeben lässt? Siehst du dann, was du erwarten würdest? Wieso die Sache mit dem Scissor Rect?

    Kleiner Tipp aus langjähriger Erfahrung: Schwarz ist so ziemlich die schlechteste Clear Color, die man sich vorstellen kann, wenn man gerade ein Problem eingrenzen möchte. Alle möglichen Operationen (Texture Fetches z.B. 😉 ) liefern im Fehlerfall Schwarz. Am Ende wird man dann von einem schwarzen Viewport angeschwiegen. Wenn du stattdessen beispielsweise irgendeine beliebige, möglichst unspezielle Farbe nimmst, hast du zumindest schonmal die Chance, z.B. ein schwarzes Objekt vor dem Hintergrund zu sehen...



  • Heyho dot,

    danke für den Hinweis, leider kann ich alles ausschließen was nicht direkt mit den 2 Texturen zusammenhängt.
    Wenn ich die texture2 auf eine 3D-Textur mit der Tiefe 1 ändere, bekomme ich nämlich das gewünschte Ergebnis.

    Allerdings ist das ein ziemlich dreckiger workaround und führt zu Problemen sobald ich dann vllt mal ne 3te Textur brauchen sollte. Daher würd ichs gerne auf dem Weg lösen, der dafür vorgesehen ist ^^.

    Das mit dem Scissor kann ich dir grad ausm stehgreif nicht genau sagen warum das da hin muss, in den Tiefen tiefen meines Projektes gab es einen Befehl, der ohne nicht Funktioniert hat. Kann ihn aber leider gerade nicht betitteln ^^.

    Gruß


  • Mod

    wenn eine 2d und eine 3d textur funktioniert, aber zwei 2d nicht, klingt es als ob etwas mit der 2d textur nicht stimmt, falsch aufgesetzt? kannst du in einem viewport beide renderings sehen?

    scissor braucht man damit der clear nur den viewport loescht, sonst loescht clear den screen und nicht nur den viewport.

    ist scissor enabled? (seh ich nicht im code und default ist disabled).


Anmelden zum Antworten