// OpenGL + libpng sample // // PNGファイルをOpenGLで扱う話 // https://proken.mydns.jp/index.php?plugin=attach&refer=pg_koneta%2FPNGInOpenGL&openfile=PNGInOpenGL.html #include #include #include #include GLuint texture; GLuint createTextureFromPNGFile(const char *filename) { FILE *fp; png_structp png_ptr = NULL; png_infop info_ptr = NULL; int depth, colorType, interlaceType; unsigned int width, height; int rowSize, imgSize; unsigned int i; unsigned char *data; GLuint texture; // Open PNG file fp = fopen(filename, "rb"); if (!fp) { fprintf(stderr, "createTextureFromPNGFile: Failed to fopen %s\n", filename); exit(1); } // create struct to load PNG file png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); info_ptr = png_create_info_struct(png_ptr); // init libpng png_init_io(png_ptr, fp); // Load image information // get width, height, bit depth, color type, interlace mode png_read_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &width, &height, &depth, &colorType, &interlaceType, NULL, NULL); // support RGB and RGBA if (colorType != PNG_COLOR_TYPE_RGB && colorType != PNG_COLOR_TYPE_RGBA) { fprintf(stderr, "createTextureFromPNGFile: Supprted color type are RGB and RGBA."); return 0; } // not support interlace if (interlaceType != PNG_INTERLACE_NONE) { fprintf(stderr, "createTextureFromPNGFile: Interlace image is not supprted."); return 0; } // calc memory size rowSize = png_get_rowbytes(png_ptr, info_ptr); imgSize = rowSize * height; data = malloc(imgSize); // read pixel for (i = 0; i < height; i++) { png_read_row(png_ptr, &data[i * rowSize], NULL); } png_read_end(png_ptr, info_ptr); // create OpenGL texture glGenTextures(1, &texture); // select texture glBindTexture(GL_TEXTURE_2D, texture); // set texture from PNG image glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); // cleaning free(data); png_destroy_info_struct(png_ptr, &info_ptr); png_destroy_read_struct(&png_ptr, NULL, NULL); fclose(fp); return texture; } void display() { // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); // enable texture glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texture); // draw polygon glBegin(GL_QUADS); GLfloat v = 0.85f; glTexCoord2f(0.0, 0.0); // set texture u, v glVertex2f(-v, v); glTexCoord2f(0.0, 1.0); glVertex2f(-v, -v); glTexCoord2f(1.0, 1.0); glVertex2f(v, -v); glTexCoord2f(1.0, 0.0); glVertex2f(v, v); glEnd(); // disable texture glDisable(GL_TEXTURE_2D); glFlush(); } /* Keyboard callback function */ void keyboard(unsigned char key, int x, int y) { switch (key) { case '\x1B': case 'q': /* Exit on escape or 'q' key press */ glutLeaveMainLoop(); // exit(EXIT_SUCCESS); break; } } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA); glutInitWindowSize(1280, 720); glutCreateWindow("OpenGL Texture Example"); // create OpenGL texture from PNG image texture = createTextureFromPNGFile("texture.png"); if (!texture) { fprintf(stderr, "Failed to createTextureFromPNGFile\n"); } glClearColor(0.2f, 0.4f, 0.8f, 1.0f); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glutKeyboardFunc(keyboard); glutDisplayFunc(display); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS); glutMainLoop(); return EXIT_SUCCESS; }