What I'm looking to do is take either 1 or 2 vertices I input, and output 2 polygons that form a rectangle. The rectangle itself is to have a width/height of 8 pixels (prior to matrix calculations), so in a case where I have 2 points, they would be on opposite corners of the shape, so the geometry shader would use them to generate the two other vertices to form an axis-aligned rectangle (using one's X and the other's Y). This is how BlargSNES currently handles tiles for modes other than Mode7, as they are axis-aligned. I am attempting to incorporate a model-view matrix that'll define the scale/rotation for a group of tiles (from either full-screen or per-scanline), but the results are not correct because I implemented it via the vertex shader.
The image itself is not rotating the tiles, but is instead squishing either horizontally or vertically because the 2 vertices are processed with model-view matrix calculations in the vertex shader (which now I know is done before the geometry shader, not after). I tried to shift such calculations to the geometry shader, but it didn't like that, resulting in a blank screen and eventually led to a crash.
Here's the code that would produce the results of the image above.
Code: Select all
; setup constants
.const c9, 0.0, 0.0, 0.0078125, 1.0
; setup outmap
.out o0, result.position
.out o1, result.color
.out o2, result.texcoord0
; setup uniform map (not required)
.uniform c0, c3, projMtx
.vsh vmain, end_vmain
.gsh gmain, end_gmain
; INPUT
; - VERTEX ATTRIBUTES -
; v0: vertex (x, y, and optional z)
; v1: texcoord
; - UNIFORMS -
; c0-c3: projection matrix
; c4: texcoord scale
;code
vmain:
mov r2, v0 (0x4)
mov r2, c9 (0x3)
; my inclusion of modelview-matrix calculation, which this (and projMtx) may need to be in the geometry shader if possible?
dp4 r1, c5, r2 (0x0)
dp4 r1, c6, r2 (0x1)
dp4 r1, c7, r2 (0x2)
dp4 r1, c8, r2 (0x3)
; result.pos = projMtx * temp.pos
dp4 o0, c0, r1 (0x0)
dp4 o0, c1, r1 (0x1)
dp4 o0, c2, r1 (0x2)
dp4 o0, c3, r1 (0x3)
; result.texcoord = in.texcoord * (uniform scale in c4)
mul r1, c4, v1 (0x5)
mov o1, r1 (0x5)
flush
end_vmain:
gmain:
; turn two vertices into a rectangle
; setemit: vtxid, primemit, winding
; v0 = vertex 0, position
; v1 = vertex 0, texcoord
; v2 = vertex 1, position
; v3 = vertex 1, texcoord
; x1 y1
setemit vtx0, false, false
mov o0, v0 (0x5)
mov o1, c9 (0x8)
mov o2, v1 (0x5)
emit
; x2 y1
setemit vtx1, false, false
mov o0, v2 (0x6)
mov o0, v0 (0x7)
mov o1, c9 (0x8)
mov o2, v3 (0x6)
mov o2, v1 (0x7)
emit
; x1 y2
setemit vtx2, true, false
mov o0, v0 (0x6)
mov o0, v2 (0x7)
mov o1, c9 (0x8)
mov o2, v1 (0x6)
mov o2, v3 (0x7)
emit
; x2 y2
setemit vtx0, true, true
mov o0, v2 (0x5)
mov o1, c9 (0x8)
mov o2, v3 (0x5)
emit
flush
end_gmain:
;operand descriptors
.opdesc x___, xyzw, xyzw ; 0x0
.opdesc _y__, xyzw, xyzw ; 0x1
.opdesc __z_, xyzw, xyzw ; 0x2
.opdesc ___w, xyzw, xyzw ; 0x3
.opdesc xyz_, xyzw, xyzw ; 0x4
.opdesc xyzw, xyzw, xyzw ; 0x5
.opdesc x_zw, xyzw, xyzw ; 0x6
.opdesc _y__, yyyw, xyzw ; 0x7
.opdesc xyzw, wwww, wwww ; 0x8