<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>Drawing 3D graphics to a bitmap smaller than the display.</title>
		<link>http://www.allegro.cc/forums/view/617581</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Mon, 15 Oct 2018 02:56:58 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I&#39;m trying to draw some 3D graphics to a bitmap and then scaling that up to get a pixelated effect.</p><p>I&#39;m having trouble figuring out the right math and transformations to get the graphics to appear at the right scale and position.  Currently things are appearing too big and not centered.  I guess they the projection matrix should be smaller and offset by some amount but I don&#39;t know what.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (roger levy)</author>
		<pubDate>Sat, 13 Oct 2018 07:02:22 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Can you post your code to construct the projection, view, and world matrices (whichever applicable)? As well the code you use to draw the model?</p><p>The easiest method would be to create a projection matrix then use al_build_camera_transform to center the camera at a specific distance (position) from the target (look) using a proper up vector (usually [0, 1, 0]). If the model is centered origin, then look would be [0, 0, 0] and eye would be (for example) [0, 0, distance_from_model (or zoom)].</p><p><b>*edit:</b>* correction
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Erin Maus)</author>
		<pubDate>Sat, 13 Oct 2018 19:36:46 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>How would al_build_camera_transform know about the size of the drawing surface?</p><p>I never even heard of the world matrix before now.  (Help)</p><p>I&#39;ll post the code but standard disclaimer about it being in Forth etc</p><pre>
transform p 
80 value fov

: f  fov &gt;rad 2 / tan ;
: asp  viewwh / ;

: ofs  displaywh -2 2 2/ viewwh 2 -2 2/ 2+ ;  \ absolutely no idea what i&#39;m doing here

\ sets up the projection
: 3d
    p al_identity_transform
    p 0 0 -1 3af al_translate_transform_3d
    p   asp f * negate 1af   f 1af           1 1af
        asp f * 1af          f negate 1af    1000 1af
    al_perspective_transform
\     p 1 globalscale / dup dup  3af al_scale_transform_3d
\     p ofs 0 3af al_translate_transform_3d
    p al_use_projection_transform
    
    ALLEGRO_DEPTH_TEST #1 al_set_render_state
    1 1af al_clear_depth_buf
;

transform t
: modelview
    t al_identity_transform
    t scl 3@ 3af al_scale_transform_3d
    t 0 0 1 3af rtn z@ &gt;rad 1af al_rotate_transform_3d
    t 0 1 0 3af rtn y@ &gt;rad 1af al_rotate_transform_3d
    t 1 0 0 3af rtn x@ &gt;rad 1af al_rotate_transform_3d
    t pos 3@ 3af al_translate_transform_3d
    t al_use_transform
;

\ drawing the model
: texture@  tex @ dup if &gt;bmp then ;

: model  ( -- )
    mdl @ -exit
    modelview    
    mdl @ indices @ if 
        mdl @ vertices @
        0 \ vertex decl
        texture@
        mdl @ indices 2@ 1i
        mdl @ primtype @
        al_draw_indexed_prim
    else
        mdl @ vertices 2@ 1i &gt;r
        0 \ vertex decl
        texture@
        0 \ first vertex
        r&gt; \ last vertex
        mdl @ primtype @
        al_draw_prim
    then ;

</pre><p>

Here is the code for the &quot;upscaler&quot;, it uses other functions in my library so just assume that it&#39;s calling al_set_target_bitmap.</p><pre>
depend ramen/lib/draw.f
nativewh canvas: canv
: (upscale)  canv &gt;bmp onto&gt;  unmount call  ;
: upscale&gt;  ( -- &lt;code&gt; )  r&gt;  (upscale)  mount  0 0 at  canv &gt;bmp blit ;
</pre><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (roger levy)</author>
		<pubDate>Sat, 13 Oct 2018 22:56:13 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I have no idea what the Forth code is doing unfortunately.</p><p>This is how you draw a model:</p><div class="source-code"><div class="toolbar"><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number">  1</span><a href="http://www.allegro.cc/manual/ALLEGRO_TRANSFORM"><span class="a">ALLEGRO_TRANSFORM</span></a> alx_not_useless_and_dumb_perspective<span class="k2">(</span>
<span class="number">  2</span>  <a href="http://www.allegro.cc/manual/ALLEGRO_TRANSFORM"><span class="a">ALLEGRO_TRANSFORM</span></a> <span class="k3">*</span>transform,
<span class="number">  3</span>  <span class="k1">float</span> fov_y,
<span class="number">  4</span>  <span class="k1">float</span> aspect,
<span class="number">  5</span>  <span class="k1">float</span> near, <span class="k1">float</span> far<span class="k2">)</span>
<span class="number">  6</span><span class="k2">{</span>
<span class="number">  7</span>  <span class="k1">float</span> h <span class="k3">=</span> <a href="http://www.delorie.com/djgpp/doc/libc/libc_803.html" target="_blank">tan</a><span class="k2">(</span>fov_y <span class="k3">/</span> <span class="n">2</span><span class="k2">)</span> <span class="k3">*</span> near<span class="k2">;</span>
<span class="number">  8</span>  <span class="k1">float</span> w <span class="k3">=</span> h <span class="k3">*</span> aspect<span class="k2">;</span>
<span class="number">  9</span>
<span class="number"> 10</span>  <a href="http://www.allegro.cc/manual/al_identity_transform"><span class="a">al_identity_transform</span></a><span class="k2">(</span>transform<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 11</span>
<span class="number"> 12</span>  <span class="c">// this is a very idiosyncratic function</span>
<span class="number"> 13</span>  <span class="c">// it annoys me /a lot/</span>
<span class="number"> 14</span>  al_perspective_transform<span class="k2">(</span>transform, <span class="k3">-</span>w, <span class="k3">-</span>h, near, w, h, far<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 15</span><span class="k2">}</span>
<span class="number"> 16</span>
<span class="number"> 17</span><span class="k1">void</span> prepare_camera<span class="k2">(</span><span class="k1">const</span> model <span class="k3">*</span>model, <span class="k1">const</span> <a href="http://www.allegro.cc/manual/ALLEGRO_BITMAP"><span class="a">ALLEGRO_BITMAP</span></a> <span class="k3">*</span>surface<span class="k2">)</span>
<span class="number"> 18</span><span class="k2">{</span>
<span class="number"> 19</span>  <span class="k1">float</span> min_x, min_y, min_z<span class="k2">;</span>
<span class="number"> 20</span>  <span class="k1">float</span> max_x, max_y, max_z<span class="k2">;</span>
<span class="number"> 21</span>  get_model_bounds<span class="k2">(</span>model, <span class="k3">&amp;</span>min_x, <span class="k3">&amp;</span>min_y, <span class="k3">&amp;</span>min_z, <span class="k3">&amp;</span>max_x, <span class="k3">&amp;</span>max_y, <span class="k3">&amp;</span>max_z<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 22</span>
<span class="number"> 23</span>  <a href="http://www.allegro.cc/manual/ALLEGRO_TRANSFORM"><span class="a">ALLEGRO_TRANSFORM</span></a> projection<span class="k2">;</span>
<span class="number"> 24</span>  alx_not_useless_and_dumb_perspective<span class="k2">(</span>
<span class="number"> 25</span>    <span class="k3">&amp;</span>projection,
<span class="number"> 26</span>    <a href="http://www.allegro.cc/manual/ALLEGRO_PI"><span class="a">ALLEGRO_PI</span></a> <span class="k3">/</span> <span class="n">3</span> <span class="c">/* whatever, tweak this */</span>,
<span class="number"> 27</span>    <span class="k2">(</span><span class="k1">float</span><span class="k2">)</span><a href="http://www.allegro.cc/manual/al_get_bitmap_width"><span class="a">al_get_bitmap_width</span></a><span class="k2">(</span>surface<span class="k2">)</span> <span class="k3">/</span> <span class="k2">(</span><span class="k1">float</span><span class="k2">)</span><a href="http://www.allegro.cc/manual/al_get_bitmap_height"><span class="a">al_get_bitmap_height</span></a><span class="k2">(</span>surface<span class="k2">)</span>,
<span class="number"> 28</span>    <span class="n">1</span>.<span class="n">0f</span>,
<span class="number"> 29</span>    max_z <span class="k3">-</span> min_z <span class="k3">+</span> <span class="n">1</span>.<span class="n">0f</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 30</span>
<span class="number"> 31</span>  <a href="http://www.allegro.cc/manual/ALLEGRO_TRANSFORM"><span class="a">ALLEGRO_TRANSFORM</span></a> view<span class="k2">;</span>
<span class="number"> 32</span>  <a href="http://www.allegro.cc/manual/al_identity_transform"><span class="a">al_identity_transform</span></a><span class="k2">(</span><span class="k3">&amp;</span>view<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 33</span>  al_build_camera_transform<span class="k2">(</span>
<span class="number"> 34</span>    <span class="k3">&amp;</span>view,
<span class="number"> 35</span>    min_x <span class="k3">+</span> <span class="k2">(</span>max_x <span class="k3">-</span> min_x<span class="k2">)</span> <span class="k3">/</span> <span class="n">2</span>.<span class="n">0f</span>,
<span class="number"> 36</span>    min_y <span class="k3">+</span> <span class="k2">(</span>max_y <span class="k3">-</span> min_y<span class="k2">)</span> <span class="k3">/</span> <span class="n">2</span>.<span class="n">0f</span>,
<span class="number"> 37</span>    min_z <span class="k3">-</span> <span class="n">1</span>.<span class="n">0</span>,
<span class="number"> 38</span>    min_x <span class="k3">+</span> <span class="k2">(</span>max_x <span class="k3">-</span> min_x<span class="k2">)</span> <span class="k3">/</span> <span class="n">2</span>.<span class="n">0f</span>,
<span class="number"> 39</span>    min_y <span class="k3">+</span> <span class="k2">(</span>max_y <span class="k3">-</span> min_y<span class="k2">)</span> <span class="k3">/</span> <span class="n">2</span>.<span class="n">0f</span>,
<span class="number"> 40</span>    max_z <span class="k3">+</span> <span class="n">1</span>.<span class="n">0f</span>,
<span class="number"> 41</span>    <span class="n">0</span>.<span class="n">0f</span>,
<span class="number"> 42</span>    <span class="n">1</span>.<span class="n">0f</span>,
<span class="number"> 43</span>    <span class="n">0</span>.<span class="n">0f</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 44</span>
<span class="number"> 45</span>  al_use_projection_matrix<span class="k2">(</span><span class="k3">&amp;</span>projection<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 46</span>  <a href="http://www.allegro.cc/manual/al_use_transform"><span class="a">al_use_transform</span></a><span class="k2">(</span><span class="k3">&amp;</span>view<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 47</span><span class="k2">}</span>
</div></div><p>

The idea is you build a perspective matrix (tweak fov_y until it looks good), then build a camera transform that has the viewport contain the model. The perspective really doesn&#39;t matter for this; we just want near / far set to values that don&#39;t result in the model getting clipped.</p><p>Depending on which way your model is facing, you may need to look down the X or Y axes. Currently it looks down the Z axis, which requires models to be looking down Z. (For example, if you open Blender and press NumPad 1 (Front Ortho), you should see the model&#39;s face.)</p><p><span class="source-code">al_perspective_transform</span> should be renamed to <span class="source-code">al_perspective_frustum_transform</span> or something... It&#39;s not a very well named function, and its argument order is wack.</p><p>Not tested at all but it&#39;s identical in logic to how I render 3D previews of models in my game editor.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Erin Maus)</author>
		<pubDate>Sat, 13 Oct 2018 23:36:26 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Forgive me, but I don&#39;t understand how this takes into account the actual size of the bitmap.  I see that your perspective function uses the aspect ratio, but the bitmap is not mentioned anywhere else so how does Allegro know where the &quot;center&quot; of the bitmap is supposed to be and how big it should draw things?  </p><p>Keep in mind I am not having any trouble rendering to the display, things look fine there - only when I try to render my bitmap.</p><p>EDIT:  I solved it.  After analyzing the Allegro source code I found out glViewport is called only by al_set_perspective_transform, and it depends on the size of the target bitmap.  I had set my target bitmap to the wrong size.  After setting it to the right size, it works!  </p><pre>
depend ramen/lib/draw.f
nativewh canvas: canv

: (size)  viewwh canv resize-canvas ;   \ &lt;-- what I wasn&#39;t doing!
: (upscale)  canv &gt;bmp onto&gt;  red backdrop   unmount call ;
: upscale&gt;  ( -- &lt;code&gt; )  (size)  r&gt;  (upscale)  mount  0 0 at  canv &gt;bmp blit ;
</pre><p>

Video -&gt; <a href="https://twitter.com/RamenEngine/status/1051203794552406016">https://twitter.com/RamenEngine/status/1051203794552406016</a>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (roger levy)</author>
		<pubDate>Sun, 14 Oct 2018 00:37:24 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Yeah, use glViewport to set the size of the target bitmap. Sorry I didn&#39;t say that earlier, could have saved you some trouble.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Edgar Reynaldo)</author>
		<pubDate>Mon, 15 Oct 2018 02:56:58 +0000</pubDate>
	</item>
</rss>
