9 #include <librsvg/rsvg.h>
10 #include <librsvg/rsvg-cairo.h>
12 #define TRECT(x,y,w,h, tw, th) glBegin(GL_TRIANGLE_STRIP);glTexCoord2f(0.0,h/th);glVertex2f(x, y+1*h);glTexCoord2f(0.0,0.0);glVertex2f(x, y);glTexCoord2f(w/tw,h/th);glVertex2f(x+1*w, y+1*h);glTexCoord2f(w/tw,0.0);glVertex2f(x+1*w, y);glEnd();
13 #define RECT(x,y,w,h) glBegin(GL_TRIANGLE_STRIP);glVertex2f(x, y+1*h);glVertex2f(x, y);glVertex2f(x+1*w, y+1*h);glVertex2f(x+1*w, y);glEnd();
15 #define TTRECT(x,y,w,h,sw,sh, tw, th) glBegin(GL_TRIANGLE_STRIP);glTexCoord2f(0.0,sh/th);glVertex2f(x, y+1*h);glTexCoord2f(0.0,0.0);glVertex2f(x, y);glTexCoord2f(sw/tw,sh/th);glVertex2f(x+1*w, y+1*h);glTexCoord2f(sw/tw,0.0);glVertex2f(x+1*w, y);glEnd();
17 unsigned int occupied
=0;
21 unsigned int allocated
;
24 SurfaceList gsprite_surfaces
;
25 int AddSurface(GLuint s
);
26 void RemoveSurface(GLuint s
);
27 void RemoveSID(int SID
);
28 void FlushSpriteSurfaces();
29 int SetVideoMode(int width
, int height
);
34 unsigned int allocated
;
38 int AddSprite(Sprite
*s
);
39 void RemoveSprite(Sprite
*s
);
52 SpriteQueueItem
*items
;
53 unsigned int allocated
;
56 SpriteQueue gsprite_queue
;
57 SpriteQueue gsprite_queue_sorted
;
58 void FlushSpriteQueue();
59 void RotateSurface(int SID
, int rotation
);
63 GLuint
load_svg (char *file
, int width
, int height
, double *pdw
, double *pdh
);
69 return (x
/(double)SCREEN_WIDTH
)*GetConfig().screen_width
;
72 return (y
/(double)SCREEN_HEIGHT
)*GetConfig().screen_height
;
75 int SetVideoMode(int width
, int height
){
82 Config config
=GetConfig();
84 SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER
, 1 );
87 flags
= flags
|SDL_FULLSCREEN
;
88 /* Get available fullscreen/hardware modes */
89 modes
=SDL_ListModes(NULL
, flags
);
91 /* Check if there are any modes available */
92 if(modes
== (SDL_Rect
**)0){
93 printf("No modes available!\n");
97 /* Check if our resolution is restricted */
98 if(modes
== (SDL_Rect
**)-1){
99 printf("All resolutions available.\n");
100 gscreen
= SDL_SetVideoMode(config
.screen_width
, config
.screen_height
, 0, flags
);
103 /* Print valid modes */
104 printf("Available Modes\n");
105 bestdif
= abs((modes
[0]->w
- config
.screen_width
) + (modes
[0]->h
- config
.screen_height
));
107 for(i
=0;modes
[i
];++i
){
108 printf(" %d x %d\n", modes
[i
]->w
, modes
[i
]->h
);
109 if(bestdif
> abs((modes
[i
]->w
- config
.screen_width
) + (modes
[i
]->h
- config
.screen_height
))){
110 bestdif
= abs((modes
[i
]->w
- config
.screen_width
) + (modes
[i
]->h
- config
.screen_height
));
114 printf("Using: %d x %d\n", modes
[ibest
]->w
, modes
[ibest
]->h
);
115 gscreen
= SDL_SetVideoMode(modes
[ibest
]->w
, modes
[ibest
]->h
, 0, flags
);
116 config
.screen_height
= modes
[ibest
]->h
;
117 config
.screen_width
= modes
[ibest
]->w
;
123 int AddSurface(GLuint s
){ //returns -1 on error, SID if success
126 for(i
=0;i
<gsprite_surfaces
.allocated
;i
++)
127 if( gsprite_surfaces
.surfaces
[i
]==s
){
131 for(i
=0;i
<gsprite_surfaces
.allocated
;i
++)
132 if( gsprite_surfaces
.surfaces
[i
]==0 ){
133 gsprite_surfaces
.surfaces
[i
]=s
;
136 i
=gsprite_surfaces
.allocated
;
137 tmp
= (GLuint
*) realloc(gsprite_surfaces
.surfaces
, sizeof(GLuint
)*i
*2); //if the allocated space is not wide enough, then allocate double space than previous
140 gsprite_surfaces
.surfaces
=tmp
;
141 memset(&gsprite_surfaces
.surfaces
[i
],0, sizeof(GLuint
)*i
); //zero newly allocated space
142 gsprite_surfaces
.allocated
=i
*2;
143 gsprite_surfaces
.surfaces
[i
]=s
;
147 void RemoveSurface(GLuint s
){
148 int i
,iwannakillyoubitch
;
150 iwannakillyoubitch
=1;
151 for(i
=0;i
<gsprite_surfaces
.allocated
;i
++){
152 if( gsprite_surfaces
.surfaces
[i
]==s
){
153 gsprite_surfaces
.surfaces
[i
]=0;
155 if( i
>=gsprite_surfaces
.allocated
/2 && iwannakillyoubitch
&& gsprite_surfaces
.surfaces
[i
]!=0 )
156 iwannakillyoubitch
=0;
159 if(iwannakillyoubitch
){
160 gsprite_surfaces
.allocated
/=2;
161 gsprite_surfaces
.surfaces
= (GLuint
*)realloc(gsprite_surfaces
.surfaces
, sizeof(GLuint
)*gsprite_surfaces
.allocated
);//TODO:check return value
165 void RemoveSID(int SID
){
166 int i
,iwannakillyoubitch
;
168 iwannakillyoubitch
=1;
169 for(i
=0;i
<gsprite_surfaces
.allocated
;i
++){
171 gsprite_surfaces
.surfaces
[i
]=0;
173 if( i
>=gsprite_surfaces
.allocated
/2 && iwannakillyoubitch
&& gsprite_surfaces
.surfaces
[i
]!=0 )
174 iwannakillyoubitch
=0;
177 if(iwannakillyoubitch
){
178 gsprite_surfaces
.allocated
/=2;
179 gsprite_surfaces
.surfaces
= (GLuint
*)realloc(gsprite_surfaces
.surfaces
, sizeof(GLuint
)*gsprite_surfaces
.allocated
);//TODO:check return value
183 int AddSprite(Sprite
*s
){//returns 0 on error, Sprite ID on success
186 for(i
=0;i
<gsprites
.allocated
;i
++)
187 if( gsprites
.sprites
[i
]==s
){
191 for(i
=0;i
<gsprites
.allocated
;i
++)
192 if( gsprites
.sprites
[i
]==0 ){
193 gsprites
.sprites
[i
]=s
;
196 i
=gsprites
.allocated
;
197 tmp
=(Sprite
**)realloc(gsprites
.sprites
, sizeof(Sprite
*)*i
*2); //if the allocated space is not wide enough, then allocate double space than previous
200 gsprites
.sprites
=tmp
;
201 memset(&gsprites
.sprites
[i
],0, sizeof(Sprite
*)*i
); //zero newly allocated space
202 gsprites
.allocated
=i
*2;
203 gsprites
.sprites
[i
]=s
;
207 void RemoveSprite(Sprite
*s
){
208 int i
,iwannakillyoubitch
;
210 iwannakillyoubitch
=1;
211 for(i
=0;i
<gsprites
.allocated
;i
++){
212 if( gsprites
.sprites
[i
]==s
){
213 gsprites
.sprites
[i
]=0;
215 if( i
>=gsprites
.allocated
/2 && iwannakillyoubitch
&& gsprites
.sprites
[i
]!=0 )
216 iwannakillyoubitch
=0;
219 if(iwannakillyoubitch
){
220 gsprites
.allocated
/=2;
221 gsprites
.sprites
= (Sprite
**) realloc(gsprites
.sprites
, sizeof(Sprite
*)*gsprites
.allocated
);//TODO:check return value
230 FlushSpriteSurfaces();
233 free(gsprite_surfaces
.surfaces
);
234 gsprite_surfaces
.surfaces
=0;
237 for(i
=0; i
<gsprites
.allocated
; i
++)
238 if(gsprites
.sprites
[i
]){
239 free(gsprites
.sprites
[i
]->fname
);
240 free(gsprites
.sprites
[i
]);
241 gsprites
.sprites
[i
]=0;
244 gsprites
.allocated
= 0;
248 SetVideoMode(config
.screen_width
, config
.screen_height
);
258 gsprite_surfaces
.surfaces
= (GLuint
*) calloc(2, sizeof(GLuint
));
259 if( gsprite_surfaces
.surfaces
== 0 )
262 gsprite_surfaces
.allocated
= 2;
263 memset(gsprite_surfaces
.surfaces
, 0, gsprite_surfaces
.allocated
* sizeof(GLuint
));
265 gsprites
.sprites
= (Sprite
**) calloc(2,sizeof(Sprite
*));
266 if( gsprites
.sprites
== 0 )
268 memset(gsprites
.sprites
, 0, gsprites
.allocated
* sizeof(Sprite
*));
269 gsprites
.allocated
= 2;
272 gsprite_queue
.allocated
=2;
273 gsprite_queue
.items
=(SpriteQueueItem
*) malloc(sizeof(SpriteQueueItem
)*2);
274 gsprite_queue
.next_id
=0;
276 SetVideoMode(config
.screen_width
, config
.screen_height
);
278 glClearColor(0.0f
, 0.0f
, 0.0f
, 0.5f
);
280 glDisable(GL_DEPTH_TEST
);
281 //glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
283 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
284 //glEnable(GL_ALPHA_TEST);
285 //glAlphaFunc(GL_GREATER, 0);
286 SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL
, 1);
288 glViewport(0, 0, config
.screen_width
, config
.screen_height
);
289 glMatrixMode(GL_PROJECTION
);
292 glOrtho(0.0f
,config
.screen_width
, config
.screen_height
,0.0f
,-1.0f
,1.0f
);
294 glMatrixMode(GL_MODELVIEW
);
300 void FlushSpriteSurfaces(){
303 for(i
=0;i
<gsprite_surfaces
.allocated
;i
++){
304 if(gsprite_surfaces
.surfaces
[i
]){
305 glDeleteTextures(1, &gsprite_surfaces
.surfaces
[i
]);
306 gsprite_surfaces
.surfaces
[i
]=0;
312 int RegenerateSprites(){
322 FlushSpriteSurfaces();
324 SetVideoMode(config
.screen_width
, config
.screen_height
);
327 for(i
=0;i
<gsprites
.allocated
;i
++)
328 if(gsprites
.sprites
[i
]){
329 tmpsprite
=gsprites
.sprites
[i
];
330 xx
= (tmpsprite
->width
/SCREEN_WIDTH
)*config
.screen_width
;
331 yy
= (tmpsprite
->height
/SCREEN_HEIGHT
)*config
.screen_height
;
333 tmpsurface
=load_svg(tmpsprite
->fname
, xx
, yy
, &tmpsprite
->twidth
, &tmpsprite
->theight
);
335 SID
=AddSurface(tmpsurface
);
339 RotateSurface(SID
,tmpsprite
->rotation
);
346 void InvalidateSprites(){
351 void FlushSpriteQueue(){
354 for(i
=0;i
<gsprite_queue
.allocated
;i
++){
355 gsprite_queue
.items
[i
].sprite
= 0;
357 if(gsprite_queue
.next_id
< gsprite_queue
.allocated
/2){
358 //TODO:dopsat zmenseni fronty
360 gsprite_queue
.next_id
= 0;
363 void SwapSpriteQueueItems(int aid
, int bid
){
365 memcpy(&c
, &gsprite_queue_sorted
.items
[aid
], sizeof(SpriteQueueItem
));
366 memcpy(&gsprite_queue_sorted
.items
[aid
], &gsprite_queue_sorted
.items
[bid
], sizeof(SpriteQueueItem
));
367 memcpy(&gsprite_queue_sorted
.items
[bid
], &c
, sizeof(SpriteQueueItem
));
368 /*c.sprite = gsprite_queue_sorted.items[aid].sprite;
369 c.x = gsprite_queue_sorted.items[aid].x;
370 c.xx = gsprite_queue_sorted.items[aid].xx;
371 c.y = gsprite_queue_sorted.items[aid].y;
372 c.yy = gsprite_queue_sorted.items[aid].yy;
373 c.z = gsprite_queue_sorted.items[aid].z;
374 c.c = gsprite_queue_sorted.items[aid].c;
376 gsprite_queue_sorted.items[aid].sprite = gsprite_queue_sorted.items[bid].sprite ;
377 gsprite_queue_sorted.items[aid].x = gsprite_queue_sorted.items[bid].x ;
378 gsprite_queue_sorted.items[aid].xx = gsprite_queue_sorted.items[bid].xx ;
379 gsprite_queue_sorted.items[aid].y = gsprite_queue_sorted.items[bid].y ;
380 gsprite_queue_sorted.items[aid].yy = gsprite_queue_sorted.items[bid].yy ;
381 gsprite_queue_sorted.items[aid].z = gsprite_queue_sorted.items[bid].z ;
382 gsprite_queue_sorted.items[aid].c = gsprite_queue_sorted.items[bid].c ;
384 gsprite_queue_sorted.items[bid].sprite = c.sprite;
385 gsprite_queue_sorted.items[bid].x = c.x;
386 gsprite_queue_sorted.items[bid].xx = c.xx;
387 gsprite_queue_sorted.items[bid].y = c.y;
388 gsprite_queue_sorted.items[bid].yy = c.yy;
389 gsprite_queue_sorted.items[bid].z = c.z;
390 gsprite_queue_sorted.items[bid].c = c.c;*/
393 void YSortSpriteQueue(int from
, int to
){
397 //TODO:validity check
400 for(i
= from
; i
< to
; i
++){
401 y1
= gsprite_queue_sorted
.items
[i
].sprite
->height
* 0.5 + gsprite_queue_sorted
.items
[i
].y
;
402 y2
= gsprite_queue_sorted
.items
[i
+1].sprite
->height
* 0.5 + gsprite_queue_sorted
.items
[i
+1].y
;
405 SwapSpriteQueueItems(i
+1, i
);
411 void ZSortSpriteQueue(){
412 int minz
, lastminz
, found
;
414 int ysortfrom
, ysortto
;
419 gsprite_queue_sorted
.next_id
= 0;
423 //we seek for smallest z bigger than z in last iteration
424 for(i
=0; i
<gsprite_queue
.next_id
; i
++){
425 if( gsprite_queue
.items
[i
].z
< minz
&& gsprite_queue
.items
[i
].z
> lastminz
){
427 minz
= gsprite_queue
.items
[i
].z
;
432 //now we copy all items on z==minz
433 ysortfrom
= gsprite_queue_sorted
.next_id
;
434 for(i
=0; i
< gsprite_queue
.next_id
; i
++){
435 if(gsprite_queue
.items
[i
].z
== minz
){
436 memcpy(&gsprite_queue_sorted
.items
[gsprite_queue_sorted
.next_id
], &gsprite_queue
.items
[i
], sizeof(SpriteQueueItem
));
437 ysortto
= gsprite_queue_sorted
.next_id
;
438 gsprite_queue_sorted
.next_id
++;
441 YSortSpriteQueue(ysortfrom
, ysortto
);
459 gsprite_queue_sorted
.allocated
= gsprite_queue
.allocated
;
460 gsprite_queue_sorted
.next_id
= 0;
461 gsprite_queue_sorted
.items
= malloc(sizeof(SpriteQueueItem
)* gsprite_queue_sorted
.allocated
);
464 // select modulate to mix texture with color for shading
465 glTexEnvf( GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_MODULATE
);
466 glEnable(GL_TEXTURE_2D
);
468 for(i
=0;i
<gsprite_queue_sorted
.next_id
;i
++)
469 if(gsprite_queue_sorted
.items
[i
].sprite
){
470 dspr
= gsprite_queue_sorted
.items
[i
].sprite
;
471 ds
= gsprite_surfaces
.surfaces
[dspr
->SID
];
472 dest
.x
= G2SX(gsprite_queue_sorted
.items
[i
].x
);
473 dest
.y
= G2SY(gsprite_queue_sorted
.items
[i
].y
);
474 dest
.w
= G2SX(gsprite_queue_sorted
.items
[i
].xx
);
475 dest
.h
= G2SX(gsprite_queue_sorted
.items
[i
].yy
);
478 src
.w
= G2SX(gsprite_queue_sorted
.items
[i
].sprite
->width
);
479 src
.h
= G2SX(gsprite_queue_sorted
.items
[i
].sprite
->height
);
482 glBindTexture(GL_TEXTURE_2D
, ds
);
483 glColor4ub(gsprite_queue_sorted
.items
[i
].c
.r
, gsprite_queue_sorted
.items
[i
].c
.g
, gsprite_queue_sorted
.items
[i
].c
.b
, gsprite_queue_sorted
.items
[i
].c
.unused
);
484 TTRECT(dest
.x
, dest
.y
, dest
.w
, dest
.h
, src
.w
, src
.h
, dspr
->twidth
, dspr
->theight
);
487 glDisable(GL_TEXTURE_2D
);
489 gsprite_queue_sorted
.allocated
= 0;
490 gsprite_queue_sorted
.next_id
= 0;
491 free(gsprite_queue_sorted
.items
);
492 gsprite_queue_sorted
.items
= 0;
495 SDL_GL_SwapBuffers();
501 //SDL_FillRect(gscreen, 0, 0x0);
505 Sprite
* LoadSpriteSVG(char *fname
, double width
, double height
){
509 Config conf
=GetConfig();
511 xx
= width
*(double)conf
.screen_width
/SCREEN_WIDTH
;
512 yy
= height
*(double)conf
.screen_height
/SCREEN_HEIGHT
;
515 sprite
= (Sprite
*)malloc(sizeof(Sprite
));
516 surface
= load_svg(fname
, xx
, yy
, &sprite
->twidth
, &sprite
->theight
);
517 sprite
->fname
= malloc(sizeof(char)*(strlen(fname
)+2));
518 strcpy(sprite
->fname
, fname
);
519 sprite
->width
= width
;
520 sprite
->height
= height
;
521 sprite
->rotation
= 0;
522 sprite
->SID
= AddSurface(surface
);
527 void DestroySprite(Sprite
*sprite
){
528 RemoveSprite(sprite
);
531 glDeleteTextures(1, &gsprite_surfaces
.surfaces
[sprite
->SID
]);
532 RemoveSID(sprite
->SID
);
536 Sprite
* CopySprite(Sprite
*old
){
537 printf("CopySprite not Implemented\n");
543 void RotateSurface(int SID
, int rotation
){
547 fprintf(stderr
, "Rotation of sprites not implemented :(\n");
550 void RotateClockwise(Sprite
*sprite
){
551 RotateSurface(sprite
->SID
,1);
555 void QueueDrawSprite(Sprite
*sprite
, double x
, double y
, int z
){
556 SDL_Color white
= {255, 255, 255, 255};
557 QueueDrawSpriteColorize(sprite
, x
, y
, z
, white
);
560 void QueueDrawSpriteColorize(Sprite
*sprite
, double x
, double y
, int z
, SDL_Color color
){
561 SpriteQueueItem
*item
;
563 printf("NULL sprite*\n");
566 if(gsprite_queue
.next_id
>=gsprite_queue
.allocated
){
567 item
= (SpriteQueueItem
*) realloc(gsprite_queue
.items
, sizeof(SpriteQueueItem
)*gsprite_queue
.allocated
*2);
569 fprintf(stderr
, "Can't allocate enough memory for sprite queue\n");
572 gsprite_queue
.allocated
*= 2;
573 gsprite_queue
.items
= item
;
576 item
= &gsprite_queue
.items
[gsprite_queue
.next_id
];
577 item
->sprite
= sprite
;
579 item
->xx
= sprite
->width
;
581 item
->yy
= sprite
->height
;
585 gsprite_queue
.next_id
++;
588 void QueueDrawSpriteColorizeStretch(Sprite
*sprite
, double x
, double y
, double xx
, double yy
, int z
, SDL_Color color
){
589 SpriteQueueItem
*item
;
591 printf("NULL sprite*\n");
594 if(gsprite_queue
.next_id
>=gsprite_queue
.allocated
){
595 item
= (SpriteQueueItem
*) realloc(gsprite_queue
.items
, sizeof(SpriteQueueItem
)*gsprite_queue
.allocated
*2);
597 fprintf(stderr
, "Can't allocate enough memory for sprite queue\n");
600 gsprite_queue
.allocated
*= 2;
601 gsprite_queue
.items
= item
;
604 item
= &gsprite_queue
.items
[gsprite_queue
.next_id
];
605 item
->sprite
= sprite
;
613 gsprite_queue
.next_id
++;
617 unsigned int closestpoweroftwo(unsigned int i
){
628 //load_svg borrowed from cairo demo
630 /* load_svg: This is what you're probably interested in!
631 * -----------------------------------------------------
632 * If width and height are greater than 0, the image will
633 * be scaled to that size. wscale and hscale would be ignored.
635 * If width and height are less than 1, wscale and hscale will
636 * resize the width and the height to the specified scales.
638 * If width and height are less than 1, and wscale and hscale
639 * are either 0 or 1, then the image will be loaded at it's
642 * See main() for examples.
644 GLuint
load_svg (char *file
, int width
, int height
, double *pdw
, double *pdh
) {
645 RsvgDimensionData g_DimensionData
;
646 RsvgHandle
* rsvghandle
;
652 unsigned int rheight
;
653 unsigned int pw
,ph
; //power of two dimensions
654 double wscale
,hscale
;
655 Config config
=GetConfig();
657 // Create the SVG cairo stuff.
658 rsvghandle
= rsvg_handle_new_from_file(file
, &pError
);
660 rsvg_handle_get_dimensions( rsvghandle
, &g_DimensionData
);
661 rwidth
= g_DimensionData
.width
;
662 rheight
= g_DimensionData
.height
;
663 *pdw
= closestpoweroftwo(width
);
664 *pdh
= closestpoweroftwo(height
);
665 width
= width
>>config
.texture_lod
;
666 height
= height
>>config
.texture_lod
;
667 printf("w:%u h:%u\n",width
, height
);
669 /*Calculate final width and height of our surface based on the parameters passed */
671 wscale
=(float)width
/(float)rwidth
;
673 width
=(int)(rwidth
*wscale
);
676 hscale
=(float)height
/(float)rheight
;
678 height
=(int)(rheight
*hscale
);
688 /* We will create a CAIRO_FORMAT_ARGB32 surface. We don't need to match
689 the screen SDL format, but we are interested in the alpha bit */
690 bpp
=32; /*bits per pixel*/
691 btpp
=4; /*bytes per pixel*/
694 int stride
=width
* btpp
;
696 /* Allocate an image */
697 unsigned char *image
=calloc(stride
*height
, 1);
699 /* Create the cairo surface with the adjusted width and height */
700 cairo_surface_t
*cairo_surface
;
701 cairo_surface
= cairo_image_surface_create_for_data (image
,
703 width
, height
, stride
);
705 cairo_t
*cr
=cairo_create(cairo_surface
);
706 cairo_scale (cr
, wscale
, hscale
);
708 /* Render SVG to our surface */
709 rsvg_handle_render_cairo(rsvghandle
, cr
);
710 rsvg_handle_free(rsvghandle
);
713 cairo_surface_destroy (cairo_surface
);
716 /*Destroy the svg_cairo structure */
718 /*Adjust the SDL surface mask to ARGB, matching the cairo surface created.*/
719 Uint32 rmask
, gmask
, bmask
, amask
;
726 /* Create the SDL surface using the pixel data stored. It will automatically be set to use alpha using these mask values */
727 SDL_Surface
*sdl_surface
=SDL_CreateRGBSurfaceFrom( (void *) image
, width
, height
, bpp
, stride
, rmask
, gmask
, bmask
, amask
);
728 SDL_SetAlpha(sdl_surface
, 0, 255);
733 pw
= closestpoweroftwo(width
);
734 ph
= closestpoweroftwo(height
);
735 SDL_Surface
*sdl_rgba_surface
=SDL_CreateRGBSurface( SDL_SWSURFACE
, pw
, ph
, bpp
, rmask
, gmask
, bmask
, amask
);
736 SDL_BlitSurface(sdl_surface
, 0, sdl_rgba_surface
, 0);
737 SDL_FreeSurface(sdl_surface
);
740 SDL_LockSurface(sdl_rgba_surface
);
743 glGenTextures(1, &tid
);
744 glBindTexture(GL_TEXTURE_2D
, tid
);
745 glTexParameteri(GL_TEXTURE_2D
,GL_TEXTURE_MAG_FILTER
,GL_LINEAR
); // scale linearly when image bigger than texture
746 glTexParameteri(GL_TEXTURE_2D
,GL_TEXTURE_MIN_FILTER
,GL_LINEAR
); // scale linearly when image smalled than texture
747 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA
, pw
, ph
, 0, GL_RGBA
, GL_UNSIGNED_BYTE
, sdl_rgba_surface
->pixels
);
748 SDL_UnlockSurface(sdl_rgba_surface
);
749 SDL_FreeSurface(sdl_rgba_surface
);
751 printf("Occupied: %u\n", occupied
);