IamEasy_Man

Filled With Confidence , And Never Say Give Up !

【原创】OPGL ES加载PNG图片为纹理

因为BMP图片在显示的时候周边有比较难看的锯齿图,OPGL ES基本上都是使用对BMP加载纹理图的做法,很少加载PNG纹理图,今天在某国外网站看到这么一段使用OPGL加载PNG纹理图代码,摘录下来。

论坛上有人试验成功,但是我使用libpng库的时候,用png_read_info 读取png图片信息时出错,正在调试中。大家讨论讨论。

通过该链接可以下载库和源码http://www.tenik.co.jp/~adachi/wince/zlibce/index.html 

源码如下:

  1 /*
  2  * png.c -- png texture loader
  3  * last modification: aug. 14, 2007
  4  *
  5  * Copyright (c) 2005-2007 David HENRY
  6  *
  7  * Permission is hereby granted, free of charge, to any person
  8  * obtaining a copy of this software and associated documentation
  9  * files (the "Software"), to deal in the Software without
 10  * restriction, including without limitation the rights to use,
 11  * copy, modify, merge, publish, distribute, sublicense, and/or
 12  * sell copies of the Software, and to permit persons to whom the
 13  * Software is furnished to do so, subject to the following conditions:
 14  *
 15  * The above copyright notice and this permission notice shall be
 16  * included in all copies or substantial portions of the Software.
 17  *
 18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 19  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 21  * NONINFRINGEMENT.
 22  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
 23  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
 24  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 25  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 26  *
 27  * gcc -Wall -ansi -lGL -lGLU -lglut
 28  *    `libpng12-config --cflags --libs` png.c -o png
 29  */
 30 
 31 #include <GL/glut.h>
 32 #include <stdio.h>
 33 #include <stdlib.h>
 34 #include <string.h>
 35 
 36 #include <png.h>
 37 
 38 /* Microsoft Visual C++ */
 39 #ifdef _MSC_VER
 40 #pragma comment (lib, "libpng.lib")
 41 #pragma comment (lib, "zlib.lib")
 42 #pragma comment (linker, "/nodefaultlib:libc")
 43 #endif    /* _MSC_VER */
 44 
 45 /* OpenGL texture info */
 46 struct gl_texture_t
 47 {
 48   GLsizei width;
 49   GLsizei height;
 50 
 51   GLenum format;
 52   GLint internalFormat;
 53   GLuint id;
 54 
 55   GLubyte *texels;
 56 };
 57 
 58 /* Texture id for the demo */
 59 GLuint texId;
 60 
 61 
 62 static void
 63 GetPNGtextureInfo (int color_type, struct gl_texture_t *texinfo)
 64 {
 65   switch (color_type)
 66     {
 67     case PNG_COLOR_TYPE_GRAY:
 68       texinfo->format = GL_LUMINANCE;
 69       texinfo->internalFormat = 1;
 70       break;
 71 
 72     case PNG_COLOR_TYPE_GRAY_ALPHA:
 73       texinfo->format = GL_LUMINANCE_ALPHA;
 74       texinfo->internalFormat = 2;
 75       break;
 76 
 77     case PNG_COLOR_TYPE_RGB:
 78       texinfo->format = GL_RGB;
 79       texinfo->internalFormat = 3;
 80       break;
 81 
 82     case PNG_COLOR_TYPE_RGB_ALPHA:
 83       texinfo->format = GL_RGBA;
 84       texinfo->internalFormat = 4;
 85       break;
 86 
 87     default:
 88       /* Badness */
 89       break;
 90     }
 91 }
 92 
 93 static struct gl_texture_t *
 94 ReadPNGFromFile (const char *filename)
 95 {
 96   struct gl_texture_t *texinfo;
 97   png_byte magic[8];
 98   png_structp png_ptr;
 99   png_infop info_ptr;
100   int bit_depth, color_type;
101   FILE *fp = NULL;
102   png_bytep *row_pointers = NULL;
103   png_uint_32 w, h;
104   int i;
105 
106   /* Open image file */
107   fp = fopen (filename, "rb");
108   if (!fp)
109     {
110       fprintf (stderr, "error: couldn't open \"%s\"!\n", filename);
111       return NULL;
112     }
113 
114   /* Read magic number */
115   fread (magic, 1sizeof (magic), fp);
116 
117   /* Check for valid magic number */
118   if (!png_check_sig (magic, sizeof (magic)))
119     {
120       fprintf (stderr, "error: \"%s\" is not a valid PNG image!\n",
121            filename);
122       fclose (fp);
123       return NULL;
124     }
125 
126   /* Create a png read struct */
127   png_ptr = png_create_read_struct
128     (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
129   if (!png_ptr)
130     {
131       fclose (fp);
132       return NULL;
133     }
134 
135   /* Create a png info struct */
136   info_ptr = png_create_info_struct (png_ptr);
137   if (!info_ptr)
138     {
139       fclose (fp);
140       png_destroy_read_struct (&png_ptr, NULL, NULL);
141       return NULL;
142     }
143 
144   /* Create our OpenGL texture object */
145   texinfo = (struct gl_texture_t *)
146     malloc (sizeof (struct gl_texture_t));
147 
148   /* Initialize the setjmp for returning properly after a libpng
149      error occured */
150   if (setjmp (png_jmpbuf (png_ptr)))
151     {
152       fclose (fp);
153       png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
154 
155       if (row_pointers)
156     free (row_pointers);
157 
158       if (texinfo)
159     {
160       if (texinfo->texels)
161         free (texinfo->texels);
162 
163       free (texinfo);
164     }
165 
166       return NULL;
167     }
168 
169   /* Setup libpng for using standard C fread() function
170      with our FILE pointer */
171   png_init_io (png_ptr, fp);
172 
173   /* Tell libpng that we have already read the magic number */
174   png_set_sig_bytes (png_ptr, sizeof (magic));
175 
176   /* Read png info */
177   png_read_info (png_ptr, info_ptr);
178 
179   /* Get some usefull information from header */
180   bit_depth = png_get_bit_depth (png_ptr, info_ptr);
181   color_type = png_get_color_type (png_ptr, info_ptr);
182 
183   /* Convert index color images to RGB images */
184   if (color_type == PNG_COLOR_TYPE_PALETTE)
185     png_set_palette_to_rgb (png_ptr);
186 
187   /* Convert 1-2-4 bits grayscale images to 8 bits
188      grayscale. */
189   if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
190     png_set_gray_1_2_4_to_8 (png_ptr);
191 
192   if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
193     png_set_tRNS_to_alpha (png_ptr);
194 
195   if (bit_depth == 16)
196     png_set_strip_16 (png_ptr);
197   else if (bit_depth < 8)
198     png_set_packing (png_ptr);
199 
200   /* Update info structure to apply transformations */
201   png_read_update_info (png_ptr, info_ptr);
202 
203   /* Retrieve updated information */
204   png_get_IHDR (png_ptr, info_ptr, &w, &h, &bit_depth,
205         &color_type, NULL, NULL, NULL);
206   texinfo->width = w;
207   texinfo->height = h;
208 
209   /* Get image format and components per pixel */
210   GetPNGtextureInfo (color_type, texinfo);
211 
212   /* We can now allocate memory for storing pixel data */
213   texinfo->texels = (GLubyte *)malloc (sizeof (GLubyte) * texinfo->width
214            * texinfo->height * texinfo->internalFormat);
215 
216   /* Setup a pointer array.  Each one points at the begening of a row. */
217   row_pointers = (png_bytep *)malloc (sizeof (png_bytep) * texinfo->height);
218 
219   for (i = 0; i < texinfo->height; ++i)
220     {
221       row_pointers[i] = (png_bytep)(texinfo->texels +
222     ((texinfo->height - (i + 1)) * texinfo->width * texinfo->internalFormat));
223     }
224 
225   /* Read pixel data using row pointers */
226   png_read_image (png_ptr, row_pointers);
227 
228   /* Finish decompression and release memory */
229   png_read_end (png_ptr, NULL);
230   png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
231 
232   /* We don't need row pointers anymore */
233   free (row_pointers);
234 
235   fclose (fp);
236   return texinfo;
237 }
238 
239 GLuint
240 loadPNGTexture (const char *filename)
241 {
242   struct gl_texture_t *png_tex = NULL;
243   GLuint tex_id = 0;
244 
245   png_tex = ReadPNGFromFile (filename);
246 
247   if (png_tex && png_tex->texels)
248     {
249       /* Generate texture */
250       glGenTextures (1&png_tex->id);
251       glBindTexture (GL_TEXTURE_2D, png_tex->id);
252 
253       /* Setup some parameters for texture filters and mipmapping */
254       glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
255       glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
256 
257 #if 0
258       glTexImage2D (GL_TEXTURE_2D, 0, png_tex->internalFormat,
259             png_tex->width, png_tex->height, 0, png_tex->format,
260             GL_UNSIGNED_BYTE, png_tex->texels);
261 #else
262       gluBuild2DMipmaps (GL_TEXTURE_2D, png_tex->internalFormat,
263              png_tex->width, png_tex->height,
264              png_tex->format, GL_UNSIGNED_BYTE, png_tex->texels);
265 #endif
266 
267       tex_id = png_tex->id;
268 
269       /* OpenGL has its own copy of texture data */
270       free (png_tex->texels);
271       free (png_tex);
272     }
273 
274   return tex_id;
275 }
276 
277 static void
278 cleanup ()
279 {
280   glDeleteTextures (1&texId);
281 }
282 
283 static void
284 init (const char *filename)
285 {
286   /* Initialize OpenGL */
287   glClearColor (10.8f0.8f,0.0f);
288   glShadeModel (GL_SMOOTH);
289 
290   glEnable (GL_DEPTH_TEST);
291 
292   glEnable (GL_BLEND);
293   glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
294 
295   /* Load PNG texture from file */
296   texId = loadPNGTexture (filename);
297   if (!texId)
298     exit (EXIT_FAILURE);
299 }
300 
301 static void
302 reshape (int w, int h)
303 {
304   if (h == 0)
305     h = 1;
306   glViewport (00, (GLsizei)w, (GLsizei)h);
307 
308   glMatrixMode (GL_PROJECTION);
309   glLoadIdentity ();
310   gluPerspective (45.0, w/(GLdouble)h, 0.11000.0);
311 
312   glMatrixMode (GL_MODELVIEW);
313   glLoadIdentity ();
314 
315   glutPostRedisplay ();
316 }
317 
318 static void
319 display ()
320 {
321   glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
322   glLoadIdentity ();
323 
324   glEnable (GL_TEXTURE_2D);
325   glBindTexture (GL_TEXTURE_2D, texId);
326 
327   /* Draw textured quad */
328   glTranslatef (0.00.0-5.0);
329   glBegin (GL_QUADS);
330     glTexCoord2f (0.0f0.0f);
331     glVertex3f (-1.0f-1.0f0.0f);
332 
333     glTexCoord2f (1.0f0.0f);
334     glVertex3f (1.0f-1.0f0.0f);
335 
336     glTexCoord2f (1.0f1.0f);
337     glVertex3f (1.0f1.0f0.0f);
338 
339     glTexCoord2f (0.0f1.0f);
340     glVertex3f (-1.0f1.0f0.0f);
341 
342     glTexCoord2f(0,0);
343     glVertex3f(0,-1,-1);
344 
345     glTexCoord2f(1,0);
346     glVertex3f(0,1,-1);
347 
348     glTexCoord2f(1,1);
349     glVertex3f(0,1,1);
350 
351     glTexCoord2f(0,1);
352     glVertex3f(0,-1,1);
353   glEnd  ();
354 
355   glDisable (GL_TEXTURE_2D);
356 
357   glutSwapBuffers ();
358 }
359 
360 static void
361 keyboard (unsigned char key, int x, int y)
362 {
363   /* Escape */
364   if (key == 27)
365     exit (0);
366 }
367 
368 int
369 main (int argc, char *argv[])
370 {
371   if (argc < 2)
372     {
373       fprintf (stderr, "usage: %s <filename.png>\n", argv[0]);
374       return -1;
375     }
376 
377   glutInit (&argc, argv);
378   glutInitDisplayMode (GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
379   glutInitWindowSize (640480);
380   glutCreateWindow ("PNG Texture Demo");
381 
382   atexit (cleanup);
383   init (argv[1]);
384 
385   glutReshapeFunc (reshape);
386   glutDisplayFunc (display);
387   glutKeyboardFunc (keyboard);
388 
389   glutMainLoop ();
390 
391   return 0;
392 }

 

 

posted on 2009-12-14 19:49  IamEasy_Man  阅读(3329)  评论(6)    收藏  举报

导航