zoukankan      html  css  js  c++  java
  • 【转】 OpenGL使用libPng读取png图片

    觉得自己越来越无耻了呢?原文:http://laoyin.blog.51cto.com/4885213/895554

    我复制到windows下也可以正常跑出来。

      1 #include<stdarg.h>
      2 #include<png.h>
      3 #include<glut.h>
      4 #include<math.h>
      5 #include<iostream>
      6 
      7 
      8 #pragma comment(lib,"libpng16.lib")//读取png图片
      9 GLuint CreateTextureFromPng(const char* filename)
     10 {
     11  unsigned char header[8];     //8
     12  int k;   //用于循环
     13  GLuint textureID; //贴图名字
     14  int width, height; //记录图片到宽和高
     15  png_byte color_type; //图片到类型(可能会用在是否是开启来通道)
     16  png_byte bit_depth; //字节深度
     17 
     18  png_structp png_ptr; //图片
     19  png_infop info_ptr; //图片的信息
     20  int number_of_passes; //隔行扫描
     21  png_bytep * row_pointers;//图片的数据内容
     22  int row,col,pos;  //用于改变png像素排列的问题。
     23  GLubyte *rgba;
     24 
     25  FILE *fp=fopen(filename,"rb");//以只读形式打开文件名为file_name的文件
     26  if(!fp)//做出相应可能的错误处理
     27  {
     28   fclose(fp);//关闭打开的文件!给出默认贴图
     29   return 0;//此处应该调用一个生成默认贴图返回ID的函数
     30  }
     31         //读取文件头判断是否所png图片.不是则做出相应处理
     32         fread(header, 1, 8, fp);
     33  if(png_sig_cmp(header,0,8))
     34  {
     35   fclose(fp);
     36   return 0; //每个错误处理都是一样的!这样报错之后锁定就要花点小时间来!
     37  }
     38    
     39  //根据libpng的libpng-manual.txt的说明使用文档 接下来必须初始化png_structp 和 png_infop
     40  png_ptr=png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL); //后三个是绑定错误以及警告的函数这里设置为空
     41  if(!png_ptr)//做出相应到初始化失败的处理
     42  { 
     43   fclose(fp);
     44   return 0;
     45  }
     46  //根据初始化的png_ptr初始化png_infop
     47  info_ptr=png_create_info_struct(png_ptr);
     48 
     49  if(!info_ptr)
     50  {
     51   //初始化失败以后销毁png_structp
     52   png_destroy_read_struct(&png_ptr,(png_infopp)NULL,(png_infopp)NULL);
     53   fclose(fp);
     54   return 0;
     55  }
     56 
     57  
     58  //老老实实按照libpng给到的说明稳定步骤来  错误处理!
     59         if (setjmp(png_jmpbuf(png_ptr)))
     60 
     61      {
     62   //释放占用的内存!然后关闭文件返回一个贴图ID此处应该调用一个生成默认贴图返回ID的函数
     63 
     64          png_destroy_read_struct(&png_ptr,(png_infopp)NULL,(png_infopp)NULL);
     65 
     66          fclose(fp);
     67 
     68          return 0;
     69 
     70      }
     71  //你需要确保是通过2进制打开的文件。通过i/o定制函数png_init_io
     72  png_init_io(png_ptr,fp);
     73  //似乎是说要告诉libpng文件从第几个开始missing
     74         png_set_sig_bytes(png_ptr, 8);
     75  //如果你只想简单的操作你现在可以实际读取图片信息了!
     76         png_read_info(png_ptr, info_ptr);
     77  //获得图片到信息 width height 颜色类型  字节深度
     78         width = png_get_image_width(png_ptr, info_ptr);
     79         height = png_get_image_height(png_ptr, info_ptr);
     80         color_type = png_get_color_type(png_ptr, info_ptr);
     81  //如果图片带有alpha通道就需要
     82 // if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
     83 
     84         // png_set_swap_alpha(png_ptr);
     85         bit_depth = png_get_bit_depth(png_ptr, info_ptr);
     86  //隔行扫描图片  这个必须要调用才能进行
     87         number_of_passes = png_set_interlace_handling(png_ptr);
     88  //将读取到的信息更新到info_ptr
     89         png_read_update_info(png_ptr, info_ptr);
     90 
     91  //读文件
     92         if (setjmp(png_jmpbuf(png_ptr))){
     93   fclose(fp);
     94                 return 0;
     95  }
     96         rgba=(GLubyte*)malloc(width * height * 4);
     97  //使用动态数组  设置长度
     98         row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height);
     99  
    100  for (k = 0; k < height; k++)
    101         row_pointers[k] = NULL;
    102   
    103  //通过扫描流里面的每一行将得到的数据赋值给动态数组       
    104  for (k=0; k<height; k++)
    105                 //row_pointers[k] = (png_byte*) malloc(png_get_rowbytes(png_ptr,info_ptr));
    106    row_pointers[k] = (png_bytep)png_malloc(png_ptr, png_get_rowbytes(png_ptr,
    107          info_ptr));
    108  //由于png他的像素是由 左-右-从顶到底 而贴图需要的像素都是从左-右-底到顶的所以在这里需要把像素内容进行一个从新排列
    109  //读图片
    110         png_read_image(png_ptr, row_pointers);
    111 
    112             pos = (width * height * 4) - (4 * width);
    113      for( row = 0; row < height; row++)
    114      {
    115         for( col = 0; col < (4 * width); col += 4)
    116         {
    117      rgba[pos++] = row_pointers[row][col];        // red
    118      rgba[pos++] = row_pointers[row][col + 1];    // green
    119      rgba[pos++] = row_pointers[row][col + 2];    // blue
    120      rgba[pos++] = row_pointers[row][col + 3];    // alpha
    121         }
    122         pos=(pos - (width * 4)*2);
    123      }
    124 
    125 
    126  //开启纹理贴图特效
    127         glEnable(GL_TEXTURE_2D);
    128  
    129  //创建纹理 
    130         glGenTextures(1,&textureID);
    131  //绑定纹理
    132         glBindTexture(GL_TEXTURE_2D,textureID); //将纹理绑定到名字
    133  
    134  //设置贴图和纹理的混合效果这里是默认只用纹理
    135     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
    136  //设置纹理所用到图片数据
    137         glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,rgba);
    138  
    139         //glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
    140         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
    141  
    142  free(row_pointers); 
    143  fclose(fp);
    144         return textureID;
    145 }
    146 
    147 void display()
    148 {
    149     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    150     glEnable(GL_TEXTURE_2D);
    151     glBindTexture(GL_TEXTURE_2D,CreateTextureFromPng("test.png"));
    152     glBegin(GL_QUADS);
    153     glTexCoord2f(0.0f,0.0f);glVertex2f(-60.0f,-60.0f);
    154      glTexCoord2f(1.0f, 0.0f); glVertex2f(60.0f, -60.0f);
    155     glTexCoord2f(1.0f, 1.0f); glVertex2f( 60.0f, 60.0f);
    156     glTexCoord2f(0.0f, 1.0f); glVertex2f( -60.0f, 60.0f); 
    157     glEnd();
    158     glDisable(GL_TEXTURE_2D);
    159     glutSwapBuffers();
    160 }
    161 
    162 void Reshape(GLsizei w,GLsizei h)
    163 {
    164     if(h<0)
    165     {
    166         h=1;
    167     }
    168     glViewport(0,0,w,h);
    169     glMatrixMode(GL_PROJECTION);
    170     glLoadIdentity();
    171     glOrtho(-100,100,-100,100,-100,100);
    172     glMatrixMode(GL_MODELVIEW);
    173     glLoadIdentity();
    174 }
    175 
    176 int main(int ac,char** av)
    177 {
    178     glutInit(&ac,av);
    179     glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    180     glutCreateWindow("pngtest");
    181     glClearColor(1.0,1.0,1.0,1.0);
    182     glutDisplayFunc(display);
    183     glutReshapeFunc(Reshape);
    184     glutMainLoop();
    185     return 0;
    186 }
  • 相关阅读:
    pktgen使用指南
    常见的网卡调优
    网络PPS测试
    网络性能测试工具qperf
    设置虚拟机静态IP
    superset填坑
    js格式化
    《你不知道的JavaScript》读书笔记(一):JS是如何查找变量的
    技术分享PPT整理(三):网页渲染流程
    技术分享PPT整理(二):C#常用类型与数据结构
  • 原文地址:https://www.cnblogs.com/slysky/p/3937236.html
Copyright © 2011-2022 走看看