Skip to content

Instantly share code, notes, and snippets.

@FreeCX
Created February 13, 2013 17:01
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FreeCX/4946105 to your computer and use it in GitHub Desktop.
Save FreeCX/4946105 to your computer and use it in GitHub Desktop.
using libpng in opengl
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <GL/glut.h>
#include <png.h>
#include <setjmp.h>
void system_init( int *argc, char *argv[] );
void system_opengl( void );
void system_render( void );
void system_resize( const int width, const int height );
void system_destroy( void );
int texture_load( const char *file, int *width, int *height );
GLuint tex;
int width, height;
void system_init( int *argc, char *argv[] )
{
glutInit( argc, argv );
glutInitWindowSize( 500, 500 );
glutInitWindowPosition( 200, 50 );
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
glutCreateWindow( "libpng test" );
glutReshapeFunc( system_resize );
glutDisplayFunc( system_render );
system_opengl();
glutMainLoop();
}
void system_opengl( void )
{
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
tex = texture_load( "arch_logo.png", &width, &height );
}
void system_render( void )
{
usleep( (1.0 / 60.0) * 1000000 );
glClear( GL_COLOR_BUFFER_BIT );
glEnable( GL_TEXTURE_2D );
glBegin( GL_QUADS );
glTexCoord2f( 1.0f, 0.0f );
glVertex3f( 1.0f, -1.0, 0.0f );
glTexCoord2f( 0.0f, 0.0f );
glVertex3f( -1.0f, -1.0f, 0.0f );
glTexCoord2f( 0.0f, 1.0f );
glVertex3f( -1.0f, 1.0f, 0.0f );
glTexCoord2f( 1.0f, 1.0f );
glVertex3f( 1.0f, 1.0f, 0.0f );
glEnd();
glutSwapBuffers();
}
void system_resize( const int width, const int height )
{
const float n = 1.5f;
const float a = (float) width / (float) height;
glViewport( 0, 0, width, height );
glMatrixMode( GL_PROJECTION );
if ( width <= height ) {
glOrtho( -n, n, -n / a, n / a, n, -n );
} else {
glOrtho( -n * a, n * a, -n, n, n, -n );
}
gluPerspective( 0.0f, a, 0.0f, 100.0f );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
}
void system_destroy( void )
{
/* free using resource */
}
int texture_load( const char *file, int *width, int *height )
{
FILE *f;
int is_png, bit_depth, color_type, row_bytes, i;
png_infop info_ptr, end_info;
png_uint_32 t_width, t_height;
png_byte header[8], *image_data;
png_bytepp row_pointers;
png_structp png_ptr;
GLuint texture;
int alpha;
if ( !( f = fopen(file, "r" ) ) ) {
return NULL;
}
fread( header, 1, 8, f );
is_png = !png_sig_cmp( header, 0, 8 );
if ( !is_png ) {
fclose( f );
return NULL;
}
png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL,
NULL, NULL );
if ( !png_ptr ) {
fclose( f );
return NULL;
}
info_ptr = png_create_info_struct( png_ptr );
if ( !info_ptr ) {
png_destroy_read_struct( &png_ptr, (png_infopp) NULL,
(png_infopp) NULL );
fclose( f );
return NULL;
}
end_info = png_create_info_struct( png_ptr );
if ( !end_info ) {
png_destroy_read_struct( &png_ptr, (png_infopp) NULL,
(png_infopp) NULL );
fclose( f );
return NULL;
}
if ( setjmp( png_jmpbuf( png_ptr ) ) ) {
png_destroy_read_struct( &png_ptr, &info_ptr, &end_info );
fclose( f );
return NULL;
}
png_init_io( png_ptr, f );
png_set_sig_bytes( png_ptr, 8 );
png_read_info( png_ptr, info_ptr );
png_get_IHDR( png_ptr, info_ptr, &t_width, &t_height, &bit_depth,
&color_type, NULL, NULL, NULL );
width = t_width;
height = t_height;
png_read_update_info( png_ptr, info_ptr );
row_bytes = png_get_rowbytes( png_ptr, info_ptr );
image_data = (png_bytep) malloc( row_bytes * t_height * sizeof(png_byte) );
if ( !image_data ) {
png_destroy_read_struct( &png_ptr, &info_ptr, &end_info );
fclose( f );
return NULL;
}
row_pointers = (png_bytepp) malloc( t_height * sizeof(png_bytep) );
if ( !row_pointers ) {
png_destroy_read_struct( &png_ptr, &info_ptr, &end_info );
free( image_data );
fclose( f );
return NULL;
}
for ( i = 0; i < t_height; ++i ) {
row_pointers[t_height - 1 - i] = image_data + i * row_bytes;
}
png_read_image( png_ptr, row_pointers );
switch ( png_get_color_type( png_ptr, info_ptr ) ) {
case PNG_COLOR_TYPE_RGBA:
alpha = GL_RGBA;
break;
case PNG_COLOR_TYPE_RGB:
alpha = GL_RGB;
break;
default:
printf( "Color type %d not supported!\n",
png_get_color_type( png_ptr, info_ptr ) );
png_destroy_read_struct( &png_ptr, &info_ptr, &end_info );
return NULL;
}
glGenTextures( 1, &texture );
glBindTexture( GL_TEXTURE_2D, texture );
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, t_width, t_height, 0,
alpha, GL_UNSIGNED_BYTE, (GLvoid *) image_data );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
png_destroy_read_struct( &png_ptr, &info_ptr, &end_info );
free( image_data );
free( row_pointers );
fclose( f );
return texture;
}
int main( int argc, char *argv[] )
{
system_init( &argc, argv );
system_destroy();
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment