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

11.11.2009, 04:54

2D mit HLSL

Hi!

Ich versuche gerade (was ich schon lange vor mir her geschoben habe) das zeichnen im 2 dimensionalen zu ermöglichen.

Ich erstelle einen Vertex- und IndexBuffer, welche ein Quadtrat bilden sollen. Außerdem erstelle ich eine Orthogonale Projektionsmatrix mit D3DXMatrixOrthoLH() um ganz sicher zu gehen das dort kein Fehler liegt. Anschließend übergebe ich meinem Shader die Projektionsmatrix. Der VertexShader multipliziert die Positionen mit der Orthogonalen Projektionsmatrix und der PixelShader setzt dann bloß schwarze Pixel an den betroffenen stellen.

Mein HLSL Code sieht 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
45
46
float4x4 ProjectionMatrix;

struct VS_IN
{
    float4 Position : POSITION;
};

struct VS_OUT
{
    float4 Position : POSITION;
};

struct PS_OUT
{
    float4 Color : COLOR0;
};

VS_OUT VS(VS_IN In)
{
    VS_OUT Out = (VS_OUT)0;
     
    Out.Position = mul(In.Position, ProjectionMatrix); 

    return Out;
}
 
PS_OUT PS(VS_OUT In)
{
    PS_OUT Out = (PS_OUT)0;    
 
    
    Out.Color = float4(0,0,0,0);

 
    return Out;
}
 

technique Sprite
{
    pass Pass0
    {
        VertexShader = compile vs_1_1 VS();
        PixelShader  = compile ps_2_0 PS();
    }
}


Leider wird auf meinem Bildschirm nichts angezeigt. Culling habe ich schon aus geschaltet und wenn ich als wireframe rendere ist auch nichts zu sehen.

Hab ich vieleicht etwas vergessen?

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

2

11.11.2009, 08:14

FVF wäe hilfreich bzw. allgemein der code drumherum. ansonsten setzt du die farbe auf schwarz, wenn dein hintergrund auch schwarz ist etwas unpraktisch, probier mal float4(1,1,1,1) als farbe. und poste bitte mehr code sonst ist keine analyse möglich. deine othogonale matrix kann falsch sein oder deine koordinaten.

3

11.11.2009, 11:55

EDIT:::

Das Problem hat sich erledigt, der Fehler lag an der erstellung des IndexBuffers. Ich benutze den Direct3D Wrapper meiner Engine, dabei hatte ich zuvor die IndexBuffer Klasse umgestaltet. Wenn ich die Klasse nun mit dem Parameter "AveSixteenBits" erstellt habe, hat der Constructor den Direct3D IndexBuffer jedoch als 32 Bit Buffer erstellt.

Nun funktioniert es einwandfrei.

4

11.11.2009, 19:50

Kuze Frage noch:

Wie könnte ich die Y Achse vertauschen? Im moment Zeigt die Achse nach oben, was ich jedoch vermeiden möchte. Der Startpunkt des Bildes soll links oben sein, und das Ende rechts unsten?

Ich könnte nun einfach bei der erstellung des VertexBuffers vor dem Y ein Minus setzen, jedoch würde das nicht so viel bringen, da wenn ich das Bild nochmal extra Positionieren will, also mit der WorldMatrix multipliziere, ist die Achse immernoch verkehrt herum.

5

10.12.2009, 13:13

Meinst du wirklich nur 2D ?

Dazu brauche ich nicht eine einzige Matrize !!

Gib einfach x,y,x2,y2 an:


// Umwandlung von ScreenSpace in ViewSpace

float sx = 2.0f/(window_width); // -1,+1
float sy = 2.0f/(window_height); // +1,-1

float dx = -1.0f +sx *x;
float dy = 1.0f -sy *y;
float dx2 = -1.0f +sx *x2;
float dy2 = 1.0f -sy *y2;

VertexArray[0].Pos = D3DXVECTOR3( dx, dy, z );
VertexArray[1].Pos = D3DXVECTOR3( dx2, dy, z );
VertexArray[2].Pos = D3DXVECTOR3( dx2, dy2, z );
VertexArray[3].Pos = D3DXVECTOR3( dx, dy2, z );

Für die Z gib an was immer du willst (zwischen 0-1).

Damit gibts auch kein Y Problem.

.

6

10.12.2009, 14:28

Und im VS müsste ich die Vertex Positionen dann einfach untransformiert an den PS weiter geben?

7

10.12.2009, 17:38

Stimmt genau.
Das ist ja der Witz an der Geschichte !
Damit sollte man nachträglich nichts mehr damit verrechnen.
Also OUT = IN.

Gib einfach vier Bildschirmpunkte ( zB. 0,0,200,200 ) an und rechne Sie um,
diese sind Deine Quad-Vertexkoordinaten.

Das Quad geht planeben von links oben 0,0 bis 200,200 rechts unten.
Die Tiefe Z bestimmst Du.
Allerdings wird es nach hinten nicht kleiner, wenn du das z einsetzt.

Wenn man Koordinaten durch Matrizen schickt errechnest man auch nur 2D-Punkte die du an den VS weitergibst.

Natürlich kann man diese weiter transformieren oder rotieren oder skalieren, aber
Du wolltest SCREEN-Koordinaten frei von Experimenten zu Matrizenanpassungen um das Window genau zu erwischen.
Und Bildschirmkoordinaten sind einfach immer 2-Dimensional.

Der Profi hats leicht und erspart sich die langsamen C++ Zeilen für eine Implementierung in der GPU_HW via Geometry-Shader.

8

10.12.2009, 20:02

Zitat von »"zodX"«

Der Profi hats leicht und erspart sich die langsamen C++ Zeilen für eine Implementierung in der GPU_HW via Geometry-Shader.


Langsame Zeilen?
Und zählst du dich zu einen dieser Profis?

9

10.12.2009, 20:19

GS´s brauchte ich bisher noch nicht (für mein Projekt).
Habe einiges verstanden: Arbeite oft mit C++,DX10,Direct2D,HLSL.

Trotzdem habe ich ein Problem mit der Anweisungsplatzierung von den beiden Befehlen ValidateRect() und InvalidateRect().

Werbeanzeige