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

flux

Treue Seele

  • »flux« ist der Autor dieses Themas
  • Private Nachricht senden

1

20.04.2010, 15:20

OpenGL Hintergrundbild zeichnen

Hallo Zusammen.

Ich habe folgendes Problem:
Ich möchte gerne in meinem OpenGL Fenster ein Hintergrundbild zeichnen.
Das Fenster ist 800 x 600 groß und das Bild 320 x 240.

Die Einstellungen von OpenGL sind:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
glViewport(0, 0, width, height);

    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity();

    float zNear = 1.0f;
    float aspect = (float)width / (float) height;
    float fov = 60.0f;
    float deg2rad = 0.01745329f;
    float tanFOV = tan((fov * 0.5f) * deg2rad);

    GLdouble top = zNear * tanFOV;
    GLdouble bottom = -top;

    GLdouble left = aspect * bottom;
    GLdouble right = aspect * top;
    glFrustum(left, right, bottom, top, zNear, zFar);// zFar ist an anderer Stelle auf 200 gesetzt worden

Das Zeichnen des Hintergrundes sieht im Moment so aus:

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
glDisable(GL_DEPTH_TEST);

    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 

    bindIplImageAsTexture(image);
    
    glTranslatef(-4.0,-3.0,-5);
    
    glBegin(GL_QUADS);
        glNormal3f(0, 0, 1);

        glTexCoord2f(0.0f, 1.0f);
        glVertex3f(0.0f,  0.0f, 0);
            
        glTexCoord2f(1.0f, 1.0f);
        glVertex3f(8.0f,  0.0f, 0); 
            
        glTexCoord2f(1.0f, 0.0f);
        glVertex3f(8.0f, 6.0f, 0);
            
        glTexCoord2f(0.0f, 0.0f);
        glVertex3f(0.0f, 6.0f, 0);
    glEnd();
        
    glEnable(GL_DEPTH_TEST);

Das Bild füllt nicht das gesamte Fenster aus, sondern entweder ist es zu klein oder zu groß. Also je nachdem wie weit ich es nach hinten schiebe. Aber das kann ja nicht die Lösung sein, so lange herum zu probieren, bis es genau passt.

Könnt ihr mir helfen und mir sagen, wie ich die richtige Position berechnen kann oder wie ihr es anders lösen würdet?

Ich hoffe ihr könnt mir helfen ;)

Alyx

Treue Seele

Beiträge: 236

Wohnort: Hannover

Beruf: Head Of Software Development

  • Private Nachricht senden

2

20.04.2010, 15:37

Das geht via glOrtho, Quelltext folgt...

Alyx

Treue Seele

Beiträge: 236

Wohnort: Hannover

Beruf: Head Of Software Development

  • Private Nachricht senden

3

20.04.2010, 15:46

Matrix selbst berechnen:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    void CalculateOrtho(ftype NearClip, ftype FarClip, ftype Left, ftype Right, ftype Top, ftype Bottom)
    {
        memset(this,0,sizeof(*this));

        ftype   wd      = (Right-Left),
                hd      = (Top-Bottom),
                diff    = FarClip-NearClip;

        this->mf00 = 2/wd;
        this->mf11 = 2/hd;
        this->mf30 = -(Right+Left)/wd;
        this->mf31 = -(Top+Bottom)/hd;
        this->mf22 = -1/diff*2;
        this->mf32 = -(FarClip+NearClip)/diff;
        this->mf33 = 1.0;   
    }

...

        mlpCurScreen->mmfProjection.CalculateOrtho(-100,100,miX,miX+miWidth,miY,miY+miHeight);


wobei X und Y in deinem Fall 0 sein muessten und Width und Height die horizontale und vertikale Bildaufloesung sind. Damit kannst du dann ganz normal mit 2D-Koordinaten zeichnen. Um dann im 3D-Modus weiter zu zeichnen, einfach die Frustum-Matrize laden bzw. glLoadIdentity -> glFrustum aufrufen wie gehabt (im Projection-Matrix-Mode versteht sich). Ausserdem in dem Fall nicht vergessen nach dem 2D-Part entweder den Z-Buffer zu clearn oder noch besser gleich vor dem Zeichnen des Hintergrundes die DepthMask aus zu schalten und anschliessend wieder an.

glOrtho (anstelle von glFrustum):

procedure glOrtho(left, right, bottom, top, znear, zfar : double); http://wiki.delphigl.com/index.php/glOrtho

(also z. Bsp. glOrtho(0.0,800.0,0.0,600.0,-100.0,+100.0);

LG
Alyx

Alyx

Treue Seele

Beiträge: 236

Wohnort: Hannover

Beruf: Head Of Software Development

  • Private Nachricht senden

4

20.04.2010, 15:51

p.s. Wenn dein Fenster 800x600 Pixel gross ist, hast du natuerlich keinen 800x600 grossen Zeichenbereich, sofern es irgendeinen Rand hat.

...
if( Message==WM_SIZE )
{
...
ow->miClientWidth = LParam&0xFFFF;
ow->miClientHeight = LParam>>16;
}
...

das sind in dem Fall die Werte ,die du brauchst.

LG
Alyx

flux

Treue Seele

  • »flux« ist der Autor dieses Themas
  • Private Nachricht senden

5

20.04.2010, 16:04

Ok, Danke ;) . Habs dann mit glOrtho gemacht.
Jetzt passt's :)

Der Anzeigebereich ist 800 x 600.

Das ganze sieht dann jetzt so aus:

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
void Projection::drawBackground(const IplImage *image){
    glDisable(GL_DEPTH_TEST);

    switchToOrtho();

    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 

    bindIplImageAsTexture(image);
        
    glBegin(GL_QUADS);
        glNormal3f(0, 0, 1);

        glTexCoord2f(0.0f, 1.0f);
        glVertex3f(0.0f,  0.0f, -1.0f);
            
        glTexCoord2f(1.0f, 1.0f);
        glVertex3f(800.0f,  0.0f, -1.0f); 
            
        glTexCoord2f(1.0f, 0.0f);
        glVertex3f(800.0f, 600.0f, -1.0f);
            
        glTexCoord2f(0.0f, 0.0f);
        glVertex3f(0.0f, 600.0f, -1.0f);
    glEnd();
        
    switchToFrustum();
    
    glEnable(GL_DEPTH_TEST);
}

void Projection::switchToOrtho(){
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity();

    glOrtho(0, width, 0, height, zNear, zFar);
}

void Projection::switchToFrustum(){
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity();

    glFrustum(left, right, bottom, top, zNear, zFar);
}

Alyx

Treue Seele

Beiträge: 236

Wohnort: Hannover

Beruf: Head Of Software Development

  • Private Nachricht senden

6

20.04.2010, 16:17

Vorbidlich sauberer Code :-). Wie gesagt "glDepthMask(GL_FALSE);" noch vor und mit GL_TRUE nach dem 2D-Zeichnen, damit du dir den Z-Buffer nicht zumuellst und dir den deutlich teureren Clear sparst ;-).

LG
Alyx

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

7

20.04.2010, 16:21

Oder auflösungsunabhängig:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
    
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();

glBegin(GL_QUADS);
glVertex3i(-1, -1, -1);
glVertex3i( 1, -1, -1);
glVertex3i( 1,  1, -1);
glVertex3i(-1,  1, -1);
glEnd();

glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
@D13_Dreinig

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »David_pb« (20.04.2010, 16:42)


flux

Treue Seele

  • »flux« ist der Autor dieses Themas
  • Private Nachricht senden

8

20.04.2010, 18:42

Hab das glDepthMask noch eingebaut.

@David_pb: Danke, damit brauch ich dann ja jetzt auch nicht mehr jedes mal die Perspektive ändern.

Hab mich noch nicht wirklich mit OpenGL beschäftigt, aber langsam macht's mir Spaß. Mal sehen... könnte mich ja auch mal an ein kleines Spielchen wagen.

Alyx

Treue Seele

Beiträge: 236

Wohnort: Hannover

Beruf: Head Of Software Development

  • Private Nachricht senden

9

20.04.2010, 21:52

Mit OpenGL bist du derzeit auf jeden Fall auf der richtigen Seite und ich denke ein kleines Spielchen zu bauen und dran zu pfeilen ist der beste Weg es zu lernen :-).

LG
Alyx

ArthurII

Treue Seele

Beiträge: 132

Wohnort: Aachen

Beruf: Student

  • Private Nachricht senden

10

21.04.2010, 16:21

wieso funzt denn jetzt der weg von david_pb auch?? da komm ich irgendwie nicht mit...

ist der punkt (1 | 1 | -1) immer in der "Ecke" meines Blickfeldes?? oder kommt das aus dem glMatrixMode(GL_PROJECTION) ??

verändere ich über die angabe von glVertex die projectionsmatrix??
Ich bin nicht verrückt - nur verhaltensoriginell!
Project-Seite: Aura

Werbeanzeige