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

Architekt

Community-Fossil

  • »Architekt« ist der Autor dieses Themas

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

1

19.01.2012, 11:55

Probleme mit glCopyTexImage

Hey ho.
Ich habe derzeit ein Problem mit glCopyTexImage. Ich bin relativ neu in OpenGL und nachdem Lesen einiger Tutorials wollte ich auch direkt mal einen Teilausschnitt aus einer meiner Texturen holen, aber irgendwie funktioniert mein Code nicht "optimal", denn ich erhalte diesen Output http://imageshack.us/photo/my-images/27/wringcopy.png/ wobei das Original Bild so aussieht: http://imageshack.us/photo/my-images/210/test2cf.png/.
Ich habe mich dabei primär auf dieses und dieses Tutorial gestützt.

Mein verwendeter Code ist folgender (ich verwende jetzt einfach mal C# CodeTags. Eigentlich handelt es sich um die Sprache D, aber das ist insofern ja irrelevant):

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
Texture subimage() {
    assert(this._pixels !is null);
    
    const ushort w = 80;
    const ushort h = 80;
    
    void * memory = GC.malloc(w * h * 3);
    
    GLuint Screen;
    glGenTextures(1, &Screen);
    glBindTexture(GL_TEXTURE_2D, Screen);
    
    // Daten in den Speicher, Lineares Filtering aktivieren
        glTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, this._pixels);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    
    GC.free(memory);
    
    glClearColor(0.0, 0.0, 0.0,0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    glViewport(0, 0, w, h);
    glBindTexture(GL_TEXTURE_2D, Screen);
    
    this.bind();
    
    glBegin(GL_QUADS);
        // top left
        glTexCoord2i(0, 0);
        glVertex2f(0, 0);
        // top right
        glTexCoord2i(0, 1);
        glVertex2f(w, 0);
        // bottom right
        glTexCoord2i(1, 1);
        glVertex2f(w, h);
        // bottom left
        glTexCoord2i(1, 0);
        glVertex2f(0, h);
    glEnd();
    
    glBindTexture(GL_TEXTURE_2D, Screen);
    glCopyTexImage2D(GL_TEXTURE_2D, 0, this._format, 0, 0, w, h, 0);
    
    // Löschen des Color-Buffers. Deaktiviert sieht man eine weitere Textur unten.
    glClearColor(1.0, 1.0, 1.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    glViewport(0, 0, 400, 400);

    glBindTexture(GL_TEXTURE_2D, Screen);
    
    const ubyte d = 5;
    
    glBegin(GL_QUADS);
        // top left
        glTexCoord2i(0, 0);
        glVertex2f(d, d);
        // top right
        glTexCoord2i(0, 1);
        glVertex2f(w + d, d);
        // bottom right
        glTexCoord2i(1, 1);
        glVertex2f(w + d, h + d);
        // bottom left
        glTexCoord2i(1, 0);
        glVertex2f(d, h + d);
    glEnd();
    
    //glDeleteTextures(1, &Screen);
    
    //return new Texture(null, Screen, this);
    return null;
}


Verwende ich den Code so, sehe ich mein oben geposteten Output. Ändere ich Zeile 14 von

Quellcode

1
glTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, this._pixels);
in

Quellcode

1
glTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, memory);
erhalte ich lediglich ein schwarzes Quadrat in der Größe des Original Bildes. Sprich meinen Output ohne den eigentlichen Output des bunten Teilausschnittes.
Ich weiß die Frage mag für manche sehr noobig klingen und ich habe zuvor auch viel im Internet recherchiert, aber irgendwie habe ich bislang keine Lösung gefunden.
Was noch erwähnt werden sollte: ich rufe diese Methode _in_ der main Loop auf. Mein anfänglicher Plan, sie (wie man es sich auch denken würde) vorher aufzurufen und das neue Textur Objekt dann in der Mainloop zu rendern, misslingt, da ich keinerlei (sichtbare) Ausgabe bekomme.

edit: Falls gebraucht, habe ich auch mal meine Textur Lade Methode(n) hochgeladen. Sie sind hier zu finden: http://www.rswhite.de/code/index.php?q=1…ef067b66207eb03
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Architekt« (19.01.2012, 12:00)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

2

19.01.2012, 12:18

Das sieht nach 2 Problemen aus:
1) scheint die Textur in den Zeilen verschoben zu sein, das passiert üblicher Weise, wenn man sie falsch lädt (Speicher-"Breite" stimmt nicht mit Anzahl Daten pro Zeile überein - manche Formate haben mehr Pixel als das Bild laut Header breit ist - wegen Padding)). Wie sieht denn der Output nach dem ersten Rendering aus? Stimmt der überhaupt?

2) Das Kopieren erfolgt von anderen Textur-Koordinaten, als Du es scheinbar erwartest, womit dann der Großteil Schwarz bleibt wie Dein Bildschirm ebenfalls. OpenGL arbeitet "auf dem Kopf" (der Nullpunkt bei Texturen ist unten links, nicht oben links), daran könnte es eventuell liegen. Den Code hab' ich nur grob überflogen und komme mit den Koordinaten selbst oft durcheinander, daher hier keine Garantie.
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]

Architekt

Community-Fossil

  • »Architekt« ist der Autor dieses Themas

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

3

19.01.2012, 12:29

Zitat

Wie sieht denn der Output nach dem ersten Rendering aus? Stimmt der überhaupt?

Ich mache nur das Rendering von Szene zur Textur, nichts weiter. Und das Resultat siehst du ja da oben. Oder missverstehe ich dich?

Wie sehen denn die Koordinaten dann aus? Etwa umgekehrt zu denen, mit denen ich die Original Textur vor dem kopieren zeichne?
Also hier zeichne ich ja die Original Textur:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
glBegin(GL_QUADS);
    // top left
    glTexCoord2i(0, 0);
    glVertex2f(0, 0);
    // top right
    glTexCoord2i(0, 1);
    glVertex2f(w, 0);
    // bottom right
    glTexCoord2i(1, 1);
    glVertex2f(w, h);
    // bottom left
    glTexCoord2i(1, 0);
    glVertex2f(0, h);
glEnd();


Inwiefern drehe ich das jetzt um?
Ganz simpel, indem ich die Koordinaten von unten nach oben packe, also so:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
glBegin(GL_QUADS);
    // bottom left
    glTexCoord2i(1, 0);
    glVertex2f(0, h);
    // bottom right
    glTexCoord2i(1, 1);
    glVertex2f(w, h);
    // top right
    glTexCoord2i(0, 1);
    glVertex2f(w, 0);
    // top left
    glTexCoord2i(0, 0);
    glVertex2f(0, 0);
glEnd();
?
Werde es mal ausprobieren.

Zitat

scheint die Textur in den Zeilen verschoben zu sein, das passiert üblicher Weise, wenn man sie falsch lädt (Speicher-"Breite" stimmt nicht mit Anzahl Daten pro Zeile überein - manche Formate haben mehr Pixel als das Bild laut Header breit ist - wegen Padding)).

Ich verwende .png. Sollte ich mal .jpeg, .tgs oder gar .bmp ausprobieren?
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

4

19.01.2012, 12:39

Zitat

Wie sieht denn der Output nach dem ersten Rendering aus? Stimmt der überhaupt?

Ich mache nur das Rendering von Szene zur Textur, nichts weiter. Und das Resultat siehst du ja da oben. Oder missverstehe ich dich?

Ja, eventuell. Du hast doch zwei Renderings. Einmal rendest Du die Textur, dann kopierst Du das Ergebnis und danach rendest Du das. Lass mal das Kopieren und zweite Rendering weg. Wird dann die Textur korrekt gerendert oder ist die auch schon so "lustig verschoben"? Das vermute ich nämlich sehr stark. Das kann eventuell auch mit der Speicher-Organisation von D zusammenhängen, weiß ich nicht genau, es sieht aber definitiv aus als wäre das Bild mit einer falschen Breite geladen worden oder der Speicher-Bereich hatte Padding, welches Du nicht beachtet hast.

Wie sehen denn die Koordinaten dann aus? Etwa umgekehrt zu denen, mit denen ich die Original Textur vor dem kopieren zeichne?
(...)
Inwiefern drehe ich das jetzt um?
Ganz simpel, indem ich die Koordinaten von unten nach oben packe, also so (...)?

Das ist der Punkt, wo ich selbst immer durcheinander komme. Jedenfalls vermute ich, dass Du eben nicht den Teil kopierst, den Du glaubst (nämlich den Viewport 0/0 bis 80/80, sondern den Backbuffer zwischen height-80/0 bis height/80). Ich kann mich hier irren, aber solchen Quark hatte ich auch mal vor Urzeiten, weil ich falsche Vermutungen über die Koordinaten gemacht habe und hatte dann eben nicht den Ausschnitt von oben links, sondern den von unten links oder sogar unten rechts - frag mich nicht, is schon lange her.
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]

Architekt

Community-Fossil

  • »Architekt« ist der Autor dieses Themas

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

5

19.01.2012, 12:46

Ay ay ay. Mit diesem Code

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
Texture subimage() {
    assert(this._pixels !is null);
    
    const ushort w = 80;
    const ushort h = 80;
    
    void * memory = GC.malloc(w * h * 3);
    
    GLuint Screen;
    glGenTextures(1, &Screen);
    glBindTexture(GL_TEXTURE_2D, Screen);
    
    // Daten in den Speicher, Lineares Filtering aktivieren
    glTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, this._pixels);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    
    GC.free(memory);
    
    //glClearColor(0.0, 0.0, 0.0,0);
    //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    //glViewport(0, 0, w, h);
    //glBindTexture(GL_TEXTURE_2D, Screen);
    
    this.bind();
    
    glBegin(GL_QUADS);
        // top left
        glTexCoord2i(0, 0);
        glVertex2f(0, 0);
        // top right
        glTexCoord2i(0, 1);
        glVertex2f(w, 0);
        // bottom right
        glTexCoord2i(1, 1);
        glVertex2f(w, h);
        // bottom left
        glTexCoord2i(1, 0);
        glVertex2f(0, h);
    glEnd();
    /*
    glBindTexture(GL_TEXTURE_2D, Screen);
    glCopyTexImage2D(GL_TEXTURE_2D, 0, this._format, 0, 0, w, h, 0);
    
    // Löschen des Color-Buffers. Deaktiviert sieht man eine weitere Textur unten.
    glClearColor(1.0, 1.0, 1.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    glViewport(0, 0, 400, 400);

    glBindTexture(GL_TEXTURE_2D, Screen);
    
    const ubyte d = 5;
    
    glBegin(GL_QUADS);
        // top left
        glTexCoord2i(0, 0);
        glVertex2f(d, d);
        // top right
        glTexCoord2i(0, 1);
        glVertex2f(w + d, d);
        // bottom right
        glTexCoord2i(1, 1);
        glVertex2f(w + d, h + d);
        // bottom left
        glTexCoord2i(1, 0);
        glVertex2f(d, h + d);
    glEnd();
    */
    glDeleteTextures(1, &Screen);
    
    //return new Texture(null, Screen, this);
    return null;
}


erhalte ich nun dieses Ergebnis:
http://imageshack.us/photo/my-images/854/verzerrtesbild.png/

Scheint als hättest du recht. Dem werd ich mich erst mal annehmen.

edit:
Allerdings mit diesem Code http://www.rswhite.de/code/index.php?q=6…bea998b5d50ab14 (hab es mal ausgelagert, wir brauchen hier echt Spoiler Tags).
bekomme ich dieses Bild zusehen: http://imageshack.us/photo/my-images/856/korrektesbild.png/. Also korrektes Bliting.
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

19.01.2012, 12:59

Bei dem zweiten ist doch alles auskommentiert zwischen /* und */, wie kommt da überhaupt was raus? Bzw. wo wird da "this" geladen und in eine Textur kopiert? Mach in das zweite mal noch ein Clear, ich kann nicht glauben, dass das die Ausgabe sein soll, außer Du lädst das Bild tatsächlich außerhalb und verpfuschst die mit dem ersten Code hier aus dem Topic irgendwie (in den auskommentierten Bereichen).

Edit:
Ist das hier eventuell gar keine Absicht?
glTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, this._pixels);
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]

Architekt

Community-Fossil

  • »Architekt« ist der Autor dieses Themas

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

7

19.01.2012, 13:04

Das ist ja eine Klasse und das Original Bild intern längst geladen, deswegen hatte ich auch die Lade Methoden per edit in meinen Startpost ergänzt. Habe ich aber vergessen zu erwähnen, sry.
Also das Original Bild ist in der Klasse bereits geladen und ich kann es binden und normal zeichnen, das funktioniert ohne Probleme.
Binde und zeichne ich es aber, nachdem ich bereits die Textur, die später den Teil Ausschnitt beinhalten soll, generiert und gebunden habe, sowie den Viewport angepasst habe, dann kommt murks raus, wie man bei meinem ersten Teil meines letzten Posts sieht. Oder noch etwas unklar?
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

8

19.01.2012, 13:05

Siehe Edit. Du bindest die Textur nicht nur, du weißt ihr auch neuen Inhalt zu? Und wozu das "GC.malloc" und "delete", wenn Du den Speicher gar nicht benutzt? :hmm: Außerdem allozierst du h*w*3, gibst aber bei glTexImage2D an, dass jedes Pixel 4 Byte groß ist (auch wenn Du den Speicher da gar nicht übergibst, es hat aber Bug-Potential). Da kann natürlich nur Murks rauskommen, denn das "this._pixels" ist ja nicht nur 80x80, oder doch?
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]

Architekt

Community-Fossil

  • »Architekt« ist der Autor dieses Themas

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

9

19.01.2012, 13:09

Siehe Edit. Du bindest die Textur nicht nur, du weißt ihr auch neuen Inhalt zu - wozu? Und wozu das "GC.malloc" und "delete", wenn Du den Speicher gar nicht benutzt? :hmm:

Ich bin ein ziemlich Neuling in GL daher entschuldige die Frage: inwiefern weise ich ihr neuen Inhalt zu? Und inwiefern ließe sich das umgehen, also meine falsche Handhabung korrigieren?

Da D eine Garbage Collector basierende Sprache ist muss ich eben diesen benutzen, um Speicher anzufordern den ich verwalte. Aber wenn ich diesen Speicher benutze (Siehe Startpost, ganz unten) erhalte ich nur ein schwarzes Quadrat in den Ausmaßen der Original Textur.

edit: Ja du hast recht, es müsste * 4 heißen. Hatte ich auch schon probiert aber das fehlen jeglichen Inhalts blieb gleich. Das "this._pixels" sind die Pixeldaten der Originaltextur, welche 128x128 Px groß ist.
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

10

19.01.2012, 13:10

Ich denke Dein Problem ist das hier:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
void * memory = GC.malloc(w * h * 3);
 
GLuint Screen;
glGenTextures(1, &Screen);
glBindTexture(GL_TEXTURE_2D, Screen);
 
// Daten in den Speicher, Lineares Filtering aktivieren
glTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, this._pixels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 
GC.free(memory);


Das sollte so heißen:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
void * memory = GC.malloc(w * h * 4);
 
GLuint Screen;
glGenTextures(1, &Screen);
glBindTexture(GL_TEXTURE_2D, Screen);
 
// Daten in den Speicher, Lineares Filtering aktivieren
glTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, memory);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 
GC.free(memory);
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]

Werbeanzeige