Clone of mesa.
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

df_reflect.c 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. /*
  2. (c) Copyright 2001 convergence integrated media GmbH.
  3. All rights reserved.
  4. Written by Denis Oliver Kropp <dok@convergence.de> and
  5. Andreas Hundt <andi@convergence.de>.
  6. This library is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU Lesser General Public
  8. License as published by the Free Software Foundation; either
  9. version 2 of the License, or (at your option) any later version.
  10. This library is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. Lesser General Public License for more details.
  14. You should have received a copy of the GNU Lesser General Public
  15. License along with this library; if not, write to the
  16. Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  17. Boston, MA 02111-1307, USA.
  18. */
  19. #include <stdlib.h>
  20. #include <stdio.h>
  21. #include <string.h>
  22. #include <math.h>
  23. #include <directfb.h>
  24. #include <directfbgl.h>
  25. #include <GL/glu.h>
  26. #include "util/showbuffer.c"
  27. #include "util/readtex.c"
  28. /* the super interface */
  29. IDirectFB *dfb;
  30. /* the primary surface (surface of primary layer) */
  31. IDirectFBSurface *primary;
  32. /* the GL context */
  33. IDirectFBGL *primary_gl;
  34. /* our font */
  35. IDirectFBFont *font;
  36. /* event buffer */
  37. IDirectFBEventBuffer *events;
  38. /* macro for a safe call to DirectFB functions */
  39. #define DFBCHECK(x...) \
  40. { \
  41. err = x; \
  42. if (err != DFB_OK) { \
  43. fprintf( stderr, "%s <%d>:\n\t", __FILE__, __LINE__ ); \
  44. DirectFBErrorFatal( #x, err ); \
  45. } \
  46. }
  47. static int screen_width, screen_height;
  48. static unsigned long T0 = 0;
  49. static GLint Frames = 0;
  50. static GLfloat fps = 0;
  51. static inline unsigned long get_millis()
  52. {
  53. struct timeval tv;
  54. gettimeofday (&tv, NULL);
  55. return (tv.tv_sec * 1000 + tv.tv_usec / 1000);
  56. }
  57. /*******************************/
  58. #define DEG2RAD (3.14159/180.0)
  59. #define TABLE_TEXTURE "../images/tile.rgb"
  60. static GLint ImgWidth, ImgHeight;
  61. static GLenum ImgFormat;
  62. static GLubyte *Image = NULL;
  63. #define MAX_OBJECTS 2
  64. static GLint table_list;
  65. static GLint objects_list[MAX_OBJECTS];
  66. static GLfloat xrot, yrot;
  67. static GLfloat spin;
  68. static GLint Width = 400, Height = 300;
  69. static GLenum ShowBuffer = GL_NONE;
  70. static void make_table( void )
  71. {
  72. static GLfloat table_mat[] = { 1.0, 1.0, 1.0, 0.6 };
  73. static GLfloat gray[] = { 0.4, 0.4, 0.4, 1.0 };
  74. table_list = glGenLists(1);
  75. glNewList( table_list, GL_COMPILE );
  76. /* load table's texture */
  77. glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, table_mat );
  78. /* glMaterialfv( GL_FRONT, GL_EMISSION, gray );*/
  79. glMaterialfv( GL_FRONT, GL_DIFFUSE, table_mat );
  80. glMaterialfv( GL_FRONT, GL_AMBIENT, gray );
  81. /* draw textured square for the table */
  82. glPushMatrix();
  83. glScalef( 4.0, 4.0, 4.0 );
  84. glBegin( GL_POLYGON );
  85. glNormal3f( 0.0, 1.0, 0.0 );
  86. glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0, 0.0, 1.0 );
  87. glTexCoord2f( 1.0, 0.0 ); glVertex3f( 1.0, 0.0, 1.0 );
  88. glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 0.0, -1.0 );
  89. glTexCoord2f( 0.0, 1.0 ); glVertex3f( -1.0, 0.0, -1.0 );
  90. glEnd();
  91. glPopMatrix();
  92. glDisable( GL_TEXTURE_2D );
  93. glEndList();
  94. }
  95. static void make_objects( void )
  96. {
  97. GLUquadricObj *q;
  98. static GLfloat cyan[] = { 0.0, 1.0, 1.0, 1.0 };
  99. static GLfloat green[] = { 0.2, 1.0, 0.2, 1.0 };
  100. static GLfloat black[] = { 0.0, 0.0, 0.0, 0.0 };
  101. q = gluNewQuadric();
  102. gluQuadricDrawStyle( q, GLU_FILL );
  103. gluQuadricNormals( q, GLU_SMOOTH );
  104. objects_list[0] = glGenLists(1);
  105. glNewList( objects_list[0], GL_COMPILE );
  106. glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cyan );
  107. glMaterialfv( GL_FRONT, GL_EMISSION, black );
  108. gluCylinder( q, 0.5, 0.5, 1.0, 15, 1 );
  109. glEndList();
  110. objects_list[1] = glGenLists(1);
  111. glNewList( objects_list[1], GL_COMPILE );
  112. glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green );
  113. glMaterialfv( GL_FRONT, GL_EMISSION, black );
  114. gluCylinder( q, 1.5, 0.0, 2.5, 15, 1 );
  115. glEndList();
  116. }
  117. static void init( void )
  118. {
  119. make_table();
  120. make_objects();
  121. Image = LoadRGBImage( TABLE_TEXTURE, &ImgWidth, &ImgHeight, &ImgFormat );
  122. if (!Image) {
  123. printf("Couldn't read %s\n", TABLE_TEXTURE);
  124. exit(0);
  125. }
  126. gluBuild2DMipmaps(GL_TEXTURE_2D, 3, ImgWidth, ImgHeight,
  127. ImgFormat, GL_UNSIGNED_BYTE, Image);
  128. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
  129. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
  130. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
  131. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
  132. xrot = 30.0;
  133. yrot = 50.0;
  134. spin = 0.0;
  135. glShadeModel( GL_FLAT );
  136. glEnable( GL_LIGHT0 );
  137. glEnable( GL_LIGHTING );
  138. glClearColor( 0.5, 0.5, 0.9, 0.0 );
  139. glEnable( GL_NORMALIZE );
  140. }
  141. static void reshape(int w, int h)
  142. {
  143. GLfloat yAspect = 2.5;
  144. GLfloat xAspect = yAspect * (float) w / (float) h;
  145. Width = w;
  146. Height = h;
  147. glViewport(0, 0, w, h);
  148. glMatrixMode(GL_PROJECTION);
  149. glLoadIdentity();
  150. glFrustum( -xAspect, xAspect, -yAspect, yAspect, 10.0, 30.0 );
  151. glMatrixMode(GL_MODELVIEW);
  152. glLoadIdentity();
  153. }
  154. static void draw_objects( GLfloat eyex, GLfloat eyey, GLfloat eyez )
  155. {
  156. (void) eyex;
  157. (void) eyey;
  158. (void) eyez;
  159. #ifndef USE_ZBUFFER
  160. if (eyex<0.5) {
  161. #endif
  162. glPushMatrix();
  163. glTranslatef( 1.0, 1.5, 0.0 );
  164. glRotatef( spin, 1.0, 0.5, 0.0 );
  165. glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
  166. glCallList( objects_list[0] );
  167. glPopMatrix();
  168. glPushMatrix();
  169. glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*spin) ), 0.0 );
  170. glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
  171. glRotatef( spin, 1.0, 0.5, 0.0 );
  172. glScalef( 0.5, 0.5, 0.5 );
  173. glCallList( objects_list[1] );
  174. glPopMatrix();
  175. #ifndef USE_ZBUFFER
  176. }
  177. else {
  178. glPushMatrix();
  179. glTranslatef( -1.0, 0.85+3.0*fabs( cos(0.01*spin) ), 0.0 );
  180. glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
  181. glRotatef( spin, 1.0, 0.5, 0.0 );
  182. glScalef( 0.5, 0.5, 0.5 );
  183. glCallList( objects_list[1] );
  184. glPopMatrix();
  185. glPushMatrix();
  186. glTranslatef( 1.0, 1.5, 0.0 );
  187. glRotatef( spin, 1.0, 0.5, 0.0 );
  188. glRotatef( 0.5*spin, 0.0, 0.5, 1.0 );
  189. glCallList( objects_list[0] );
  190. glPopMatrix();
  191. }
  192. #endif
  193. }
  194. static void draw_table( void )
  195. {
  196. glCallList( table_list );
  197. }
  198. static void draw( void )
  199. {
  200. static GLfloat light_pos[] = { 0.0, 20.0, 0.0, 1.0 };
  201. GLfloat dist = 20.0;
  202. GLfloat eyex, eyey, eyez;
  203. glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  204. eyex = dist * cos(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
  205. eyez = dist * sin(yrot*DEG2RAD) * cos(xrot*DEG2RAD);
  206. eyey = dist * sin(xrot*DEG2RAD);
  207. /* view from top */
  208. glPushMatrix();
  209. gluLookAt( eyex, eyey, eyez, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 );
  210. glLightfv( GL_LIGHT0, GL_POSITION, light_pos );
  211. /* draw table into stencil planes */
  212. glDisable( GL_DEPTH_TEST );
  213. glEnable( GL_STENCIL_TEST );
  214. glStencilFunc( GL_ALWAYS, 1, 0xffffffff );
  215. glStencilOp( GL_REPLACE, GL_REPLACE, GL_REPLACE );
  216. glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
  217. draw_table();
  218. glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
  219. glEnable( GL_DEPTH_TEST );
  220. /* render view from below (reflected viewport) */
  221. /* only draw where stencil==1 */
  222. if (eyey>0.0) {
  223. glPushMatrix();
  224. glStencilFunc( GL_EQUAL, 1, 0xffffffff ); /* draw if ==1 */
  225. glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
  226. glScalef( 1.0, -1.0, 1.0 );
  227. /* Reposition light in reflected space. */
  228. glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
  229. draw_objects(eyex, eyey, eyez);
  230. glPopMatrix();
  231. /* Restore light's original unreflected position. */
  232. glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
  233. }
  234. glDisable( GL_STENCIL_TEST );
  235. glEnable( GL_BLEND );
  236. glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
  237. glEnable( GL_TEXTURE_2D );
  238. draw_table();
  239. glDisable( GL_TEXTURE_2D );
  240. glDisable( GL_BLEND );
  241. /* view from top */
  242. glPushMatrix();
  243. draw_objects(eyex, eyey, eyez);
  244. glPopMatrix();
  245. glPopMatrix();
  246. if (ShowBuffer == GL_DEPTH) {
  247. ShowDepthBuffer(Width, Height, 1.0, 0.0);
  248. }
  249. else if (ShowBuffer == GL_STENCIL) {
  250. ShowStencilBuffer(Width, Height, 255.0, 0.0);
  251. }
  252. else if (ShowBuffer == GL_ALPHA) {
  253. ShowAlphaBuffer(Width, Height);
  254. }
  255. }
  256. /*******************************/
  257. int main( int argc, char *argv[] )
  258. {
  259. int quit = 0;
  260. DFBResult err;
  261. DFBSurfaceDescription dsc;
  262. DFBCHECK(DirectFBInit( &argc, &argv ));
  263. /* create the super interface */
  264. DFBCHECK(DirectFBCreate( &dfb ));
  265. /* create an event buffer for all devices with these caps */
  266. DFBCHECK(dfb->CreateInputEventBuffer( dfb, DICAPS_ALL, DFB_FALSE, &events ));
  267. /* set our cooperative level to DFSCL_FULLSCREEN
  268. for exclusive access to the primary layer */
  269. dfb->SetCooperativeLevel( dfb, DFSCL_FULLSCREEN );
  270. /* get the primary surface, i.e. the surface of the
  271. primary layer we have exclusive access to */
  272. dsc.flags = DSDESC_CAPS;
  273. dsc.caps = (DFBSurfaceCapabilities)(DSCAPS_PRIMARY | DSCAPS_DOUBLE);
  274. DFBCHECK(dfb->CreateSurface( dfb, &dsc, &primary ));
  275. /* get the size of the surface and fill it */
  276. DFBCHECK(primary->GetSize( primary, &screen_width, &screen_height ));
  277. DFBCHECK(primary->FillRectangle( primary, 0, 0,
  278. screen_width, screen_height ));
  279. /* create the default font and set it */
  280. DFBCHECK(dfb->CreateFont( dfb, NULL, NULL, &font ));
  281. DFBCHECK(primary->SetFont( primary, font ));
  282. /* get the GL context */
  283. DFBCHECK(primary->GetGL( primary, &primary_gl ));
  284. DFBCHECK(primary_gl->Lock( primary_gl ));
  285. init();
  286. reshape(screen_width, screen_height);
  287. DFBCHECK(primary_gl->Unlock( primary_gl ));
  288. T0 = get_millis();
  289. while (!quit) {
  290. DFBInputEvent evt;
  291. unsigned long t;
  292. DFBCHECK(primary_gl->Lock( primary_gl ));
  293. draw();
  294. DFBCHECK(primary_gl->Unlock( primary_gl ));
  295. if (fps) {
  296. char buf[64];
  297. sprintf(buf, "%4.1f FPS\n", fps);
  298. primary->SetColor( primary, 0xff, 0, 0, 0xff );
  299. primary->DrawString( primary, buf, -1, screen_width - 5, 5, DSTF_TOPRIGHT );
  300. }
  301. primary->Flip( primary, NULL, (DFBSurfaceFlipFlags)0 );
  302. Frames++;
  303. t = get_millis();
  304. if (t - T0 >= 1000) {
  305. GLfloat seconds = (t - T0) / 1000.0;
  306. fps = Frames / seconds;
  307. T0 = t;
  308. Frames = 0;
  309. }
  310. while (events->GetEvent( events, DFB_EVENT(&evt) ) == DFB_OK) {
  311. switch (evt.type) {
  312. case DIET_KEYPRESS:
  313. switch (DFB_LOWER_CASE(evt.key_symbol)) {
  314. case DIKS_ESCAPE:
  315. quit = 1;
  316. break;
  317. case DIKS_CURSOR_UP:
  318. xrot += 3.0;
  319. if ( xrot > 85 )
  320. xrot = 85;
  321. break;
  322. case DIKS_CURSOR_DOWN:
  323. xrot -= 3.0;
  324. if ( xrot < 5 )
  325. xrot = 5;
  326. break;
  327. case DIKS_CURSOR_LEFT:
  328. yrot += 3.0;
  329. break;
  330. case DIKS_CURSOR_RIGHT:
  331. yrot -= 3.0;
  332. break;
  333. case DIKS_SMALL_D:
  334. ShowBuffer = GL_DEPTH;
  335. break;
  336. case DIKS_SMALL_S:
  337. ShowBuffer = GL_STENCIL;
  338. break;
  339. case DIKS_SMALL_A:
  340. ShowBuffer = GL_ALPHA;
  341. break;
  342. default:
  343. ShowBuffer = GL_NONE;
  344. }
  345. break;
  346. case DIET_AXISMOTION:
  347. if (evt.flags & DIEF_AXISREL) {
  348. switch (evt.axis) {
  349. case DIAI_X:
  350. yrot += evt.axisrel / 2.0;
  351. break;
  352. case DIAI_Y:
  353. xrot += evt.axisrel / 2.0;
  354. break;
  355. default:
  356. ;
  357. }
  358. }
  359. break;
  360. default:
  361. ;
  362. }
  363. }
  364. spin += 2.0;
  365. yrot += 3.0;
  366. }
  367. /* release our interfaces to shutdown DirectFB */
  368. primary_gl->Release( primary_gl );
  369. primary->Release( primary );
  370. font->Release( font );
  371. events->Release( events );
  372. dfb->Release( dfb );
  373. return 0;
  374. }