132001f49Smrg/*
232001f49Smrg * Test vertex arrays and multitexture.
332001f49Smrg * Press 'a' to toggle vertex arrays on/off.
432001f49Smrg * When you run this program you should see a square with four colors:
532001f49Smrg *
632001f49Smrg *      +------+------+
732001f49Smrg *      |yellow| pink |
832001f49Smrg *      +------+------+
932001f49Smrg *      |green | blue |
1032001f49Smrg *      +------+------+
1132001f49Smrg */
1232001f49Smrg
1332001f49Smrg
1432001f49Smrg#include <assert.h>
1532001f49Smrg#include <math.h>
1632001f49Smrg#include <stdlib.h>
1732001f49Smrg#include <stdio.h>
1832001f49Smrg#include <string.h>
1932001f49Smrg#include "GL/glew.h"
2032001f49Smrg#include "glut_wrap.h"
2132001f49Smrg
2232001f49Smrgstatic GLuint Window = 0;
2332001f49Smrg
2432001f49Smrgstatic GLuint TexObj[2];
2532001f49Smrgstatic GLfloat Angle = 0.0f;
2632001f49Smrgstatic GLboolean UseArrays = 1, Anim = 0;
2732001f49Smrg
2832001f49Smrgstatic GLfloat VertArray[4][2] = {
2932001f49Smrg   {-1.2, -1.2}, {1.2, -1.2}, {1.2, 1.2}, {-1.2, 1.2}
3032001f49Smrg};
3132001f49Smrg
3232001f49Smrgstatic GLfloat Tex0Array[4][2] = {
3332001f49Smrg   {0, 0}, {1, 0}, {1, 1}, {0, 1}
3432001f49Smrg};
3532001f49Smrg
3632001f49Smrgstatic GLfloat Tex1Array[4][2] = {
3732001f49Smrg   {0, 0}, {1, 0}, {1, 1}, {0, 1}
3832001f49Smrg};
3932001f49Smrg
4032001f49Smrg
4132001f49Smrgstatic void init_arrays(void)
4232001f49Smrg{
4332001f49Smrg   glVertexPointer(2, GL_FLOAT, 0, VertArray);
4432001f49Smrg   glEnableClientState(GL_VERTEX_ARRAY);
4532001f49Smrg
4632001f49Smrg   glClientActiveTextureARB(GL_TEXTURE0_ARB);
4732001f49Smrg   glTexCoordPointer(2, GL_FLOAT, 0, Tex0Array);
4832001f49Smrg   glEnableClientState(GL_TEXTURE_COORD_ARRAY);
4932001f49Smrg
5032001f49Smrg   glClientActiveTextureARB(GL_TEXTURE1_ARB);
5132001f49Smrg   glTexCoordPointer(2, GL_FLOAT, 0, Tex1Array);
5232001f49Smrg   glEnableClientState(GL_TEXTURE_COORD_ARRAY);
5332001f49Smrg}
5432001f49Smrg
5532001f49Smrg
5632001f49Smrgstatic void draw( void )
5732001f49Smrg{
5832001f49Smrg   glClear( GL_COLOR_BUFFER_BIT );
5932001f49Smrg
6032001f49Smrg   glColor3f( 0.0, 0.0, 0.0 );
6132001f49Smrg
6232001f49Smrg   /* draw first polygon */
6332001f49Smrg   glPushMatrix();
6432001f49Smrg      glRotatef( Angle, 0.0, 0.0, 1.0 );
6532001f49Smrg
6632001f49Smrg      if (UseArrays) {
6732001f49Smrg         glDrawArrays(GL_POLYGON, 0, 4);
6832001f49Smrg      }
6932001f49Smrg      else {
7032001f49Smrg         glBegin( GL_POLYGON );
7132001f49Smrg            glTexCoord2f( 0.0, 0.0 );
7232001f49Smrg            glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0, 0.0);
7332001f49Smrg            glVertex2f( -1.0, -1.0 );
7432001f49Smrg
7532001f49Smrg            glTexCoord2f( 1.0, 0.0 );
7632001f49Smrg            glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0, 0.0);
7732001f49Smrg            glVertex2f(  1.0, -1.0 );
7832001f49Smrg
7932001f49Smrg            glTexCoord2f( 1.0, 1.0 );
8032001f49Smrg            glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0, 1.0);
8132001f49Smrg            glVertex2f(  1.0,  1.0 );
8232001f49Smrg
8332001f49Smrg            glTexCoord2f( 0.0, 1.0 );
8432001f49Smrg            glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0, 1.0);
8532001f49Smrg            glVertex2f( -1.0,  1.0 );
8632001f49Smrg         glEnd();
8732001f49Smrg      }
8832001f49Smrg
8932001f49Smrg   glPopMatrix();
9032001f49Smrg
9132001f49Smrg   glutSwapBuffers();
9232001f49Smrg}
9332001f49Smrg
9432001f49Smrg
9532001f49Smrg
9632001f49Smrgstatic void idle( void )
9732001f49Smrg{
9832001f49Smrg   Angle += 2.0;
9932001f49Smrg   glutPostRedisplay();
10032001f49Smrg}
10132001f49Smrg
10232001f49Smrg
10332001f49Smrg
10432001f49Smrg/* change view Angle, exit upon ESC */
10532001f49Smrgstatic void key(unsigned char k, int x, int y)
10632001f49Smrg{
10732001f49Smrg   (void) x;
10832001f49Smrg   (void) y;
10932001f49Smrg   switch (k) {
11032001f49Smrg      case 'a':
11132001f49Smrg         UseArrays = !UseArrays;
11232001f49Smrg         printf("UseArrays: %d\n", UseArrays);
11332001f49Smrg         break;
11432001f49Smrg      case ' ':
11532001f49Smrg         Anim = !Anim;
11632001f49Smrg         if (Anim)
11732001f49Smrg            glutIdleFunc(idle);
11832001f49Smrg         else
11932001f49Smrg            glutIdleFunc(NULL);
12032001f49Smrg         break;
12132001f49Smrg      case 27:
12232001f49Smrg         glDeleteTextures( 2, TexObj );
12332001f49Smrg         glutDestroyWindow(Window);
12432001f49Smrg         exit(0);
12532001f49Smrg   }
12632001f49Smrg   glutPostRedisplay();
12732001f49Smrg}
12832001f49Smrg
12932001f49Smrg
13032001f49Smrg
13132001f49Smrg/* new window size or exposure */
13232001f49Smrgstatic void reshape( int width, int height )
13332001f49Smrg{
13432001f49Smrg   glViewport(0, 0, (GLint)width, (GLint)height);
13532001f49Smrg   glMatrixMode(GL_PROJECTION);
13632001f49Smrg   glLoadIdentity();
13732001f49Smrg   /*   glOrtho( -3.0, 3.0, -3.0, 3.0, -10.0, 10.0 );*/
13832001f49Smrg   glFrustum( -2.0, 2.0, -2.0, 2.0, 6.0, 20.0 );
13932001f49Smrg   glMatrixMode(GL_MODELVIEW);
14032001f49Smrg   glLoadIdentity();
14132001f49Smrg   glTranslatef( 0.0, 0.0, -8.0 );
14232001f49Smrg}
14332001f49Smrg
14432001f49Smrg
14532001f49Smrgstatic void init( void )
14632001f49Smrg{
14732001f49Smrg   static int width=8, height=8;
14832001f49Smrg   GLubyte tex[64][3];
14932001f49Smrg   GLint i, j;
15032001f49Smrg
15132001f49Smrg   /* generate texture object IDs */
15232001f49Smrg   glGenTextures( 2, TexObj );
15332001f49Smrg
15432001f49Smrg   /*
15532001f49Smrg    * setup first texture object
15632001f49Smrg    */
15732001f49Smrg   glActiveTextureARB(GL_TEXTURE0_ARB);
15832001f49Smrg   glEnable( GL_TEXTURE_2D );
15932001f49Smrg   glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD );
16032001f49Smrg
16132001f49Smrg   glBindTexture( GL_TEXTURE_2D, TexObj[0] );
16232001f49Smrg   assert(glIsTexture(TexObj[0]));
16332001f49Smrg
16432001f49Smrg   /* red over black */
16532001f49Smrg   for (i=0;i<height;i++) {
16632001f49Smrg      for (j=0;j<width;j++) {
16732001f49Smrg         int p = i*width+j;
16832001f49Smrg         if (i < height / 2) {
16932001f49Smrg            tex[p][0] = 0;   tex[p][1] = 0;   tex[p][2] = 0;
17032001f49Smrg         }
17132001f49Smrg         else {
17232001f49Smrg            tex[p][0] = 255;   tex[p][1] = 0;     tex[p][2] = 0;
17332001f49Smrg         }
17432001f49Smrg      }
17532001f49Smrg   }
17632001f49Smrg
17732001f49Smrg   glTexImage2D( GL_TEXTURE_2D, 0, 3, width, height, 0,
17832001f49Smrg                 GL_RGB, GL_UNSIGNED_BYTE, tex );
17932001f49Smrg   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
18032001f49Smrg   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
18132001f49Smrg   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
18232001f49Smrg   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
18332001f49Smrg
18432001f49Smrg
18532001f49Smrg   /*
18632001f49Smrg    * setup second texture object
18732001f49Smrg    */
18832001f49Smrg   glActiveTextureARB(GL_TEXTURE1_ARB);
18932001f49Smrg   glEnable( GL_TEXTURE_2D );
19032001f49Smrg   glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD );
19132001f49Smrg
19232001f49Smrg   glBindTexture( GL_TEXTURE_2D, TexObj[1] );
19332001f49Smrg   assert(glIsTexture(TexObj[1]));
19432001f49Smrg
19532001f49Smrg   /* left=green, right = blue */
19632001f49Smrg   for (i=0;i<height;i++) {
19732001f49Smrg      for (j=0;j<width;j++) {
19832001f49Smrg         int p = i*width+j;
19932001f49Smrg         if (j < width / 2) {
20032001f49Smrg            tex[p][0] = 0;     tex[p][1] = 255;   tex[p][2] = 0;
20132001f49Smrg         }
20232001f49Smrg         else {
20332001f49Smrg            tex[p][0] = 0;     tex[p][1] = 0;     tex[p][2] = 255;
20432001f49Smrg         }
20532001f49Smrg      }
20632001f49Smrg   }
20732001f49Smrg   glTexImage2D( GL_TEXTURE_2D, 0, 3, width, height, 0,
20832001f49Smrg                 GL_RGB, GL_UNSIGNED_BYTE, tex );
20932001f49Smrg   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
21032001f49Smrg   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
21132001f49Smrg   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
21232001f49Smrg   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
21332001f49Smrg}
21432001f49Smrg
21532001f49Smrg
21632001f49Smrg
21732001f49Smrgint main( int argc, char *argv[] )
21832001f49Smrg{
21932001f49Smrg   glutInit(&argc, argv);
22032001f49Smrg   glutInitWindowPosition(0, 0);
22132001f49Smrg   glutInitWindowSize(300, 300);
22232001f49Smrg   glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
22332001f49Smrg
22432001f49Smrg   Window = glutCreateWindow("Texture Objects");
22532001f49Smrg   glewInit();
22632001f49Smrg   if (!Window) {
22732001f49Smrg      exit(1);
22832001f49Smrg   }
22932001f49Smrg
23032001f49Smrg   init();
23132001f49Smrg   init_arrays();
23232001f49Smrg
23332001f49Smrg   glutReshapeFunc( reshape );
23432001f49Smrg   glutKeyboardFunc( key );
23532001f49Smrg   if (Anim)
23632001f49Smrg      glutIdleFunc( idle );
23732001f49Smrg   glutDisplayFunc( draw );
23832001f49Smrg   glutMainLoop();
23932001f49Smrg   return 0;
24032001f49Smrg}
241