Du bist nicht angemeldet.

Werbeanzeige

BlueCobold

Community-Fossil

Beiträge: 10 859

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

21

01.10.2014, 12:09

Ich meinte natürlich Orthographische Projektion
Eine Parallelprojektion ist eine orthographische Projektion und auch eine orthogonale. Das ist alles dasselbe. Die Projektion allein hilft Dir dabei nicht mit dem Problem der verzerrten Seitenverhältnisse, sondern nur ein Faktor, der diese Verhältnisse beinhaltet. Den hast Du scheinbar im Zuge der Projektion ordentlich mit verbaut, aber das Verständnis fehlt scheinbar noch etwas für das, was Du (?) da gebaut hast.
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]

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »BlueCobold« (01.10.2014, 12:15)


stef

Treue Seele

  • »stef« ist der Autor dieses Themas

Beiträge: 241

Wohnort: Kassel

Beruf: Softwareentwickler

  • Private Nachricht senden

22

01.10.2014, 13:22

Dann sag mal wo der Faktor bei mir steckt ...

Hier meine PM mit nWidth=1920 und g_nHight=1080:

C-/C++-Quelltext

1
Shader_Sprite.SetUniform_ProjectionMatrix(CMatrix44::Build_OrthographicProjectionMatrix(-g_nWidth/2.0f, g_nWidth/2.0f, -g_nHight/2.0f, g_nHight/2.0f, 0.0f, 1.0f));


Hier die Funktion welche anhand der Texture Breite und Höhe (in Pixeln) das Rechteck bestehend aus zwei Dreiecken berechnet:
(Die Funktion soll einen Sprite bestehend aus einer Textur in Originalgröße an einer bestimmten Position darstellen (nCenterPosX, nCenterPosY). Optional kann man noch Scalieren und Drehen)

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
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
void CSprite::Draw(int nCenterPosX, int nCenterPosY, float fScaleX, float fScaleY, float fAngle)
{
    CMatrix33 m33Scale;
    CMatrix33 m33Rot;
    CMatrix33 m33Trans;
    CVector2 Vertex[6];
    CVector2 Texture[6];
    CVector3 v3Temp;
    int i;
    float fX1;
    float fX2;
    float fY1;
    float fY2;

    // use texture width and hights to calculate coordinates
    fX1 = (float)((CTexture_2D*)GetTexture2D())->m_nWidth/-2.0f;
    fX2 = (float)((CTexture_2D*)GetTexture2D())->m_nWidth/2.0f;
    fY1 = (float)((CTexture_2D*)GetTexture2D())->m_nHeight/2.0f;
    fY2 = (float)((CTexture_2D*)GetTexture2D())->m_nHeight/-2.0f;

    // triangle 1
    Vertex[0] = CVector2(fX1,fY1);
    Vertex[1] = CVector2(fX1,fY2);
    Vertex[2] = CVector2(fX2,fY2);

    // triangle 2
    Vertex[3] = CVector2(fX1,fY1);
    Vertex[4] = CVector2(fX2,fY2);
    Vertex[5] = CVector2(fX2,fY1);

    m33Scale = CMatrix33::Build_2DScaleMatrix      (fScaleX, fScaleY); 
    m33Rot   = CMatrix33::Build_2DRotationMatrix   (fAngle);
    m33Trans = CMatrix33::Build_2DTranslationMatrix((float)nCenterPosX, (float)nCenterPosY);
    for(i=0; i<6; i++)
    {
        Vertex[i] = m33Scale * Vertex[i];
        Vertex[i] = m33Rot   * Vertex[i];
        Vertex[i] = m33Trans * Vertex[i];
    }

    // texture trianngle 1
    Texture[0] = CVector2(0.0f, 1.0f);
    Texture[1] = CVector2(0.0f, 0.0f);
    Texture[2] = CVector2(1.0f, 0.0f);

    // texture trianngle 2
    Texture[3] = CVector2(0.0f, 1.0f);
    Texture[4] = CVector2(1.0f, 0.0f);
    Texture[5] = CVector2(1.0f, 1.0f);

    glBindVertexArray(m_unVAO);
    {
        glBindBuffer(GL_ARRAY_BUFFER, m_unVBO);
        
        glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) + sizeof(Texture), NULL, GL_DYNAMIC_DRAW);
        glBufferSubData(GL_ARRAY_BUFFER, 0,              sizeof(Vertex),  Vertex);
        glBufferSubData(GL_ARRAY_BUFFER, sizeof(Vertex), sizeof(Texture), Texture);

        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
        glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)sizeof(Vertex));
        glEnableVertexAttribArray(0);
        glEnableVertexAttribArray(1);

        glEnable(GL_BLEND);
        glDepthMask(GL_FALSE);
        glDrawArrays(GL_TRIANGLES, 0, 6);
        glDepthMask(GL_TRUE);
        glDisable(GL_BLEND);

        glDisableVertexAttribArray(0);
        glDisableVertexAttribArray(1);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
    }
    glBindVertexArray(0);
}


Hier noch der Shader mit der Einzigen Änderung das die Finale Geometrie noch mal mit der PM multipliziert wird:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
static char sVertexShader[] =
    "#version 330\n"
    "precision highp float;\n"
    "precision highp int;\n"
    "\n"
    "layout (location = 0) in vec2 _v2Vertex;\n"
    "layout (location = 1) in vec2 _v2Texture;\n"
    "\n"
    "uniform mat4 u_m4PM;\n"
    "\n"
    "out vec2 _v2Texture_;\n"
    "\n"
    "void main (void)\n"
    "{\n"
    "   _v2Texture_ = _v2Texture;\n"
    "   gl_Position = u_m4PM * vec4(_v2Vertex.x, _v2Vertex.y, -0.5, 1.0);\n"  <--- Hier die mul. mit PM 
    "}\n";


Funktioniert mit Translation, Scalierung und Rotation tadellos ohne Verzerrungen.
"In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." — Bjarne Stroustrup.

BlueCobold

Community-Fossil

Beiträge: 10 859

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

23

01.10.2014, 13:29

Dann sag mal wo der Faktor bei mir steckt ...
Genau da:
Shader_Sprite.SetUniform_ProjectionMatrix(CMatrix44::Build_OrthographicProjectionMatrix(-g_nWidth/2.0f, g_nWidth/2.0f, -g_nHight/2.0f, g_nHight/2.0f, 0.0f, 1.0f));
Die Projection Matrix kannst Du auch mit -1..+1 bauen, was wohl vorher scheinbar der Fall war (oder Du hast gar keine gesetzt). Jetzt setzt Du eine mit dem richtigen Faktor.
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]

David Scherfgen

Administrator

Beiträge: 10 297

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

24

01.10.2014, 14:10

"Height" schreibt man übrigens mit "e".

stef

Treue Seele

  • »stef« ist der Autor dieses Themas

Beiträge: 241

Wohnort: Kassel

Beruf: Softwareentwickler

  • Private Nachricht senden

25

01.10.2014, 15:47

"Height" schreibt man übrigens mit "e".

Ja ... sehr schön ...
"In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." — Bjarne Stroustrup.

stef

Treue Seele

  • »stef« ist der Autor dieses Themas

Beiträge: 241

Wohnort: Kassel

Beruf: Softwareentwickler

  • Private Nachricht senden

26

01.10.2014, 16:04

Dann sag mal wo der Faktor bei mir steckt ...
Genau da:
Shader_Sprite.SetUniform_ProjectionMatrix(CMatrix44::Build_OrthographicProjectionMatrix(-g_nWidth/2.0f, g_nWidth/2.0f, -g_nHight/2.0f, g_nHight/2.0f, 0.0f, 1.0f));
Die Projection Matrix kannst Du auch mit -1..+1 bauen, was wohl vorher scheinbar der Fall war (oder Du hast gar keine gesetzt). Jetzt setzt Du eine mit dem richtigen Faktor.

Ich hatte keine PM.
Ich hatte meine Dreieckskoordinaten gleich auf die relativen Werte (-1,1 - 1,-1) umgerechnet ...

C-/C++-Quelltext

1
2
3
4
    float fX1 = 2.0f *  (float)nSpritePosX / (float)nScreenWidth - 1.0f;
    float fX2 = 2.0f * ((float)nSpritePosX + (float)nSpriteWidth) / (float)nScreenWidth - 1.0f;
    float fY1 = -2.0f *  (float)nSpritePosY / (float)nScreenHight + 1.0f;
    float fY2 = -2.0f * ((float)nSpritePosY + (float)nSpriteHight) / (float)nScreenHight + 1.0f;

... und dann Transformiert (Scale & Rot)
Das Problem ist das ich hier mathematisch die Projektion vor der Transformation vorgenommen habe.
Beim benutzen der PM kommt die Projektion ganz am Schluß.
"In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." — Bjarne Stroustrup.

Schrompf

Alter Hase

Beiträge: 1 403

Wohnort: Dresden

Beruf: Softwareentwickler

  • Private Nachricht senden

27

01.10.2014, 16:29

Hmm... eventuell verstehe ich Dich falsch, aber es funktioniert jetzt bei Dir? Dann ist doch prima. Ziemlich ineffizient, für jedes Sprite einen eigenen DrawCall aufzumachen, aber es geht zumindest erstmal. Gute Sache.
Häuptling von Dreamworlds. Baut aktuell an nichts konkretem, weil das Vollzeitangestelltenverhältnis ihn fest im Griff hat. Baut daneben nur noch sehr selten an der Open Asset Import Library mit.

Nimelrian

Alter Hase

Beiträge: 1 260

Beruf: Softwareentwickler (aktuell Web/Node); Freiberuflicher Google Proxy

  • Private Nachricht senden

28

01.10.2014, 16:40

"Height" schreibt man übrigens mit "e".

Ja ... sehr schön ...

Stell dir mal vor, jemand anderes liest deinen Code irgendwann.
Stell dir mal vor, du liest den (deutschen, *schauder*) Code von jemand anderem und siehst sowas:

C-/C++-Quelltext

1
2
3
int main() {
    MaineKlasse obje ckt = MaineKlasse(Vecktor3(1, 1, 1), Vecktor3 (2, 3, 4));
}


(obje_ckt wird geblockt. GJ David!)
Code soll sprechend sein. Sprechend kann Code nur sein, wenn man ihn flüssig lesen kann, ohne lang nachzudenken, was genau gemeint ist, weil der Dev mit Rechtschreibfehlern um sich wirft.
Ich bin kein UserSideGoogleProxy. Und nein, dieses Forum ist kein UserSideGoogleProxyAbstractFactorySingleton.

stef

Treue Seele

  • »stef« ist der Autor dieses Themas

Beiträge: 241

Wohnort: Kassel

Beruf: Softwareentwickler

  • Private Nachricht senden

29

01.10.2014, 16:59

Hmm... eventuell verstehe ich Dich falsch, aber es funktioniert jetzt bei Dir? Dann ist doch prima. Ziemlich ineffizient, für jedes Sprite einen eigenen DrawCall aufzumachen, aber es geht zumindest erstmal. Gute Sache.

Hast recht :D ... ist auch nur zum anzeigen von Menübuchstaben gedacht.
"In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." — Bjarne Stroustrup.

stef

Treue Seele

  • »stef« ist der Autor dieses Themas

Beiträge: 241

Wohnort: Kassel

Beruf: Softwareentwickler

  • Private Nachricht senden

30

01.10.2014, 17:07

"Height" schreibt man übrigens mit "e".

Ja ... sehr schön ...

Stell dir mal vor, jemand anderes liest deinen Code irgendwann.
Stell dir mal vor, du liest den (deutschen, *schauder*) Code von jemand anderem und siehst sowas:

C-/C++-Quelltext

1
2
3
int main() {
    MaineKlasse obje ckt = MaineKlasse(Vecktor3(1, 1, 1), Vecktor3 (2, 3, 4));
}


(obje_ckt wird geblockt. GJ David!)
Code soll sprechend sein. Sprechend kann Code nur sein, wenn man ihn flüssig lesen kann, ohne lang nachzudenken, was genau gemeint ist, weil der Dev mit Rechtschreibfehlern um sich wirft.


Hoffnungslos Übertrieben ...
Deinen 500sten Post hättest du mal für was sinnvolles verwenden sollen.
Ich müsste mich schon ganz schön zudrönen um lange über folgenden Kommentar dachdenken zu müssen ...

C-/C++-Quelltext

1
// use texture width and hights to calculate coordinates
"In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." — Bjarne Stroustrup.

Werbeanzeige