home *** CD-ROM | disk | FTP | other *** search
/ Computer Panoráma / computer_panorama_1997-12-hibas.iso / SHARE / GRAPH / PTC051.ZIP / EXAMPLES / RAND32.TXT < prev    next >
Text File  |  1997-09-04  |  10KB  |  224 lines

  1.                       =================================
  2.                       = random 32bit putpixel example =
  3.                       =================================
  4.  
  5.  
  6. Overview
  7. --------
  8.  
  9. This example draws random pixels to a 32bit ARGB8888 system memory surface
  10. and updates this 32bit surface to the display - converting to the output
  11. format if necessary. It demonstrates working in "virtual 32bit" with fuzzy
  12. 32bit mode setting.
  13.  
  14. NOTE: From now on when i say "32bit" i mean "32bit ARGB8888" the major 32bit
  15.       pixel format supported in PTC
  16.  
  17.  
  18.  
  19. Step 1 - PTC Initialization
  20. ---------------------------
  21.  
  22. >    // try to init ptc from command line (i.e. "random 640 480 ARGB8888")
  23. >    PTC ptc(argc,argv);
  24. >    if (!ptc.ok())
  25. >    {
  26. >        // command line init failed - fall back to 320x200 fuzzy 32bit
  27. >        if (!ptc.Init(320,200))
  28. >        { 
  29. >            ptc.Close();
  30. >            cout << "could not initialize ptc\n";
  31. >            return 1;
  32. >        }
  33. >    }
  34.  
  35. The code above first tried to initialize a PTC graphics mode from the command
  36. line, then if that fails, falls back onto a "fuzzy" 32bit mode set. Note that
  37. when both mode sets fail (command line and fuzzy32) the ptc object is first
  38. closed to make sure that we restore textmode before outputting an error
  39. message "could not initialize ptc". Note that you do NOT need to manually
  40. close the PTC object before exiting the program, the destructor will always
  41. take care of this for you.
  42.  
  43.  
  44. When initializing rand32 from the command line. The format is as below:
  45.  
  46.     rand32 [xres] [yres] [format]
  47.  
  48.     e.g. rand32 320 200 RGB565
  49.  
  50. NOTE: if you go "PTC ptc(320,200,argc,argv)" it will let you get the output
  51.       format alone from the command line, and let you control the xres and
  52.       yres of the mode yourself.
  53.  
  54. If the command line initialize fails, the PTC::ok() returns 0 and the rand32
  55. program falls back onto "fuzzy 32bit". Note that the second time the PTC
  56. object is initialized (using ptc.Init) it just uses "ptc.Init(320,200)"
  57. FUZZY32 is the default third parameter.
  58.  
  59.  
  60. What are fuzzy mode sets? Fuzzy mode sets are what makes ptc cool! When a
  61. fuzzy 32bit mode set is requested PTC tries to set a mode "close to 32bit".
  62. The exact sequence of events occurring in a FUZZY32 mode set are as follows:
  63.  
  64. try to set xres,yres at:
  65.  
  66.    1. ARGB8888   (32bit)
  67.    2. RGBA8888   (32bit)
  68.    3. BGRA8888   (32bit)
  69.    4. ABGR8888   (32bit)
  70.    5. RGB888     (24bit)
  71.    6. BGR888     (24bit)
  72.    7. RGB565     (16bit)
  73.    8. BGR565     (16bit)
  74.    9. ARGB1555   (16bit "15bit")
  75.   10. ABGR1555   (16bit "15bit")
  76.   11. FAKEMODE2A (emulated truecolor)
  77.  
  78.  
  79. FUZZY32 mode sets are cool because they allow you to work "virtually" in 32bit
  80. while converting when you update to the display. Try the rand32 function with
  81. all the output formats available for a bit of fun (see "globals.h" for a list
  82. of all predefined formats you can try).
  83.  
  84.  
  85.  
  86. Step Two - Surface initialization
  87. ---------------------------------
  88.  
  89. >    // get display resolution
  90. >    int xres=ptc.GetXResolution();
  91. >    int yres=ptc.GetYResolution();
  92. >
  93. >    // create fullscreen 32bit ARGB8888 surface
  94. >    Surface surface(ptc,xres,yres,ARGB8888);
  95.  
  96. This code here queries the display output x and y resolution, then creates
  97. a system memory surface of format ARGB8888 that is bound to the PTC object
  98. we just initialized (see "surface.h").
  99.  
  100. A surface is just a chunk of pixel data. Much like a "ramscreen". Surfaces
  101. however, are smarter than just an array of bytes and provide a lot of cool
  102. things for you the programmer. Most importantly, each surface knows what
  103. format that its pixel data is stored as - if one surface is being BitBlt'd
  104. to another surface and they are NOT identical pixel formats. PTC will attempt
  105. a pixel format conversion transparently. You can retrieve the format of a
  106. surface with Surface::GetFormat. See the "format.h" for the declaration of the
  107. FORMAT class - the class that is used by PTC to describe pixel formats.
  108.  
  109.  
  110. You may have noticed how the PTC object was passed as the first parameter of
  111. the surface constructor. When a ptc object is passed to a surface constructor,
  112. the surface is "bound" to that interface (the ptc object's "interface" to the
  113. graphics hardware). Bound surfaces are volatile - if you nuke the interface
  114. (the ptc object), then all the bound surfaces are nuked as well.
  115.  
  116. This of course sucks - so there is an alternative. If you DONT pass a ptc
  117. object to the constructor, then the surface is "unbound". The surface is
  118. not dependant on an interface object (ptc object), and will exist until YOU
  119. delete it. Unbound surfaces do have their limitations, as they are unable to
  120. latch onto native features of the interface, such as hardware acceleration.
  121. For example, when using PTC with DirectX, bound surfaces bind to the IDirectX
  122. interface (managed inside the PTC object) and are implemented internally
  123. as native DirectDraw surfaces and doing so they gain hardware acceleration).
  124. Unbound surfaces under DirectX however, don't know about hardware acceleration
  125. because they are just implemented as dumb blocks of memory.
  126.  
  127.  
  128.  
  129. Step 3 - The main loop
  130. ----------------------
  131.  
  132. >    // main loop
  133. >    while (!ptc.kbhit())
  134. >    {
  135. >        // lock surface
  136. >        uint* buffer=(uint*)surface.Lock();
  137. >        if (!buffer)
  138. >        {
  139. >            ptc.Close();
  140. >            cout << "null surface lock!\n";
  141. >            return 1;
  142. >        }
  143. >        
  144. >        // plot 100 random pixels
  145. >        for (int i=0; i<100; i++)
  146. >        {
  147. >            int x=random(xres);
  148. >            int y=random(yres);
  149. >            buffer[xres*y+x]=RGB32(random(255),random(255),random(255));
  150. >        }
  151. >
  152. >        // unlock surface
  153. >        surface.Unlock();
  154. >
  155. >        // update to display
  156. >        surface.Update();
  157. >    }
  158. >    return 0;
  159.  
  160. The first thing you may notice, is that the main loop uses "ptc.kbhit" not
  161. kbhit to loop until a key is pressed. This is a portability issue, and is
  162. designed like this so that win32 programs can still "think" they are console
  163. applications and not need to worry about windows keyboard messages etc. This
  164. greatly speeds porting between dos <-> windows as you do NOT need to manage
  165. your own window (note. win32 support is NOT included with PTC050, it is in
  166. the middle of a rewrite and should be back in ptc with version 060, along
  167. with linux and xwindows support).
  168.  
  169.  
  170. Secondly, a strange function "surface.Lock" is being called. What this
  171. function does is return a pointer to the surfaces pixel data. It is this
  172. pointer you use to draw directly to the surface.
  173.  
  174. Surface::Lock may fail. If it does so, then it will return NULL. Please,
  175. *PLEASE* check that surface lock returns a non-null pointer before you start
  176. writing to it!
  177.  
  178. When does a lock fail? When the surface is invalid. When is a surface invalid?
  179. Typically this occurs when a) a bound surface was nuked because its interface
  180. was nuked b) the surface was a video surface and it was nuked because you
  181. switched modes c) DirectDraw nuked your surface because it felt like it. A
  182. surface can be checked for validity with the Surface::ok function. I guarantee
  183. to you that no surface will ever fail to lock while it is valid - however,
  184. this doesn't mean that you should remove your check for NULL because DirectDraw
  185. has a nasty habit of nuking surfaces whenever it feels like - especially VIDEO
  186. surfaces, and makes no guarantees about SYSTEM surfaces either :P ... If you
  187. want portable and stable code please check for NULL!
  188.  
  189.  
  190. After the surface is locked, the variable "buffer" points to the pixel data.
  191. We use this pointer to then write to it. The function RGB32 packs three color
  192. chars r,g,b into an ARGB8888 color integer (which is the format of the surface
  193. we are working with).
  194.  
  195. Finally, the surface is unlocked and the program loops. Please Lock/Unlock
  196. for each frame. Don't just lock the surface once and use that pointer for the
  197. entire program. If you do this under DirectX with PTC, then you will run into
  198. BIG problems. Finally, remember that all successful (non-NULL) locks need to
  199. be m