// OpenGL + stb sample. PNG image is in memory // // PNGファイルをOpenGLで扱う話 // https://proken.mydns.jp/index.php?plugin=attach&refer=pg_koneta%2FPNGInOpenGL&openfile=PNGInOpenGL.html // // 008 PNGテクスチャの読み込み [stepism] // https://stepism.sakura.ne.jp/wiki/doku.php?id=wiki:opengl:tips:008 // // nothings/stb: stb single-file public domain libraries for C/C++ // https://github.com/nothings/stb #include #include #include // use stb library #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" // include png image binary #include "texture.h" GLuint texture; /** * Load texture from png image on memory * * @param[in] _pngData png binary on memory * @param[in] _pngDataLen png binary size * return GLuint OpenGL texture ID. if 0, process fails */ GLuint createTextureFromPngInMemory(const unsigned char* _pngData, int _pngLen) { GLuint texture; int width = 0, height = 0, bpp = 0; unsigned char *data = NULL; data = stbi_load_from_memory(_pngData, _pngLen, &width, &height, &bpp, 4); // create OpenGL texture glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); // Release allocated all memory stbi_image_free(data); return texture; } // draw OpenGL void display() { 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 = createTextureFromPngInMemory((void *)&texture_png, texture_png_size); if (!texture) { fprintf(stderr, "Failed create texture\n"); exit(1); } 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_LINEAR); 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; }