Fixed some little errors with the drawing functions.
[luagame.git] / funcs_video.cpp
blob5431a58eb1de4bc238dbfe5f79717ec2c03e2b37
1 /*
2 Copyright (c)2006-2008 - Brett Lajzer
4 See LICENSE for license information.
5 */
7 #include <iostream>
9 #include <GL/gl.h>
10 #include <GL/glu.h>
11 #include <SDL/SDL.h>
12 #include <SDL/SDL_image.h>
13 #include <lua.hpp>
14 #include "globals.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;
20 GLuint tex;
22 if (s->format->BytesPerPixel == 4){
23 if (s->format->Rmask == 0x000000ff)
24 texture_format = GL_RGBA;
25 else
26 texture_format = GL_BGRA;
27 } else if (s->format->BytesPerPixel == 3){
28 if (s->format->Rmask == 0x000000ff)
29 texture_format = GL_RGB;
30 else
31 texture_format = GL_BGR;
32 }else{
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 );
42 return tex;
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());
55 if(temp == NULL){
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);
68 }else{
69 lua_pushlightuserdata(L, im->second);
70 lua_pushinteger(L, (lua_Integer)im->second->w);
71 lua_pushinteger(L, (lua_Integer)im->second->h);
73 return 3;
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));
83 delete im->second;
84 image_store.erase(im);
87 return 0;
91 //function for updating the display surface
92 int l_flip(lua_State *L){
93 SDL_GL_SwapBuffers();
94 return 0;
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;
109 if(tex == NULL){
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);
118 glPushMatrix();
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);
124 //draw here
125 glBegin(GL_QUADS);
126 // Top-left vertex (corner)
127 glTexCoord2i(0, 0);
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);
141 glEnd();
143 glPopMatrix();
145 return 0;
149 //function for displaying a frame of an animation
150 //frames are laid out horizontally
151 //frames start at 0
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;
163 if(tex == NULL){
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);
175 glPushMatrix();
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);
181 //draw here
182 glBegin(GL_QUADS);
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);
198 glEnd();
200 glPopMatrix();
202 return 0;
206 //cursor toggler
207 int l_show_cursor(lua_State *L){
208 bool show = lua_toboolean(L, 1);
210 SDL_ShowCursor((show ? SDL_ENABLE : SDL_DISABLE));
212 return 0;
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);
220 return 0;
224 //free surface interface
225 int l_delete_image(lua_State *L){
226 GLSurface *tmp = (GLSurface*)lua_touserdata(L,1);
228 if(tmp == NULL){
229 return luaL_error(L, "ERROR: Can't free. Image is null.");
232 glDeleteTextures(1, &(tmp->texture));
233 delete tmp;
234 lua_pushnil(L);
235 return 1;