2 Copyright (c)2006-2008 - Brett Lajzer
4 See LICENSE for license information.
12 #include <SDL/SDL_image.h>
17 //loads an SDL_Surface into a texture and returns the handle
18 GLuint
surfaceToTexture(lua_State
*L
, SDL_Surface
*s
){
19 GLenum texture_format
;
22 if (s
->format
->BytesPerPixel
== 4){
23 if (s
->format
->Rmask
== 0x000000ff)
24 texture_format
= GL_RGBA
;
26 texture_format
= GL_BGRA
;
27 } else if (s
->format
->BytesPerPixel
== 3){
28 if (s
->format
->Rmask
== 0x000000ff)
29 texture_format
= GL_RGB
;
31 texture_format
= GL_BGR
;
33 return luaL_error(L
, "ERROR: Can't create texture from image. Image must be 24 or 32 bpp.");
36 glGenTextures(1, &tex
);
37 glBindTexture(GL_TEXTURE_RECTANGLE_ARB
, tex
);
38 glTexParameteri(GL_TEXTURE_RECTANGLE_ARB
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
39 glTexParameteri(GL_TEXTURE_RECTANGLE_ARB
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
40 glTexImage2D(GL_TEXTURE_RECTANGLE_ARB
, 0, s
->format
->BytesPerPixel
, s
->w
, s
->h
, 0, texture_format
, GL_UNSIGNED_BYTE
, s
->pixels
);
46 //function for loading a surface from many different formats
47 int l_getimage(lua_State
*L
){
48 std::string
filename(luaL_checkstring(L
,1));
49 std::map
<std::string
, GLSurface
*>::iterator im
= image_store
.find(filename
);
51 //search for the image in the store, if not found, load it
52 if(im
== image_store
.end()){
53 SDL_Surface
*temp
= IMG_Load(filename
.c_str());
56 return luaL_error(L
, "ERROR: Can't find image file: \"%s\".", filename
.c_str());
59 GLuint texture
= surfaceToTexture(L
, temp
);
61 GLSurface
*surf
= new GLSurface(texture
, temp
->w
, temp
->h
);
62 image_store
[filename
] = surf
;
63 lua_pushlightuserdata(L
, surf
);
64 lua_pushinteger(L
, (lua_Integer
)temp
->w
);
65 lua_pushinteger(L
, (lua_Integer
)temp
->h
);
67 SDL_FreeSurface(temp
);
69 lua_pushlightuserdata(L
, im
->second
);
70 lua_pushinteger(L
, (lua_Integer
)im
->second
->w
);
71 lua_pushinteger(L
, (lua_Integer
)im
->second
->h
);
76 //forces an image to be unloaded from memory
77 int l_releaseimage(lua_State
*L
){
78 std::string
filename(luaL_checkstring(L
,1));
79 std::map
<std::string
, GLSurface
*>::iterator im
= image_store
.find(filename
);
81 if(im
!= image_store
.end()){
82 glDeleteTextures(1, &(im
->second
->texture
));
84 image_store
.erase(im
);
91 //function for updating the display surface
92 int l_flip(lua_State
*L
){
98 //function for simple displaying of images (non-animated)
99 int l_display(lua_State
*L
){
100 GLSurface
*tex
= (GLSurface
*)lua_touserdata(L
,1);
102 float x
= (float)lua_tonumber(L
,2);
103 float y
= (float)lua_tonumber(L
,3);
104 double rot
= lua_tonumber(L
,4);
105 double scale_x
= lua_tonumber(L
,5);
106 double scale_y
= lua_tonumber(L
,6);
107 float alpha
= lua_tonumber(L
, 7)/255.0;
110 return luaL_error(L
, "ERROR: Can't draw. Image is null.");
113 float w_half
= tex
->w
/2.0;
114 float h_half
= tex
->h
/2.0;
116 glColor4f(1.0,1.0,1.0, alpha
);
119 glTranslatef(x
+ w_half
, y
+ h_half
, 0.0f
);
120 glScalef(scale_x
, scale_y
, 1.0f
);
121 glRotatef(rot
, 0.0f
, 0.0f
, -1.0f
);
123 glBindTexture(GL_TEXTURE_RECTANGLE_ARB
, tex
->texture
);
126 // Top-left vertex (corner)
128 glVertex2f(-w_half
, -h_half
);
130 // Bottom-left vertex (corner)
131 glTexCoord2i(0, tex
->h
);
132 glVertex2f(-w_half
, h_half
);
134 // Bottom-right vertex (corner)
135 glTexCoord2i(tex
->w
, tex
->h
);
136 glVertex2f(w_half
, h_half
);
138 // Top-right vertex (corner)
139 glTexCoord2i(tex
->w
, 0);
140 glVertex2f(w_half
, -h_half
);
149 //function for displaying a frame of an animation
150 //frames are laid out horizontally
152 int l_displayframe(lua_State
*L
){
153 GLSurface
*tex
= (GLSurface
*)lua_touserdata(L
,1);
154 float x
= (float)lua_tonumber(L
,2);
155 float y
= (float)lua_tonumber(L
,3);
156 int numframes
= lua_tointeger(L
,4);
157 int frame
= lua_tointeger(L
,5);
158 double rot
= lua_tonumber(L
,6);
159 double scale_x
= lua_tonumber(L
,7);
160 double scale_y
= lua_tonumber(L
,8);
161 float alpha
= lua_tonumber(L
, 9)/255.0;
164 return luaL_error(L
, "ERROR: Can't draw. Image is null.");
167 int width
= tex
->w
/numframes
;
168 int frame_offset
= frame
* width
;
170 float w_half
= width
/2.0;
171 float h_half
= tex
->h
/2.0;
173 glColor4f(1.0,1.0,1.0, alpha
);
176 glTranslatef(x
+ w_half
, y
+ h_half
, 0.0f
);
177 glScalef(scale_x
, scale_y
, 1.0f
);
178 glRotatef(rot
, 0.0f
, 0.0f
, -1.0f
);
180 glBindTexture(GL_TEXTURE_RECTANGLE_ARB
, tex
->texture
);
183 // Top-left vertex (corner)
184 glTexCoord2i(frame_offset
, 0);
185 glVertex2f(-w_half
, -h_half
);
187 // Bottom-left vertex (corner)
188 glTexCoord2i(frame_offset
, tex
->h
);
189 glVertex2f(-w_half
, h_half
);
191 // Bottom-right vertex (corner)
192 glTexCoord2i(frame_offset
+ width
, tex
->h
);
193 glVertex2f(w_half
, h_half
);
195 // Top-right vertex (corner)
196 glTexCoord2i(frame_offset
+ width
, 0);
197 glVertex2f(w_half
, -h_half
);
207 int l_show_cursor(lua_State
*L
){
208 bool show
= lua_toboolean(L
, 1);
210 SDL_ShowCursor((show
? SDL_ENABLE
: SDL_DISABLE
));
216 //fills screen with a color
217 int l_fill_screen(lua_State
*L
){
218 glClearColor(lua_tointeger(L
,1)/255.0, lua_tointeger(L
,2)/255.0, lua_tointeger(L
,3)/255.0, 0.0f
);
219 glClear(GL_COLOR_BUFFER_BIT
);
224 //free surface interface
225 int l_delete_image(lua_State
*L
){
226 GLSurface
*tmp
= (GLSurface
*)lua_touserdata(L
,1);
229 return luaL_error(L
, "ERROR: Can't free. Image is null.");
232 glDeleteTextures(1, &(tmp
->texture
));