First commit of LuaGame with an OpenGL backend.
[luagame.git] / funcs_video.cpp
blob1093eaf93008df7f83b506a70d5d0f051f750e93
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.");
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);
108 if(tex == NULL){
109 return luaL_error(L, "ERROR: Can't draw. Image is null.");
112 float w_half = tex->w/2.0;
113 float h_half = tex->h/2.0;
115 glPushMatrix();
116 glTranslatef(x + w_half, y + h_half, 0.0f);
117 glScalef(scale_x, scale_y, 1.0f);
118 glRotatef(rot, 0.0f, 0.0f, -1.0f);
120 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex->texture);
121 //draw here
122 glBegin(GL_QUADS);
123 // Top-left vertex (corner)
124 glTexCoord2i(0, 0);
125 glVertex2f(-w_half, -h_half);
127 // Bottom-left vertex (corner)
128 glTexCoord2i(0, tex->h);
129 glVertex2f(-w_half, h_half);
131 // Bottom-right vertex (corner)
132 glTexCoord2i(tex->w, tex->h);
133 glVertex2f(w_half, h_half);
135 // Top-right vertex (corner)
136 glTexCoord2i(tex->w, 0);
137 glVertex2f(w_half, -h_half);
138 glEnd();
140 glPopMatrix();
142 return 0;
146 //function for displaying a frame of an animation
147 //frames are laid out horizontally
148 //frames start at 0
149 int l_displayframe(lua_State *L){
150 GLSurface *tex = (GLSurface*)lua_touserdata(L,1);
151 float x = (float)lua_tonumber(L,2);
152 float y = (float)lua_tonumber(L,3);
153 int numframes = lua_tointeger(L,4);
154 int frame = lua_tointeger(L,5);
155 double rot = lua_tonumber(L,6);
156 double scale_x = lua_tonumber(L,7);
157 double scale_y = lua_tonumber(L,8);
159 if(tex == NULL){
160 return luaL_error(L, "ERROR: Can't draw. Image is null.");
163 int width = tex->w/numframes;
164 int frame_offset = frame * width;
166 float w_half = width/2.0;
167 float h_half = tex->h/2.0;
169 glPushMatrix();
170 glTranslatef(x + w_half, y + h_half, 0.0f);
171 glScalef(scale_x, scale_y, 1.0f);
172 glRotatef(rot, 0.0f, 0.0f, -1.0f);
174 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex->texture);
175 //draw here
176 glBegin(GL_QUADS);
177 // Top-left vertex (corner)
178 glTexCoord2i(frame_offset, 0);
179 glVertex2f(-w_half, -h_half);
181 // Bottom-left vertex (corner)
182 glTexCoord2i(frame_offset, tex->h);
183 glVertex2f(-w_half, h_half);
185 // Bottom-right vertex (corner)
186 glTexCoord2i(frame_offset + width, tex->h);
187 glVertex2f(w_half, h_half);
189 // Top-right vertex (corner)
190 glTexCoord2i(frame_offset + width, 0);
191 glVertex2f(w_half, -h_half);
192 glEnd();
194 glPopMatrix();
196 return 0;
200 //cursor toggler
201 int l_show_cursor(lua_State *L){
202 bool show = lua_toboolean(L, 1);
204 SDL_ShowCursor((show ? SDL_ENABLE : SDL_DISABLE));
206 return 0;
210 //fills screen with a color
211 int l_fill_screen(lua_State *L){
212 glClearColor(lua_tointeger(L,1)/255.0, lua_tointeger(L,2)/255.0, lua_tointeger(L,3)/255.0, 0.0f);
213 glClear(GL_COLOR_BUFFER_BIT);
214 return 0;
218 //free surface interface
219 int l_delete_image(lua_State *L){
220 GLSurface *tmp = (GLSurface*)lua_touserdata(L,1);
222 if(tmp == NULL){
223 return luaL_error(L, "ERROR: Can't free. Image is null.");
226 glDeleteTextures(1, &(tmp->texture));
227 delete tmp;
228 lua_pushnil(L);
229 return 1;