From b83e05218a346663fb5e3120773bb1385309d294 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Tue, 3 Nov 2009 02:53:31 +0000 Subject: [PATCH] added ag::loadTexture() and ag::object::setTexture() git-svn-id: svn://anubis/anaglym/trunk@149 99a6e188-d820-4881-8870-2d33a10e2619 --- Engine.cc | 44 +++++++++++++++++++++++++++++++-- Engine.h | 3 +++ ag.cc | 51 +++++++++++++++++++++++++++++++++++---- ag.h | 2 ++ tests/managed_objects.lua | 10 +++++--- 5 files changed, 99 insertions(+), 11 deletions(-) diff --git a/Engine.cc b/Engine.cc index bc01b98..80c594d 100644 --- a/Engine.cc +++ b/Engine.cc @@ -420,6 +420,12 @@ bool Engine::import(const char * name) return false; } +GLuint Engine::loadTexture(const char * name) +{ + FileLoader::Path path("", name); + return m_textureCache.load(path, *m_fileLoader); +} + /* called by SDL when the update timer expires */ Uint32 Engine::updateCallback(Uint32 interval, void * param) { @@ -684,6 +690,7 @@ Engine::Object::Object(bool is_static, OdeWorld & world, m_args = args; for (int i = 0; i < 4; i++) m_color[i] = 1.0f; + m_texture = 0; createManagedObject(); } @@ -760,12 +767,25 @@ void Engine::Object::render() if (m_display_list <= 0) m_display_list = glGenLists(1); glNewList(m_display_list, GL_COMPILE); - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, m_color); GLUquadric * quad = gluNewQuadric(); + if (m_texture != 0) + { + gluQuadricTexture(quad, 1); + glPushAttrib(GL_ENABLE_BIT); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, m_texture); + } + else + { + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, m_color); + } switch (m_geom_type) { case OdeWorld::BOX: { - struct { float norm[3]; float verts[4][3]; } sides[] = { + const static struct { + float norm[3]; + float verts[4][3]; + } sides[] = { { {1, 0, 0}, /* right */ {{1, -1, -1}, {1, 1, -1}, {1, 1, 1}, {1, -1, 1}} }, { {-1, 0, 0}, /* left */ @@ -779,6 +799,9 @@ void Engine::Object::render() { {0, 0, -1}, /* bottom */ {{1, -1, -1}, {-1, -1, -1}, {-1, 1, -1}, {1, 1, -1}} } }; + const float tex_coords[4][2] = { + {0, 0}, {1, 0}, {1, 1}, {0, 1} + }; glBegin(GL_QUADS); float width = (*m_args)[0]; float depth = (*m_args)[1]; @@ -790,6 +813,10 @@ void Engine::Object::render() glNormal3fv(sides[s].norm); for (int v = 0; v < 4; v++) { + if (m_texture != 0) + { + glTexCoord2fv(tex_coords[v]); + } glVertex3f(sides[s].verts[v][0] * width / 2.0, sides[s].verts[v][1] * depth / 2.0, sides[s].verts[v][2] * height / 2.0); @@ -919,6 +946,10 @@ void Engine::Object::render() break; } gluDeleteQuadric(quad); + if (m_texture != 0) + { + glPopAttrib(); + } glEndList(); } @@ -982,6 +1013,15 @@ void Engine::Object::loadPhy(const FileLoader::Path & path) m_ode_object->finalize(); } +void Engine::Object::setTexture(GLuint tex) +{ + if (m_is_managed) + { + m_texture = tex; + render(); + } +} + void Engine::Object::draw() { if (m_is_visible) diff --git a/Engine.h b/Engine.h index 0e2dd9c..4f1b2be 100644 --- a/Engine.h +++ b/Engine.h @@ -65,6 +65,7 @@ class Engine m_color[2] = b; render(); } + void setTexture(GLuint tex); void draw(); @@ -78,6 +79,7 @@ class Engine float m_scale; bool m_is_scaled; bool m_is_managed; + GLuint m_texture; /* for "pre-loaded" objects */ int * m_display_list_refcnt; @@ -130,6 +132,7 @@ class Engine bool isKeyDown(const std::string & key); void exit(); bool import(const char * name); + GLuint loadTexture(const char * name); /* lua services */ int setCamera(lua_State * L); diff --git a/ag.cc b/ag.cc index 5b79fb0..92d9a77 100644 --- a/ag.cc +++ b/ag.cc @@ -42,6 +42,7 @@ namespace ag { "clearEventHandler", clearEventHandler }, { "exit", exit }, { "import", import }, + { "loadTexture", loadTexture }, { "createBox", createBox}, { "createStaticBox", createStaticBox}, @@ -152,6 +153,8 @@ namespace ag lua_setfield(L, -2, "addRelTorque"); lua_pushcfunction(L, object::setColor); lua_setfield(L, -2, "setColor"); + lua_pushcfunction(L, object::setTexture); + lua_setfield(L, -2, "setTexture"); } static int loadModelSpecify(lua_State * L, bool static_data) @@ -316,6 +319,24 @@ namespace ag return 1; } + int loadTexture(lua_State * L) + { + int argc = lua_gettop(L); + if (argc == 1 && lua_isstring(L, 1)) + { + GLuint texture; + if ((texture = g_engine->loadTexture(lua_tostring(L, 1))) != 0) + { + lua_newtable(L); + lua_pushinteger(L, texture); + lua_setfield(L, -2, "id"); + return 1; + } + } + lua_pushnil(L); + return 1; + } + static void addManagedObject(lua_State * L, bool is_static, OdeWorld::GeomType geom_type, refptr< vector > args) { @@ -701,13 +722,13 @@ namespace ag int setColor(lua_State * L) { int argc = lua_gettop(L); - if (argc == 4) + if (argc == 4 && + lua_isnumber(L, 2) && + lua_isnumber(L, 3) && + lua_isnumber(L, 4)) { Engine::Object * obj = getObject(L, 1); - if (obj != NULL && - lua_isnumber(L, 2) && - lua_isnumber(L, 3) && - lua_isnumber(L, 4)) + if (obj != NULL) { obj->setColor(lua_tonumber(L, 2), lua_tonumber(L, 3), @@ -716,5 +737,25 @@ namespace ag } return 0; } + + int setTexture(lua_State * L) + { + int argc = lua_gettop(L); + if (argc == 2 && lua_istable(L, 1) && lua_istable(L, 2)) + { + Engine::Object * obj = getObject(L, 1); + if (obj != NULL) + { + lua_getfield(L, 2, "id"); + if (lua_isnumber(L, -1)) + { + GLuint id = (GLuint) lua_tointeger(L, -1); + obj->setTexture(id); + } + lua_pop(L, 1); + } + } + return 0; + } } } diff --git a/ag.h b/ag.h index 595f91e..debf7ac 100644 --- a/ag.h +++ b/ag.h @@ -28,6 +28,7 @@ namespace ag int clearEventHandler(lua_State * L); int exit(lua_State * L); int import(lua_State * L); + int loadTexture(lua_State * L); int createBox(lua_State * L); int createStaticBox(lua_State * L); @@ -54,6 +55,7 @@ namespace ag int addTorque(lua_State * L); int addRelTorque(lua_State * L); int setColor(lua_State * L); + int setTexture(lua_State * L); } } diff --git a/tests/managed_objects.lua b/tests/managed_objects.lua index 74b6d1d..90342d7 100644 --- a/tests/managed_objects.lua +++ b/tests/managed_objects.lua @@ -2,6 +2,7 @@ ground = ag.createStaticPlane(0, 0, 0, 0, 0, 0) ground:setColor(0.2, 1.0, 0.2) ag.setCamera(10, -10, 10, 0, 0, 0) +crate_texture = ag.loadTexture("crate.png") if (ag.import("rot_camera") ~= true) then ag.println("error importing rot_camera") @@ -19,16 +20,17 @@ end function key_down_event(key) if (key == "b") then - box = ag.createBox(1, 1, 1) + local box = ag.createBox(1, 1, 1) + box:setTexture(crate_texture) init(box) elseif (key == "c") then - cyl = ag.createCylinder(0.5, 1) + local cyl = ag.createCylinder(0.5, 1) init(cyl) elseif (key == "a") then - ccyl = ag.createCapsule(0.5, 1) + local ccyl = ag.createCapsule(0.5, 1) init(ccyl) elseif (key == "s") then - sphere = ag.createSphere(0.8) + local sphere = ag.createSphere(0.8) init(sphere) elseif (key == "q") then ag.exit()