diff options
author | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2020-11-05 01:49:19 +0000 |
---|---|---|
committer | giraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8> | 2020-11-05 01:49:19 +0000 |
commit | dcdcd798c9609a740e457077ea9d5ecc2df898e0 (patch) | |
tree | 57f73d47321bfeaf42261bff9a2645332977aca8 | |
parent | addc698fd51a9d99527cf008dc34a085142c7e91 (diff) | |
download | netpbm-mirror-dcdcd798c9609a740e457077ea9d5ecc2df898e0.tar.gz netpbm-mirror-dcdcd798c9609a740e457077ea9d5ecc2df898e0.tar.xz netpbm-mirror-dcdcd798c9609a740e457077ea9d5ecc2df898e0.zip |
miscellaneous update
git-svn-id: http://svn.code.sf.net/p/netpbm/code/userguide@3981 9d0c8265-081b-0410-96cb-a4ca84ce46f8
-rw-r--r-- | pamarith.html | 4 | ||||
-rw-r--r-- | pamtris.html | 221 |
2 files changed, 124 insertions, 101 deletions
diff --git a/pamarith.html b/pamarith.html index 17bb4558..0f300048 100644 --- a/pamarith.html +++ b/pamarith.html @@ -271,6 +271,8 @@ number of bit positions to shift. <p>Note that the maxval (see <a href="#maxval">Maxval</a>) determines the width of the frame within which you are shifting. +</dl> + <h3 id="otheroptions">Other</h3> <dl compact> @@ -279,8 +281,6 @@ the width of the frame within which you are shifting. <dd>This changes the meaning of <b>-equal</b>. It is not valid with any other function. See the description of <b>-equal</b>. -</dt> - </dl> <h2 id="seealso">SEE ALSO</h2> diff --git a/pamtris.html b/pamtris.html index 1e2bf7fa..8538e5b3 100644 --- a/pamtris.html +++ b/pamtris.html @@ -2,8 +2,8 @@ <html><head><title>Pamtris User Manual</title></head> <body> <h1>pamtris</h1> -Updated: 15 June 2019 -<br> +Updated: 05 November 2020 +<p> <a href="#index">Table Of Contents</a> <h2>NAME</h2> @@ -64,9 +64,10 @@ as a (potentially multi-image) PAM stream on Standard Output. </code> </pre> -<p>produces this: +<p>produces this: -<img src="pamtris_fan.png" alt="Example Pamtris output for fan mode"> +<p> +<img src="pamtris_fan.png" alt="Example pamtris output for FAN mode"> <p>The input file gives triangle data by setting the appropriate drawing mode, if necessary, and then providing a list of vertices. Each vertex is also @@ -76,8 +77,8 @@ values between 0 and a given maxval. In the most common usage, you use are an RGB specification of a color. Such attribute lists may be provided on a per-vertex basis. -<p>Before images can be effectively written to Standard Output, <b>pamtris</b> -gradually rasterizes them on an internal frame buffer which consists of an +<p>Prior to effectively writing a PAM image to Standard Output, <b>pamtris</b> +first rasterizes it onto an internal frame buffer, which consists of an "image buffer" and a "depth buffer." The image buffer consists of a sequence of <i>height</i> rows containing a sequence of <i>width</i> tuples. There is one sample for each vertex attribute in every tuple plus an opacity (alpha) @@ -182,7 +183,7 @@ and process it with: to yield: <p> -<img src="pamtris_strip.png" alt="Example Pamtris output for strip mode"> +<img src="pamtris_strip.png" alt="Example pamtris output for STRIP mode"> <h3 id="examples_triangles">Triangle Mode</h3> @@ -220,7 +221,7 @@ and process it with: to yield: <p> -<img src="pamtris_pierce.png" alt="Example Pamtris output for triangle mode"> +<img src="pamtris_pierce.png" alt="Example pamtris output for TRIANGLES mode"> <h3 id="pamtris_c">Meta-programming</h3> @@ -230,10 +231,16 @@ directly for any serious drawing; you will probably want to use a general purpose programming language to generate a temporary <b>pamtris</b> command file. -<p>For example, the following C program generates <b>pamtris</b> instructions -to produce a picture of NAMCO's Pac-Man. It generates dozens of -<b>vertex</b> commands tracing around the perimeter of a circle. +<p>For example, the <b>draw_pacman</b> procedure in the following C program +generates <b>pamtris</b> instructions to produce a picture of NAMCO's Pac-Man, +with custom colors, position, radius, orientation and mouth opening angle. It +generates dozens of <b>vertex</b> commands tracing around the perimeter of a +circle. (Note: The PAM image produced by piping the output of the below program +into <b>pamtris</b> was subsequently downscaled through +<b>pamscale -linear -xscale 0.5 -yscale 0.5</b> to achieve +an <a href="#antialias">anti-aliased</a> effect.) +<p> <img alt="Pac-Man" src="pamtris_pacman.png"> <pre> @@ -245,62 +252,85 @@ to produce a picture of NAMCO's Pac-Man. It generates dozens of * tupletyple = RGB_ALPHA * --------------------------------- */ +#include <stdint.h> #include <stdio.h> #include <math.h> -#define PI 3.141592 -#define PI2 (2.0 * PI) +#define PI 3.14159265358979323844 + +struct rgb_spec { uint8_t r, g, b; }; + +void draw_pacman ( + int const center_x, + int const center_y, + int const radius, + int const depth, + struct rgb_spec const inner_color, + struct rgb_spec const outer_color, + int const orientation, /* <-- Angle of mouth's horizontal axis, in + * degrees. */ + int const mouth_half_angle /* <-- Half angle between mouth's top and + * bottom, in degrees. Use something between 0 + * and 180. */ +) { + double const ori_rad = PI*orientation/180; + double const mha_rad = PI*mouth_half_angle/180; + + printf("mode fan\n" + "attr %d %d %d\n" + "vert %d %d %d\n" + "attr %d %d %d\n", + inner_color.r, inner_color.g, inner_color.b, + center_x, center_y, depth, + outer_color.r, outer_color.g, outer_color.b + ); + + { + double angle; + + for(angle = mha_rad; angle <= 2*PI - mha_rad; angle += 2*PI/360) + { + int const x = round(center_x + cos(ori_rad + angle) * radius); + int const y = round(center_y - sin(ori_rad + angle) * radius); -#define WIDTH 256 -#define HEIGHT WIDTH + printf("vertex %d %d %d\n", x, y, depth); + } + } +} int main(void) { - int const center_x = 0.5 * WIDTH; - int const center_y = 0.5 * HEIGHT; - - double const radius = 0.48 * WIDTH; - - int const sectors = round(0.125 * PI * radius + 1); - - puts("mode triangles"); - - printf("vertex %d %d 0\n", center_x, center_y); - printf("vertex %d %d 0\n", WIDTH, 0); - printf("vertex %d %d 0\n", WIDTH, HEIGHT); + struct rgb_spec const inner_colors[3] = { + {255, 255, 0}, { 0, 200, 255}, {0, 255, 80} + }; + struct rgb_spec const outer_colors[3] = { + {255, 25, 0}, {200, 0, 255}, {0, 100, 10} + }; - puts("clear image"); - puts("mode fan"); - puts("attribs 255 255 0"); - printf("vertex %d %d 1\n", center_x, center_y); - puts("attribs 255 128 0"); + int i; - double const angle_step = PI2 / (sectors - 1); + for(i = 0; i < 3; i++) + draw_pacman(128 + cos(i*2*PI/3)*72, 128 - sin(i*2*PI/3)*72, + 58 , 0 , + inner_colors[i] , outer_colors[i] , + i*120 , (3-i)*15 + ); - unsigned int i; + puts("!"); - for (i = 0; i < sectors; i++) - { - double const angle = angle_step * i; - int const x = round(cos(angle) * radius + center_x); - int const y = round(sin(angle) * radius + center_y); - - printf("vertex %d %d 1\n", x, y); - } - - puts("print"); - - return 0; + return 0; } + </code> </pre> -<p>Below are two other examples which, although not as trivial, demonstrate -what else can be feasibly obtained through this meta-programming approach, -especially when combining <b>pamtris</b> with other Netpbm programs (Earth -texture from -<a href="https://visibleearth.nasa.gov/view.php?id=73580">nasa.gov</a>): +<p>Below are two other examples which demonstrate what else can be feasibly +obtained through this meta-programming approach, especially when combining +<b>pamtris</b> with other Netpbm programs (Earth texture from +<a href="https://visibleearth.nasa.gov/view.php?id=73580" target="_tab"> +nasa.gov</a>): +<p> <img alt="Isometric Rainbow Waves" src="pamtris_isowaves.gif"> <img alt="Rotating Earth" src="pamtris_earth.gif"> @@ -328,11 +358,11 @@ the closed range [1, 8192]. <p>This option is mandatory.</dd> <dt><b>-num_attribs=</b><i>attributes_per_vertex</i></dt> -<dd>This is the number of attributes per vertex and, by extension, the depth -of the output PAM images, which is equal to this value plus one (to accomodate -the alpha plane). The argument must be an integer in the closed range [1, 20]. +<dd>This is the number of attributes per vertex. The depth of the output +PAM images equals this value plus one (to accomodate the alpha plane). The +argument must be an integer in the closed range [1, 20]. -<p>The input instruction sequence may override this with a <b>reset</b> +<p>The input instruction stream may override this with a <b>reset</b> command. <p>You must specify exactly one of <b>-num_attribs</b>, <b>-rgb</b>, @@ -343,7 +373,7 @@ and <b>-grayscale</b>. <dd>This is the tuple type for the output PAM images. The argument is a string which may be no longer than 255 characters. -<p>The input instruction sequence may override this with a <b>reset</b> +<p>The input instruction stream may override this with a <b>reset</b> command. <p>The default is an empty (null) string. @@ -362,7 +392,7 @@ RGB(_ALPHA) color images directly, and the three vertex attributes are the red, green and blue levels of the color associated with the vertex, in that order. -<p>The input instruction sequence may override this with a <b>reset</b> +<p>The input instruction stream may override this with a <b>reset</b> command. <p>You must specify exactly one of <b>-num_attribs</b>, <b>-rgb</b>, @@ -376,7 +406,7 @@ Another convenience option, similar to <b>-rgb</b>; except this one is an alias for <b>-num_attribs=</b>1 <b>-tupletype=GRAYSCALE_ALPHA</b>. The one vertex attribute is the gray level associated with the vertex. -<p>The input instruction sequence may override this with a <b>reset</b> +<p>The input instruction stream may override this with a <b>reset</b> command. <p>You must specify exactly one of <b>-num_attribs</b>, <b>-rgb</b>, @@ -391,15 +421,15 @@ closed range [1, 65535]. <p>The default value is 255. -<p>The input instruction sequence may override this with a +<p>The input instruction stream may override this with a <b>reset</b> command. </dd> </dl> <h2 id="instruction_code">INSTRUCTION CODE</h2> -<p>The input for <b>pamtris</b> consists of a sequence of text lines sent to -it through the Standard Input mechanism. +<p>The input for <b>pamtris</b> consists of a stream of text lines read from +Standard Input. <p>Empty lines or lines that contain only white space characters are called blank lines and are ignored. @@ -409,14 +439,14 @@ along with every character after it. In other words, everything from the <b>#</b> until the end of the line receives the same treatment as white space. -<p>Lines which are not blank must contain a sequence of strings separated by -white space, called tokens. The first such token must be one of the +<p>Lines which are not blank must contain a sequence of strings, called +tokens, separated by white space. The first such token must be one of the commands recognized by <b>pamtris</b>, and all further tokens are interpreted as the arguments for that command, if it takes any. When an insufficient number of arguments is provided for a command, the line is considered invalid -and is given the same treatment as a blank line. The same happens when an -out of range argument or one of a kind different of what is expected is given -(for example, when you give a string of letters where a numerical value is +and is given the same treatment as a blank line. The same happens when an out +of range argument or one of a kind different of what is expected is given (for +example, when you give a string of letters where a numerical value is expected), or when an unrecognized command/argument is found. When a number of arguments greater than that required for a particular command is provided, only the portion of the line up to the last required argument is considered @@ -498,7 +528,8 @@ means that every <i>N</i><sup>th</sup> triangle is specified by vertices </dd> <dt> -<b>attribs</b> <i>a<sub>0</sub></i> ... <i>a<sub>num_attribs - 1</sub></i> +<b>attribs</b> <i>a<sub>0</sub></i> <i>a<sub>1</sub></i> +<i>a<sub>2</sub></i> ... <i>a<sub>num_attribs - 1</sub></i> </dt> <dd> <p>This updates the current attribute values list. This command takes as @@ -571,34 +602,26 @@ perspective, you must provide an appropriate value for this parameter, otherwise the output images might look very wrong. <i>w</i> was new in Netpbm 10.85 (December 2018). -<p>One way to compute <i>w</i> for a vertex in a image which is -intended to look as in perspective is as follows. First, consider the -<a href="https://en.wikipedia.org/wiki/Viewing_frustum">typical model</a> -of the so-colled "viewing frustum" used to project vertices in 3D -"world space" onto a planar "image space." The value of <i>w</i> for a -vertex is simply the -<a id="vertex_note_link" href="#vertex_note">dot product*</a> between the 3D -vector <b>r</b> and the 3D unit vector <b>n</b> (i.e. the length of the -orthogonal projection of <b>r</b> on the line determined by <b>n</b>) in -pixels; where <b>r</b> is the vector which goes from the projection reference -point (PRP, or "eye") to the vertex, and <b>n</b> is a view-plane normal -(VPN) of unit length which points away from the PRP. - -<p>In case you are performing a mere multiplication of a 4D vector with -x, y, z and w components by a so-called perspective projection 4x4 matrix -in order to compute the projection of a vertex onto the image plane, -then you may supply for <i>w</i> a value which is directly proportional -to the absolute value of the w component of the resulting vector. - -<p>[<a id="vertex_note" href="#vertex_note_link">*</a>]: -For any two 3D vectors <b>a</b> and <b>b</b>, with respective -real scalar components a<sub>x</sub>, a<sub>y</sub>, a<sub>z</sub> and -b<sub>x</sub>, b<sub>y</sub>, b<sub>z</sub>, the dot product between -<b>a</b> and <b>b</b> is simply -a<sub>x</sub> * b<sub>x</sub> + -a<sub>y</sub> * b<sub>y</sub> + -a<sub>z</sub> * b<sub>z</sub>. - +<p>Consider the +<a href="https://en.wikipedia.org/wiki/Viewing_frustum" target="_tab"> +typical model</a> of the so-called "viewing frustum" used to project vertices +in 3D "world space" onto a planar "image space." If we adopt the convention +that a "z-plane" means any plane parallel to the view-plane (a.k.a. picture +plane, a.k.a. near plane), the value of <i>w</i> for a vertex should then be +the (smallest/euclidean/orthogonal) distance in pixels between the projection +reference point (PRP, or "eye") and the z-plane containing the vertex. One +way to compute this value amounts to simply taking the dot product between +the 3D vector <b>r</b> and the 3D unit vector <b>n</b>, where <b>r</b> is +the vector which goes from the projection reference point (PRP, or "eye") to +the vertex, and <b>n</b> is a view-plane normal (VPN) of unit length which +points away from the PRP. In other words, this is equal to the length of the +orthogonal projection of <b>r</b> on the line "determined" by <b>n</b>. + +<p>(Note: For any two 3D vectors <b>a</b> and <b>b</b>, with respective real +scalar components a<sub>x</sub>, a<sub>y</sub>, a<sub>z</sub> and +b<sub>x</sub>, b<sub>y</sub>, b<sub>z</sub>, the dot product between <b>a</b> +and <b>b</b> is simply +a<sub>x</sub>*b<sub>x</sub> + a<sub>y</sub>*b<sub>y</sub> + a<sub>z</sub>*b<sub>z</sub>.) </dd> <dt><b>print</b></dt> @@ -710,14 +733,14 @@ the images produced by <b>pamtris</b> are perspective-correct. inteded to be "repeated" along triangle meshes. -<h3>Anti-aliased edges</h3> +<h3 id="antialias">Anti-aliased edges</h3> <p><b>pamtris</b> performs no anti-aliasing on triangle edges by itself. However, it is possible to obtain anti-aliased images through a "super-sampling" approach: draw your image(s) at a size larger than -the desired final size, and then, when all post-processing is done, -down-scale the final image(s) to the desired size. Drawing images with -twice the desired width and height, then down-scaling them to the intended +the desired final size, and then, when all postprocessing is done, +downscale the final image(s) to the desired size. Drawing images with +twice the desired width and height, then downscaling them to the intended size while disregarding gamma (i.e. what <b>pamscale -linear</b> does) often produces good enough results. |