1/*
2 * Test vertex arrays and multitexture.
3 * Press 'a' to toggle vertex arrays on/off.
4 * When you run this program you should see a square with four colors:
5 *
6 *      +------+------+
7 *      |yellow| pink |
8 *      +------+------+
9 *      |green | blue |
10 *      +------+------+
11 */
12
13
14#include <assert.h>
15#include <math.h>
16#include <stdlib.h>
17#include <stdio.h>
18#include <string.h>
19#include "GL/glew.h"
20#include "glut_wrap.h"
21
22static GLuint Window = 0;
23
24static GLuint TexObj[2];
25static GLfloat Angle = 0.0f;
26static GLboolean UseArrays = 1, Anim = 0;
27
28static GLfloat VertArray[4][2] = {
29   {-1.2, -1.2}, {1.2, -1.2}, {1.2, 1.2}, {-1.2, 1.2}
30};
31
32static GLfloat Tex0Array[4][2] = {
33   {0, 0}, {1, 0}, {1, 1}, {0, 1}
34};
35
36static GLfloat Tex1Array[4][2] = {
37   {0, 0}, {1, 0}, {1, 1}, {0, 1}
38};
39
40
41static void init_arrays(void)
42{
43   glVertexPointer(2, GL_FLOAT, 0, VertArray);
44   glEnableClientState(GL_VERTEX_ARRAY);
45
46   glClientActiveTextureARB(GL_TEXTURE0_ARB);
47   glTexCoordPointer(2, GL_FLOAT, 0, Tex0Array);
48   glEnableClientState(GL_TEXTURE_COORD_ARRAY);
49
50   glClientActiveTextureARB(GL_TEXTURE1_ARB);
51   glTexCoordPointer(2, GL_FLOAT, 0, Tex1Array);
52   glEnableClientState(GL_TEXTURE_COORD_ARRAY);
53}
54
55
56static void draw( void )
57{
58   glClear( GL_COLOR_BUFFER_BIT );
59
60   glColor3f( 0.0, 0.0, 0.0 );
61
62   /* draw first polygon */
63   glPushMatrix();
64      glRotatef( Angle, 0.0, 0.0, 1.0 );
65
66      if (UseArrays) {
67         glDrawArrays(GL_POLYGON, 0, 4);
68      }
69      else {
70         glBegin( GL_POLYGON );
71            glTexCoord2f( 0.0, 0.0 );
72            glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0, 0.0);
73            glVertex2f( -1.0, -1.0 );
74
75            glTexCoord2f( 1.0, 0.0 );
76            glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0, 0.0);
77            glVertex2f(  1.0, -1.0 );
78
79            glTexCoord2f( 1.0, 1.0 );
80            glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 1.0, 1.0);
81            glVertex2f(  1.0,  1.0 );
82
83            glTexCoord2f( 0.0, 1.0 );
84            glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0, 1.0);
85            glVertex2f( -1.0,  1.0 );
86         glEnd();
87      }
88
89   glPopMatrix();
90
91   glutSwapBuffers();
92}
93
94
95
96static void idle( void )
97{
98   Angle += 2.0;
99   glutPostRedisplay();
100}
101
102
103
104/* change view Angle, exit upon ESC */
105static void key(unsigned char k, int x, int y)
106{
107   (void) x;
108   (void) y;
109   switch (k) {
110      case 'a':
111         UseArrays = !UseArrays;
112         printf("UseArrays: %d\n", UseArrays);
113         break;
114      case ' ':
115         Anim = !Anim;
116         if (Anim)
117            glutIdleFunc(idle);
118         else
119            glutIdleFunc(NULL);
120         break;
121      case 27:
122         glDeleteTextures( 2, TexObj );
123         glutDestroyWindow(Window);
124         exit(0);
125   }
126   glutPostRedisplay();
127}
128
129
130
131/* new window size or exposure */
132static void reshape( int width, int height )
133{
134   glViewport(0, 0, (GLint)width, (GLint)height);
135   glMatrixMode(GL_PROJECTION);
136   glLoadIdentity();
137   /*   glOrtho( -3.0, 3.0, -3.0, 3.0, -10.0, 10.0 );*/
138   glFrustum( -2.0, 2.0, -2.0, 2.0, 6.0, 20.0 );
139   glMatrixMode(GL_MODELVIEW);
140   glLoadIdentity();
141   glTranslatef( 0.0, 0.0, -8.0 );
142}
143
144
145static void init( void )
146{
147   static int width=8, height=8;
148   GLubyte tex[64][3];
149   GLint i, j;
150
151   /* generate texture object IDs */
152   glGenTextures( 2, TexObj );
153
154   /*
155    * setup first texture object
156    */
157   glActiveTextureARB(GL_TEXTURE0_ARB);
158   glEnable( GL_TEXTURE_2D );
159   glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD );
160
161   glBindTexture( GL_TEXTURE_2D, TexObj[0] );
162   assert(glIsTexture(TexObj[0]));
163
164   /* red over black */
165   for (i=0;i<height;i++) {
166      for (j=0;j<width;j++) {
167         int p = i*width+j;
168         if (i < height / 2) {
169            tex[p][0] = 0;   tex[p][1] = 0;   tex[p][2] = 0;
170         }
171         else {
172            tex[p][0] = 255;   tex[p][1] = 0;     tex[p][2] = 0;
173         }
174      }
175   }
176
177   glTexImage2D( GL_TEXTURE_2D, 0, 3, width, height, 0,
178                 GL_RGB, GL_UNSIGNED_BYTE, tex );
179   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
180   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
181   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
182   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
183
184
185   /*
186    * setup second texture object
187    */
188   glActiveTextureARB(GL_TEXTURE1_ARB);
189   glEnable( GL_TEXTURE_2D );
190   glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD );
191
192   glBindTexture( GL_TEXTURE_2D, TexObj[1] );
193   assert(glIsTexture(TexObj[1]));
194
195   /* left=green, right = blue */
196   for (i=0;i<height;i++) {
197      for (j=0;j<width;j++) {
198         int p = i*width+j;
199         if (j < width / 2) {
200            tex[p][0] = 0;     tex[p][1] = 255;   tex[p][2] = 0;
201         }
202         else {
203            tex[p][0] = 0;     tex[p][1] = 0;     tex[p][2] = 255;
204         }
205      }
206   }
207   glTexImage2D( GL_TEXTURE_2D, 0, 3, width, height, 0,
208                 GL_RGB, GL_UNSIGNED_BYTE, tex );
209   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
210   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
211   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
212   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
213}
214
215
216
217int main( int argc, char *argv[] )
218{
219   glutInit(&argc, argv);
220   glutInitWindowPosition(0, 0);
221   glutInitWindowSize(300, 300);
222   glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
223
224   Window = glutCreateWindow("Texture Objects");
225   glewInit();
226   if (!Window) {
227      exit(1);
228   }
229
230   init();
231   init_arrays();
232
233   glutReshapeFunc( reshape );
234   glutKeyboardFunc( key );
235   if (Anim)
236      glutIdleFunc( idle );
237   glutDisplayFunc( draw );
238   glutMainLoop();
239   return 0;
240}
241