Main Page | Modules | File List | Globals | Related Pages

videovtb.c

Go to the documentation of this file.
00001 
00009 #include <string.h>
00010 
00011 #include <allegro.h>
00012 
00013 #ifdef ALLEGRO_WINDOWS
00014 #include <winalleg.h>
00015 #endif
00016 
00017 #include "alleggl.h"
00018 #include "allglint.h"
00019 #include "glvtable.h"
00020 #include <allegro/internal/aintern.h>
00021 #ifdef ALLEGRO_MACOSX
00022 #include <OpenGL/glu.h>
00023 #else
00024 #include <GL/glu.h>
00025 #endif
00026 
00027 
00028 static GFX_VTABLE allegro_gl_video_vtable;
00029 
00030 /* Counter for video bitmaps. screen = 1 */
00031 static int video_bitmap_count = 2;
00032 
00033 
00034 /* Will make a piece-wise texture out of the specified bitmap
00035  * Source -must- be a memory bitmap or memory subbitmap (created by Allegro
00036  * only).
00037  *
00038  * And must be a 32bpp image
00039  */
00040 static BITMAP *allegro_gl_make_video_bitmap(BITMAP *bmp) {
00041     
00042     int i, j;
00043 
00044     /* XXX <rohannessian> If ARB_np2 is support, just use that.
00045      * Is [EXT|NV]_texture_rectangle is available, use that.
00046      * 
00047      * Otherwise, try this algo instead:
00048      *  1. Round to next higher power of 2, if not power-of-2
00049      *  2. If wasted space > 25% of area
00050      *   2.1 Split into 4 textures using lower nearest power-of-2
00051      *   2.2 Remainder is rounded to next higher power-of-2
00052      *   2.3 Repeat step 2.
00053      *
00054      *  We also need to check for the implementation's highest texture size.
00055      */
00056     int n_w = (bmp->w + 255) / 256,
00057         n_h = (bmp->h + 255) / 256;
00058         
00059     AGL_VIDEO_BITMAP **pvid = (AGL_VIDEO_BITMAP**)&bmp->extra;
00060     
00061     GLuint old_bind;
00062     glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_bind);
00063     
00064     for (j = 0; j < n_h; j++) {
00065         for (i = 0; i < n_w; i++) {
00066             BITMAP *mem;
00067             
00068             (*pvid) = malloc(sizeof(AGL_VIDEO_BITMAP));
00069             
00070             if (!(*pvid))
00071                 goto agl_error;
00072                 
00073             memset(*pvid, 0, sizeof(AGL_VIDEO_BITMAP));
00074             
00075             /* Create associated bitmap */
00076             (*pvid)->memory_copy = create_bitmap_ex(32, 
00077                 ((i < (n_w - 1)) || ((bmp->w & 255) == 0))
00078                     ? 256 : __allegro_gl_make_power_of_2(bmp->w & 255),
00079                 ((j < (n_h - 1)) || ((bmp->h & 255) == 0))
00080                     ? 256 : __allegro_gl_make_power_of_2(bmp->h & 255));
00081                 
00082             if (!(*pvid)->memory_copy)
00083                 goto agl_error;
00084                 
00085             /* Fill in some values in the bitmap to make it act as a subbitmap
00086              */
00087             mem = (*pvid)->memory_copy;
00088             (*pvid)->x_ofs = i * 256;
00089             (*pvid)->y_ofs = j * 256;
00090 
00091             /* Make a texture out of it */
00092             glGenTextures(1, &((*pvid)->tex));
00093             if (!((*pvid)->tex))
00094                 goto agl_error;
00095 
00096             glBindTexture(GL_TEXTURE_2D, ((*pvid)->tex));
00097 
00098             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, mem->w, mem->h,
00099                     0, GL_RGBA, GL_UNSIGNED_BYTE, mem->line[0]);                    
00100 
00101             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00102             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00103             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
00104             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
00105                     
00106             pvid = &((*pvid)->next);
00107         }
00108     }
00109     glBindTexture(GL_TEXTURE_2D, old_bind);
00110     (*pvid) = NULL;
00111     
00112     return bmp;
00113     
00114     agl_error: {
00115         AGL_VIDEO_BITMAP *vid = bmp ? bmp->extra : NULL, *next;
00116 
00117         while (vid) {
00118             if (vid->memory_copy)
00119                 destroy_bitmap(vid->memory_copy);
00120                 
00121             if (vid->tex)
00122                 glDeleteTextures(1, &vid->tex);
00123                                 
00124             next = vid->next;
00125             free(vid);
00126             vid = next;
00127         }
00128     }
00129     return NULL;
00130 }
00131 
00132 
00133 
00134 /* BITMAP *allegro_gl_create_video_bitmap(int w, int h) */
00142 BITMAP *allegro_gl_create_video_bitmap(int w, int h) {
00143 
00144     BITMAP *bitmap;
00145     
00146     bitmap = malloc(sizeof(BITMAP) + sizeof(char *));
00147     
00148     if (!bitmap)
00149         return NULL;
00150 
00151     bitmap->dat = NULL;
00152     bitmap->w = bitmap->cr = w;
00153     bitmap->h = bitmap->cb = h;
00154     bitmap->clip = TRUE;
00155     bitmap->cl = bitmap->ct = 0;
00156     bitmap->write_bank = bitmap->read_bank = NULL;
00157     /* We should keep tracks of allocated bitmaps for the ref counter */
00158     bitmap->id = BMP_ID_VIDEO | video_bitmap_count;
00159     bitmap->extra = NULL;
00160     bitmap->x_ofs = 0;
00161     bitmap->y_ofs = 0;
00162     bitmap->seg = _default_ds();
00163     bitmap->line[0] = NULL;
00164 
00165     if (!allegro_gl_make_video_bitmap(bitmap)) {
00166         free(bitmap);
00167         return NULL;
00168     }
00169     video_bitmap_count++;
00170     
00171     /* XXX <rohannessian> We ought to leave the Allegro values intact
00172      * Avoids bad interaction with correct Allegro programs.
00173      */
00174     allegro_gl_video_vtable.color_depth = 32;
00175     allegro_gl_video_vtable.mask_color = makecol32(255, 0, 255);
00176     bitmap->vtable = &allegro_gl_video_vtable;
00177 
00178     return bitmap;
00179 }
00180 
00181 
00182 
00183 /* void allegro_gl_destroy_video_bitmap(BITMAP *bmp) */
00188 void allegro_gl_destroy_video_bitmap(BITMAP *bmp) {
00189 
00190     AGL_VIDEO_BITMAP *vid = bmp ? bmp->extra : NULL, *next;
00191     
00192     if (!bmp)
00193         return;
00194     
00195     while (vid) {
00196         if (vid->memory_copy)
00197             destroy_bitmap(vid->memory_copy);
00198                 
00199         if (vid->tex)
00200             glDeleteTextures(1, &vid->tex);
00201                                 
00202         next = vid->next;
00203         free(vid);
00204         vid = next;
00205     }
00206     
00207     free(bmp);
00208     
00209     return;
00210 }
00211 
00212 
00213 
00214 /* static void allegro_gl_video_acquire(struct BITMAP *bmp) */
00221 static void allegro_gl_video_acquire(struct BITMAP *bmp) {}
00222 
00223 
00224 
00225 /* static void allegro_gl_video_release(struct BITMAP *bmp) */
00232 static void allegro_gl_video_release(struct BITMAP *bmp) {}
00233 
00234 
00235 
00236 static int allegro_gl_video_getpixel(struct BITMAP *bmp, int x, int y)
00237 {
00238     int pix = -1;
00239     AGL_VIDEO_BITMAP *vid;
00240     AGL_LOG(2, "glvtable.c:allegro_gl_screen_getpixel\n");  
00241     
00242     vid = bmp->extra;
00243     
00244     /* TODO: support for subbitmaps and clipping */
00245     
00246     while (vid) {
00247         if (vid->x_ofs <= x && vid->y_ofs <= y
00248             && vid->x_ofs + vid->memory_copy->w > x
00249             && vid->y_ofs + vid->memory_copy->h > y) {
00250             
00251             pix = getpixel(vid->memory_copy, x - vid->x_ofs, y - vid->y_ofs);
00252             break;
00253         }
00254         vid = vid->next;
00255     }
00256     
00257     if (pix != -1) {
00258         return makeacol_depth(bitmap_color_depth(screen),
00259                               getr_depth(32, pix), getg_depth(32, pix),
00260                               getb_depth(32, pix), geta_depth(32, pix));
00261     }
00262     
00263     return -1;
00264 }
00265 
00266 
00267 
00268 static void allegro_gl_video_putpixel(struct BITMAP *bmp, int x, int y,
00269                                       int color) {
00270     GLbyte pixel[4];
00271     AGL_VIDEO_BITMAP *vid;
00272 
00273     split_color(color, &pixel[0], &pixel[1], &pixel[2], &pixel[3],
00274                 bitmap_color_depth(screen));
00275     vid = bmp->extra;
00276     
00277     /* TODO: support for subbitmaps and clipping */
00278     
00279     while (vid) {
00280         if (vid->x_ofs <= x && vid->y_ofs <= y
00281             && vid->x_ofs + vid->memory_copy->w > x
00282             && vid->y_ofs + vid->memory_copy->h > y) {
00283             
00284             putpixel(vid->memory_copy, x, y,
00285                     makeacol_depth(32, pixel[0], pixel[1], pixel[2], pixel[3]));
00286             
00287             glBindTexture(GL_TEXTURE_2D, vid->tex);
00288             glTexSubImage2D(GL_TEXTURE_2D, 0, x - vid->x_ofs,
00289                 y - vid->y_ofs, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
00290                 
00291             break;
00292         }
00293         vid = vid->next;
00294     }
00295     
00296     glBindTexture(GL_TEXTURE_2D, 0);
00297     
00298     return;
00299 }
00300 
00301 
00302 
00303 static void allegro_gl_video_vline(BITMAP *bmp, int x, int y1, int y2,
00304                                    int color) {
00305 
00306     GLubyte pixel[4];
00307     AGL_VIDEO_BITMAP *vid;
00308     GLint saved_row_length;
00309     
00310     AGL_LOG(2, "glvtable.c:allegro_gl_video_vline\n");
00311     split_color(color, &pixel[0], &pixel[1], &pixel[2], &pixel[3],
00312                 bitmap_color_depth(screen));
00313     vid = bmp->extra;
00314     
00315     glGetIntegerv(GL_UNPACK_ROW_LENGTH, &saved_row_length);
00316     
00317     /* TODO: support for subbitmaps and clipping */
00318     
00319     if (y1 > y2) {
00320         int temp = y1;
00321         y1 = y2;
00322         y2 = temp;
00323     }
00324     
00325     while (vid) {
00326         int _y1, _y2, _x;
00327         if (vid->x_ofs > x || vid->y_ofs > y2
00328             || vid->x_ofs + vid->memory_copy->w <= x
00329             || vid->y_ofs + vid->memory_copy->h <= y1) {
00330             
00331             vid = vid->next;
00332             continue;
00333         }
00334         
00335         _y1 = MAX(y1, vid->y_ofs) - vid->y_ofs;
00336         _y2 = MIN(y2, vid->y_ofs + vid->memory_copy->h - 1) - vid->y_ofs;
00337         _x = x - vid->x_ofs;
00338 
00339         vline(vid->memory_copy, _x, _y1, _y2,
00340             makeacol_depth(32, pixel[0], pixel[1], pixel[2], pixel[3]));
00341         
00342         /* XXX <rohannessian> We should remove the hard-coded numbers here */
00343         glPixelStorei(GL_UNPACK_ROW_LENGTH,
00344                    (vid->memory_copy->line[1] - vid->memory_copy->line[0]) / 4);
00345             
00346         glBindTexture(GL_TEXTURE_2D, vid->tex);
00347         glTexSubImage2D(GL_TEXTURE_2D, 0, _x, _y1, 1, _y2 - _y1 + 1, GL_RGBA,
00348             GL_UNSIGNED_BYTE, vid->memory_copy->line[_y1] + _x * 4);
00349 
00350         vid = vid->next;
00351     }
00352     
00353     glPixelStorei(GL_UNPACK_ROW_LENGTH, saved_row_length);
00354     glBindTexture(GL_TEXTURE_2D, 0);
00355     
00356     return;
00357 }
00358 
00359 
00360 
00361 static void allegro_gl_video_hline(BITMAP *bmp, int x1, int y, int x2,
00362                                    int color) {
00363 
00364     GLubyte pixel[4];
00365     AGL_VIDEO_BITMAP *vid;
00366     
00367     AGL_LOG(2, "glvtable.c:allegro_gl_video_hline\n");
00368     split_color(color, &pixel[0], &pixel[1], &pixel[2], &pixel[3],
00369                 bitmap_color_depth(screen));
00370     vid = bmp->extra;
00371     
00372     /* TODO: support for subbitmaps and clipping */
00373     
00374     if (x1 > x2) {
00375         int temp = x1;
00376         x1 = x2;
00377         x2 = temp;
00378     }
00379     
00380     while (vid) {
00381         int _x1, _x2, _y;
00382         if (vid->y_ofs > y || vid->x_ofs > x2
00383             || vid->x_ofs + vid->memory_copy->w <= x1
00384             || vid->y_ofs + vid->memory_copy->h <= y) {
00385             
00386             vid = vid->next;
00387             continue;
00388         }
00389         
00390         _x1 = MAX(x1, vid->x_ofs) - vid->x_ofs;
00391         _x2 = MIN(x2, vid->x_ofs + vid->memory_copy->w - 1) - vid->x_ofs;
00392         _y = y - vid->y_ofs;
00393 
00394         hline(vid->memory_copy, _x1, _y, _x2,
00395             makeacol_depth(32, pixel[0], pixel[1], pixel[2], pixel[3]));
00396         
00397         
00398         glBindTexture(GL_TEXTURE_2D, vid->tex);
00399         glTexSubImage2D(GL_TEXTURE_2D, 0, _x1, _y, _x2 - _x1 + 1, 1, GL_RGBA,
00400             GL_UNSIGNED_BYTE, vid->memory_copy->line[_y] + _x1 * 4);
00401 
00402         vid = vid->next;
00403     }
00404     
00405     glBindTexture(GL_TEXTURE_2D, 0);
00406     
00407     return;
00408 }
00409 
00410 
00411 
00412 static void allegro_gl_video_line(struct BITMAP *bmp, int x1, int y1, int x2,
00413                                   int y2, int color) {
00414     
00415     /* Note: very very slow */                      
00416     do_line(bmp, x1, y1, x2, y2, color, allegro_gl_video_putpixel);
00417     
00418     return;
00419 }
00420     
00421 
00422 
00423 static void allegro_gl_video_rectfill(struct BITMAP *bmp, int x1, int y1,
00424                                       int x2, int y2, int color) {
00425 
00426     GLubyte pixel[4];
00427     AGL_VIDEO_BITMAP *vid;
00428     GLint saved_row_length;
00429     
00430     AGL_LOG(2, "glvtable.c:allegro_gl_video_rectfill\n");
00431     split_color(color, &pixel[0], &pixel[1], &pixel[2], &pixel[3],
00432                 bitmap_color_depth(screen));
00433     vid = bmp->extra;
00434     
00435     glGetIntegerv(GL_UNPACK_ROW_LENGTH, &saved_row_length);
00436     
00437     /* TODO: support for subbitmaps and clipping */
00438     
00439     if (y1 > y2) {
00440         int temp = y1;
00441         y1 = y2;
00442         y2 = temp;
00443     }
00444 
00445     if (x1 > x2) {
00446         int temp = x1;
00447         x1 = x2;
00448         x2 = temp;
00449     }
00450     
00451     while (vid) {
00452         int _y1, _y2, _x1, _x2;
00453         if (vid->x_ofs > x2 || vid->y_ofs > y2
00454             || vid->x_ofs + vid->memory_copy->w <= x1
00455             || vid->y_ofs + vid->memory_copy->h <= y1) {
00456             
00457             vid = vid->next;
00458             continue;
00459         }
00460         
00461         _y1 = MAX(y1, vid->y_ofs) - vid->y_ofs;
00462         _y2 = MIN(y2, vid->y_ofs + vid->memory_copy->h - 1) - vid->y_ofs;
00463         _x1 = MAX(x1, vid->x_ofs) - vid->x_ofs;
00464         _x2 = MIN(x2, vid->x_ofs + vid->memory_copy->w - 1) - vid->x_ofs;
00465 
00466         rectfill(vid->memory_copy, _x1, _y1, _x2, _y2,
00467             makeacol_depth(32, pixel[0], pixel[1], pixel[2], pixel[3]));
00468         
00469         glPixelStorei(GL_UNPACK_ROW_LENGTH,
00470                    (vid->memory_copy->line[1] - vid->memory_copy->line[0]) / 4);
00471             
00472         glBindTexture(GL_TEXTURE_2D, vid->tex);
00473         glTexSubImage2D(GL_TEXTURE_2D, 0,
00474             _x1, _y1, _x2 - _x1 + 1, _y2 - _y1 + 1, GL_RGBA,
00475             GL_UNSIGNED_BYTE, vid->memory_copy->line[_y1] + _x1 * 4);
00476 
00477         vid = vid->next;
00478     }
00479     
00480     glPixelStorei(GL_UNPACK_ROW_LENGTH, saved_row_length);
00481     glBindTexture(GL_TEXTURE_2D, 0);
00482     
00483     return;
00484 }
00485 
00486 
00487 
00488 static int allegro_gl_video_triangle(struct BITMAP *bmp, int x1, int y1,
00489                                      int x2, int y2, int x3, int y3, int color)
00490 {   
00491     GLubyte pixel[4];
00492     AGL_VIDEO_BITMAP *vid;
00493     GLint saved_row_length;
00494     int min_y, max_y, min_x, max_x;
00495     
00496     AGL_LOG(2, "glvtable.c:allegro_gl_video_triangle\n");
00497     split_color(color, &pixel[0], &pixel[1], &pixel[2], &pixel[3],
00498                 bitmap_color_depth(screen));
00499     vid = bmp->extra;
00500     
00501     glGetIntegerv(GL_UNPACK_ROW_LENGTH, &saved_row_length);
00502 
00503     min_y = MIN(y1, MIN(y2, y3));
00504     min_x = MIN(x1, MIN(x2, x3));
00505     max_y = MAX(y1, MAX(y2, y3));
00506     max_x = MAX(x1, MAX(x2, x3));
00507     
00508     /* TODO: Support for subbitmaps and clipping */
00509     
00510     while (vid) {
00511         int _y1, _y2, _x1, _x2, _x3, _y3;
00512         if (vid->x_ofs > max_x || vid->y_ofs > max_y
00513             || vid->x_ofs + vid->memory_copy->w <= min_x
00514             || vid->y_ofs + vid->memory_copy->h <= min_y) {
00515             
00516             vid = vid->next;
00517             continue;
00518         }               
00519         
00520         _y1 = y1 - vid->y_ofs;
00521         _y2 = y2 - vid->y_ofs;
00522         _y3 = y3 - vid->y_ofs;
00523         _x1 = x1 - vid->x_ofs;
00524         _x2 = x2 - vid->x_ofs;
00525         _x3 = x3 - vid->x_ofs;
00526 
00527         triangle(vid->memory_copy, _x1, _y1, _x2, _y2, _x3, _y3,
00528             makeacol_depth(32, pixel[0], pixel[1], pixel[2], pixel[3]));
00529         
00530         glPixelStorei(GL_UNPACK_ROW_LENGTH,
00531                    (vid->memory_copy->line[1] - vid->memory_copy->line[0]) / 4);
00532         
00533         /* Not quite the minimal rectangle occupied by the triangle, but
00534          * pretty close
00535          */
00536         _y1 = MAX(0, min_y - vid->y_ofs);
00537         _y2 = MIN(vid->memory_copy->h, max_y - vid->y_ofs);
00538         _x1 = MAX(0, min_x - vid->x_ofs);
00539         _x2 = MIN(vid->memory_copy->w, max_x - vid->x_ofs);
00540             
00541         glBindTexture(GL_TEXTURE_2D, vid->tex);
00542         glTexSubImage2D(GL_TEXTURE_2D, 0,
00543             _x1, _y1, _x2 - _x1 + 1, _y2 - _y1 + 1, GL_RGBA,
00544             GL_UNSIGNED_BYTE, vid->memory_copy->line[_y1] + _x1 * 4);
00545 
00546         vid = vid->next;
00547     }
00548     
00549     glPixelStorei(GL_UNPACK_ROW_LENGTH, saved_row_length);
00550     glBindTexture(GL_TEXTURE_2D, 0);    
00551     
00552     return 1;
00553 }
00554 
00555 
00556 
00557 void allegro_gl_video_blit_from_memory(struct BITMAP *source,
00558                 struct BITMAP *dest, int source_x, int source_y,
00559                 int dest_x, int dest_y, int width, int height) {
00560 
00561     AGL_VIDEO_BITMAP *vid;
00562     BITMAP *dest_parent = dest;
00563     GLint saved_row_length;
00564     
00565     AGL_LOG(2, "glvtable.c:allegro_gl_video_blit_from_memory\n");
00566 
00567     if (is_sub_bitmap (dest)) {
00568        dest_x += dest->x_ofs;
00569        dest_y += dest->y_ofs;
00570        while (dest_parent->id & BMP_ID_SUB)
00571           dest_parent = (BITMAP *)dest_parent->extra;
00572     }
00573     vid = dest_parent->extra;
00574     
00575     glGetIntegerv(GL_UNPACK_ROW_LENGTH, &saved_row_length);
00576     
00577     /* TODO: support for clipping */
00578 
00579     while (vid) {
00580         int _x, _y, _w, _h;
00581         if (vid->x_ofs >= dest_x + width || vid->y_ofs >= dest_y + height
00582             || vid->x_ofs + vid->memory_copy->w <= dest_x
00583             || vid->y_ofs + vid->memory_copy->h <= dest_y) {
00584             
00585             vid = vid->next;
00586             continue;
00587         }
00588 
00589         _x = MAX (vid->x_ofs, dest_x) - vid->x_ofs;
00590         _w = MIN (vid->x_ofs + vid->memory_copy->w, dest_x + width)
00591            - vid->x_ofs - _x;
00592         _y = MAX (vid->y_ofs, dest_y) - vid->y_ofs;
00593         _h = MIN (vid->y_ofs + vid->memory_copy->h, dest_y + height)
00594            - vid->y_ofs - _y;
00595 
00596         blit(source, vid->memory_copy, source_x + vid->x_ofs + _x - dest_x,
00597             source_y + vid->y_ofs + _y - dest_y, _x, _y, _w, _h);
00598 
00599         glPixelStorei(GL_UNPACK_ROW_LENGTH,
00600                    (vid->memory_copy->line[1] - vid->memory_copy->line[0]) / 4);
00601 
00602         glBindTexture(GL_TEXTURE_2D, vid->tex);
00603         glTexSubImage2D(GL_TEXTURE_2D, 0, _x, _y, _w, _h,
00604             GL_RGBA, GL_UNSIGNED_BYTE,
00605             vid->memory_copy->line[_y] + _x * 4);
00606             
00607         vid = vid->next;
00608     }
00609     
00610     glPixelStorei(GL_UNPACK_ROW_LENGTH, saved_row_length);
00611     glBindTexture(GL_TEXTURE_2D, 0);
00612 
00613     return; 
00614 }
00615 
00616 
00617 
00618 void allegro_gl_video_blit_to_memory(struct BITMAP *source, struct BITMAP *dest,
00619                          int source_x, int source_y, int dest_x, int dest_y,
00620                          int width, int height) {
00621 
00622     AGL_VIDEO_BITMAP *vid;
00623     
00624     int i, j;   
00625     int n_w = (source->w + 255) / 256,
00626         n_h = (source->h + 255) / 256;
00627     
00628     AGL_LOG(2, "glvtable.c:allegro_gl_video_blit_to_memory\n");
00629     vid = source->extra;
00630     
00631     /* TODO: support for subbitmaps and clipping */
00632     
00633     for (j = 0; j < n_h; j++) {
00634         for (i = 0; i < n_w; i++) {
00635         
00636             blit(vid->memory_copy, dest, i * 256 > source_x ? 0 : source_x
00637                     - i * 256, j * 256 > source_y ? 0 : source_y - j * 256,
00638                 dest_x + (i == 0 ? 0 : i * 256 - source_x),
00639                 dest_y + (j == 0 ? 0 : j * 256 - source_y),
00640                 width - i * 256, height - j * 256);
00641             
00642             vid = vid->next;
00643         }
00644     }
00645 
00646     return; 
00647 }
00648 
00649 
00650 
00651 static void allegro_gl_video_clear_to_color(BITMAP *bmp, int color) {
00652 
00653     GLubyte pixel[4];
00654     AGL_VIDEO_BITMAP *vid;
00655     GLint saved_row_length;
00656     
00657     glGetIntegerv(GL_UNPACK_ROW_LENGTH, &saved_row_length);
00658     
00659     AGL_LOG(2, "glvtable.c:allegro_gl_video_clear_to_color\n");
00660     split_color(color, &pixel[0], &pixel[1], &pixel[2], &pixel[3],
00661                 bitmap_color_depth(screen));
00662     vid = bmp->extra;
00663     
00664     /* TODO: support for video sub bitmaps and clipping */
00665     
00666     while (vid) {
00667         clear_to_color(vid->memory_copy,
00668                     makeacol_depth(32, pixel[0], pixel[1], pixel[2], pixel[3]));
00669         
00670         glBindTexture(GL_TEXTURE_2D, vid->tex);
00671         
00672         glPixelStorei(GL_UNPACK_ROW_LENGTH,
00673                    (vid->memory_copy->line[1] - vid->memory_copy->line[0]) / 4);
00674         
00675         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
00676             vid->memory_copy->w, vid->memory_copy->h,
00677             GL_RGBA, GL_UNSIGNED_BYTE, vid->memory_copy->line[0]);
00678 
00679         vid = vid->next;
00680     }
00681     
00682     glBindTexture(GL_TEXTURE_2D, 0);
00683     glPixelStorei(GL_UNPACK_ROW_LENGTH, saved_row_length);
00684 
00685     return;
00686 }
00687 
00688 
00689 
00690 static void dummy_unwrite_bank(void)
00691 {
00692 }
00693 
00694 
00695 
00696 static GFX_VTABLE allegro_gl_video_vtable = {
00697     0,
00698     0,
00699     dummy_unwrite_bank,         //void *unwrite_bank;  /* C function on some machines, asm on i386 */
00700     NULL,                       //AL_METHOD(void, set_clip, (struct BITMAP *bmp));
00701     allegro_gl_video_acquire,
00702     allegro_gl_video_release,
00703     NULL,                       //AL_METHOD(struct BITMAP *, create_sub_bitmap, (struct BITMAP *parent, int x, int y, int width, int height));
00704     allegro_gl_created_sub_bitmap,
00705     allegro_gl_video_getpixel,
00706     allegro_gl_video_putpixel,
00707     allegro_gl_video_vline,
00708     allegro_gl_video_hline,
00709     allegro_gl_video_hline,
00710     allegro_gl_video_line,
00711 #if GET_ALLEGRO_VERSION() >= MAKE_VER(4, 1, 13)
00712     allegro_gl_video_line,
00713 #endif  
00714     allegro_gl_video_rectfill,
00715     allegro_gl_video_triangle,
00716     NULL,/*allegro_gl_screen_draw_sprite,*/
00717     NULL,                       //AL_METHOD(void, draw_256_sprite, (struct BITMAP *bmp, struct BITMAP *sprite, int x, int y));
00718     NULL,/*allegro_gl_screen_draw_sprite_v_flip,*/
00719     NULL,/*allegro_gl_screen_draw_sprite_h_flip,*/
00720     NULL,/*allegro_gl_screen_draw_sprite_vh_flip,*/
00721     NULL,                       //AL_METHOD(void, draw_trans_sprite, (struct BITMAP *bmp, struct BITMAP *sprite, int x, int y));
00722     NULL,                       //AL_METHOD(void, draw_trans_rgba_sprite, (struct BITMAP *bmp, struct BITMAP *sprite, int x, int y));
00723     NULL,                       //AL_METHOD(void, draw_lit_sprite, (struct BITMAP *bmp, struct BITMAP *sprite, int x, int y, int color));
00724     NULL,                       //AL_METHOD(void, draw_rle_sprite, (struct BITMAP *bmp, struct RLE_SPRITE *sprite, int x, int y));
00725     NULL,                       //AL_METHOD(void, draw_trans_rle_sprite, (struct BITMAP *bmp, struct RLE_SPRITE *sprite, int x, int y));
00726     NULL,                       //AL_METHOD(void, draw_trans_rgba_rle_sprite, (struct BITMAP *bmp, struct RLE_SPRITE *sprite, int x, int y));
00727     NULL,                       //AL_METHOD(void, draw_lit_rle_sprite, (struct BITMAP *bmp, struct RLE_SPRITE *sprite, int x, int y, int color));
00728     NULL,                       //AL_METHOD(void, draw_character, (struct BITMAP *bmp, struct BITMAP *sprite, int x, int y, int color));
00729     NULL,/*allegro_gl_screen_draw_glyph,*/
00730     allegro_gl_video_blit_from_memory,
00731     allegro_gl_video_blit_to_memory,
00732     NULL,                       //AL_METHOD(void, blit_from_system, (struct BITMAP *source, struct BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height));
00733     NULL,                       //AL_METHOD(void, blit_to_system, (struct BITMAP *source, struct BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height));
00734     allegro_gl_screen_blit_to_self, /* Video bitmaps use same method as screen */
00735     allegro_gl_screen_blit_to_self, /* ..._forward */
00736     allegro_gl_screen_blit_to_self, /* ..._backward */
00737     allegro_gl_memory_blit_between_formats,
00738     NULL,                       //AL_METHOD(void, masked_blit, (struct BITMAP *source, struct BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height));
00739     allegro_gl_video_clear_to_color,
00740     NULL,                       //AL_METHOD(void, pivot_scaled_sprite_flip, (struct BITMAP *bmp, struct BITMAP *sprite, fixed x, fixed y, fixed cx, fixed cy, fixed angle, fixed scale, int v_flip));
00741     NULL,/*allegro_gl_screen_draw_sprite_end,*/
00742     NULL                        //AL_METHOD(void, blit_end, (void));
00743 };
00744 

Generated on Wed Jun 30 23:59:52 2004 for AllegroGL by doxygen 1.3.5