2 * Copyright (C) 2008 Tunsgten Graphics,Inc. All Rights Reserved.
6 * Draw a lit, textured torus with X/EGL and OpenGL ES 1.x
21 GLenum internalFormat
;
26 { GL_PALETTE4_RGB8_OES
, "GL_PALETTE4_RGB8_OES", 16, 3 },
27 { GL_PALETTE4_RGBA8_OES
, "GL_PALETTE4_RGBA8_OES", 16, 4 },
28 { GL_PALETTE4_R5_G6_B5_OES
, "GL_PALETTE4_R5_G6_B5_OES", 16, 2 },
29 { GL_PALETTE4_RGBA4_OES
, "GL_PALETTE4_RGBA4_OES", 16, 2 },
30 { GL_PALETTE4_RGB5_A1_OES
, "GL_PALETTE4_RGB5_A1_OES", 16, 2 },
31 { GL_PALETTE8_RGB8_OES
, "GL_PALETTE8_RGB8_OES", 256, 3 },
32 { GL_PALETTE8_RGBA8_OES
, "GL_PALETTE8_RGBA8_OES", 256, 4 },
33 { GL_PALETTE8_R5_G6_B5_OES
, "GL_PALETTE8_R5_G6_B5_OES", 256, 2 },
34 { GL_PALETTE8_RGBA4_OES
, "GL_PALETTE8_RGBA4_OES", 256, 2 },
35 { GL_PALETTE8_RGB5_A1_OES
, "GL_PALETTE8_RGB5_A1_OES", 256, 2 }
37 #define NUM_CPAL_FORMATS (sizeof(cpal_formats) / sizeof(cpal_formats[0]))
39 static GLfloat view_rotx
= 0.0, view_roty
= 0.0, view_rotz
= 0.0;
40 static GLint tex_format
= NUM_CPAL_FORMATS
;
41 static GLboolean animate
= GL_TRUE
;
46 Normal(GLfloat
*n
, GLfloat nx
, GLfloat ny
, GLfloat nz
)
54 Vertex(GLfloat
*v
, GLfloat vx
, GLfloat vy
, GLfloat vz
)
62 Texcoord(GLfloat
*v
, GLfloat s
, GLfloat t
)
69 /* Borrowed from glut, adapted */
71 draw_torus(GLfloat r
, GLfloat R
, GLint nsides
, GLint rings
)
74 GLfloat theta
, phi
, theta1
;
75 GLfloat cosTheta
, sinTheta
;
76 GLfloat cosTheta1
, sinTheta1
;
77 GLfloat ringDelta
, sideDelta
;
78 GLfloat varray
[100][3], narray
[100][3], tarray
[100][2];
81 glVertexPointer(3, GL_FLOAT
, 0, varray
);
82 glNormalPointer(GL_FLOAT
, 0, narray
);
83 glTexCoordPointer(2, GL_FLOAT
, 0, tarray
);
84 glEnableClientState(GL_VERTEX_ARRAY
);
85 glEnableClientState(GL_NORMAL_ARRAY
);
86 glEnableClientState(GL_TEXTURE_COORD_ARRAY
);
88 ringDelta
= 2.0 * M_PI
/ rings
;
89 sideDelta
= 2.0 * M_PI
/ nsides
;
94 for (i
= rings
- 1; i
>= 0; i
--) {
95 theta1
= theta
+ ringDelta
;
96 cosTheta1
= cos(theta1
);
97 sinTheta1
= sin(theta1
);
99 vcount
= 0; /* glBegin(GL_QUAD_STRIP); */
102 for (j
= nsides
; j
>= 0; j
--) {
104 GLfloat cosPhi
, sinPhi
, dist
;
109 dist
= R
+ r
* cosPhi
;
111 s0
= 20.0 * theta
/ (2.0 * M_PI
);
112 s1
= 20.0 * theta1
/ (2.0 * M_PI
);
113 t
= 8.0 * phi
/ (2.0 * M_PI
);
115 Normal(narray
[vcount
], cosTheta1
* cosPhi
, -sinTheta1
* cosPhi
, sinPhi
);
116 Texcoord(tarray
[vcount
], s1
, t
);
117 Vertex(varray
[vcount
], cosTheta1
* dist
, -sinTheta1
* dist
, r
* sinPhi
);
120 Normal(narray
[vcount
], cosTheta
* cosPhi
, -sinTheta
* cosPhi
, sinPhi
);
121 Texcoord(tarray
[vcount
], s0
, t
);
122 Vertex(varray
[vcount
], cosTheta
* dist
, -sinTheta
* dist
, r
* sinPhi
);
127 assert(vcount
<= 100);
128 glDrawArrays(GL_TRIANGLE_STRIP
, 0, vcount
);
131 cosTheta
= cosTheta1
;
132 sinTheta
= sinTheta1
;
135 glDisableClientState(GL_VERTEX_ARRAY
);
136 glDisableClientState(GL_NORMAL_ARRAY
);
137 glDisableClientState(GL_TEXTURE_COORD_ARRAY
);
144 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
147 glRotatef(view_rotx
, 1, 0, 0);
148 glRotatef(view_roty
, 0, 1, 0);
149 glRotatef(view_rotz
, 0, 0, 1);
150 glScalef(0.5, 0.5, 0.5);
152 draw_torus(1.0, 3.0, 30, 60);
158 /* new window size or exposure */
160 reshape(int width
, int height
)
162 GLfloat ar
= (GLfloat
) width
/ (GLfloat
) height
;
164 glViewport(0, 0, (GLint
) width
, (GLint
) height
);
166 glMatrixMode(GL_PROJECTION
);
169 #ifdef GL_VERSION_ES_CM_1_0
170 glFrustumf(-ar
, ar
, -1, 1, 5.0, 60.0);
172 glFrustum(-ar
, ar
, -1, 1, 5.0, 60.0);
175 glMatrixMode(GL_MODELVIEW
);
177 glTranslatef(0.0, 0.0, -15.0);
182 make_cpal_texture(GLint idx
)
185 GLenum internalFormat
= GL_PALETTE4_RGB8_OES
+ idx
;
186 GLenum Filter
= GL_LINEAR
;
187 GLubyte palette
[256 * 4 + SZ
* SZ
];
191 GLuint packed_indices
= 0;
193 assert(cpal_formats
[idx
].internalFormat
== internalFormat
);
196 switch (internalFormat
) {
197 case GL_PALETTE4_RGB8_OES
:
198 case GL_PALETTE8_RGB8_OES
:
208 case GL_PALETTE4_RGBA8_OES
:
209 case GL_PALETTE8_RGBA8_OES
:
221 case GL_PALETTE4_R5_G6_B5_OES
:
222 case GL_PALETTE8_R5_G6_B5_OES
:
224 GLushort
*pal
= (GLushort
*) palette
;
226 pal
[0] = (31 << 11 | 63 << 5 | 31);
228 pal
[1] = (15 << 11 | 31 << 5 | 15);
231 case GL_PALETTE4_RGBA4_OES
:
232 case GL_PALETTE8_RGBA4_OES
:
234 GLushort
*pal
= (GLushort
*) palette
;
236 pal
[0] = (15 << 12 | 15 << 8 | 15 << 4 | 15);
238 pal
[1] = (7 << 12 | 7 << 8 | 7 << 4 | 15);
241 case GL_PALETTE4_RGB5_A1_OES
:
242 case GL_PALETTE8_RGB5_A1_OES
:
244 GLushort
*pal
= (GLushort
*) palette
;
246 pal
[0] = (31 << 11 | 31 << 6 | 31 << 1 | 1);
248 pal
[1] = (15 << 11 | 15 << 6 | 15 << 1 | 1);
253 image_size
= cpal_formats
[idx
].size
* cpal_formats
[idx
].num_entries
;
254 indices
= palette
+ image_size
;
255 for (i
= 0; i
< SZ
; i
++) {
256 for (j
= 0; j
< SZ
; j
++) {
259 d
= (i
- SZ
/2) * (i
- SZ
/2) + (j
- SZ
/2) * (j
- SZ
/2);
261 index
= (d
< SZ
/ 3) ? 0 : 1;
263 if (cpal_formats
[idx
].num_entries
== 16) {
264 /* 4-bit indices packed in GLubyte */
265 packed_indices
|= index
<< (4 * (1 - (j
% 2)));
267 *(indices
+ (i
* SZ
+ j
- 1) / 2) = packed_indices
& 0xff;
274 *(indices
+ i
* SZ
+ j
) = index
;
280 glActiveTexture(GL_TEXTURE0
); /* unit 0 */
281 glBindTexture(GL_TEXTURE_2D
, 42);
282 glCompressedTexImage2D(GL_TEXTURE_2D
, 0, internalFormat
, SZ
, SZ
, 0,
283 image_size
, palette
);
285 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, Filter
);
286 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, Filter
);
287 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_REPEAT
);
288 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_REPEAT
);
299 GLenum Filter
= GL_LINEAR
;
300 GLubyte image
[SZ
][SZ
][4];
303 for (i
= 0; i
< SZ
; i
++) {
304 for (j
= 0; j
< SZ
; j
++) {
305 GLfloat d
= (i
- SZ
/2) * (i
- SZ
/2) + (j
- SZ
/2) * (j
- SZ
/2);
308 image
[i
][j
][0] = 255;
309 image
[i
][j
][1] = 255;
310 image
[i
][j
][2] = 255;
311 image
[i
][j
][3] = 255;
314 image
[i
][j
][0] = 127;
315 image
[i
][j
][1] = 127;
316 image
[i
][j
][2] = 127;
317 image
[i
][j
][3] = 255;
322 glActiveTexture(GL_TEXTURE0
); /* unit 0 */
323 glBindTexture(GL_TEXTURE_2D
, 42);
324 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA
, SZ
, SZ
, 0,
325 GL_RGBA
, GL_UNSIGNED_BYTE
, image
);
326 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, Filter
);
327 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, Filter
);
328 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_REPEAT
);
329 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_REPEAT
);
332 return sizeof(image
);
340 static const GLfloat red
[4] = {1, 0, 0, 0};
341 static const GLfloat white
[4] = {1.0, 1.0, 1.0, 1.0};
342 static const GLfloat diffuse
[4] = {0.7, 0.7, 0.7, 1.0};
343 static const GLfloat specular
[4] = {0.001, 0.001, 0.001, 1.0};
344 static const GLfloat pos
[4] = {20, 20, 50, 1};
346 glMaterialfv(GL_FRONT_AND_BACK
, GL_AMBIENT_AND_DIFFUSE
, red
);
347 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, white
);
348 glMaterialf(GL_FRONT_AND_BACK
, GL_SHININESS
, 9.0);
350 glEnable(GL_LIGHTING
);
352 glLightfv(GL_LIGHT0
, GL_POSITION
, pos
);
353 glLightfv(GL_LIGHT0
, GL_DIFFUSE
, diffuse
);
354 glLightfv(GL_LIGHT0
, GL_SPECULAR
, specular
);
356 glClearColor(0.4, 0.4, 0.4, 0.0);
357 glEnable(GL_DEPTH_TEST
);
360 glEnable(GL_TEXTURE_2D
);
370 eglutPostRedisplay();
375 key(unsigned char key
)
384 tex_format
= (tex_format
+ 1) % (NUM_CPAL_FORMATS
+ 1);
385 if (tex_format
< NUM_CPAL_FORMATS
) {
386 size
= make_cpal_texture(tex_format
);
387 printf("Using %s (%d bytes)\n",
388 cpal_formats
[tex_format
].name
, size
);
391 size
= make_texture();
392 printf("Using uncompressed texture (%d bytes)\n", size
);
395 eglutPostRedisplay();
399 eglutDestroyWindow(win
);
414 case EGLUT_KEY_RIGHT
:
429 main(int argc
, char *argv
[])
431 eglutInitWindowSize(300, 300);
432 eglutInitAPIMask(EGLUT_OPENGL_ES1_BIT
);
433 eglutInit(argc
, argv
);
435 win
= eglutCreateWindow("torus");
438 eglutReshapeFunc(reshape
);
439 eglutDisplayFunc(draw
);
440 eglutKeyboardFunc(key
);
441 eglutSpecialFunc(special_key
);