Repository navigation
Expand file tree
/
Copy pathgraphicsapi.html
More file actions
332 lines (258 loc) · 35.7 KB
/
Copy pathgraphicsapi.html
File metadata and controls
332 lines (258 loc) · 35.7 KB
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
<!DOCTYPE html><html xmlns:dc="http://purl.org/dc/terms/" xmlns:og="http://ogp.me/ns#" ><head><meta http-equiv=Content-Type content="text/html; charset=utf-8"><title>Lean Programming Interfaces for Classic Graphics</title><meta name="citation_pdf_url" content="https://peteroupc.github.io/graphicsapi.pdf"><meta name="citation_url" content="https://peteroupc.github.io/graphicsapi.html"><meta name="citation_title" content="Lean Programming Interfaces for Classic Graphics"><meta name="dc.date" content="2026-10-14"><meta name="citation_date" content="2026/10/14"><meta name="citation_publication_date" content="2026/10/14"><meta name="citation_online_date" content="2026/10/14"><meta name="og:title" content="Lean Programming Interfaces for Classic Graphics"><meta name="og:type" content="article"><meta name="og:url" content="https://peteroupc.github.io/graphicsapi.html"><meta name="og:site_name" content="peteroupc.github.io"><meta name="dc.format" content="text/html"><meta name="dc.language" content="en"><meta name="title" content="Lean Programming Interfaces for Classic Graphics"><meta name="dc.title" content="Lean Programming Interfaces for Classic Graphics"><meta name="twitter:title" content="Lean Programming Interfaces for Classic Graphics"><meta name="dc.creator" content="Peter Occil"/><meta name="author" content="Peter Occil"/><meta name="citation_author" content="Peter Occil"/><meta name="viewport" content="width=device-width"><link rel=stylesheet type="text/css" href="/style.css">
<script type="text/x-mathjax-config"> MathJax.Hub.Config({"HTML-CSS": { availableFonts: ["STIX","TeX"], linebreaks: { automatic:true }, preferredFont: "TeX" },
tex2jax: { displayMath: [ ["$$","$$"], ["\\[", "\\]"] ], inlineMath: [ ["$", "$"], ["\\\\(","\\\\)"] ], processEscapes: true } });
</script><script type="text/javascript" async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-AMS_HTML-full"></script></head><body> <div class="header">
<nav><p><a href="#navigation">Menu</a> - <a href="#top">Top</a> - <a href="/">Home</a></nav></div>
<div class="mainarea" id="top">
<h1 id="lean-programming-interfaces-for-classic-graphics">Lean Programming Interfaces for Classic Graphics</h1><p>This version of the document is dated 2026-10-14. <a href='https://github.com/peteroupc/peteroupc.github.io/issues'>Post an issue or comment on this document</a>.</p>
<p><a href="mailto:poccil14@gmail.com"><strong>Peter Occil</strong></a></p>
<p>Notes on developing an application programming interface (API) for classic graphics with as few entry points as possible. As given in my <a href="https://peteroupc.github.io/graphics.html"><strong>specification for such graphics</strong></a>, <em>classic graphics</em> generally means 2-D or 3-D graphics achieved by video games before the year 2000 and the rise of programmable “shaders”. In general, pre-2000 graphics involve a screen with no more pixels than a 640-×-480 screen, up to 12,800 3-D polygons at a time (fewer if the game screen is smaller), and tile- or sprite-based 2-D graphics.</p>
<p><a id="Goal_An_Open_Source_Engine_or_API_for_Classic_Graphics"></a></p>
<h2 id="goal-an-open-source-engine-or-api-for-classic-graphics">Goal: An Open-Source Engine or API for Classic Graphics</h2>
<p>It would be of interest to write a free and open-source graphics engine that implements <a href="https://peteroupc.github.io/graphics.html#The_Specification"><strong>the classic-graphics specification</strong></a> and renders graphics in software (with a minimum of source code and dependencies),<sup id="fnref:1"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup> or to establish a lean API for that specification. The following are examples:</p>
<ul>
<li><em>Quake</em> (1996), <em>Quake II</em> (1997), and <em>Quake III Arena</em> (1999) popularized the practice of using only a subset of the OpenGL 1.1 programming interface for a game’s graphics rendering<sup id="fnref:2"><a href="#fn:2" class="footnote" rel="footnote" role="doc-noteref">2</a></sup>.</li>
<li>The <a href="https://github.com/kitao/pyxel?tab=readme-ov-file#api-reference"><strong>API reference</strong></a> for the two-dimensional (2-D) game engine <em>Pyxel</em>. But, in addition to the efforts there, a minimal version of the Python language runtime and nonreliance on hardware acceleration would be worthwhile.</li>
<li>The <a href="https://registry.khronos.org/OpenGL/index_es.php"><strong>OpenGL ES</strong></a> 1.1 or 1.0 (either the Common profile or the Common-Lite profile with fixed-point but not floating-point arithmetic) is an approximation of pre-2000 3-D graphics.</li>
<li>Borland Graphics Interface (BGI), a 2-D graphics API (for example, <em>Turbo C User’s Guide</em>, chapter 8).</li>
<li>Certain game-oriented <a href="https://leikareipa.github.io/blog/wrapping-old-graphics-apis/"><strong>3-D graphics APIs</strong></a> from the 1990s, such as 3dfx’s Glide, S3’s S3d, ATI’s CIF, and Matrox Simple Interface.</li>
</ul>
<p>The graphics engine is intended to run even on computers from around 2005 (and maybe even on older computers), and with low resources, and so to enable video games that run with acceptable performance on those computers.</p>
<p><a id="2_D_Graphics"></a></p>
<h2 id="d-graphics">2-D Graphics</h2>
<p>The simplest way to proceed is to give the application a <em>frame buffer</em>, a block of system memory consisting of a rectangular array of pixel samples. The nature of each pixel sample depends on the game’s needs; for example, it may be an 8-bit index to a color palette, or a 16-bit color value. In this case, the application must render graphics in software.<sup id="fnref:1:1"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup></p>
<blockquote>
<p><strong>Note:</strong> Under the classic-graphics specification, the frame buffer has no more than 307,200 pixels, that is, no more pixels than a 640-×-480 screen.</p>
</blockquote>
<p>A tile- and sprite-based API suggested by the classic-graphics specification is yet to be determined.</p>
<p>The following is a sketch of what could be included in a lean API for copying and stretching 2-D images as well as for geometric drawing.</p>
<ul>
<li>Getting and setting pixel values of an image.</li>
<li>Filling with a solid color a rectangular area (whose edges have integer coordinates) of an image.</li>
<li>Copying a rectangular area (whose edges have integer coordinates) of an image onto the same or another image, with optional nearest-neighbor scaling. The copying can optionally support transparency, in the sense that transparent pixels or pixels of a certain color are excluded.</li>
<li>Filling 2-D paths with a solid color, with even/odd or nonzero winding order. 2-D paths are sequences of path segments (line segments, quadratic Bézier curves, cubic Bézier curves, and elliptical arcs).</li>
<li>Drawing simple outlines of 2-D paths with a solid color.<sup id="fnref:3"><a href="#fn:3" class="footnote" rel="footnote" role="doc-noteref">3</a></sup></li>
<li>Flood filling colored areas of an image.<sup id="fnref:4"><a href="#fn:4" class="footnote" rel="footnote" role="doc-noteref">4</a></sup></li>
<li>Optionally, “inverting” the colors or color indices of an image within a rectangular area (whose edges have integer coordinates).</li>
<li>Optionally, fading an image to or from black.<sup id="fnref:5"><a href="#fn:5" class="footnote" rel="footnote" role="doc-noteref">5</a></sup></li>
</ul>
<p>A leaner API could provide for the following instead:</p>
<ul>
<li>Getting and setting pixel values of an image.</li>
<li>Filling the following figures with a solid color.
<ul>
<li>Rectangles whose edges have integer coordinates, and ellipses that are tightly contained in them.</li>
<li>Polygons with integer coordinates and even/odd or nonzero winding order. The API can choose to support arbitrary polygons, convex polygons only, or monotone-vertical polygons only.<sup id="fnref:6"><a href="#fn:6" class="footnote" rel="footnote" role="doc-noteref">6</a></sup></li>
</ul>
</li>
<li>Drawing simple outlines of line segments with a solid color, supporting only integer coordinates.<sup id="fnref:3:1"><a href="#fn:3" class="footnote" rel="footnote" role="doc-noteref">3</a></sup></li>
<li>Flood filling colored areas of an image.<sup id="fnref:4:1"><a href="#fn:4" class="footnote" rel="footnote" role="doc-noteref">4</a></sup></li>
<li>Optionally:
<ul>
<li>“Inverting” the colors or color indices of an image within a rectangular area (whose edges have integer coordinates).</li>
<li>Drawing simple outlines of elliptical arcs with a solid color, supporting only integer coordinates.<sup id="fnref:3:2"><a href="#fn:3" class="footnote" rel="footnote" role="doc-noteref">3</a></sup>, <sup id="fnref:7"><a href="#fn:7" class="footnote" rel="footnote" role="doc-noteref">7</a></sup></li>
<li>Copying a rectangular area (whose edges have integer coordinates) of an image onto the same or another image, with no scaling or transparency supported.</li>
</ul>
</li>
</ul>
<p>For both APIs, antialiasing (smoothing) is optional, and it’s enough for the APIs to draw to images stored in system memory, and not also to support drawing to video memory or directly to the screen.</p>
<p>The following is not included in either API.</p>
<ul>
<li>Color palette functions. Images may or may not have a color table, and the application is assumed to handle colors on an image-by-image basis. (There is the matter of sending finished images to the user’s display, which may vary in the number of colors it supports, but the lean 2-D API need not be concerned about this.)</li>
<li>Text rendering (see next section).</li>
</ul>
<p><a id="Text_Rendering"></a></p>
<h3 id="text-rendering">Text Rendering</h3>
<p><a href="https://behdad.org/text2024"><strong>Text rendering</strong></a> is essentially the drawing of <em>glyphs</em> of text.</p>
<p><em>Glyphs</em> are graphics that represent elements of text (examples are letters, digits, the <em>i</em>’s dot, and the <em>f-f-l</em> combination). A <em>font</em> is a collection of these glyphs along with rules for drawing and placing them. Glyphs are often but not always mapped one-to-one to letters or other writing symbols.</p>
<p>Before 2000,<sup id="fnref:8"><a href="#fn:8" class="footnote" rel="footnote" role="doc-noteref">8</a></sup> there were three kinds of fonts for screen display:</p>
<ul>
<li>Raster fonts (the glyphs are images).</li>
<li>Vector fonts (the glyphs are made of line segments and/or curves; Hershey, Modern, and Script are examples)</li>
<li>Outline fonts (the glyphs are filled 2-D paths; TrueType fonts are examples).</li>
</ul>
<p>For example, Borland Graphics Interface supports raster and vector fonts (called “bit-mapped” and “stroked” fonts in <em>Turbo C User’s Guide</em>, chapter 8), while Windows CE 2.0 supports raster and outline fonts (Christiansen).</p>
<p>In most cases in the 1990s and earlier, glyphs were drawn unsmoothed and in a single color.<sup id="fnref:9"><a href="#fn:9" class="footnote" rel="footnote" role="doc-noteref">9</a></sup></p>
<p>Text rendering need not be supported by either API mentioned previously, since the needs of applications in supporting writing systems and languages vary, as do approaches to rendering text. Moreover, the conversion of text to glyphs and the positioning of such glyphs is often nontrivial. If text rendering is supported, glyph smoothing is optional.</p>
<p><a id="Possible_Additions"></a></p>
<h3 id="possible-additions">Possible Additions</h3>
<p>It is unclear whether to include any of the following in the lean 2-D graphics API; this will depend on how heavily pre-2000 or pre-1995 video games (spanning PCs, home computers, game consoles, and arcade machines) made use of them.</p>
<ol>
<li>2-D affine transformations (which keep parallel lines parallel; examples are scalings, shears, and rotations).</li>
<li>Translations, rotations and scalings, but no other 2-D affine transformations.</li>
<li>Translations, rotations, scalings, and reflections, but no other 2-D affine transformations.</li>
<li>So-called “<a href="https://learn.microsoft.com/en-us/windows/win32/gdi/raster-operation-codes"><strong>raster operations</strong></a>” (bit-by-bit operations between two images), such as those found in the Windows API (for example, <code>BitBlt</code>) and in the “Microsoft C runtime” (for example, <code>_putimage</code>, <code>_setwritemode</code>).</li>
<li><a href="https://ciechanow.ski/alpha-compositing/"><strong>Alpha compositing</strong></a> while drawing 2-D graphics.</li>
<li>Drawing one image part over another (the “over” operation of Porter and Duff 1984), with optional translucency, but no other nontrivial alpha compositing. The images may have translucent (semitransparent) or transparent pixels.</li>
<li>Same as point 6, except the images can’t have translucent pixels.</li>
<li>Drawing dashed 2-D paths, also known as “styled lines” or “stippled lines”.</li>
<li>Filling rectangular areas with a repeating image pattern without transparent or translucent pixels.</li>
<li>Filling rectangular areas with a repeating image pattern. The image may have transparent pixels.</li>
<li>Filling arbitrary 2-D paths with a repeating image pattern. The image may have transparent pixels.</li>
<li>Drawing a solid color over an image, with optional translucency, but no other nontrivial alpha compositing. This implements “fading in” and “fading out”.</li>
</ol>
<blockquote>
<p><strong>Notes:</strong></p>
<ul>
<li>Note on points 1 to 3: Unlike the Windows NT GDI, the 16-bit GDI did not support arbitrary affine transformations; notably, it did not support rotations or shears (for references, see “Further Reading”).</li>
<li>Note on point 8: Simple outlines of 2-D paths are dashed (“styled”) by leaving out pixels (examples include the “Microsoft C Runtime”’s <code>_getlinestyle</code>, the Borland Graphics Interface’s <code>setlinestyle</code>, OpenGL 1.1’s <code>glLineStipple</code>, or the <a href="https://learn.microsoft.com/en-us/previous-versions/windows/drivers/display/styled-cosmetic-lines"><strong>sophisticated approach</strong></a> in the Windows NT GDI that depends on the horizontal and vertical spacing between pixels). More general outlines of a 2-D path are dashed by leaving out parts of the path (an example is <a href="https://learn.microsoft.com/en-us/previous-versions/windows/drivers/display/geometric-wide-lines"><strong>found in Windows NT’s model</strong></a>).</li>
<li>Note on points 9 to 11: Windows’s <code>CreatePatternBrush</code> function for creating repeating image patterns supported only 8 × 8 or smaller images in Windows 95 and Windows 3.x.</li>
</ul>
</blockquote>
<p><a id="3_D_Graphics"></a></p>
<h2 id="d-graphics-1">3-D Graphics</h2>
<p>Unlike with today’s programmable “shaders”, classic 3-D video-game graphics support only simple, yet admirable capabilities for real-time rendering of three-dimensional scenes, as well as a low scene complexity by today’s standards (fewer than 20,000 triangles per frame).</p>
<p>This section gives suggestions for a lean API supporting 3-D graphics. Any implementation of it should render graphics in software<sup id="fnref:1:2"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup> and optionally with hardware acceleration. As with 2-D, the 3-D API is allowed to support drawing to images stored in system memory without also supporting drawing to video memory or directly to the screen.</p>
<p>The <a href="https://peteroupc.github.io/graphics.html"><strong>classic-graphics specification</strong></a> allows the following <a href="https://peteroupc.github.io/graphics.html#3_D_graphics"><strong>3-D graphics capabilities</strong></a>:</p>
<ul>
<li>Z buffering (depth buffering).</li>
<li>Bilinear filtering.</li>
<li>Flat shading and Gouraud shading.</li>
<li>Perspective correction.</li>
<li>Per-vertex specular highlighting.</li>
<li>Per-vertex depth-based fog.</li>
<li>3-D line drawing.</li>
<li>Two-texture blending.</li>
<li>Edge antialiasing (smoothing).</li>
<li>MIP mapping.</li>
<li>Source and destination alpha blending.</li>
</ul>
<p>These features were more or less supported by 3-D graphics accelerators offered to consumers from 1995 to 1999, and by widely distributed 3-D game consoles throughout the 1990s. The <em>PC 99 System Design Guide</em> (1998) sections 14.27 to 14.34 (except for the screen resolution, frame rate, and double buffering requirements) are also in scope.</p>
<p>Stencil buffers, bump mapping, and three- or four-texture blending are borderline capabilities.</p>
<p><a id="Suggested_C_Language_Functions"></a></p>
<h3 id="suggested-c-language-functions">Suggested C-Language Functions</h3>
<pre>DrawTrianglesOneTex(State3D *state, float* vertices, uint32_t numvertices,
uint32_t * indices, uint32_t numindices, Texture *texture);
</pre>
<p>Draws a sequence of triangles. The <code>vertices</code> array is a rectangular array of numbers organized into “vertex blocks”. The number of <code>float</code>s pointed to must equal the number of <code>float</code>s per vertex block times <code>numvertices</code>. The number of indices (<code>numindices</code>) must be a multiple of 3. <code>float</code> is a number in IEEE 754 binary32 format.<sup id="fnref:10"><a href="#fn:10" class="footnote" rel="footnote" role="doc-noteref">10</a></sup></p>
<blockquote>
<p><strong>Note:</strong> As given in the classic graphics specification, the number of vertices per frame should be no more than 38,400 for a screen resolution of 640 × 480.</p>
</blockquote>
<p>There are several possibilities for “vertex blocks”:</p>
<ul>
<li>Each “vertex block” has eight <code>float</code> values: the x-, y-, and z-coordinates; the normal vector’s X, Y, and Z components; and the texture coordinates (U and V).</li>
<li>Each “vertex block” has five <code>float</code> values: the x-, y-, and z-coordinates; and the two texture coordinates. This is for games that render only textured triangles and calculate their own lighting.</li>
</ul>
<p><code>state</code> is the 3-D graphics state, to be determined. This state will include the game’s frame buffer, and possibly additional parameters yet to be determined.</p>
<p><code>texture</code> is information about the texture, to be determined. This information will include the texture’s image data and a blending operation (add, modulate, etc.).</p>
<pre>DrawTriangleFanOneTex(State3D * state, float* vertices, uint32_t numvertices, Texture *texture);
</pre>
<p>Draws a triangle fan. <code>vertices</code>, <code>texture</code>, and <code>numvertices</code> are as in <code>DrawTrianglesOneTex</code>. Moreover, <code>numvertices</code> must be 3 or greater.</p>
<pre>DrawTriangleStripOneTex(State3D * state, float* vertices, uint32_t numvertices, Texture *texture);
</pre>
<p>Draws a triangle strip. <code>vertices</code>, <code>texture</code>, and <code>numvertices</code> are as in <code>DrawTrianglesOneTex</code>. Moreover, <code>numvertices</code> must be 3 or greater.</p>
<pre>DrawTrianglesTwoTex(State3D * state, float* vertices, uint32_t numvertices,
uint32_t * indices, uint32_t numindices, Texture *texture1, Texture *texture2);
DrawTriangleFanTwoTex(State3D * state, float* vertices, uint32_t numvertices,
Texture *texture1, Texture *texture2);
DrawTriangleStripTwoTex(State3D * state, float* vertices, uint32_t numvertices,
Texture *texture1, Texture *texture2);
</pre>
<p>Like the corresponding <code>...OneTex</code> versions, with the following exceptions. Each vertex block has ten <code>float</code> values: the x-, y-, and z-coordinates; the normal vector’s X, Y, and Z components; the texture coordinates (U and V) for <code>texture1</code>; and the texture coordinates for <code>texture2</code>. These functions are suggested here because some games from the late 1990s rely on so-called <em>light-map</em> textures and two-texture blending rather than in-game lighting calculations.</p>
<pre>DrawTriangles(State3D *state, float* vertices, uint32_t numvertices,
uint32_t * indices, uint32_t numindices);
DrawTriangleFan(State3D *state, float* vertices, uint32_t numvertices);
DrawTriangleStrip(State3D *state, float* vertices, uint32_t numvertices);
</pre>
<p>Draws triangles without textures. Like the corresponding <code>...OneTex</code> versions, with the following exceptions. Each “vertex block” has six <code>float</code> values: the x-, y-, and z-coordinates; and a color’s red, green, and blue values, each ranging from 0 through 1. This is for games that render only triangles without textures. These functions are suggested here because some games from the mid- to late 1990s often draw polygons without textures.</p>
<p>This is far from a complete list of useful 3-D drawing functions; there may be others, but the goal is to define a compact set of functions supporting only those 3-D capabilities actually used by video games in the 1990s and earlier.</p>
<p><a id="Further_Reading"></a></p>
<h2 id="further-reading">Further Reading</h2>
<ul>
<li>Abrash, M., <a href="https://github.com/jagregory/abrash-black-book"><strong><em>Michael Abrash’s Graphics Programming Black Book: Special Edition</em></strong></a>, 1997.</li>
<li>Apple Computer Inc., <em>3D Graphics Programming With QuickDraw 3D 1.5.4</em>, 1997.</li>
<li>Borland International, <em>Turbo C Reference Guide: Version 2.0</em>, 1988.</li>
<li>Borland International, <em>Turbo C User’s Guide: Version 2.0</em>, 1988. Chapter 8 under “Programming in Graphics Mode” discusses the BGI graphics library.</li>
<li>Bresenham, Jack E., “Algorithm for computer control of a digital plotter.” <em>IBM Systems Journal</em> 4.1 (1965): 25-30, <a href="https://doi.org/10.1147/sj.41.0025"><strong>https://doi.org/10.1147/sj.41.0025</strong></a> (simple outlines of line segments).</li>
<li>Bresenham J.E., “A linear algorithm for incremental digital display of circular arcs”, Commun. ACM 20, 2 (Feb. 1977), 100–106, <a href="https://doi.org/10.1145/359423.359432"><strong>https://doi.org/10.1145/359423.359432</strong></a> (simple outlines of circular arcs).</li>
<li>Gery, R, “Primitive Cool”, Microsoft Developer Network, Mar. 17, 1992 (discusses how Windows 3.1 implements some graphical operations).</li>
<li>Intel & Microsoft, <em>PC 99 System Design Guide</em>, Microsoft Press, 1998. ISBN 0-7356-0518-1.</li>
<li><em>Microsoft C/C++ Version 7.0 Run-Time Library Reference</em> (1991), section 2.6 (“Microsoft C runtime”). Describes the graphics routines the named library supports.</li>
<li>Porter, T., and Duff, T. “Compositing Digital Images.” Computer Graphics 18(3), p 253 ff., 1984. <a href="https://doi.org/10.1145/800031.808606"><strong>https://doi.org/10.1145/800031.808606</strong></a></li>
<li>Ted Gruber Software, <em>Fastgraph User’s Guide</em>, April 1993.</li>
<li>Ted Gruber Software, <em>Fastgraph Reference Manual</em>, April 1993.</li>
<li>Van Aken, J.R., “An Efficient Ellipse-Drawing Algorithm,” in IEEE Computer Graphics and Applications, vol. 4, no. 9, pp. 24-35, Sept. 1984, <a href="https://doi.org/10.1109/MCG.1984.275994"><strong>https://doi.org/10.1109/MCG.1984.275994</strong></a>.</li>
<li>Zingl, A., “<a href="https://zingl.github.io/Bresenham.pdf"><strong>A Rasterizing Algorithm for Drawing Curves</strong></a>”, Technikum-Wien, 2016 (simple outlines of paths).</li>
<li>Woo, Mason, et al., <em>OpenGL Programming Guide: The Official Guide to Learning OpenGL, Version 1.1</em>, second edition, Addison Wesley Longman, 1997. ISBN 0-201-46138-2.</li>
</ul>
<p><a id="Windows_GDI"></a></p>
<h3 id="windows-gdi">Windows GDI</h3>
<p>Information about the Windows graphics device interface (GDI) is scattered in many documents.</p>
<ul>
<li>The GDI supported in Windows 95, Windows 98, and Windows 3.x (the “16-bit GDI”), along with its limitations, is described in the following references:
<ul>
<li>“Microsoft Windows Software Development Kit: Programmer’s Reference” (for Windows 3.1).</li>
<li>Charles Petzold, <em>Programming Windows 3.1: The Microsoft Guide to Writing Applications for Windows 3.1</em>, Microsoft Press, 1992. ISBN 1-55615-395-3.</li>
<li><em>Microsoft Win32 Programmer’s Reference</em> (for Windows 95 and Windows 98).</li>
<li>“Microsoft Win32 API Overview”, Microsoft Developer Network, February 1994.</li>
<li>“INFO: Developing Win32-Based GDI Apps for Windows 95 and Windows NT or Windows2000”, Microsoft Knowledge Base article Q136989.</li>
</ul>
</li>
<li>The Windows NT GDI is described in the following references. Its dashed-line feature did not materially change between the two references.
<ul>
<li>Chapter 3 of the <em>Graphics Driver Design Guide</em>, part of the Windows NT 4.0 Device Driver Kit.</li>
<li>The <a href="https://learn.microsoft.com/en-us/previous-versions/windows/drivers/display/"><strong>archived documentation for the XDDM</strong></a>, the driver model supported in Windows 2000, Windows XP, Windows Vista, and Windows 7.</li>
</ul>
</li>
<li>Windows CE’s GDI.<sup id="fnref:11"><a href="#fn:11" class="footnote" rel="footnote" role="doc-noteref">11</a></sup> Windows CE was an operating system for embedded and handheld computers.
<ul>
<li>Jon Christiansen, “Microsoft Windows CE Graphics Features” (undated, about 1997), describes Windows CE 2.0’s version of the GDI and its 2-D graphics features.</li>
<li><a href="https://learn.microsoft.com/en-us/previous-versions/windows/embedded/ms905330%28v=msdn.10%29"><strong>Windows CE 5.0 documentation</strong></a> (2006) has useful information on 2-D graphics operations for embedded and handheld computers, especially the pages on <a href="https://learn.microsoft.com/en-us/previous-versions/windows/embedded/aa447503%28v=msdn.10%29"><strong>video driver recommendations</strong></a>, <a href="https://learn.microsoft.com/en-us/previous-versions/windows/embedded/ms892485%28v=msdn.10%29"><strong>line drawing</strong></a>, and <a href="https://learn.microsoft.com/en-us/previous-versions/windows/embedded/aa452651%28v=msdn.10%29"><strong>supported features</strong></a>. (This information did not materially change in <a href="https://learn.microsoft.com/en-us/previous-versions/windows/embedded/ee504812%28v=winembedded.60%29"><strong>Windows Embedded CE 6.0</strong></a> [2010].) Notably, relatively few 2-D graphics operations (especially solid color fills, image area copying, and simple outlines of line segments) were worth accelerating in hardware; more complicated ones could be done in software or broken into simpler ones.<sup id="fnref:12"><a href="#fn:12" class="footnote" rel="footnote" role="doc-noteref">12</a></sup></li>
</ul>
</li>
</ul>
<p><a id="License"></a></p>
<h2 id="license">License</h2>
<p>Any copyright to this page is released to the Public Domain. In case this is not possible, this page is also licensed under <a href="https://creativecommons.org/publicdomain/zero/1.0/"><strong>Creative Commons Zero</strong></a>.</p>
<p><a id="Notes"></a></p>
<h2 id="notes">Notes</h2>
<div class="footnotes" role="doc-endnotes">
<ol>
<li id="fn:1">
<p>In this document, “rendering in software” means that the rendering of graphics does not rely on a video card or graphics accelerator, whether directly or indirectly (such as through GDI, OpenGL, or Direct3D), with the sole exception of sending a finished game screen image to the player’s display (such as through GDI’s <code>StretchDIBits</code> or copying to video memory). (Implementing a subset of <a href="https://registry.khronos.org/OpenGL/index_es.php"><strong>OpenGL ES</strong></a> 1.1 or <a href="https://registry.khronos.org/OpenGL/index_gl.php"><strong>OpenGL</strong></a> 1.1 in software without relying on a video card or graphics accelerator is allowed.) <a href="#fnref:1" class="reversefootnote" role="doc-backlink">↩</a> <a href="#fnref:1:1" class="reversefootnote" role="doc-backlink">↩<sup>2</sup></a> <a href="#fnref:1:2" class="reversefootnote" role="doc-backlink">↩<sup>3</sup></a></p>
</li>
<li id="fn:2">
<p>See, for example, “Optimizing OpenGL drivers for Quake3” by John Carmack, referenced in .plan, April 30, 1999. <a href="#fnref:2" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:3">
<p>In this document, a <em>simple outline</em> of a 2-D path (including a line segment, curve, or arc) is drawn by approximating the path with a sequence of points at integer coordinates and coloring the pixels at those points. (For example, if the path is a line segment whose endpoints have integer coordinates, an algorithm by Bresenham [1965] draws a simple outline of it.)<br />A “thicker” than simple outline can be drawn by approximating the 2-D path with line segments, then:<br />1. Drawing filled circles around each segment’s endpoints, then drawing filled rectangles that follow the path of each line segment, as in the 16-bit GDI (see Gery 1992). Or… <br />2. For each segment, drawing multiple simple outlines of that segment, shifted horizontally or vertically depending on the segment’s slope, as in OpenGL 1.1 (see Woo et al. 1997, chapter 2).<br />Thus, a lean graphics API need not support nonsimple outlines of paths. See also Bresenham (1965, 1977), Van Aken (1984), Zingl (2016). <a href="#fnref:3" class="reversefootnote" role="doc-backlink">↩</a> <a href="#fnref:3:1" class="reversefootnote" role="doc-backlink">↩<sup>2</sup></a> <a href="#fnref:3:2" class="reversefootnote" role="doc-backlink">↩<sup>3</sup></a></p>
</li>
<li id="fn:4">
<p>But the <em>Turbo C Reference Guide</em>, which describes a <code>floodfill</code> function, recommended an alternative to that function for compatibility reasons. <a href="#fnref:4" class="reversefootnote" role="doc-backlink">↩</a> <a href="#fnref:4:1" class="reversefootnote" role="doc-backlink">↩<sup>2</sup></a></p>
</li>
<li id="fn:5">
<p>This is not required for games that display no more than 256 colors at a time, since the game is assumed to have a game screen image with a color table, so that the fade effect can be implemented by altering the color table. <a href="#fnref:5" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:6">
<p>A “monotone-vertical” polygon is one that changes direction along the y-axis exactly twice, whether or not the polygon is self-intersecting. Every convex polygon is monotone-vertical. See chapter 41 of Abrash (1997). <a href="#fnref:6" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:7">
<p>Elliptical arcs were not available in Windows CE version 2.0 and earlier, unlike Windows 95, Windows NT, and Windows 3.x. See Jon Christiansen, “Microsoft Windows CE Graphics Features”, Bresenham (1975), Van Aken (1984). <a href="#fnref:7" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:8">
<p>Later developments in text rendering saw:<br />(1) The addition of scalable colored graphics, especially <em>emoji</em>, to outline fonts.<br />(2) <a href="http://rastertragedy.com/RTRCh2.htm#Sec2"><strong>“Subpixel” antialiasing</strong></a> of glyphs, such as the ClearType technology announced in November 1998.)<br />Both features are outside the scope of this document. <a href="#fnref:8" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:9">
<p>Windows 98 supported a systemwide setting to smooth the glyphs of outline fonts when the text size and bits per screen pixel are high enough. <a href="#fnref:9" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:10">
<p>This function and others in this section were inspired by APIs for drawing a block of 3-D primitives, such as the API introduced in DirectX 5’s Direct3D (Immediate Mode). By contrast, the approach of <em>execute buffers</em>, found in DirectX versions 2 and 3, is not adopted in this section since many game developers reportedly found it hard to use. Likewise, Direct3D Retained Mode, a high-level API built on top of Direct3D Immediate Mode, was very rarely used in practice. <a href="#fnref:10" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:11">
<p>In addition to the GDI, Windows CE 5.0 supports <a href="https://learn.microsoft.com/en-us/previous-versions/windows/embedded/aa452478%28v=msdn.10%29"><strong>Direct3D Mobile</strong></a>, and Windows CE .NET 4.2 supports a version of <a href="https://learn.microsoft.com/en-us/previous-versions/windows/embedded/ms892057%28v=msdn.10%29"><strong>Direct3D</strong></a>. Both APIs approximate pre-2000 three-dimensional computer graphics. <a href="#fnref:11" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
<li id="fn:12">
<p>Indeed, much “hardware acceleration” in graphics is simply the offloading of memory reads and writes to other processors. For example, a CPU can tell another processor to draw a line or circle onto a frame buffer, or to copy a rectangular area of memory, or to fill it with a 2-byte color value, rather than do those operations itself. <a href="#fnref:12" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
</ol>
</div>
</div><nav id="navigation"><ul>
<li><a href="/">Back to start site.</a>
<li><a href="https://github.com/peteroupc/peteroupc.github.io">This site's repository (source code)</a>
<li><a href="https://github.com/peteroupc/peteroupc.github.io/issues">Post an issue or comment</a></ul>
<div class="noprint">
<p>
<a href="//x.com/intent/post?text=Lean+Programming+Interfaces+for+Classic+Graphics&url=https%3A%2F%2Fpeteroupc.github.io%2Fgraphicsapi.html">Share via X (Twitter)</a>, <a href="//www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fpeteroupc.github.io%2Fgraphicsapi.html">Share via Facebook</a>, <a href="//news.ycombinator.com/submitlink?u=https%3A%2F%2Fpeteroupc.github.io%2Fgraphicsapi.html&t=Lean+Programming+Interfaces+for+Classic+Graphics">Share via Hacker News</a>, <a href="//www.reddit.com/submit?url=https%3A%2F%2Fpeteroupc.github.io%2Fgraphicsapi.html&title=Lean+Programming+Interfaces+for+Classic+Graphics">Share via Reddit</a>
</p>
</div>
<p style='font-size:120%;font-weight:bold'><a href='https://peteroupc.github.io/graphicsapi.pdf'>Download a PDF of this page</a></p><p>Of interest to the computer graphics and music community:</p><ul><li><a href='https://peteroupc.github.io/graphics.html'><b>Graphics for classic-style game development</b></a>.<li><a href='https://peteroupc.github.io/graphics.html#Building_a_Public_Domain_music_synthesis_library_and_instrument_banks'><b>MIDI music synthesis for classic-style games and apps</b></a>.<li><a href='https://peteroupc.github.io/classic-wallpaper'><b>Tileable wallpapers with limited colors and resolution</b></a>.<li><a href='https://peteroupc.github.io/graphicsapi.html'><b>Lean programming interfaces for classic graphics</b></a>.<li><a href='https://peteroupc.github.io/classic-wallpaper/docs/uielements.html'><b>Traditional user-interface graphics</b></a>.<li><a href='https://peteroupc.github.io/classic-wallpaper/docs/pixeltovector.html'><b>Converting images to vector graphics</b></a>.</ul><p>Open questions for math and probability experts:</p><ul><li><a href='https://peteroupc.github.io/requests.html'><b>Requests and open questions</b></a>.<li><a href='https://peteroupc.github.io/bernreq.html'><b>Open questions on the Bernoulli factory problem (the new-coins-from-old problem)</b></a>.<li><a href='https://peteroupc.github.io/requestsother.html'><b>Other open questions on probability</b></a>.<li><a href='https://peteroupc.github.io/sampling.html'><b>The sampling problem</b></a>.</ul></nav></body></html>