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

1

02.01.2004, 13:08

3D nach 2D-Bildschirmkoordinate

Hi,

ich wollte in meinem Spiel LenseFlares einbauen. Das Problem ist nun folgendes:

Ich habe eine Sonne und möchte nun die 3D-Sonnenkoordinaten in 2D-Bildschirmkoordinaten umrechenen.

So geht es nur leider nicht:

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
    // Sone rendern 
    D3DLIGHT9       PointLight;
    ZeroMemory(&PointLight, sizeof(D3DLIGHT9));
    PointLight.Type         = D3DLIGHT_POINT;               // Punktlicht
    PointLight.Diffuse      = tbColor(1.0f, 1.0f, 0.75f);   // Gelbe Streufarbe
    PointLight.Ambient      = tbColor(1.0f, 1.0f, 0.75f);   // Gelbe Hintergrundfarbe
    PointLight.Position     = tbVector3(0,0,0);     // Die Position der Sonne
    PointLight.Range        = 1000.0f;                      // 1000 Einheiten Reichweite
    PointLight.Attenuation0 = 1.0f;                         // Lichtabschwächung
    PointLight.Attenuation1 = 0.0f;                         // ...
    PointLight.Attenuation2 = 0.0f;                         // ...

    D3DXVECTOR3 v;
    D3DVIEWPORT9 vp;

    vp.X=0;
    vp.Y=0;
    vp.Width=tbDirect3D::GetScreenSize().x;
    vp.Height=tbDirect3D::GetScreenSize().y;
    vp.MinZ=0.0f;
    vp.MaxZ=m_fLast;

    D3DXVECTOR3 vLightPos=PointLight.Position;
    D3DXVec3Project(&vLightPos,
                        &v,
                        &vp,
                        (const D3DXMATRIX*)&m_mProjection,
                        (const D3DXMATRIX*)&m_mCamera,
                        (const D3DXMATRIX*)&tbMatrixIdentity());

    tbVector2 vCenterScreen=tbDirect3D::GetScreenSize()/2;

    tbVector2 vDirection=tbVector2(vCenterScreen.x-vLightPos.x,vCenterScreen.y-vLightPos.y);

    vDirection=tbVector2Normalize(vDirection);

    // LenseFlare rendern
    // ...

    // Licht einsetzen und aktivieren
    tbDirect3D::GetDevice()->SetLight(0, &PointLight);
    tbDirect3D::GetDevice()->LightEnable(0, TRUE);


Ich kriege nur Vektoren wie

1060.41 -164.41 7000.10, obwohl die Kamera die Position 0,0,0 hat; wie das Sonnenlicht...

Und 2. Warum verlangt D3DXVec3Project als ersten Parameter einen 3-er Vektor? Ein 2-er Vektor würde doch genügen?

Danke,

Chrissi

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

2

02.01.2004, 13:47

Im 3er-Vektor ist noch Platz für den w-Wert, durch den bei der Projektion dividiert wird. Wenn Kamera und Licht dieselbe Position haben, ist das schlecht - das wird möglicherweise durch null dividiert. Nimm doch mal eine andere Position!

3

03.01.2004, 18:51

Aha,

jezt funktioniert es. :) . Leider sehe ich aber keine schönen Lense-Flares auf dem Bildschirm.

Kannst du dir vielleicht mal das angucken?

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
46
47
48
49
50
51
52
53
54
55
56
// Weltmatrix zurücksetzen
    tbDirect3D::GetDevice()->SetTransform(D3DTS_WORLD, (D3DMATRIX*)(&tbMatrixIdentity()));

    // Sonne und LenseFlares rendern
    D3DLIGHT9       PointLight;
    ZeroMemory(&PointLight, sizeof(D3DLIGHT9));
    PointLight.Type         = D3DLIGHT_POINT;               // Punktlicht
    PointLight.Diffuse      = tbColor(1.0f, 1.0f, 0.75f);   // Gelbe Streufarbe
    PointLight.Ambient      = tbColor(1.0f, 1.0f, 0.75f);   // Gelbe Hintergrundfarbe
    PointLight.Position     = tbVector3(0,0,0);             // Die Position der Sonne
    PointLight.Range        = m_fLast/2;                    // Reichweite
    PointLight.Attenuation0 = 0.75f;                        // Lichtabschwächung
    PointLight.Attenuation1 = 0.0f;                         // ...
    PointLight.Attenuation2 = 0.0f;                         // ...

    tbDirect3D::SetRS(D3DRS_AMBIENT, (DWORD)tbColor(1.0f, 1.0f, 1.0f));

    tbVector2 vTranslation, vDirection, vNorm;

    float fLenght;

    float fTrans[]={1.0f,2.0f,3.0f,8.0f,-2.0f,-4.0f,-5.5f};
    float fScale[]={1.0f,0.5f,0.25f,1.0f,5.0f,0.25f,0.25f};
    int iSprite[]={0,1,0,3,2,0,3};

    D3DXVECTOR3 vLightPos=PointLight.Position;

    // ----------------------------------------

    D3DXVec3Project(&vLightPos,
                        &vLightPos,
                        &m_vp,
                        (const D3DXMATRIX*)&m_mProjection,
                        (const D3DXMATRIX*)&m_mCamera,
                        (const D3DXMATRIX*)&tbMatrixIdentity());

    vDirection=tbVector2(m_vScreenCenter.x-vLightPos.x,m_vScreenCenter.y-vLightPos.y);

    fLenght=tbVector2Length(vDirection);

    vNorm=tbVector2Normalize(vDirection);

    for(int i=0; i<7;i++)
    { 
        fLenght/=fTrans[i];

        vNorm.x*=fLenght;
        vNorm.y*=fLenght;

        m_pSpriteEngine->AddSprite(iSprite[i], tbVector3(vNorm.x+m_vScreenCenter.x, vNorm.y+m_vScreenCenter.y, m_vCameraPos.z+0.5f), tbColor(1.0f), tbVector2(fScale[i]));
    
    }

    // Licht einsetzen und aktivieren
    tbDirect3D::GetDevice()->SetLight(0, &PointLight);
    tbDirect3D::GetDevice()->LightEnable(0, TRUE);


Naja,

hoffe auf Hilfe,
Cu,

Chrissi[/code]

Werbeanzeige