⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 glmovie-tile.c

📁 This code is based on mpeg_play, available from: http://bmrc.berkeley.edu/frame/research/mpeg/
💻 C
字号:
/* * MODIFIED by Bruce Merry (bmerry@iafrica.com) on 10/11/2000 * - fixed to handle arbitrary tile dimensions, not just 1x2 * - max_texture_size renamed to texture_size and used as a variable *   (to change the max texture size, edit the assigned value in the decl) * - hardcoded 256's changed to texture_size to allow small texture sizes *   (e.g. for very low-res movies) * - all pieces of movie copied into the top left corner of texture tiles, *   instead of being offset * - mechanism for keeping tiles aligned changed: a one texel border is *   included in the tiles, which I think is used by the filtering even though *   it is not explicitly selected for rendering (I think - I don't know much *   about OpenGL, I've just fiddled until it looked right) * - removed glmovie_is_power_of_2: it was not needed and *   it only went up to 2048 anyway. */#include "glmovie.h"#include <malloc.h>#include <string.h>/* Some data is redundant at this stage. */typedef struct glmovie_texture_t {    GLuint id;           /* OpenGL texture id. */    GLuint poly_width;   /* Quad width for tile. */    GLuint poly_height;  /* Quad height for tile. */    GLuint movie_width;  /* Width of movie inside tile. */    GLuint movie_height; /* Height of movie inside tile. */    GLuint skip_rows;    /* Number of rows of movie to skip */    GLuint skip_pixels;  /* Number of columns of movie to skip */    GLuint row;          /* Row number of tile in scheme. */    GLuint col;          /* Column number of tile in scheme. */} glmovie_texture;/* Boy, is this not thread safe. *//* Our evil maximum texture size. Boo 3Dfx! */static GLuint texture_size = 256;/* Keep this around for easy freeing later. */static GLuint* texture_ids = NULL;/* Our main data. */static glmovie_texture* textures = NULL;static GLuint num_texture_rows = 0;static GLuint num_texture_cols = 0;/* Width and height of all tiling. */static GLuint tiled_width = 0;static GLuint tiled_height = 0;/* Width and height of entire movie. */static GLuint movie_width = 0;static GLuint movie_height = 0;/* * Draw the frame data. * * Parameters: *    frame: Actual RGBA frame data */void glmovie_draw( GLubyte* frame ){    GLuint i;    GLdouble shift;    glClear( GL_COLOR_BUFFER_BIT );    glMatrixMode( GL_MODELVIEW );    glLoadIdentity( );    shift = 1 / ((double) texture_size);    for (i = 0; i < num_texture_rows * num_texture_cols; i++) {        glBindTexture( GL_TEXTURE_2D, textures[i].id );        glPixelStorei( GL_UNPACK_ROW_LENGTH, movie_width );        glPixelStorei( GL_UNPACK_SKIP_ROWS, textures[i].skip_rows );        glPixelStorei( GL_UNPACK_SKIP_PIXELS, textures[i].skip_pixels );        glTexSubImage2D( GL_TEXTURE_2D,                         0,                         0,                       /* offset_x */                         0,                       /* offset_y */                         textures[i].movie_width + 2,                         textures[i].movie_height + 2,                         GL_RGBA,                         GL_UNSIGNED_BYTE,                         frame );        glBegin( GL_QUADS );        glTexCoord2f( shift, shift );        glVertex2i( textures[i].col * texture_size,                    textures[i].row * texture_size );        glTexCoord2f( shift, shift + (textures[i].movie_height)/((double) texture_size) );        glVertex2i( textures[i].col * texture_size,                    (textures[i].row + 1) * texture_size);        glTexCoord2f( shift + (textures[i].movie_width)/((double) texture_size),                      shift + (textures[i].movie_height)/((double) texture_size) );        glVertex2i( (textures[i].col + 1) * texture_size,                    (textures[i].row + 1) * texture_size);        glTexCoord2f( shift + (textures[i].movie_width)/((double) texture_size), shift );        glVertex2i( (textures[i].col + 1) * texture_size,                    textures[i].row * texture_size );        glEnd( );    }}/* * Here we need to center the OpenGL viewport within the * window size that we are given. * * Parameters: *     width: Width of the window in pixels *     height: Height of the window in pixels */void glmovie_resize( GLuint width, GLuint height ){    glViewport( 0, 0, width, height );    glMatrixMode( GL_PROJECTION );    glLoadIdentity( );    gluOrtho2D( 0, tiled_width, tiled_height, 0 );}/* * Calculates the next power of 2 given a particular value. * Useful for calculating proper texture sizes for non power-of-2 * aligned texures. * * Parameters: *     seed: Value to begin from * Returns: *     Next power of 2 beginning from 'seed' */GLuint glmovie_next_power_of_2( GLuint seed ){    GLuint i;    for( i = 1; i < seed; i *= 2 ) { };    return i;}/* * Initialize the movie player subsystem with the width and height * of the *movie data* (as opposed to the window). * * Parameters: *     width: Width of movie in pixels *     height: Height of movie in pixels * Returns: *     GL_NO_ERROR on success *     Any of the enumerated GL errors on failure */GLenum glmovie_init( GLuint width, GLuint height ){    /* Initial black texels. */    GLubyte* pixels;    /* Absolute offsets from within tiled frame. */    GLuint offset_x = 0;    GLuint offset_y = 0;    GLuint skip_rows = 0;    GLuint skip_pixels = 0;    GLuint i, j, current;    /* Save original movie dimensions. */    movie_width = width;    movie_height = height;    /* Get the power of 2 dimensions. */    tiled_width = glmovie_next_power_of_2( width );    tiled_height = glmovie_next_power_of_2( height );    while ( texture_size > tiled_width || texture_size > tiled_height )        texture_size /= 2;    /* Now break it up into quads. */    num_texture_rows = tiled_height / texture_size;    num_texture_cols = tiled_width / texture_size;    /* Time for fun with data structures. */    glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );    glEnable( GL_TEXTURE_2D );    glEnable( GL_DITHER );    texture_ids = (GLuint*) malloc( sizeof( GLuint ) * num_texture_rows * num_texture_cols );    if( !texture_ids ) {        return GL_OUT_OF_MEMORY;    }    glGenTextures( num_texture_rows * num_texture_cols, texture_ids );    textures = (glmovie_texture*) malloc( sizeof( glmovie_texture ) *                                          num_texture_rows * num_texture_cols );    if( !textures ) {        glDeleteTextures( num_texture_rows * num_texture_cols, texture_ids );        free( texture_ids );        return GL_OUT_OF_MEMORY;    }    for ( i = 0; i < num_texture_rows; i++ ) {        skip_pixels = 0;        for ( j = 0; j < num_texture_cols; j++ ) {            current = i * num_texture_cols + j;            /* Setup texture. */            textures[current].id = texture_ids[current];            textures[current].poly_width = texture_size;            textures[current].poly_height = texture_size;            textures[current].movie_width =                (movie_width - 2) * (j + 1) / num_texture_cols - skip_pixels;            textures[current].movie_height =                (movie_height - 2) * (i + 1) / num_texture_rows - skip_rows;            textures[current].row = i;            textures[current].col = j;            textures[current].skip_pixels = skip_pixels;            textures[current].skip_rows = skip_rows;            skip_pixels += textures[current].movie_width;            pixels = (GLubyte*) malloc( textures[current].poly_width * textures[current].poly_height * 4 );            memset( pixels, 0, textures[current].poly_width * textures[current].poly_height * 4 );            if( !pixels ) {                glDeleteTextures( num_texture_rows * num_texture_cols, texture_ids );                free( texture_ids );                free( textures );                return GL_OUT_OF_MEMORY;            }            /* Do all of our useful binding. */            glBindTexture( GL_TEXTURE_2D, textures[current].id );            glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL );            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );            /* Specify our 256x256 black texture. */            glTexImage2D( GL_TEXTURE_2D,                          0,                          GL_RGB,                          textures[current].poly_width,                          textures[current].poly_height,                          0,                          GL_RGBA,                          GL_UNSIGNED_BYTE,                          pixels );            free( pixels );        }        skip_rows += textures[current].movie_height;    }    /* Simple state setup at the end. */    glClearColor( 0.0, 0.0, 0.0, 0.0 );    return glGetError( );}/* * Free any resources associated with the movie player. */void glmovie_quit( void ){    glDeleteTextures( num_texture_rows * num_texture_cols, texture_ids );    free( texture_ids );    free( textures );}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -