132001f49Smrg/*
232001f49Smrg * Copyright (C) 2008  Brian Paul   All Rights Reserved.
332001f49Smrg *
432001f49Smrg * Permission is hereby granted, free of charge, to any person obtaining a
532001f49Smrg * copy of this software and associated documentation files (the "Software"),
632001f49Smrg * to deal in the Software without restriction, including without limitation
732001f49Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
832001f49Smrg * and/or sell copies of the Software, and to permit persons to whom the
932001f49Smrg * Software is furnished to do so, subject to the following conditions:
1032001f49Smrg *
1132001f49Smrg * The above copyright notice and this permission notice shall be included
1232001f49Smrg * in all copies or substantial portions of the Software.
1332001f49Smrg *
1432001f49Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1532001f49Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1632001f49Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1732001f49Smrg * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
1832001f49Smrg * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1932001f49Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2032001f49Smrg */
2132001f49Smrg
2232001f49Smrg/*
2332001f49Smrg * Draw a triangle with X/EGL and OpenGL ES 1.x
2432001f49Smrg * Brian Paul
2532001f49Smrg * 5 June 2008
2632001f49Smrg */
2732001f49Smrg
2832001f49Smrg#define USE_FIXED_POINT 1
2932001f49Smrg
3032001f49Smrg
3132001f49Smrg#include <assert.h>
3232001f49Smrg#include <math.h>
3332001f49Smrg#include <stdio.h>
3432001f49Smrg#include <GLES/gl.h>  /* use OpenGL ES 1.x */
3532001f49Smrg#include <GLES/glext.h>
3632001f49Smrg#include <EGL/egl.h>
3732001f49Smrg
3832001f49Smrg#include "eglut.h"
3932001f49Smrg
4032001f49Smrg
4132001f49Smrg#define FLOAT_TO_FIXED(X)   ((X) * 65535.0)
4232001f49Smrg
4332001f49Smrg
4432001f49Smrg
4532001f49Smrgstatic GLfloat view_rotx = 0.0, view_roty = 0.0, view_rotz = 0.0;
4632001f49Smrg
4732001f49Smrg
4832001f49Smrgstatic void
4932001f49Smrgdraw(void)
5032001f49Smrg{
5132001f49Smrg#if USE_FIXED_POINT
5232001f49Smrg   static const GLfixed verts[3][2] = {
5332001f49Smrg      { -65536, -65536 },
5432001f49Smrg      {  65536, -65536 },
5532001f49Smrg      {      0,  65536 }
5632001f49Smrg   };
5732001f49Smrg   static const GLfixed colors[3][4] = {
5832001f49Smrg      { 65536,     0,     0,    65536 },
5932001f49Smrg      {     0, 65536,     0 ,   65536},
6032001f49Smrg      {     0,     0, 65536 ,   65536}
6132001f49Smrg   };
6232001f49Smrg#else
6332001f49Smrg   static const GLfloat verts[3][2] = {
6432001f49Smrg      { -1, -1 },
6532001f49Smrg      {  1, -1 },
6632001f49Smrg      {  0,  1 }
6732001f49Smrg   };
6832001f49Smrg   static const GLfloat colors[3][4] = {
6932001f49Smrg      { 1, 0, 0, 1 },
7032001f49Smrg      { 0, 1, 0, 1 },
7132001f49Smrg      { 0, 0, 1, 1 }
7232001f49Smrg   };
7332001f49Smrg#endif
7432001f49Smrg
7532001f49Smrg   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
7632001f49Smrg
7732001f49Smrg   glPushMatrix();
7832001f49Smrg   glRotatef(view_rotx, 1, 0, 0);
7932001f49Smrg   glRotatef(view_roty, 0, 1, 0);
8032001f49Smrg   glRotatef(view_rotz, 0, 0, 1);
8132001f49Smrg
8232001f49Smrg   {
8332001f49Smrg#if USE_FIXED_POINT
8432001f49Smrg      glVertexPointer(2, GL_FIXED, 0, verts);
8532001f49Smrg      glColorPointer(4, GL_FIXED, 0, colors);
8632001f49Smrg#else
8732001f49Smrg      glVertexPointer(2, GL_FLOAT, 0, verts);
8832001f49Smrg      glColorPointer(4, GL_FLOAT, 0, colors);
8932001f49Smrg#endif
9032001f49Smrg      glEnableClientState(GL_VERTEX_ARRAY);
9132001f49Smrg      glEnableClientState(GL_COLOR_ARRAY);
9232001f49Smrg
9332001f49Smrg      /* draw triangle */
9432001f49Smrg      glDrawArrays(GL_TRIANGLES, 0, 3);
9532001f49Smrg
9632001f49Smrg      /* draw some points */
9732001f49Smrg      glPointSizex(FLOAT_TO_FIXED(15.5));
9832001f49Smrg      glDrawArrays(GL_POINTS, 0, 3);
9932001f49Smrg
10032001f49Smrg      glDisableClientState(GL_VERTEX_ARRAY);
10132001f49Smrg      glDisableClientState(GL_COLOR_ARRAY);
10232001f49Smrg   }
10332001f49Smrg
10432001f49Smrg   if (0) {
10532001f49Smrg      /* test code */
10632001f49Smrg      GLfixed size;
10732001f49Smrg      glGetFixedv(GL_POINT_SIZE, &size);
10832001f49Smrg      printf("GL_POINT_SIZE = 0x%x %f\n", size, size / 65536.0);
10932001f49Smrg   }
11032001f49Smrg
11132001f49Smrg   glPopMatrix();
11232001f49Smrg}
11332001f49Smrg
11432001f49Smrg
11532001f49Smrg/* new window size or exposure */
11632001f49Smrgstatic void
11732001f49Smrgreshape(int width, int height)
11832001f49Smrg{
11932001f49Smrg   GLfloat ar = (GLfloat) width / (GLfloat) height;
12032001f49Smrg
12132001f49Smrg   glViewport(0, 0, (GLint) width, (GLint) height);
12232001f49Smrg
12332001f49Smrg   glMatrixMode(GL_PROJECTION);
12432001f49Smrg   glLoadIdentity();
12532001f49Smrg#ifdef GL_VERSION_ES_CM_1_0
12632001f49Smrg   glFrustumf(-ar, ar, -1, 1, 5.0, 60.0);
12732001f49Smrg#else
12832001f49Smrg   glFrustum(-ar, ar, -1, 1, 5.0, 60.0);
12932001f49Smrg#endif
13032001f49Smrg
13132001f49Smrg   glMatrixMode(GL_MODELVIEW);
13232001f49Smrg   glLoadIdentity();
13332001f49Smrg   glTranslatef(0.0, 0.0, -10.0);
13432001f49Smrg}
13532001f49Smrg
13632001f49Smrg
13732001f49Smrgstatic void
13832001f49Smrgtest_query_matrix(void)
13932001f49Smrg{
14032001f49Smrg   PFNGLQUERYMATRIXXOESPROC procQueryMatrixx;
14132001f49Smrg   typedef void (*voidproc)();
14232001f49Smrg   GLfixed mantissa[16];
14332001f49Smrg   GLint exponent[16];
14432001f49Smrg   GLbitfield rv;
14532001f49Smrg   int i;
14632001f49Smrg
14732001f49Smrg   procQueryMatrixx = (PFNGLQUERYMATRIXXOESPROC) eglGetProcAddress("glQueryMatrixxOES");
14832001f49Smrg   assert(procQueryMatrixx);
14932001f49Smrg   /* Actually try out this one */
15032001f49Smrg   rv = (*procQueryMatrixx)(mantissa, exponent);
15132001f49Smrg   for (i = 0; i < 16; i++) {
15232001f49Smrg      if (rv & (1<<i)) {
15332001f49Smrg        printf("matrix[%d] invalid\n", i);
15432001f49Smrg      }
15532001f49Smrg      else {
15632001f49Smrg         printf("matrix[%d] = %f * 2^(%d)\n", i, mantissa[i]/65536.0, exponent[i]);
15732001f49Smrg      }
15832001f49Smrg   }
15932001f49Smrg   assert(!eglGetProcAddress("glFoo"));
16032001f49Smrg}
16132001f49Smrg
16232001f49Smrg
16332001f49Smrgstatic void
16432001f49Smrginit(void)
16532001f49Smrg{
16632001f49Smrg   glClearColor(0.4, 0.4, 0.4, 0.0);
16732001f49Smrg
16832001f49Smrg   if (0)
16932001f49Smrg      test_query_matrix();
17032001f49Smrg}
17132001f49Smrg
17232001f49Smrgstatic void
17332001f49Smrgspecial_key(int special)
17432001f49Smrg{
17532001f49Smrg   switch (special) {
17632001f49Smrg   case EGLUT_KEY_LEFT:
17732001f49Smrg      view_roty += 5.0;
17832001f49Smrg      break;
17932001f49Smrg   case EGLUT_KEY_RIGHT:
18032001f49Smrg      view_roty -= 5.0;
18132001f49Smrg      break;
18232001f49Smrg   case EGLUT_KEY_UP:
18332001f49Smrg      view_rotx += 5.0;
18432001f49Smrg      break;
18532001f49Smrg   case EGLUT_KEY_DOWN:
18632001f49Smrg      view_rotx -= 5.0;
18732001f49Smrg      break;
18832001f49Smrg   default:
18932001f49Smrg      break;
19032001f49Smrg   }
19132001f49Smrg}
19232001f49Smrg
19332001f49Smrgint
19432001f49Smrgmain(int argc, char *argv[])
19532001f49Smrg{
19632001f49Smrg   eglutInitWindowSize(300, 300);
19732001f49Smrg   eglutInitAPIMask(EGLUT_OPENGL_ES1_BIT);
19832001f49Smrg   eglutInit(argc, argv);
19932001f49Smrg
20032001f49Smrg   eglutCreateWindow("tri");
20132001f49Smrg
20232001f49Smrg   eglutReshapeFunc(reshape);
20332001f49Smrg   eglutDisplayFunc(draw);
20432001f49Smrg   eglutSpecialFunc(special_key);
20532001f49Smrg
20632001f49Smrg   init();
20732001f49Smrg
20832001f49Smrg   eglutMainLoop();
20932001f49Smrg
21032001f49Smrg   return 0;
21132001f49Smrg}
212