Skip to content

Commit

Permalink
[BREAKING] improved gl.render_tiles supporting size & rotation
Browse files Browse the repository at this point in the history
If you were already using this function, the breaking change is that positions now indicate the center, not the top left. Wrap this call in gl.translate float2_h: to get top left back. Also add 2 empty vector [] args if you do not need per sprite size/rotation.
  • Loading branch information
aardappel committed Sep 28, 2024
1 parent ee55c3e commit 4cd98fc
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 14 deletions.
35 changes: 25 additions & 10 deletions dev/src/graphics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1344,13 +1344,16 @@ nfr("light", "pos,params", "F}:3F}:2", "",
lights.push_back(l);
});

nfr("render_tiles", "positions,tilecoords,mapsize", "F}:2]I}:2]I}:2", "",
"Renders a list of tiles from a tilemap. Each tile rendered is 1x1 in size."
nfr("render_tiles", "positions,tilecoords,mapsize,sizes,rotations", "F}:2]I}:2]I}:2F]F]", "",
"Renders a list of tiles from a tilemap. Each tile rendered is 0.5 in radius (1x1 square around pos) unless the optional sizes vector is specified (may be empty)."
" Positions may be anywhere. tilecoords are indices into the map (0..mapsize-1), mapsize is"
" the amount of tiles in the texture. Tiles may overlap, they are drawn in order."
" Before calling this, make sure to have the texture set and a textured shader",
" the amount of tiles in the texture. rotations are optional (may be empty, faster if not specified). Tiles may overlap, they are drawn in order."
" Before calling this, make sure to have the texture set and a textured shader."
" If you want tile to use top-left as position, wrap this call in gl.translate float2_h:",
[](StackPtr &sp, VM &vm) {
TestGL(vm);
auto rotations = Pop(sp).vval();
auto sizes = Pop(sp).vval();
auto msize = float2(PopVec<int2>(sp));
auto tile = Pop(sp).vval();
auto pos = Pop(sp).vval();
Expand All @@ -1361,12 +1364,24 @@ nfr("render_tiles", "positions,tilecoords,mapsize", "F}:2]I}:2]I}:2", "",
for (iint i = 0; i < len; i++) {
auto p = ValueToFLT<2>(pos->AtSt(i), pos->width);
auto t = float2(ValueToI<2>(tile->AtSt(i), tile->width)) / msize;
vbuf[i * 6 + 0].pos = p;
vbuf[i * 6 + 1].pos = p + float2_y;
vbuf[i * 6 + 2].pos = p + float2_1;
vbuf[i * 6 + 3].pos = p;
vbuf[i * 6 + 4].pos = p + float2_1;
vbuf[i * 6 + 5].pos = p + float2_x;
auto size = i < sizes->len ? sizes->At(i).fltval() : 0.5f;
auto c1 = float2(-size);
auto c2 = float2(-size, size);
auto c3 = float2(size);
auto c4 = float2(size, -size);
if (i < rotations->len) {
auto rot = rotations->At(i).fltval();
c1 = rotate2(c1, rot * RAD);
c2 = float2(c1.y, -c1.x);
c3 = float2(c2.y, -c2.x);
c4 = float2(c3.y, -c3.x);
}
vbuf[i * 6 + 0].pos = p + c1;
vbuf[i * 6 + 1].pos = p + c2;
vbuf[i * 6 + 2].pos = p + c3;
vbuf[i * 6 + 3].pos = p + c1;
vbuf[i * 6 + 4].pos = p + c3;
vbuf[i * 6 + 5].pos = p + c4;
vbuf[i * 6 + 0].tc = t;
vbuf[i * 6 + 1].tc = t + float2_y / msize;
vbuf[i * 6 + 2].tc = t + float2_1 / msize;
Expand Down
16 changes: 13 additions & 3 deletions dev/src/lobster/geom.h
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,12 @@ template<typename T> inline float3 random_point_in_sphere(RandomNumberGenerator<
}
}


inline float2 rotate2(const float2 &v, const float2 &a) {
return float2(v.x * a.x - v.y * a.y, v.x * a.y + v.y * a.x);
}


inline float3 rotateX(const float3 &v, const float2 &a) {
return float3(v.x, v.y * a.x - v.z * a.y, v.y * a.y + v.z * a.x);
}
Expand All @@ -566,9 +572,13 @@ inline float3 rotateZ(const float3 &v, const float2 &a) {
return float3(v.x * a.x - v.y * a.y, v.x * a.y + v.y * a.x, v.z);
}

inline float3 rotateX(const float3 &v, float a) { return rotateX(v, float2(cosf(a), sinf(a))); }
inline float3 rotateY(const float3 &v, float a) { return rotateY(v, float2(cosf(a), sinf(a))); }
inline float3 rotateZ(const float3 &v, float a) { return rotateZ(v, float2(cosf(a), sinf(a))); }
inline float2 rotvec(float a) { return float2(cosf(a), sinf(a)); }

inline float2 rotate2(const float2 &v, float a) { return rotate2(v, rotvec(a)); }

inline float3 rotateX(const float3 &v, float a) { return rotateX(v, rotvec(a)); }
inline float3 rotateY(const float3 &v, float a) { return rotateY(v, rotvec(a)); }
inline float3 rotateZ(const float3 &v, float a) { return rotateZ(v, rotvec(a)); }

struct quat : float4 {
quat() {}
Expand Down
2 changes: 1 addition & 1 deletion docs/builtin_functions_reference.html
Original file line number Diff line number Diff line change
Expand Up @@ -1141,7 +1141,7 @@
<tr class="a" valign=top><td class="a"><tt><b>gl.light</b>(pos<font color="#666666">: float3</font>, params<font color="#666666">: float2</font>)</tt></td><td class="a">sets up a light at the given position for this frame. make sure to call this after your camera transforms but before any object transforms (i.e. defined in "worldspace"). params contains specular exponent in x (try 32/64/128 for different material looks) and the specular scale in y (try 1 for full intensity)</td>

</tr>
<tr class="a" valign=top><td class="a"><tt><b>gl.render_tiles</b>(positions<font color="#666666">: [float2]</font>, tilecoords<font color="#666666">: [int2]</font>, mapsize<font color="#666666">: int2</font>)</tt></td><td class="a">Renders a list of tiles from a tilemap. Each tile rendered is 1x1 in size. Positions may be anywhere. tilecoords are indices into the map (0..mapsize-1), mapsize is the amount of tiles in the texture. Tiles may overlap, they are drawn in order. Before calling this, make sure to have the texture set and a textured shader</td>
<tr class="a" valign=top><td class="a"><tt><b>gl.render_tiles</b>(positions<font color="#666666">: [float2]</font>, tilecoords<font color="#666666">: [int2]</font>, mapsize<font color="#666666">: int2</font>, sizes<font color="#666666">: [float]</font>, rotations<font color="#666666">: [float]</font>)</tt></td><td class="a">Renders a list of tiles from a tilemap. Each tile rendered is 0.5 in radius (1x1 square around pos) unless the optional sizes vector is specified (may be empty). Positions may be anywhere. tilecoords are indices into the map (0..mapsize-1), mapsize is the amount of tiles in the texture. rotations are optional (may be empty, faster if not specified). Tiles may overlap, they are drawn in order. Before calling this, make sure to have the texture set and a textured shader. If you want tile to use top-left as position, wrap this call in gl.translate float2_h:</td>

</tr>
<tr class="a" valign=top><td class="a"><tt><b>gl.debug_grid</b>(num<font color="#666666">: int3</font>, dist<font color="#666666">: float3</font>, thickness<font color="#666666">: float</font>)</tt></td><td class="a">renders a grid in space for debugging purposes. num is the number of lines in all 3 directions, and dist their spacing. thickness of the lines in the same units</td>
Expand Down

0 comments on commit 4cd98fc

Please sign in to comment.