17ec3b29aSmrg/**
27ec3b29aSmrg * Test glPolygonMode w/ different front/back face modes.
37ec3b29aSmrg *
47ec3b29aSmrg * The left half of the window draws a torus with different front/back
57ec3b29aSmrg * polygon modes.
67ec3b29aSmrg *
77ec3b29aSmrg * The right half of the windows tries to draw the same thing, but with
87ec3b29aSmrg * a different approach:
97ec3b29aSmrg *   glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
107ec3b29aSmrg *   glEnable(GL_CULL_FACE);
117ec3b29aSmrg *   glCullFace(GL_FRONT);
127ec3b29aSmrg *   draw_object();
137ec3b29aSmrg *   glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
147ec3b29aSmrg *   glEnable(GL_CULL_FACE);
157ec3b29aSmrg *   glCullFace(GL_BACK);
167ec3b29aSmrg *   draw_object();
177ec3b29aSmrg *
187ec3b29aSmrg * The outcome is often the same, but not always (turn on blending with 'b').
197ec3b29aSmrg *
207ec3b29aSmrg * Brian Paul
217ec3b29aSmrg * 2 Feb 2016
227ec3b29aSmrg */
237ec3b29aSmrg
247ec3b29aSmrg
257ec3b29aSmrg#include <stdio.h>
267ec3b29aSmrg#include <stdlib.h>
277ec3b29aSmrg#include <math.h>
287ec3b29aSmrg#include "glut_wrap.h"
297ec3b29aSmrg
307ec3b29aSmrgstatic int Win;
317ec3b29aSmrgstatic int WinWidth = 800, WinHeight = 400;
327ec3b29aSmrgstatic GLfloat Xrot = 0;
337ec3b29aSmrgstatic GLboolean Anim = GL_TRUE;
347ec3b29aSmrgstatic double t0;
357ec3b29aSmrgstatic GLboolean Blend = GL_TRUE;
367ec3b29aSmrg
377ec3b29aSmrg
387ec3b29aSmrgstatic void
397ec3b29aSmrgIdle(void)
407ec3b29aSmrg{
417ec3b29aSmrg   double t1 = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
427ec3b29aSmrg   Xrot += (t1 - t0) * 20;  /* 20 degrees per second */
437ec3b29aSmrg   t0 = t1;
447ec3b29aSmrg   glutPostRedisplay();
457ec3b29aSmrg}
467ec3b29aSmrg
477ec3b29aSmrg
487ec3b29aSmrgstatic void
497ec3b29aSmrgDraw(void)
507ec3b29aSmrg{
517ec3b29aSmrg   int hw = WinWidth / 2;
527ec3b29aSmrg
537ec3b29aSmrg   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
547ec3b29aSmrg
557ec3b29aSmrg   if (Blend) {
567ec3b29aSmrg      glEnable(GL_BLEND);
577ec3b29aSmrg      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
587ec3b29aSmrg      glBlendFunc(GL_ONE, GL_ONE);
597ec3b29aSmrg   }
607ec3b29aSmrg   else {
617ec3b29aSmrg      glDisable(GL_BLEND);
627ec3b29aSmrg   }
637ec3b29aSmrg
647ec3b29aSmrg   glPushMatrix();
657ec3b29aSmrg   glRotatef(Xrot, 1, 0, 0);
667ec3b29aSmrg
677ec3b29aSmrg   /* draw left half */
687ec3b29aSmrg   glViewport(0, 0, hw, WinHeight);
697ec3b29aSmrg
707ec3b29aSmrg   glPolygonMode(GL_FRONT, GL_LINE);
717ec3b29aSmrg   glPolygonMode(GL_BACK, GL_FILL);
727ec3b29aSmrg   glDisable(GL_CULL_FACE);
737ec3b29aSmrg   glutSolidTorus(0.75, 2.0, 10, 20);
747ec3b29aSmrg
757ec3b29aSmrg   /* draw right half */
767ec3b29aSmrg   glViewport(hw, 0, WinWidth - hw, WinHeight);
777ec3b29aSmrg
787ec3b29aSmrg   /* draw back faces */
797ec3b29aSmrg   glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
807ec3b29aSmrg   glEnable(GL_CULL_FACE);
817ec3b29aSmrg   glCullFace(GL_FRONT);
827ec3b29aSmrg   glutSolidTorus(0.75, 2.0, 10, 20);
837ec3b29aSmrg
847ec3b29aSmrg   /* draw front faces */
857ec3b29aSmrg   glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
867ec3b29aSmrg   glEnable(GL_CULL_FACE);
877ec3b29aSmrg   glCullFace(GL_BACK);
887ec3b29aSmrg   glutSolidTorus(0.75, 2.0, 10, 20);
897ec3b29aSmrg
907ec3b29aSmrg   glPopMatrix();
917ec3b29aSmrg
927ec3b29aSmrg   glutSwapBuffers();
937ec3b29aSmrg}
947ec3b29aSmrg
957ec3b29aSmrg
967ec3b29aSmrgstatic void
977ec3b29aSmrgReshape(int width, int height)
987ec3b29aSmrg{
997ec3b29aSmrg   WinWidth = width;
1007ec3b29aSmrg   WinHeight = height;
1017ec3b29aSmrg   glMatrixMode(GL_PROJECTION);
1027ec3b29aSmrg   glLoadIdentity();
1037ec3b29aSmrg   glFrustum(-1.0, 1.0, -1.0, 1.0, 3.0, 25.0);
1047ec3b29aSmrg   glMatrixMode(GL_MODELVIEW);
1057ec3b29aSmrg   glLoadIdentity();
1067ec3b29aSmrg   glTranslatef(0.0, 0.0, -10.0);
1077ec3b29aSmrg   glutPostRedisplay();
1087ec3b29aSmrg}
1097ec3b29aSmrg
1107ec3b29aSmrg
1117ec3b29aSmrgstatic void
1127ec3b29aSmrgKey(unsigned char key, int x, int y)
1137ec3b29aSmrg{
1147ec3b29aSmrg   (void) x;
1157ec3b29aSmrg   (void) y;
1167ec3b29aSmrg   switch (key) {
1177ec3b29aSmrg   case 'a':
1187ec3b29aSmrg      Anim = !Anim;
1197ec3b29aSmrg      if (Anim) {
1207ec3b29aSmrg         t0 = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
1217ec3b29aSmrg         glutIdleFunc(Idle);
1227ec3b29aSmrg      }
1237ec3b29aSmrg      else
1247ec3b29aSmrg         glutIdleFunc(NULL);
1257ec3b29aSmrg      break;
1267ec3b29aSmrg   case 'b':
1277ec3b29aSmrg      Blend = !Blend;
1287ec3b29aSmrg      break;
1297ec3b29aSmrg   case 27:
1307ec3b29aSmrg      glutDestroyWindow(Win);
1317ec3b29aSmrg      exit(0);
1327ec3b29aSmrg      break;
1337ec3b29aSmrg   }
1347ec3b29aSmrg   glutPostRedisplay();
1357ec3b29aSmrg}
1367ec3b29aSmrg
1377ec3b29aSmrg
1387ec3b29aSmrgstatic void
1397ec3b29aSmrgSpecialKey(int key, int x, int y)
1407ec3b29aSmrg{
1417ec3b29aSmrg   const GLfloat step = 3.0;
1427ec3b29aSmrg   (void) x;
1437ec3b29aSmrg   (void) y;
1447ec3b29aSmrg   switch (key) {
1457ec3b29aSmrg   case GLUT_KEY_UP:
1467ec3b29aSmrg      Xrot -= step;
1477ec3b29aSmrg      break;
1487ec3b29aSmrg   case GLUT_KEY_DOWN:
1497ec3b29aSmrg      Xrot += step;
1507ec3b29aSmrg      break;
1517ec3b29aSmrg   }
1527ec3b29aSmrg   glutPostRedisplay();
1537ec3b29aSmrg}
1547ec3b29aSmrg
1557ec3b29aSmrg
1567ec3b29aSmrgstatic void
1577ec3b29aSmrgInit(void)
1587ec3b29aSmrg{
1597ec3b29aSmrg   static const float yellow[4] = {1, 1, 0, 0.5};
1607ec3b29aSmrg   static const float blue[4] = {0.2, 0.2, 1, 0.5};
1617ec3b29aSmrg   static const float gray[4] = {0.2, 0.2, 0.2, 1.0};
1627ec3b29aSmrg
1637ec3b29aSmrg   glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, gray);
1647ec3b29aSmrg   glMaterialfv(GL_FRONT, GL_DIFFUSE, yellow);
1657ec3b29aSmrg   glMaterialfv(GL_BACK, GL_DIFFUSE, blue);
1667ec3b29aSmrg   glEnable(GL_DEPTH_TEST);
1677ec3b29aSmrg   glEnable(GL_LIGHTING);
1687ec3b29aSmrg   glEnable(GL_LIGHT0);
1697ec3b29aSmrg   glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
1707ec3b29aSmrg   glShadeModel(GL_FLAT);
1717ec3b29aSmrg
1727ec3b29aSmrg   glClearColor(0.25, 0.25, 0.25, 1.0);
1737ec3b29aSmrg}
1747ec3b29aSmrg
1757ec3b29aSmrg
1767ec3b29aSmrgint
1777ec3b29aSmrgmain(int argc, char *argv[])
1787ec3b29aSmrg{
1797ec3b29aSmrg   glutInit(&argc, argv);
1807ec3b29aSmrg   glutInitWindowSize(WinWidth, WinHeight);
1817ec3b29aSmrg   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
1827ec3b29aSmrg   Win = glutCreateWindow(argv[0]);
1837ec3b29aSmrg   glutReshapeFunc(Reshape);
1847ec3b29aSmrg   glutKeyboardFunc(Key);
1857ec3b29aSmrg   glutSpecialFunc(SpecialKey);
1867ec3b29aSmrg   glutDisplayFunc(Draw);
1877ec3b29aSmrg   if (Anim)
1887ec3b29aSmrg      glutIdleFunc(Idle);
1897ec3b29aSmrg   Init();
1907ec3b29aSmrg   glutMainLoop();
1917ec3b29aSmrg   return 0;
1927ec3b29aSmrg}
193