From patchwork Tue May 22 12:35:14 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: alexandros.frantzis@linaro.org X-Patchwork-Id: 8867 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 9490924009 for ; Tue, 22 May 2012 12:35:19 +0000 (UTC) Received: from mail-gh0-f180.google.com (mail-gh0-f180.google.com [209.85.160.180]) by fiordland.canonical.com (Postfix) with ESMTP id 38BA5A182E9 for ; Tue, 22 May 2012 12:35:19 +0000 (UTC) Received: by ghbz12 with SMTP id z12so975952ghb.11 for ; Tue, 22 May 2012 05:35:18 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf :content-type:mime-version:x-launchpad-project:x-launchpad-branch :x-launchpad-message-rationale:x-launchpad-branch-revision-number :x-launchpad-notification-type:to:from:subject:message-id:date :reply-to:sender:errors-to:precedence:x-generated-by :x-launchpad-hash:x-gm-message-state; bh=xNMfXp+StR6uuCYgIUl1S+UW7DzTD1dmNH7h6/qjG6c=; b=mzux5ceK4XF0zVpienZdTZYPsFsCKkg07iYWeAa8CXmC1l5PpmeV+VUP1x4ToW/jmB tn7vU4FJc1KVwz9UTOKS3BOYqxnT00NZak0+fZrVoAFCuL2hM3+sUeex1eDcO2QLdycb 7xxUkKQk8CBIMDeFaIcwU/iKv4uo7038xsHuOzqw5Tjnue9QTxQx9gYkuwrqHtJGxC8a VSe+xaNPfU/6Dxz0q2uB245swO94O0XCCFIckkV5wTobQSQWuuWM70awg7Muy1chVEoz 8KTfyp3+jpMdUMpinXwh7BtJdFUC2IDc2UPXTDc8KUCUAXqLomOtPal8ZiLG4WPIl3e7 VBuQ== Received: by 10.50.163.99 with SMTP id yh3mr9163750igb.53.1337690118302; Tue, 22 May 2012 05:35:18 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.231.35.72 with SMTP id o8csp363176ibd; Tue, 22 May 2012 05:35:16 -0700 (PDT) Received: by 10.180.80.97 with SMTP id q1mr34864551wix.13.1337690115628; Tue, 22 May 2012 05:35:15 -0700 (PDT) Received: from indium.canonical.com (indium.canonical.com. [91.189.90.7]) by mx.google.com with ESMTPS id g5si2681502wel.159.2012.05.22.05.35.14 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 22 May 2012 05:35:15 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.7 as permitted sender) client-ip=91.189.90.7; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.7 as permitted sender) smtp.mail=bounces@canonical.com Received: from ackee.canonical.com ([91.189.89.26]) by indium.canonical.com with esmtp (Exim 4.71 #1 (Debian)) id 1SWoJ0-0003qF-EC for ; Tue, 22 May 2012 12:35:14 +0000 Received: from ackee.canonical.com (localhost [127.0.0.1]) by ackee.canonical.com (Postfix) with ESMTP id 5E926E049E for ; Tue, 22 May 2012 12:35:14 +0000 (UTC) MIME-Version: 1.0 X-Launchpad-Project: glmark2 X-Launchpad-Branch: ~glmark2-dev/glmark2/trunk X-Launchpad-Message-Rationale: Subscriber X-Launchpad-Branch-Revision-Number: 214 X-Launchpad-Notification-Type: branch-revision To: Linaro Patch Tracker From: noreply@launchpad.net Subject: [Branch ~glmark2-dev/glmark2/trunk] Rev 214: SceneTexture: Add support for additional models and textures. Message-Id: <20120522123514.27736.70282.launchpad@ackee.canonical.com> Date: Tue, 22 May 2012 12:35:14 -0000 Reply-To: noreply@launchpad.net Sender: bounces@canonical.com Errors-To: bounces@canonical.com Precedence: bulk X-Generated-By: Launchpad (canonical.com); Revision="15275"; Instance="launchpad-lazr.conf" X-Launchpad-Hash: 8a65cdc24627dd3857444f8f76a64b87acbcda31 X-Gm-Message-State: ALoCoQnYUA1uu0l79eiXyUKmeQjUDgf0mR3MT0l3EXLZgxBMJp98Yho6zsODN99Ljarz2/fm+v5O Merge authors: Jesse Barker (jesse-barker) Related merge proposals: https://code.launchpad.net/~glmark2-dev/glmark2/texture-models/+merge/106759 proposed by: Jesse Barker (jesse-barker) ------------------------------------------------------------ revno: 214 [merge] committer: Alexandros Frantzis branch nick: trunk timestamp: Tue 2012-05-22 15:21:27 +0300 message: SceneTexture: Add support for additional models and textures. This patchset adds support for models apart from the cube, and textures apart from the crate base. Also includes 3 new square textures cropped from hi-res NASA images for use in the texture mapping scene. It also adds a new Model::calculate_texcoords() method which uses positional spherical mapping to generate texcoords for the model. added: data/textures/nasa1.png data/textures/nasa2.png data/textures/nasa3.png modified: src/model.cpp src/model.h src/scene-build.cpp src/scene-bump.cpp src/scene-desktop.cpp src/scene-effect-2d.cpp src/scene-pulsar.cpp src/scene-shading.cpp src/scene-texture.cpp src/scene.h src/text-renderer.cpp src/texture.cpp src/texture.h --- lp:glmark2 https://code.launchpad.net/~glmark2-dev/glmark2/trunk You are subscribed to branch lp:glmark2. To unsubscribe from this branch go to https://code.launchpad.net/~glmark2-dev/glmark2/trunk/+edit-subscription === added file 'data/textures/nasa1.png' Binary files data/textures/nasa1.png 1970-01-01 00:00:00 +0000 and data/textures/nasa1.png 2012-05-15 18:35:35 +0000 differ === added file 'data/textures/nasa2.png' Binary files data/textures/nasa2.png 1970-01-01 00:00:00 +0000 and data/textures/nasa2.png 2012-05-15 18:35:35 +0000 differ === added file 'data/textures/nasa3.png' Binary files data/textures/nasa3.png 1970-01-01 00:00:00 +0000 and data/textures/nasa3.png 2012-05-15 18:35:35 +0000 differ === modified file 'src/model.cpp' --- src/model.cpp 2011-11-16 10:07:47 +0000 +++ src/model.cpp 2012-05-18 13:23:26 +0000 @@ -28,6 +28,7 @@ #include "options.h" #include "util.h" #include "float.h" +#include "math.h" #include #include #include @@ -35,7 +36,6 @@ using std::string; using std::vector; using LibMatrix::vec3; -using LibMatrix::vec2; using LibMatrix::uvec3; #define read_or_fail(file, dst, size) do { \ @@ -222,6 +222,34 @@ } } +void +Model::calculate_texcoords() +{ + // Since the model didn't come with texcoords, and we don't actually know + // if it came with normals, either, we'll use positional spherical mapping + // to generate texcoords for the model. See: + // http://www.mvps.org/directx/articles/spheremap.htm for more details. + vec3 centerVec = maxVec_ + minVec_; + centerVec *= 0.5; + + for (std::vector::iterator iter = objects_.begin(); + iter != objects_.end(); + iter++) + { + Object &object = *iter; + for (vector::iterator vertexIt = object.vertices.begin(); + vertexIt != object.vertices.end(); + vertexIt++) + { + Vertex& curVertex = *vertexIt; + vec3 vnorm(curVertex.v - centerVec); + vnorm.normalize(); + curVertex.t.x(asinf(vnorm.x()) / M_PI + 0.5); + curVertex.t.y(asinf(vnorm.y()) / M_PI + 0.5); + } + } +} + /** * Calculates the normal vectors of the model vertices. */ @@ -443,6 +471,7 @@ object->vertices[i].t.y(f[1]); } } + gotTexcoords_ = true; break; //----------- Skip unknow chunks ------------ === modified file 'src/model.h' --- src/model.h 2011-11-16 10:07:47 +0000 +++ src/model.h 2012-05-15 12:44:24 +0000 @@ -77,11 +77,13 @@ AttribTypeCustom } AttribType; - Model() {} + Model() : gotTexcoords_(false) {} ~Model() {} bool load(const std::string& name); + bool needTexcoords() const { return !gotTexcoords_; } + void calculate_texcoords(); void calculate_normals(); void convert_to_mesh(Mesh &mesh); void convert_to_mesh(Mesh &mesh, @@ -90,6 +92,8 @@ const LibMatrix::vec3& maxVec() const { return maxVec_; } static const ModelMap& find_models(); private: + // If the model we loaded contained texcoord data... + bool gotTexcoords_; struct Face { uint32_t a, b, c; uint16_t face_flags; === modified file 'src/scene-build.cpp' --- src/scene-build.cpp 2011-12-08 11:09:09 +0000 +++ src/scene-build.cpp 2012-05-22 08:46:33 +0000 @@ -132,6 +132,12 @@ orientationAngle_ = -90.0; orientationVec_ = vec3(1.0, 0.0, 0.0); } + else if (whichModel == "armadillo") + { + orientModel_ = true; + orientationAngle_ = 180.0; + orientationVec_ = vec3(0.0, 1.0, 0.0); + } model.calculate_normals(); === modified file 'src/scene-bump.cpp' --- src/scene-bump.cpp 2011-12-08 11:09:09 +0000 +++ src/scene-bump.cpp 2012-05-15 18:38:47 +0000 @@ -154,7 +154,7 @@ attrib_locations.push_back(program_["texcoord"].location()); mesh_.set_attrib_locations(attrib_locations); - Texture::load(GLMARK_DATA_PATH"/textures/asteroid-normal-map.png", &texture_, + Texture::load("asteroid-normal-map", &texture_, GL_NEAREST, GL_NEAREST, 0); } @@ -206,7 +206,7 @@ attrib_locations.push_back(program_["tangent"].location()); mesh_.set_attrib_locations(attrib_locations); - Texture::load(GLMARK_DATA_PATH"/textures/asteroid-normal-map-tangent.png", &texture_, + Texture::load("asteroid-normal-map-tangent", &texture_, GL_NEAREST, GL_NEAREST, 0); } @@ -260,7 +260,7 @@ attrib_locations.push_back(program_["tangent"].location()); mesh_.set_attrib_locations(attrib_locations); - Texture::load(GLMARK_DATA_PATH"/textures/asteroid-height-map.png", &texture_, + Texture::load("asteroid-height-map", &texture_, GL_NEAREST, GL_NEAREST, 0); } @@ -270,7 +270,7 @@ Scene::setup(); const std::string &bump_render = options_["bump-render"].value; - + Texture::find_textures(); Model::find_models(); if (bump_render == "normals") setup_model_normals(); === modified file 'src/scene-desktop.cpp' --- src/scene-desktop.cpp 2012-05-07 12:45:34 +0000 +++ src/scene-desktop.cpp 2012-05-15 18:38:47 +0000 @@ -726,12 +726,12 @@ }; int RenderWindowBlur::use_count = 0; -RenderClearImage RenderWindowBlur::window_contents_(GLMARK_DATA_PATH"/textures/desktop-window.png"); +RenderClearImage RenderWindowBlur::window_contents_("desktop-window"); int RenderWindowShadow::use_count = 0; -RenderClearImage RenderWindowShadow::window_contents_(GLMARK_DATA_PATH"/textures/desktop-window.png"); -RenderClearImage RenderWindowShadow::shadow_h_(GLMARK_DATA_PATH"/textures/desktop-shadow.png"); -RenderClearImage RenderWindowShadow::shadow_v_(GLMARK_DATA_PATH"/textures/desktop-shadow.png"); -RenderClearImage RenderWindowShadow::shadow_corner_(GLMARK_DATA_PATH"/textures/desktop-shadow-corner.png"); +RenderClearImage RenderWindowShadow::window_contents_("desktop-window"); +RenderClearImage RenderWindowShadow::shadow_h_("desktop-shadow"); +RenderClearImage RenderWindowShadow::shadow_v_("desktop-shadow"); +RenderClearImage RenderWindowShadow::shadow_corner_("desktop-shadow-corner"); /******************************* * SceneDesktop implementation * @@ -748,7 +748,7 @@ std::vector windows; SceneDesktopPrivate(Canvas &canvas) : - screen(canvas), desktop(GLMARK_DATA_PATH"/textures/effect-2d.png") {} + screen(canvas), desktop("effect-2d") {} ~SceneDesktopPrivate() { Util::dispose_pointer_vector(windows); } @@ -810,6 +810,9 @@ blur_radius = Util::fromString(options_["blur-radius"].value); shadow_size = Util::fromString(options_["shadow-size"].value); + // Make sure the Texture object knows where to find our images. + Texture::find_textures(); + /* Ensure we get a transparent clear color for all following operations */ glClearColor(0.0, 0.0, 0.0, 0.0); glDisable(GL_DEPTH_TEST); === modified file 'src/scene-effect-2d.cpp' --- src/scene-effect-2d.cpp 2012-01-26 17:36:24 +0000 +++ src/scene-effect-2d.cpp 2012-05-15 18:38:47 +0000 @@ -281,7 +281,7 @@ bool SceneEffect2D::load() { - Texture::load(GLMARK_DATA_PATH"/textures/effect-2d.png", &texture_, + Texture::load("effect-2d", &texture_, GL_NEAREST, GL_NEAREST, 0); running_ = false; @@ -299,6 +299,8 @@ { Scene::setup(); + Texture::find_textures(); + static const std::string vtx_shader_filename(GLMARK_DATA_PATH"/shaders/effect-2d.vert"); std::vector kernel; === modified file 'src/scene-pulsar.cpp' --- src/scene-pulsar.cpp 2012-05-07 12:45:34 +0000 +++ src/scene-pulsar.cpp 2012-05-15 18:38:47 +0000 @@ -115,7 +115,8 @@ if (options_["texture"].value == "true") { frg_shader_filename = GLMARK_DATA_PATH"/shaders/light-basic-tex.frag"; - Texture::load(GLMARK_DATA_PATH"/textures/crate-base.png", &texture_, + Texture::find_textures(); + Texture::load("crate-base", &texture_, GL_NEAREST, GL_NEAREST, 0); } else { === modified file 'src/scene-shading.cpp' --- src/scene-shading.cpp 2011-12-08 11:09:09 +0000 +++ src/scene-shading.cpp 2012-05-22 08:46:33 +0000 @@ -212,6 +212,12 @@ orientationAngle_ = -90.0; orientationVec_ = vec3(1.0, 0.0, 0.0); } + else if (whichModel == "armadillo") + { + orientModel_ = true; + orientationAngle_ = 180.0; + orientationVec_ = vec3(0.0, 1.0, 0.0); + } model.calculate_normals(); === modified file 'src/scene-texture.cpp' --- src/scene-texture.cpp 2011-12-08 11:09:09 +0000 +++ src/scene-texture.cpp 2012-05-22 08:46:33 +0000 @@ -34,11 +34,50 @@ #include "util.h" #include +using LibMatrix::vec3; +using std::string; + SceneTexture::SceneTexture(Canvas &pCanvas) : Scene(pCanvas, "texture") { + const ModelMap& modelMap = Model::find_models(); + string optionDesc("Which model to use ["); + for (ModelMap::const_iterator modelIt = modelMap.begin(); + modelIt != modelMap.end(); + modelIt++) + { + static bool doSeparator(false); + if (doSeparator) + { + optionDesc += ", "; + } + const std::string& curName = modelIt->first; + optionDesc += curName; + doSeparator = true; + } + optionDesc += "]"; + options_["model"] = Scene::Option("model", "cube", + optionDesc); options_["texture-filter"] = Scene::Option("texture-filter", "nearest", "[nearest, linear, linear-shader, mipmap]"); + optionDesc = "Which texture to use ["; + const TextureMap& textureMap = Texture::find_textures(); + for (TextureMap::const_iterator textureIt = textureMap.begin(); + textureIt != textureMap.end(); + textureIt++) + { + static bool doSeparator(false); + if (doSeparator) + { + optionDesc += ", "; + } + const std::string& curName = textureIt->first; + optionDesc += curName; + doSeparator = true; + } + optionDesc += "]"; + options_["texture"] = Scene::Option("texture", "crate-base", + optionDesc); } SceneTexture::~SceneTexture() @@ -48,16 +87,6 @@ bool SceneTexture::load() { - Model::find_models(); - Model model; - - if(!model.load("cube")) - return false; - - model.calculate_normals(); - model.convert_to_mesh(mesh_); - mesh_.build_vbo(); - rotationSpeed_ = LibMatrix::vec3(36.0f, 36.0f, 36.0f); running_ = false; @@ -104,7 +133,8 @@ mag_filter = GL_LINEAR; } - Texture::load(GLMARK_DATA_PATH"/textures/crate-base.png", &texture_, + const string& whichTexture(options_["texture"].value); + Texture::load(whichTexture, &texture_, min_filter, mag_filter, 0); // Load shaders @@ -129,14 +159,69 @@ return; } + Model model; + const string& whichModel(options_["model"].value); + bool modelLoaded = model.load(whichModel); + if(!modelLoaded) + return; + + // Now that we're successfully loaded, there are a few quirks about + // some of the known models that we need to account for. The draw + // logic for the scene wants to rotate the model around the Y axis. + // Most of our models are described this way. Some need adjustment + // (an additional rotation that gets the model into the correct + // orientation). + // + // Here's a summary: + // + // Angel rotates around the Y axis + // Armadillo rotates around the Y axis + // Buddha rotates around the X axis + // Bunny rotates around the Y axis + // Dragon rotates around the X axis + // Horse rotates around the Y axis + if (whichModel == "buddha" || whichModel == "dragon") + { + orientModel_ = true; + orientationAngle_ = -90.0; + orientationVec_ = vec3(1.0, 0.0, 0.0); + } + else if (whichModel == "armadillo") + { + orientModel_ = true; + orientationAngle_ = 180.0; + orientationVec_ = vec3(0.0, 1.0, 0.0); + } + + if (model.needTexcoords()) + model.calculate_texcoords(); + model.calculate_normals(); + model.convert_to_mesh(mesh_); + mesh_.build_vbo(); + + // Calculate a projection matrix that is a good fit for the model + vec3 maxVec = model.maxVec(); + vec3 minVec = model.minVec(); + vec3 diffVec = maxVec - minVec; + centerVec_ = maxVec + minVec; + centerVec_ /= 2.0; + float diameter = diffVec.length(); + radius_ = diameter / 2; + float fovy = 2.0 * atanf(radius_ / (2.0 + radius_)); + fovy /= M_PI; + fovy *= 180.0; + float aspect(static_cast(canvas_.width())/static_cast(canvas_.height())); + perspective_.setIdentity(); + perspective_ *= LibMatrix::Mat4::perspective(fovy, aspect, 2.0, 2.0 + diameter); + + program_.start(); + std::vector attrib_locations; attrib_locations.push_back(program_["position"].location()); attrib_locations.push_back(program_["normal"].location()); attrib_locations.push_back(program_["texcoord"].location()); mesh_.set_attrib_locations(attrib_locations); - program_.start(); - currentFrame_ = 0; rotation_ = LibMatrix::vec3(); running_ = true; @@ -170,12 +255,15 @@ { // Load the ModelViewProjectionMatrix uniform in the shader LibMatrix::Stack4 model_view; - LibMatrix::mat4 model_view_proj(canvas_.projection()); - - model_view.translate(0.0f, 0.0f, -5.0f); + model_view.translate(-centerVec_.x(), -centerVec_.y(), -(centerVec_.z() + 2.5 + radius_)); model_view.rotate(rotation_.x(), 1.0f, 0.0f, 0.0f); model_view.rotate(rotation_.y(), 0.0f, 1.0f, 0.0f); model_view.rotate(rotation_.z(), 0.0f, 0.0f, 1.0f); + if (orientModel_) + { + model_view.rotate(orientationAngle_, orientationVec_.x(), orientationVec_.y(), orientationVec_.z()); + } + LibMatrix::mat4 model_view_proj(perspective_); model_view_proj *= model_view.getCurrent(); program_["ModelViewProjectionMatrix"] = model_view_proj; === modified file 'src/scene.h' --- src/scene.h 2012-04-27 18:00:45 +0000 +++ src/scene.h 2012-05-15 12:46:43 +0000 @@ -281,6 +281,12 @@ Program program_; Mesh mesh_; GLuint texture_; + float radius_; + bool orientModel_; + float orientationAngle_; + LibMatrix::vec3 orientationVec_; + LibMatrix::mat4 perspective_; + LibMatrix::vec3 centerVec_; LibMatrix::vec3 rotation_; LibMatrix::vec3 rotationSpeed_; }; === modified file 'src/text-renderer.cpp' --- src/text-renderer.cpp 2012-01-13 18:36:53 +0000 +++ src/text-renderer.cpp 2012-05-15 18:38:47 +0000 @@ -67,7 +67,8 @@ glUseProgram(prev_program); /* Load the glyph texture atlas */ - Texture::load(GLMARK_DATA_PATH"/textures/glyph-atlas.png", &texture_, + Texture::find_textures(); + Texture::load("glyph-atlas", &texture_, GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR,0); } === modified file 'src/texture.cpp' --- src/texture.cpp 2011-11-08 21:41:23 +0000 +++ src/texture.cpp 2012-05-15 18:38:47 +0000 @@ -28,6 +28,7 @@ #include #include #include +#include class PNGState { @@ -177,9 +178,24 @@ } } +namespace TexturePrivate +{ +TextureMap textureMap; +} + bool -Texture::load(const std::string &filename, GLuint *pTexture, ...) +Texture::load(const std::string &textureName, GLuint *pTexture, ...) { + // Make sure the named texture is in the map. + TextureMap::const_iterator textureIt = TexturePrivate::textureMap.find(textureName); + if (textureIt == TexturePrivate::textureMap.end()) + { + return false; + } + + // Pull the pathname out of the descriptor and use it for the PNG load. + TextureDescriptor* desc = textureIt->second; + const std::string& filename = desc->pathname(); ImageData image; if (!image.load_png(filename)) @@ -199,3 +215,46 @@ return true; } + +const TextureMap& +Texture::find_textures() +{ + using std::vector; + using std::string; + if (!TexturePrivate::textureMap.empty()) + { + return TexturePrivate::textureMap; + } + vector pathVec; + string dataDir(GLMARK_DATA_PATH"/textures"); + Util::list_files(dataDir, pathVec); + // Now that we have a list of all of the model files available to us, + // let's go through and pull out the names and what format they're in + // so the scene can decide which ones to use. + for(vector::const_iterator pathIt = pathVec.begin(); + pathIt != pathVec.end(); + pathIt++) + { + const string& curPath = *pathIt; + string::size_type namePos(0); + string::size_type slashPos = curPath.rfind("/"); + if (slashPos != string::npos) + { + // Advance to the first character after the last slash + namePos = slashPos + 1; + } + + string::size_type extPos = curPath.rfind(".png"); + if (extPos == string::npos) + { + // We can't trivially determine it's a PNG file so skip it... + continue; + } + + string name(curPath, namePos, extPos - namePos); + TextureDescriptor* desc = new TextureDescriptor(name, curPath); + TexturePrivate::textureMap.insert(std::make_pair(name, desc)); + } + + return TexturePrivate::textureMap; +} === modified file 'src/texture.h' --- src/texture.h 2011-11-08 21:41:23 +0000 +++ src/texture.h 2012-05-15 18:38:47 +0000 @@ -27,11 +27,50 @@ #include "gl-headers.h" #include +#include + +/** + * A descriptor for a texture file. + */ +class TextureDescriptor +{ + std::string name_; + std::string pathname_; + TextureDescriptor(); +public: + TextureDescriptor(const std::string& name, const std::string& pathname) : + name_(name), + pathname_(pathname) {} + ~TextureDescriptor() {} + const std::string& pathname() const { return pathname_; } +}; + +typedef std::map TextureMap; class Texture { public: - static bool load(const std::string &filename, GLuint *pTexture, ...); + /** + * Load a texture by name. + * + * You must initialize the available texture collection using + * Texture::find_textures() before using this method. + * + * @name: the texture name + * + * @return: true if the operation succeeded, false otherwise + */ + static bool load(const std::string &name, GLuint *pTexture, ...); + /** + * Locate all available textures. + * + * This method scans the built-in data paths and builds a database of usable + * textures available to scenes. Map is available on a read-only basis to + * scenes that might find it useful for listing textures, etc. + * + * @return: a map containing information about the located textures + */ + static const TextureMap& find_textures(); }; #endif