You are not logged in.

  • Login

mutable

Unregistered

1

Tuesday, January 17th 2012, 3:08pm

glCopyTex(Sub)Image

Ich bin aktuell dabei, mir OpenGL beizubringen, aber ich weiß nicht weiter.
Mein Ziel ist es, einen Teilausschnitt einer Textur auf eine andere kopieren so das ich eine Subtextur der ersten haben, aber irgendwie funktioniert es nicht.
Ich probiere schon seit mehreren Tagen alles mögliche aus und habe auch das Netz bereits viele male durchsucht doch die Beispiele und Doku dazu ist mehr als dürftig.

Unten ist mein Code zu sehen, der "nicht ganz" funktioniert. Ich habe den Viewport korrekt eingestellt und alles weitere bedacht, aber irgendwie bekomme ich beim versuch es zu rendern immer keine Ausgabe.

Source code

1
 Texture my_sub_image(const Rect rect) {        assert(rect !is null);                /// Damit bleibt das gesamte Fenster weiß.        /*        glMatrixMode(GL_MODELVIEW_MATRIX);        glLoadIdentity();        */        glViewport(0, 0, rect.width, rect.height);                GLuint subId;        glGenTextures(1, &subId);         // Binden den Zieltextur        glBindTexture(GL_TEXTURE_2D, subId);                // Parameter der Zieltextur        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_REPEAT);        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);         //glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);         glTexImage2D(GL_TEXTURE_2D, 0, this._format, rect.width, rect.height, 0, this._format, GL_UNSIGNED_BYTE, null);                // Quelltextur binden        this.bind();         // Quelltextur zeichnen        glBegin(GL_QUADS);            // top left            glTexCoord2i(0, 0);            glVertex2f(0, 0);            // top right            glTexCoord2i(1, 0);            glVertex2f(rect.width, 0);            // bottom right            glTexCoord2i(1, 1);            glVertex2f(rect.width, rect.height);            // bottom left            glTexCoord2i(0, 1);            glVertex2f(0, rect.height);        glEnd();                // Zieltextur binden        glBindTexture(GL_TEXTURE_2D, subId);         // kopieren        glCopyTexSubImage2D(            GL_TEXTURE_2D,            0,            rect.get_x(), rect.get_x(), // x, y            0, 0,            rect.width, rect.height        );                glViewport(0, 0, 400, 400);         return new Texture(null, subId, this);    } 


Wenn ich diese Methode vor meiner Game Loop aufrufe und dann das besagte ergebnis anzeigen lassen will -> fail.
Rufe ich diesen Teil allerdings in jedem Frame auf sehe ich in der Tat ein Quadrat von der angegebenen Größe am rechten Rand in der Mitte. Es ist allerdings völlig schwarz.

Wenn ich weitere Bilder davor und/oder danach rendere sehe ich auf dem schwarzen Dreieck die rote Schrift der original Texturen. Es sieht praktisch aus wie ein Thumbnail. Die anderen Bilder und Texturen sind allerdings komplett schwarz und flimmern hin und wieder.

Ich hab dafür mal ein paar Bilder hochgeladen, dann sieht man sicher besser was ich meine:
Einmal wie es ohne den Versuch aussieht, also die Ausgangssituation: http://imageshack.us/photo/my-images/814/copyotherwise.png/
Einmal wie es mit dem Code oben, ohne andere Texture/Primitive zu rendern, aussieht: http://imageshack.us/photo/my-images/830…looprender.png/
Einmal wie es mit dem Code von oben mit dem rendern von anderen Texturen/Primitiven aussieht: http://imageshack.us/photo/my-images/69/…pmitrender.png/
Einmal, wenn ich den Code nicht (wie in den obigen 3 Situationen) _in_ der GameLoop aufrufe, sondern davor deklariere und dann in der GameLoop zeichnen möchte: http://imageshack.us/photo/my-images/405…opmitrende.png/
Einmal wenn ich die Quelltextur binde und dann _nur_ das Quad zeichne: http://imageshack.us/photo/my-images/141…yprimitive.png/
Und einmal wie es aussieht, wenn ich

Source code

1
 glMatrixMode(GL_MODELVIEW_MATRIX);glLoadIdentity(); 
verwenden: http://imageshack.us/photo/my-images/830…adidentity.png/

mutable

Unregistered

2

Wednesday, January 18th 2012, 6:33pm

Kein einziger auch nur den Hauch einer Idee? :/

mutable

Unregistered

3

Wednesday, January 18th 2012, 10:07pm

Da hier gar keine Antworten kamen und in zwei anderen niemand wusste, wieso das nicht geht bzw. nicht, wie es richtig geht, werde ich das Thema abschließen.

4

Wednesday, January 18th 2012, 11:45pm

Das du keine richtige Hilfe bekommst liegt vl. daran, dass dein Code beschi*** Formatiert ist und man den Zussamenhang nur schwer Überblickt.

Habs mal für dich Formatiert:

C/C++ Quellcode

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
Texture my_sub_image(const Rect rect) 
{        
	assert(rect !is null);
	/// Damit bleibt das gesamte Fenster weiß.        
	/*        
	glMatrixMode(GL_MODELVIEW_MATRIX);
	glLoadIdentity();
	*/        
	glViewport(0, 0, rect.width, rect.height);
	GLuint subId;
	glGenTextures(1, &subId);
	// Binden den Zieltextur        
	glBindTexture(GL_TEXTURE_2D, subId);
	// Parameter der Zieltextur        
	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_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	//glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
	glTexImage2D(GL_TEXTURE_2D, 0, this._format, rect.width, rect.height, 0, this._format, GL_UNSIGNED_BYTE, null);
	// Quelltextur binden        
	this.bind();
	// Quelltextur zeichnen        
	glBegin(GL_QUADS);
	// top left            
	glTexCoord2i(0, 0);
	glVertex2f(0, 0);
	// top right            
	glTexCoord2i(1, 0);
	glVertex2f(rect.width, 0);
	// bottom right            
	glTexCoord2i(1, 1);
	glVertex2f(rect.width, rect.height);
	// bottom left            
	glTexCoord2i(0, 1);
	glVertex2f(0, rect.height);
	glEnd();
	// Zieltextur binden        
	glBindTexture(GL_TEXTURE_2D, subId);
	// kopieren        
	glCopyTexSubImage2D(            GL_TEXTURE_2D,            0,            rect.get_x(), rect.get_x(), // x, y 
                                                          0, 0,            rect.width, rect.height        );
	glViewport(0, 0, 400, 400);
	return new Texture(null, subId, this);
}


Ohne weiteres kann ich dir jetzt zwar auch nicht genau sagen woran das liegt, aber für mich sieht es so aus als ob du die TextureIDs (Quelle <-> Ziel) vertauscht hast btw. oder gar falasche ID verwendest.

// Edit: glCopyTexSubImage2D setzt mal Parameter 3->rect.get_x() und 4->rect.get_x() auf 0, das gibt den (X,Y)-Offset in der Zieltexture an

Mfg Rushh0ur

This post has been edited 2 times, last edit by "Rushh0ur" (Jan 19th 2012, 12:29am)


mutable

Unregistered

5

Thursday, January 19th 2012, 1:15am

Das war ein versehen, ich meinte nicht "SubImage" sondern normales kopieren.
Dazu habe ich, dank nochmaligen Lesens eurer Tutorials, dieses Resultat erzielt:
http://imageshack.us/photo/my-images/27/wringcopy.png/

Es ist allerdings nicht gerade das gelbe vom Ei, denn dies ist das eigentliche Original Bild:
http://imageshack.us/photo/my-images/210/test2cf.png/
Weißt du/ihr was da noch schief läuft?

Hier der Code, diesmal als Link, damit ihr es formatiert seht, dank Chrome scheint es beim Posten des Codes immer zur zunichte machung der Code Formation zu kommen.

http://www.rswhite.de/code/index.php?q=3…3db5b33091f57b2

6

Thursday, January 19th 2012, 2:31pm

Hab mal ein Wenig rumporbiert:

Mit der Funktion glTexImage2D werden die Eigenschaften der Textur festgelegt,
wobei als letzter Parameter ein Speicherblock mit Rohdaten im angegebenen Format angegeben werden kann, daraus wird schliesslich dann eine Texture generiert
-> Nützlich um zB. Daten aus einer Datei Daten zu verarbeit. Für dein vorhaben sollte da NULL stehen (Die Texture wird mit einer Standartfarbe gefüllt).

Mit den Funktionen glCopyTexImage2D und glCopyTexSubImage2D kann der aktuelle Backbuffer auf die aktuell Selektierte Texture gerendert werden.
Damit das Kopieren erfolgreich ist müssen mehrere Kriterien gegben sein, genauers siehe verlinkte Seiten unter Fehlermeldungen, isbesondere sei hier erwähnt das der kopierende Abshcnitt kleiner gleich der Texturgröße sein muss.
Im Falle eines Fehlers wird kein Kopiervorgang durchgeführt und die Zieltexture weird nicht geändert. (Evtl. nach durchführung dieser Operationen den Fehlerstatus abfragen.)

Nun zum korekten Rendern auf den Backbuffer:
Zunächst muss der Viewport und die Projektionsmatrix korekt gesetzt werden und schlisslich eine Texture auf den Backbuffer gerendert werden.
Ist dies Erfolgreich geschehen kann ma sich zur vergewisserung mal das Bild auf dem Monitor ausgeben lassen und wenn dies korrekt ist auf eine Textur kopieren.

Beispiel:

C/C++ Quellcode

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
glGenTextures(1, &texture[0]);					// Create The first Texture
 
		// Typical Texture Generation Using Data From The Bitmap
		glBindTexture(GL_TEXTURE_2D, texture[0]);
		glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
 
 
 
		glGenTextures(1, &texture[1]);					// Create The second Texture (SubTexture from)
		glBindTexture(GL_TEXTURE_2D, texture[1]);
		glTexImage2D(GL_TEXTURE_2D, 0, 3, 245, 95, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL /*TextureImage[0]->data*/);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
 
		// Render 2D Scene
		glEnable(GL_TEXTURE_2D);
		glDisable(GL_DEPTH_TEST);
		glShadeModel(GL_FLAT);
 
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	
		glViewport(0, 0, 256, 256);
		glMatrixMode(GL_PROJECTION);				// Select The Projection Matrix
		glLoadIdentity();							// Reset The Projection Matrix
		glOrtho(0, 256, 0, 256, 1, -1);
		glMatrixMode(GL_MODELVIEW);					// Select The Modelview Matrix
		glLoadIdentity();							// Reset The Modelview Matrix
 
		glBindTexture(GL_TEXTURE_2D, texture[0]);	// Render first Texture to Backbuffer
		glBegin(GL_QUADS);
			glColor3f(1,1,1);
			glTexCoord2f(0, 1); glVertex2f(0, 0);
			glTexCoord2f(1, 1); glVertex2f(0 + 256, 0);
			glTexCoord2f(1, 0); glVertex2f(0 + 256, 0 + 256);
			glTexCoord2f(0, 0); glVertex2f(0, 0 + 256);
		glEnd();
		glEnable(GL_DEPTH_TEST);
 
		glBindTexture(GL_TEXTURE_2D, texture[1]);	// Selekt second Texture and Copy Backbuffer
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 5, 30, 245, 95);
		//glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, 245, 95, 0);


Links PreRendered Textur auf dem Back/Frontbuffer, Rechts nach kopieren eines Teilbereichs (inkl. eines 3D Würfels mit org. Texture)

Uploaded with ImageShack.us


So wie ich dass sehe scheint bei die korekte festleggung der Projektionsmatrix zu Fehlen.

Also mit glOrtho wird die Projektiosnmatrix auf 2D stellen.
Und mit gluPerspective wird die Projektionsmatrix auf 3D gestellt.

Mfg Rushh0ur

mutable

Unregistered

7

Thursday, January 19th 2012, 4:49pm

Wow jedenfalls hast du es schon einmal hinbekommen :) Ich bekomme aber, wenn ich versuche deinen Code zu übernehmen, jetzt gar kein sichtbares Ergebnis mehr, mein Fenster ist komplett weiß: http://www.rswhite.de/code/index.php?q=0…b0de8eaaa1cc886
Aber ich werde nochmal weitergucken.

mutable

Unregistered

8

Thursday, January 19th 2012, 4:50pm

Aber bevor ich es vergesse: Danke schon mal dafür, das macht Hoffnung. :)

mutable

Unregistered

9

Thursday, January 19th 2012, 5:10pm

Ah ich glaube ich habe einen meiner Fehler entdeckt. Ich habe vorher immer bei Aufrufen von "this.bind()" geprüft, ob die Texturt schon gebunden ist. Mit diesem Code
http://www.rswhite.de/code/index.php?q=0…79acf8eb5140b89 erhalte ich nun folgenden Output:
http://imageshack.us/photo/my-images/542/firstresultat.png/
Des Weiteren ist mir aufgefallen, dass bei meinem Code es keinerlei Unterschied macht ob ich jetzt

Source code

1
glCopyTexImage2D(GL_TEXTURE_2D, 0, this._format, 0, 0, w, h, 0);
oder

Source code

1
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, -25, 25, w, h);
verwende.

10

Thursday, January 19th 2012, 11:51pm

Es macht kein unterschied?
Dann wird die Funktion nciht ausgeührt.

Jetzt ganz langsam was willst du machen?
Willst du nun aus einer schon vorhanden Textur eine Teiltexture in eine zweite extrahieren oder willst du einfach nur eine Texture aus einem Bild laden?

Ja mit dem jetzigen Code machst du auch nix anderes als die Standart Texture zu rendern.

So sollte es Funktionieren, insofern du im Anschluss die Projektions- und Modelmatrix korekt setzs.

C/C++ Quellcode

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
Texture subimage(const Rect rect) 
{
	assert(rect !is null);						// Rechteck gülltig?
 
	GLuint SubTexture;
	glGenTextures(1, &SubTexture);				// Texture erstellen (1)
	glBindTexture(GL_TEXTURE_2D, SubTexture);	// Und Binden
 
	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, 3, rect.width, rect.height, 0, this._format, GL_UNSIGNED_BYTE, null);	// Texture Dimensionen festlegen (this._format == GL_RGB[A]?)
 
	// Backbuffer rendern
	glEnable(GL_TEXTURE_2D);
	glDisable(GL_DEPTH_TEST);
	glShadeModel(GL_FLAT);
 
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	
	glViewport(0, 0, rect.width, rect.height);
	glMatrixMode(GL_PROJECTION);				
	glLoadIdentity();							
	glOrtho(0, rect.width, 0, rect.height, 1, -1);
	glMatrixMode(GL_MODELVIEW);					
	glLoadIdentity();							
 
	//glBindTexture(GL_TEXTURE_2D, this.textureid());	
	this.bind();
	glBegin(GL_QUADS);
		glColor3f(1, 1, 1);
		glTexCoord2f(0, 1); glVertex2f(0, 0 + rect.height);
		glTexCoord2f(1, 1); glVertex2f(0 + rect.width, 0 + rect.height);
		glTexCoord2f(1, 0); glVertex2f(0 + rect.width, 0 );
		glTexCoord2f(0, 0); glVertex2f(0, 0);
	glEnd();
	glFlush();
 
	// Teilrechteck auf neue Texture kopieren
	glBindTexture(GL_TEXTURE_2D, SubTexture);	 
	glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, rect.get_x(), rect.get_y(), rect.width, rect.height);
 
	return new Texture(null, SubTexture, this);
}


Mfg Rushh0ur

mutable

Unregistered

11

Friday, January 20th 2012, 2:01am

Ich habe es schon mithilfe von deiner Vorarbeit und eines anderen Forums nun gelöst. Es gibt nur noch ein, zwei kleinere Probleme:
wenn ich nun das Subimage erstelle und versuche zu zeichnen klappt das. Versuche ich nun auch das Original Bild zu zeichnen, sehe ich nicht das Originalbild sondern quasi den Teil der skalierten Original Textur, den ich gerade "ausgeschnitten" habe: http://imageshack.us/photo/my-images/585/strangeg.png/
Dazu kommt noch, dass die Texturen nach wenigen Sekunden verschwinden und ich ein weißes Fenster habe, obwohl ich sie eig. in jedem Frame neu zeichne. Habe auch bereits die "bind" Methoden gelogt, die werden regelmäßig aufgerufen und binden die korrekten Texturen.


Hier aber erstmal der Code: http://www.rswhite.de/code/index.php?q=1…a40e468ab83db7d

mutable

Unregistered

12

Friday, January 20th 2012, 9:22pm

Source code

1
Texture sub_image(const Rect rect) {	assert(rect !is null);	assert(this._pixels !is null);		GLuint Screen;	glGenTextures(1, &Screen);		glBindTexture(GL_TEXTURE_2D, Screen);		// Daten in den Speicher, Lineares Filtering aktivieren	glTexImage2D(GL_TEXTURE_2D, 0, 4, rect.width, rect.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, null);	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);		//glClearColor(0.0, 0.0, 0.0,0);	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);		glBindTexture(GL_TEXTURE_2D, Screen);		this.bind_anyway();		const ushort vp_w = Texture._window_width;	const ushort vp_h = Texture._window_height;		const float percent_x = cast(float)(vp_w) / this._width;	const float percent_y = cast(float)(vp_h) / this._height;		//glViewport(0, 0, vp_w, vp_h);		glBegin(GL_QUADS);		// top left		glTexCoord2f(0, 0);		glVertex2f(0, 0);		// top right		glTexCoord2f(1, 0);		glVertex2f(vp_w, 0);		// bottom right		glTexCoord2f(1, 1);		glVertex2f(vp_w, vp_h);		// bottom left		glTexCoord2f(0, 1);		glVertex2f(0, vp_h);	glEnd();		//glViewport(0, 0, this._width, this._height);		glBindTexture(GL_TEXTURE_2D, Screen);		glCopyTexImage2D(		GL_TEXTURE_2D, 		0, 		this._format,		cast(uint)(rect.get_x() * percent_x), cast(uint)(rect.get_y() * percent_y),		//rect.x, rect.y,		rect.width, rect.height,		0	);	/+	// Zeichnen der Sub Textur		glBindTexture(GL_TEXTURE_2D, Screen);	/*	const float tx = 300;	const float ty = 100;	*/	glBegin(GL_QUADS);		// top left		glTexCoord2f(0, 0);		glVertex2f(0, 0);		// top right		glTexCoord2f(1, 0);		glVertex2f(rect.width, 0);		// bottom right		glTexCoord2f(1, 1);		glVertex2f(rect.width, rect.height);		// bottom left		glTexCoord2f(0, 1);		glVertex2f(0, rect.height);	glEnd();		glDeleteTextures(1, &Screen);	+/	// Löschen des Color-Buffers. Deaktiviert sieht man eine weitere Textur unten.	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);		return new Texture(rect, Screen, this);	//return null;}

Das funktioniert schon fast, ich erhalte die korrekte Sub Textur. Nur wenn ich das Originalbild auch nochmals blitten möchte, kommt so etwas: http://imageshack.us/photo/my-images/18/doublestrange.png/
Lässt sich das umgehen?

mutable

Unregistered

13

Friday, January 20th 2012, 9:23pm

Das alte Leid von Chrome...
Hier formatiert: http://www.rswhite.de/code/index.php?q=8…401b69f9a2ceefe

Similar threads

Social bookmarks