home *** CD-ROM | disk | FTP | other *** search
/ Windows 95 Secrets (4th Edition) / Windows95Secrets4thEdition.iso / tools / graphics / render / teapot.c_ / teapot
Encoding:
Text File  |  1996-05-12  |  7.9 KB  |  301 lines

  1. /*
  2.  * File: teapot.c
  3.  *
  4.  * Author: Rick LaMont
  5.  *
  6.  * Date: 3/29/96
  7.  *
  8.  * Purpose: Demonstrate Windows app which uses RenderDotC interface.
  9.  *
  10.  */
  11.  
  12. #include <windows.h>
  13. #include "rdc.h"            /* RenderDotC interface definition */
  14.  
  15. /*
  16.  * Constants
  17.  */
  18. #define MAXNPTS        100        /* Can revolve this many points */
  19. #define BEZIERWIDTH    12        /* Number of points in Bezier circle */
  20. #define F        0.4142135 * 4/3    /* Magic number for Bezier circles */
  21.  
  22. /*
  23.  * Typedefs
  24.  */
  25. typedef struct {
  26.     RDCfloat x, z;            /* Define 2D points in X-Z plane */
  27. } Point2D;
  28.  
  29. /*
  30.  * function: revolve
  31.  *
  32.  * input: An array of 2D points and the number of points in the array.
  33.  *
  34.  * returns: void
  35.  *
  36.  * purpose: Creates Bezier surface of revolution around Z-axis.
  37.  *
  38.  */
  39. static void revolve(const Point2D *points, int npoints)
  40. {
  41.     /* Use control points for 2D Bezier circle as revolution coefficients */
  42.     static RDCfloat coeff[][2] = {
  43.     { 1, 0}, { 1,  F}, { F,  1}, {0,  1}, {-F,  1}, {-1,  F},
  44.     {-1, 0}, {-1, -F}, {-F, -1}, {0, -1}, { F, -1}, { 1, -F}
  45.     };
  46.  
  47.     int u, v;
  48.     RDCpoint mesh[MAXNPTS][BEZIERWIDTH];    /* Build 3D mesh here */
  49.  
  50.     for (v = 0; v < npoints; v++)
  51.     for (u = 0; u < BEZIERWIDTH; u++) {
  52.         mesh[v][u][0] = points[v].x * coeff[u][0];
  53.         mesh[v][u][1] = points[v].x * coeff[u][1];
  54.         mesh[v][u][2] = points[v].z;
  55.     }
  56.  
  57.     rdcPatchMesh(RDC_BICUBIC, BEZIERWIDTH, RDC_WRAP, npoints, RDC_NOWRAP,
  58.     RDC_POINT, (RDCvoid *)mesh,
  59.     RDC_NULL);
  60. }
  61.  
  62. /*
  63.  * function: teapot
  64.  *
  65.  * input: none
  66.  *
  67.  * returns: void
  68.  *
  69.  * purpose: Renders Utah Teapot.
  70.  *
  71.  */
  72. static void teapot(void)
  73. {
  74.     /*
  75.      * Components that are radially symmetric about the Z-axis may
  76.      * be defined in the 2D X-Z plane and automatically revolved around
  77.      * the Z-axis.
  78.      */
  79.     Point2D body[] = {
  80.     {60, 0}, {60, 3}, {80, 12}, {80, 30}, {80, 48}, {70, 69},
  81.     {60, 90}, {57.5, 95.25}, {53.5, 95.25}, {56, 90}
  82.     };
  83.     Point2D lid[] = {
  84.     {8, 102}, {16, 96}, {52, 96}, {52, 90}
  85.     };
  86.     Point2D knob[] = {
  87.     {0, 120}, {32, 120}, {0, 108}, {8, 102}
  88.     };
  89.     Point2D lip[] = {
  90.     {50, 90}, {52, 90}, {54, 90}, {56, 90}
  91.     };
  92.  
  93.     /*
  94.      * Components which are not symmetric must be fully specified in 3D.
  95.      */
  96.     RDCpoint spout[7][6] = {
  97.     {{68, 0, 51}, {68, 26.4, 51}, {68, 26.4, 18},
  98.      {68, 0, 18}, {68, -26.4, 18}, {68, -26.4, 51}},
  99.     {{104, 0, 51}, {104, 26.4, 51}, {124, 26.4, 27},
  100.      {124, 0, 27}, {124, -26.4, 27}, {104, -26.4, 51}},
  101.     {{92, 0, 78}, {92, 10, 78}, {96, 10, 75},
  102.      {96, 0, 75}, {96, -10, 75}, {92, -10, 78}},
  103.     {{108, 0, 90}, {108, 10, 90}, {132, 10, 90},
  104.      {132, 0, 90}, {132, -10, 90}, {108, -10, 90}},
  105.     {{112, 0, 93}, {112, 10, 93}, {141, 10, 93.75},
  106.      {141, 0, 93.75}, {141, -10, 93.75}, {112, -10, 93}},
  107.     {{116, 0, 93}, {116, 6, 93}, {138, 6, 94.5},
  108.      {138, 0, 94.5}, {138, -6, 94.5}, {116, -6, 93}},
  109.     {{112, 0, 90}, {112, 6, 90}, {128, 6, 90},
  110.      {128, 0, 90}, {128, -6, 90}, {112, -6, 90}}
  111.     };
  112.     RDCpoint handle[7][6] = {
  113.     {{-64, 0, 75}, {-64, 12, 75}, {-60, 12, 84},
  114.      {-60, 0, 84}, {-60, -12, 84}, {-64, -12, 75}},
  115.     {{-92, 0, 75}, {-92, 12, 75}, {-100, 12, 84},
  116.      {-100, 0, 84}, {-100, -12, 84}, {-92, -12, 75}},
  117.     {{-108, 0, 75}, {-108, 12, 75}, {-120, 12, 84},
  118.      {-120, 0, 84}, {-120, -12, 84}, {-108, -12, 75}},
  119.     {{-108, 0, 66}, {-108, 12, 66}, {-120, 12, 66},
  120.      {-120, 0, 66}, {-120, -12, 66}, {-108, -12, 66}},
  121.     {{-108, 0, 57}, {-108, 12, 57}, {-120, 12, 48},
  122.      {-120, 0, 48}, {-120, -12, 48}, {-108, -12, 57}},
  123.     {{-100, 0, 39}, {-100, 12, 39}, {-106, 12, 31.5},
  124.      {-106, 0, 31.5}, {-106, -12, 31.5}, {-100, -12, 39}},
  125.     {{-80, 0, 30}, {-80, 12, 30}, {-76, 12, 18},
  126.      {-76, 0, 18}, {-76, -12, 18}, {-80, -12, 30}}
  127.     };
  128.  
  129.     /*
  130.      * Lighting values
  131.      */
  132.     RDCfloat ambintensity = 0.4;
  133.     RDCfloat distintensity1 = 1.0;
  134.     RDCfloat distintensity2 = 0.2;
  135.     RDCpoint from1= {-50, 300, 200};
  136.     RDCpoint from2= {-50, -300, 200};
  137.     RDCpoint to = {0, 0, 0};
  138.     RDCcolor ambcolor = {0.4, 0, 1};
  139.     RDCcolor color1 = {1, 0.8, 0.7};
  140.  
  141.     /*
  142.      * Shading values
  143.      */
  144.     RDCcolor tan = {1, 0.5, 0.3};
  145.     RDCcolor specolor = {1, 0.4, 0.1};
  146.     RDCfloat ka = 0.1, kd = 0.05, ks = 1, rough = 0.1;
  147.  
  148.     /*
  149.      * Set parameters
  150.      */
  151.     rdcOutputDisplay("Utah Teapot");
  152.     rdcRasterViewport(0, 199, 0, 124);
  153.     rdcColorGamma(2.2);
  154.  
  155.     /*
  156.      * Set view
  157.      */
  158.     rdcViewPerspective(25);
  159.     rdcTranslate(0, 0, 400);
  160.     rdcRotate(-115, 1, 0, 0);
  161.     rdcRotate(19, 0, 0, 1);
  162.     rdcTranslate(-25, 0, -50);
  163.  
  164.     rdcSceneBegin();
  165.     /*
  166.      * Define lights
  167.      */
  168.     rdcLightSource(RDC_AMBIENT,
  169.         RDC_INTENSITY, (RDCvoid *)&ambintensity,
  170.         RDC_LIGHTCOLOR, (RDCvoid *)ambcolor,
  171.         RDC_NULL);
  172.     rdcLightSource(RDC_DISTANT,
  173.         RDC_INTENSITY, (RDCvoid *)&distintensity1,
  174.         RDC_FROM, (RDCvoid *)&from1,
  175.         RDC_TO, (RDCvoid *)&to,
  176.         RDC_LIGHTCOLOR, (RDCvoid *)color1,
  177.         RDC_NULL);
  178.     rdcLightSource(RDC_DISTANT,
  179.         RDC_INTENSITY, (RDCvoid *)&distintensity2,
  180.         RDC_FROM, (RDCvoid *)&from2,
  181.         RDC_TO, (RDCvoid *)&to,
  182.         RDC_NULL);
  183.  
  184.     /*
  185.      * Define surface
  186.      */
  187.     rdcColor(tan);
  188.     rdcSurface(RDC_PLASTIC,
  189.         RDC_KA, (RDCvoid *)&ka,
  190.         RDC_KD, (RDCvoid *)&kd,
  191.         RDC_KS, (RDCvoid *)&ks,
  192.         RDC_ROUGHNESS, (RDCvoid *)&rough,
  193.         RDC_SPECULARCOLOR, (RDCvoid *)specolor,
  194.         RDC_NULL);
  195.  
  196.     /*
  197.      * Define primitives
  198.      */
  199.     revolve(body, sizeof(body) / sizeof(Point2D));
  200.     revolve(lid, sizeof(lid) / sizeof(Point2D));
  201.     revolve(knob, sizeof(knob) / sizeof(Point2D));
  202.     revolve(lip, sizeof(lip) / sizeof(Point2D));
  203.     rdcPatchMesh(RDC_BICUBIC, 6, RDC_WRAP, 7, RDC_NOWRAP,
  204.         RDC_POINT, (RDCvoid *)spout,
  205.         RDC_NULL);
  206.     rdcPatchMesh(RDC_BICUBIC, 6, RDC_WRAP, 7, RDC_NOWRAP,
  207.         RDC_POINT, (RDCvoid *)handle,
  208.         RDC_NULL);
  209.  
  210.     rdcSceneEnd();
  211. }
  212.  
  213. /*
  214.  * function: MainWndProc
  215.  *
  216.  * input: Window handle, message id, first and second message parameters.
  217.  *
  218.  * returns: LRESULT - Result of message processing.
  219.  *
  220.  * purpose: Destroys app when main window closes.  Calls default for rest.
  221.  *
  222.  */
  223. static LRESULT WINAPI MainWndProc(HWND hWnd, UINT msg,
  224.     WPARAM wParam, LPARAM lParam)
  225. {
  226.     switch(msg) {
  227.     case WM_DESTROY:
  228.     PostQuitMessage(0);        /* Kill the app when the window goes */
  229.     break;
  230.  
  231.     default:                /* Do the default thing */
  232.     return DefWindowProc(hWnd, msg, wParam, lParam);
  233.     }
  234.  
  235.     return FALSE;
  236. }
  237.  
  238. /*
  239.  * function: WinMain
  240.  *
  241.  * input: Handles to current and previous instances, command line, show state.
  242.  *
  243.  * returns: int APIENTRY - 0 on success
  244.  *
  245.  * purpose: Main entry point for 32 bit windows program.
  246.  *
  247.  */
  248. int APIENTRY WinMain(HANDLE hInstance, HANDLE hPrevInstance,
  249.     LPSTR lpCmdLine, int nCmdShow)
  250. {
  251.     HWND hMainWnd;
  252.     WNDCLASS wc;
  253.     MSG msg;
  254.  
  255.     /*
  256.      * Create a main window
  257.      */
  258.     wc.style = 0;
  259.     wc.hInstance = hInstance;
  260.     wc.lpfnWndProc = MainWndProc;
  261.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  262.     wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  263.     wc.lpszClassName = "TEAPOT:MAIN";
  264.     wc.lpszMenuName = NULL;
  265.     wc.cbClsExtra = wc.cbWndExtra = 0;
  266.     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  267.     if (!RegisterClass(&wc))
  268.     return 1;
  269.     hMainWnd = CreateWindow("TEAPOT:MAIN", "Teapot App", WS_OVERLAPPEDWINDOW,
  270.     CW_USEDEFAULT, 0, 100, 100, NULL, NULL, hInstance, NULL);
  271.     if (!hMainWnd)
  272.     return 1;
  273.     ShowWindow(hMainWnd, nCmdShow);
  274.     UpdateWindow(hMainWnd);
  275.  
  276.     /*
  277.      * If creating a ".rdc" file by running this program, link
  278.      * with import library for "rdc.dll" instead of "rendc.dll".
  279.      *
  280.      * The following line sets the name of the output rdc file.
  281.      * It has no effect when using "rendc.dll".
  282.      */
  283.     rdcOutputFile(RDC_BYTESTREAM, "teapot.rdc");
  284.  
  285.     /*
  286.      * Draw the teapot
  287.      * Note: No user interaction while rendering.
  288.      */
  289.     teapot();
  290.  
  291.     /*
  292.      * Run message loop until user closes main window.
  293.      */
  294.     while (GetMessage(&msg, NULL, 0, 0)) {
  295.     TranslateMessage(&msg);
  296.     DispatchMessage(&msg);
  297.     }
  298.  
  299.     return 0;
  300. }
  301.