mehrere OpenGL Fenster welche die selben Texturen verwenden
-
Hallo
ich habe mir gestern eine Klasse zum schnellen Erstellen von OpenGL-Fenster geschrieben und dazu einen Texture-Loader. In MAIN.CPP erstelle ich 3 OpenGL-Fenster. In jedem der Fenster soll sich ein rotierenden Viereck befinden. Jedes Viereck soll die gleiche Texture verwenden ohne das ich diese mehrmals Laden muss.
Problem: nur in einem Fenster wird die Textur angezeigt, Window 3 (blau). Ist es nicht möglich eine Textur einmal zu laden und für mehrere Fenster zu verwenden?
MAIN.CPP
#include <windows.h> #include "glwindow.h" // OpenGL Window Class #include "gltextures.h" // Klasse zum S3TC-aktiveren, Laden, Entladen von Texturen in BLP2-Format Cgltextures texture; void DrawGLScene(float R, float G, float B) // Here's Where We Do All The Drawing { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer glLoadIdentity(); // Reset The View glTranslatef(0.0f,0.0f,-3.0f); // Move Into The Screen 6.0 glRotatef(GetTickCount()*0.1f,0.0f,1.0f,0.0f); glColor3f(R,G,B); //glColor3f(1.0f,1.0f,1.0f); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texture.blp2[0]); // Select Our Texture glBegin(GL_QUADS); // Draw A Quad glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 0.0f); // Bottom Left Of The Texture glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 0.0f); // Bottom Right Of The Texture glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 0.0f); // Top Right Of The Texture glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 0.0f); // Top Left Of The Texture glEnd(); // Done Drawing The Quad } int WINAPI WinMain( HINSTANCE hInstance, // Instance HINSTANCE hPrevInstance, // Previous Instance LPSTR lpCmdLine, // Command Line Parameters int nCmdShow) // Window Show State { Cglwindow wnd1,wnd2,wnd3; // Erstelle OpenGL Window 1+2+3 wnd1.CreateGLwindow(200, 200); if (!texture.EnableS3TC()) // enable S3TC texture compression, atleast one GL-RC must exist for this to work return false; //if (!texture.LoadBLP2Disk("font.blp")) // Comment entfernen und wnd1 ist texturiert // return false; wnd2.CreateGLwindow(150, 150); //if (!texture.LoadBLP2Disk("font.blp")) // Comment entfernen und wnd2 ist texturiert // return false; wnd3.CreateGLwindow(100, 100); if (!texture.LoadBLP2Disk("font.blp")) return false; while(!wnd1.done && !wnd2.done && !wnd3.done) { wnd1.Update(); DrawGLScene(1.0f,0.0f,0.0f); // Red wnd2.Update(); DrawGLScene(0.0f,1.0f,0.0f); // Green wnd3.Update(); DrawGLScene(0.0f,0.0f,1.0f); // Blue } return 0; }
GLTEXTURES.H:
...gelöscht - unrelevantGLTEXTURES.CPP:
...gelöscht - unrelevant
-
cuppuccinofreak schrieb:
Ist es nicht möglich eine Textur einmal zu laden und für mehrere Fenster zu verwenden?
texturen werden pro context angebunden, ein ogl context wird pro fenster erstellt...
bei primitiven fensteranordnungen kannst du statt den fenster einfach mit opengl in die geweiligen stellen in einem fenster rendern, z.b. die typische 4quadranten ansicht (glViewPort ist dann dein freund).
es gibt wohl auch ein paar extension um die texturen zwischen mehreren context zu sharen, wenn du die such hier benutzt koenntest du nen thread dazu finden.
alternativ kannst du immer in eine textur rendern und dann mit glreadpixel usw. die pixel rauskopieren und ins gewuenschte fenster schieben (mit den funktionen die dein OS bietet).
-
texturen werden pro context angebunden, ein ogl context wird pro fenster erstellt...
Mist, sowas in der Art hatte ich vermutet. Zum Glück habe ich dank deinem Hinweis eine Lösung gefunden: wglShareLists();
http://www.opengl.org/resources/faq/technical/texture.htm
Siehe: 16.020 How can I share display lists between different contexts?In meinem Testcode funktioniert es so:
wnd1.CreateGLwindow(200, 200); wnd2.CreateGLwindow(150, 150); wnd3.CreateGLwindow(100, 100); if (!texture.EnableS3TC()) // enable S3TC texture compression return false; if (!texture.LoadBLP2Disk("font.blp")) // Load Textures for wnd3.hrc return false; wglShareLists(wnd3.hrc, wnd2.hrc); // share wnd3.hrc -> wnd2.hrc wglShareLists(wnd2.hrc, wnd1.hrc); // share wnd2.hrc -> wnd1.hrc
Eine Frage hätte ich dazu noch:
Ich werde später ca. 70 Texturen statisch laden, sprich beim Programmstart. Während das Programm läuft muss ich bis zu 1200 weitere Texturen dynamisch laden. Wenn ich MSDN richtig verstehe reicht es aus wglShareLists nur einmal aufzurufen. Auch wenn sich die Displaylist ändert (wenn neue Texturen geladen oder alte gelöscht werden) müssten jedem Fenster die gleichen Texturen zur Verfügung stehen. (weil sie ja 'shared' sind) korrekt?MSDN:
...Once a rendering context shares a display-list space, the rendering context always uses the display-list space until the rendering context is deleted. When the last rendering context of a shared display-list space is deleted, the shared display-list space is deleted. ...
-
da steht, dass eine list solange existiert wie der am laengsten lebende context. soll also heissen, dass du einen context loeschen/freigeben kannst und die anderen trotzdem noch auf die list zugreifen koennen.
du musst dich also nicht drum sorgen dass sie eventuel verschwindet.wenn du die list selber loescht/freigibst, ist sie natuerlich fuer alle context weg.
-
perfekt! Genau das was ich brauche. Danke dir rapso. Habe es auch gerade durchgetestet und alles funtioniert so wie es soll.