132001f49Smrg/*
232001f49Smrg * Copyright (C) 2008  Tunsgten Graphics,Inc.   All Rights Reserved.
332001f49Smrg */
432001f49Smrg
532001f49Smrg/*
632001f49Smrg * Test GL_OES_draw_texture
732001f49Smrg * Brian Paul
832001f49Smrg * August 2008
932001f49Smrg */
1032001f49Smrg
1132001f49Smrg#define GL_GLEXT_PROTOTYPES
1232001f49Smrg
1332001f49Smrg#include <math.h>
1432001f49Smrg#include <stdlib.h>
1532001f49Smrg#include <stdio.h>
1632001f49Smrg#include <string.h>
1732001f49Smrg#include <GLES/gl.h>
1832001f49Smrg#include <GLES/glext.h>
1932001f49Smrg#include <EGL/egl.h>
2032001f49Smrg
2132001f49Smrg#include "eglut.h"
2232001f49Smrg
2332001f49Smrg
2432001f49Smrgstatic GLfloat view_posx = 10.0, view_posy = 20.0;
2532001f49Smrgstatic GLfloat width = 200, height = 200;
2632001f49Smrgstatic GLboolean animate = GL_FALSE;
2732001f49Smrgstatic int win;
2832001f49Smrg
2932001f49Smrgstatic PFNGLDRAWTEXFOESPROC glDrawTexfOES_func = NULL;
3032001f49Smrg
3132001f49Smrgstatic void
3232001f49Smrgdraw(void)
3332001f49Smrg{
3432001f49Smrg   glClear(GL_COLOR_BUFFER_BIT);
3532001f49Smrg
3632001f49Smrg   glDrawTexfOES_func(view_posx, view_posy, 0.0, width, height);
3732001f49Smrg}
3832001f49Smrg
3932001f49Smrg
4032001f49Smrg/* new window size or exposure */
4132001f49Smrgstatic void
4232001f49Smrgreshape(int width, int height)
4332001f49Smrg{
4432001f49Smrg   GLfloat ar = (GLfloat) width / (GLfloat) height;
4532001f49Smrg
4632001f49Smrg   glViewport(0, 0, (GLint) width, (GLint) height);
4732001f49Smrg
4832001f49Smrg   glMatrixMode(GL_PROJECTION);
4932001f49Smrg   glLoadIdentity();
5032001f49Smrg
5132001f49Smrg#ifdef GL_VERSION_ES_CM_1_0
5232001f49Smrg   glFrustumf(-ar, ar, -1, 1, 5.0, 60.0);
5332001f49Smrg#else
5432001f49Smrg   glFrustum(-ar, ar, -1, 1, 5.0, 60.0);
5532001f49Smrg#endif
5632001f49Smrg
5732001f49Smrg   glMatrixMode(GL_MODELVIEW);
5832001f49Smrg   glLoadIdentity();
5932001f49Smrg   glTranslatef(0.0, 0.0, -15.0);
6032001f49Smrg}
6132001f49Smrg
6232001f49Smrg
6332001f49Smrgstatic float
6432001f49Smrgdist(GLuint i, GLuint j, float x, float y)
6532001f49Smrg{
6632001f49Smrg   return sqrt((i-x) * (i-x) + (j-y) * (j-y));
6732001f49Smrg}
6832001f49Smrg
6932001f49Smrgstatic void
7032001f49Smrgmake_smile_texture(void)
7132001f49Smrg{
7232001f49Smrg#define SZ 128
7332001f49Smrg   GLenum Filter = GL_LINEAR;
7432001f49Smrg   GLubyte image[SZ][SZ][4];
7532001f49Smrg   GLuint i, j;
7632001f49Smrg   GLint cropRect[4];
7732001f49Smrg
7832001f49Smrg   for (i = 0; i < SZ; i++) {
7932001f49Smrg      for (j = 0; j < SZ; j++) {
8032001f49Smrg         GLfloat d_mouth = dist(i, j, SZ/2, SZ/2);
8132001f49Smrg         GLfloat d_rt_eye = dist(i, j, SZ*3/4, SZ*3/4);
8232001f49Smrg         GLfloat d_lt_eye = dist(i, j, SZ*3/4, SZ*1/4);
8332001f49Smrg         if (d_rt_eye < SZ / 8 || d_lt_eye < SZ / 8) {
8432001f49Smrg            image[i][j][0] = 20;
8532001f49Smrg            image[i][j][1] = 50;
8632001f49Smrg            image[i][j][2] = 255;
8732001f49Smrg            image[i][j][3] = 255;
8832001f49Smrg         }
8932001f49Smrg         else if (i < SZ/2 && d_mouth < SZ/3) {
9032001f49Smrg            image[i][j][0] = 255;
9132001f49Smrg            image[i][j][1] = 20;
9232001f49Smrg            image[i][j][2] = 20;
9332001f49Smrg            image[i][j][3] = 255;
9432001f49Smrg         }
9532001f49Smrg         else {
9632001f49Smrg            image[i][j][0] = 200;
9732001f49Smrg            image[i][j][1] = 200;
9832001f49Smrg            image[i][j][2] = 200;
9932001f49Smrg            image[i][j][3] = 255;
10032001f49Smrg         }
10132001f49Smrg      }
10232001f49Smrg   }
10332001f49Smrg
10432001f49Smrg   glActiveTexture(GL_TEXTURE0); /* unit 0 */
10532001f49Smrg   glBindTexture(GL_TEXTURE_2D, 42);
10632001f49Smrg   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SZ, SZ, 0,
10732001f49Smrg                GL_RGBA, GL_UNSIGNED_BYTE, image);
10832001f49Smrg   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Filter);
10932001f49Smrg   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Filter);
11032001f49Smrg   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
11132001f49Smrg   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
11232001f49Smrg
11332001f49Smrg   cropRect[0] = 0;
11432001f49Smrg   cropRect[1] = 0;
11532001f49Smrg   cropRect[2] = SZ;
11632001f49Smrg   cropRect[3] = SZ;
11732001f49Smrg   glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect);
11832001f49Smrg#undef SZ
11932001f49Smrg}
12032001f49Smrg
12132001f49Smrg
12232001f49Smrg
12332001f49Smrgstatic void
12432001f49Smrginit(void)
12532001f49Smrg{
12632001f49Smrg   const char *ext = (char *) glGetString(GL_EXTENSIONS);
12732001f49Smrg
12832001f49Smrg   if (!strstr(ext, "GL_OES_draw_texture")) {
12932001f49Smrg      fprintf(stderr, "Sorry, this program requires GL_OES_draw_texture\n");
13032001f49Smrg      exit(1);
13132001f49Smrg   }
13232001f49Smrg
13332001f49Smrg   glDrawTexfOES_func = (PFNGLDRAWTEXFOESPROC) eglGetProcAddress("glDrawTexfOES");
13432001f49Smrg
13532001f49Smrg   if (!glDrawTexfOES_func) {
13632001f49Smrg      fprintf(stderr, "Sorry, failed to resolve glDrawTexfOES function\n");
13732001f49Smrg      exit(1);
13832001f49Smrg   }
13932001f49Smrg
14032001f49Smrg   glClearColor(0.4, 0.4, 0.4, 0.0);
14132001f49Smrg
14232001f49Smrg   make_smile_texture();
14332001f49Smrg   glEnable(GL_TEXTURE_2D);
14432001f49Smrg}
14532001f49Smrg
14632001f49Smrg
14732001f49Smrgstatic void
14832001f49Smrgidle(void)
14932001f49Smrg{
15032001f49Smrg   if (animate) {
15132001f49Smrg      view_posx += 1.0;
15232001f49Smrg      view_posy += 2.0;
15332001f49Smrg      eglutPostRedisplay();
15432001f49Smrg   }
15532001f49Smrg}
15632001f49Smrg
15732001f49Smrgstatic void
15832001f49Smrgkey(unsigned char key)
15932001f49Smrg{
16032001f49Smrg   switch (key) {
16132001f49Smrg   case ' ':
16232001f49Smrg      animate = !animate;
16332001f49Smrg      break;
16432001f49Smrg   case 'w':
16532001f49Smrg      width -= 1.0f;
16632001f49Smrg      break;
16732001f49Smrg   case 'W':
16832001f49Smrg      width += 1.0f;
16932001f49Smrg      break;
17032001f49Smrg   case 'h':
17132001f49Smrg      height -= 1.0f;
17232001f49Smrg      break;
17332001f49Smrg   case 'H':
17432001f49Smrg      height += 1.0f;
17532001f49Smrg      break;
17632001f49Smrg   case 27:
17732001f49Smrg      eglutDestroyWindow(win);
17832001f49Smrg      exit(0);
17932001f49Smrg      break;
18032001f49Smrg   default:
18132001f49Smrg      break;
18232001f49Smrg   }
18332001f49Smrg}
18432001f49Smrg
18532001f49Smrgstatic void
18632001f49Smrgspecial_key(int key)
18732001f49Smrg{
18832001f49Smrg   switch (key) {
18932001f49Smrg   case EGLUT_KEY_LEFT:
19032001f49Smrg      view_posx -= 1.0;
19132001f49Smrg      break;
19232001f49Smrg   case EGLUT_KEY_RIGHT:
19332001f49Smrg      view_posx += 1.0;
19432001f49Smrg      break;
19532001f49Smrg   case EGLUT_KEY_UP:
19632001f49Smrg      view_posy += 1.0;
19732001f49Smrg      break;
19832001f49Smrg   case EGLUT_KEY_DOWN:
19932001f49Smrg      view_posy -= 1.0;
20032001f49Smrg      break;
20132001f49Smrg   default:
20232001f49Smrg      break;
20332001f49Smrg   }
20432001f49Smrg}
20532001f49Smrg
20632001f49Smrgint
20732001f49Smrgmain(int argc, char *argv[])
20832001f49Smrg{
20932001f49Smrg   eglutInitWindowSize(400, 300);
21032001f49Smrg   eglutInitAPIMask(EGLUT_OPENGL_ES1_BIT);
21132001f49Smrg   eglutInit(argc, argv);
21232001f49Smrg
21332001f49Smrg   win = eglutCreateWindow("drawtex");
21432001f49Smrg
21532001f49Smrg   eglutIdleFunc(idle);
21632001f49Smrg   eglutReshapeFunc(reshape);
21732001f49Smrg   eglutDisplayFunc(draw);
21832001f49Smrg   eglutKeyboardFunc(key);
21932001f49Smrg   eglutSpecialFunc(special_key);
22032001f49Smrg
22132001f49Smrg   init();
22232001f49Smrg
22332001f49Smrg   eglutMainLoop();
22432001f49Smrg
22532001f49Smrg   return 0;
22632001f49Smrg}
227