From e26a28538e34549aee857362ffea9f8709d1ed9d Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Sun, 19 Jul 2009 14:25:22 +0100 Subject: [PATCH] Render models with textures properly --- buildings/white_house/cube2_auv.png | Bin 0 -> 4615 bytes buildings/white_house/house.mtl | 3 +- buildings/white_house/house.obj | 124 +++++++++++++++++++++------- buildings/white_house/house.wings | Bin 501 -> 964 bytes include/ITexture.hpp | 6 +- include/ModelViewer.hpp | 2 +- src/Editor.cpp | 5 +- src/Mesh.cpp | 52 ++++++------ src/Model.cpp | 14 ++-- src/ModelViewer.cpp | 7 ++ src/Texture.cpp | 14 ++++ 11 files changed, 165 insertions(+), 62 deletions(-) create mode 100644 buildings/white_house/cube2_auv.png diff --git a/buildings/white_house/cube2_auv.png b/buildings/white_house/cube2_auv.png new file mode 100644 index 0000000000000000000000000000000000000000..7dc915f56e603b54728919c50c8d58bcdd5f05e2 GIT binary patch literal 4615 zcmeHK?N3uz7(cXttVkNtv8dCOZHSq5(@i7On(`tGZw62V8mG1>xQZipm?@%^7MNjV zi73iYCeZnY2(5K1lx?oJLL#dXTa~w57OtdBpinPj-|TJg-MQJ9{R8`A`stkKJkRrc zp7YE3JvX;5J2NGMvw{Nvh)7FK-UR>)Zdo8K6fTYvLtX$PAEhNH?mltZjwNbZQjP}~ zytp#G|4!MucO#a`{=9G@=KIDti9GVV@FQJjr2O?SmBW6~z{6ljPk$Gz;- zhAH_RH#)7stqwQ>loTcc<0sgfmWLr=#%48U9f2iih3GuF5V0^2u^ z2i)Mlcb;;il#{@SXgUqI5s~71;IkQe)ezm~k6koZ5<;iCmB$=DldRf3(Aai^aJa*} zq`+5g;#Wdjg*aP{oKRzy_v(`2(xMD}c3)N0QYGJ!Pb~;FcRP^o546=m3+&ddH_r$Z z?Wh$3K4%G*fhu%PwNA@3@@L{?5gRfwGr9>LSewNk4 zy=8qc}7JdoN+sjfze*R@=v8 ztK^=Q`LR9dd$?_RRg{5&+{!=__sdRZN>8sBLWoDDMF+?)4v$g3iqO4Ovjn@BB#_xMqSu@0oP{Y#MeuGlo4K7xZa9PB46=yAFpTMRTO5aS_1i8E5wyn9xQ+Jl{x=g{sxuF54?__c|b3lX}=h z{8vs=uF%Lkz4OG|;>j5xqYsXJd2BkX7s*8@Oh~wRatxlaN2ZU{=HHRr_=yezo;AVd z`0C9z%H&qBH3Or-_XI|5AKp(b99hiefLDGW+h zcEeS$hWBQG8CkRw#c%1(LOzrsSjxWijbIZ`n?T;oI1KqHuo1Q>&gV$L^wq4BuumER)rxB1-U}^-0<9|LV aH2dcx4>mtcN{)sEFEV}* zL1hL}nT4Zx-%HYlHtBRD3I_7p=H7Si$+_pIMB`N?PUv>o!7+_D5kj0Ms7R_73{q@V zkXURM$SO^QOEin9G-Ux@cr6B7n}_oCh6O(}%KM$ON4DJGtGplGv2xL-7k=3E!jH%3 zu}hh{a`@e^V`sI5iUgvT2}YR1GOQUKgKxai54^Qs9&IfBHrWmC*M7Wi>+qZ0!5}yf zXAFyMjfaA-KZ@AVrq%^M^Yiku@8g_X`|Df~TmVoRCxAD?ayWB$HypgNC7`Z4F)qJ}nf zx8K+fIOR;hCFJ%>5f{gNw|B638NhW1=)?yT^P>Mm4ktTmsGlRU3p!M@(pI)%4w66SJ2* z=GVHxr+#eS_VFzY@bU2rCkg?dQwne2ck0GP5*0(i(D##3uP#os?W}huB@xEnFtP zg)!H0wv8=P33#5}Xh}DT8(5pwsus!Gda;si)G@ptz~yYAshcW&qsUHZdV}P(DmX0L m##m9a%ZA|!OiXympbe+RO1MaT4yb};HnK3WhVdJ}<5=9B{?fq! literal 501 zcmV_-u45x*|moq@23Y9T~WNG+26roy~`CE|S8;FBVz5UWtLw1dzE{QdpAzgsOzF^l?hzaaJ&Oacq~AP;o`wd)^7}>i#BOHqeb( z$-cvOS2KyN6q-$mZC}Xz@uSs=fe%+J+s<9{vGH=d9Sr^--6(8IW6FI??X3P%?v6RP rlbNDy%NC6}t9jF5KGbmd_j~#KMV^`*TfFQJxE(K~bF-^o0U~d$akKHr diff --git a/include/ITexture.hpp b/include/ITexture.hpp index e2db00e..6dc23d2 100644 --- a/include/ITexture.hpp +++ b/include/ITexture.hpp @@ -19,6 +19,7 @@ #define INC_ITEXTURE_HPP #include "Platform.hpp" +#include "IResource.hpp" #include @@ -38,6 +39,9 @@ typedef shared_ptr ITexturePtr; // Load a texture and return a pointer to // A texture will only be loaded at most once no matter how many // times this is called -ITexturePtr loadTexture(const std::string& aFileName); +ITexturePtr loadTexture(const string& aFileName); + +// Load a texture from a resource +ITexturePtr loadTexture(IResourcePtr aRes, const string& aFileName); #endif diff --git a/include/ModelViewer.hpp b/include/ModelViewer.hpp index aac186b..14befbd 100644 --- a/include/ModelViewer.hpp +++ b/include/ModelViewer.hpp @@ -30,7 +30,7 @@ public: ModelViewer(int x, int y, int w, int h); ~ModelViewer(); - void setModel(IModelPtr aModel) { myModel = aModel; } + void setModel(IModelPtr aModel); // Fl_Gl_Window interface void draw(); diff --git a/src/Editor.cpp b/src/Editor.cpp index 3868b62..2ca420d 100644 --- a/src/Editor.cpp +++ b/src/Editor.cpp @@ -110,6 +110,10 @@ namespace { { theToolMenu->label(theToolMenu->text()); theEditor->setTool(aTool); + + if (aTool == Editor::BUILDING_TOOL) { + theModelViewer->setModel(loadBuilding("white_house")->model()); + } } void onSaveClick(Fl_Widget* aWidget) @@ -128,7 +132,6 @@ void addEditorGUI() theToolMenu->label("Track"); theModelViewer = new ModelViewer(0, 40, panelW, 200); - theModelViewer->setModel(loadBuilding("white_house")->model()); theSaveButton = new Fl_Button(0, 248, panelW, 25, "Save"); theSaveButton->callback(onSaveClick); diff --git a/src/Mesh.cpp b/src/Mesh.cpp index d3e2a02..3d77f00 100644 --- a/src/Mesh.cpp +++ b/src/Mesh.cpp @@ -227,28 +227,31 @@ Material::Material() } void Material::apply() const -{ - glDisable(GL_COLOR_MATERIAL); - +{ if (texture) { glEnable(GL_TEXTURE_2D); texture->bind(); + + glEnable(GL_COLOR_MATERIAL); + glColor3f(1.0f, 1.0f, 1.0f); } - else + else { + glDisable(GL_COLOR_MATERIAL); glDisable(GL_TEXTURE_2D); - float diffuse[] = { diffuseR, diffuseG, diffuseB, 1.0 }; - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse); - - float ambient[] = { ambientR, ambientG, ambientB, 1.0 }; - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient); - - // Note we're ignoring the specular values in the model - float specular[] = { 0, 0, 0, 1.0 }; - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular); - - float emission[] = { 0, 0, 0, 1 }; - glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, emission); + float diffuse[] = { diffuseR, diffuseG, diffuseB, 1.0 }; + glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse); + + float ambient[] = { ambientR, ambientG, ambientB, 1.0 }; + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient); + + // Note we're ignoring the specular values in the model + float specular[] = { 0, 0, 0, 1.0 }; + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular); + + float emission[] = { 0, 0, 0, 1 }; + glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, emission); + } } // Simple implementation using display lists @@ -350,7 +353,7 @@ namespace { if (buf->hasTexture) { vd->tx = buf->texCoords[i].x; - vd->ty = buf->texCoords[i].y; + vd->ty = 1.0f - buf->texCoords[i].y; } if (!buf->hasMaterial) { @@ -411,11 +414,6 @@ void VertexArrayMesh::render() const glDisable(GL_BLEND); - if (hasTexture) - glEnable(GL_TEXTURE_2D); - else - glDisable(GL_TEXTURE_2D); - if (hasMaterial) myMaterial.apply(); else { @@ -425,6 +423,12 @@ void VertexArrayMesh::render() const glColorPointer(3, GL_FLOAT, sizeof(VertexData), reinterpret_cast(&myVertexData->r)); } + + if (hasTexture) { + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glTexCoordPointer(2, GL_FLOAT, sizeof(VertexData), + reinterpret_cast(&myVertexData->tx)); + } glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); @@ -434,7 +438,7 @@ void VertexArrayMesh::render() const reinterpret_cast(&myVertexData->nx)); glDrawElements(GL_TRIANGLES, myIndexCount, GL_UNSIGNED_SHORT, myIndices); - + glPopClientAttrib(); glPopAttrib(); } @@ -552,7 +556,7 @@ IMeshPtr makeMesh(IMeshBufferPtr aBuffer) //aBuffer->printStats(); // Prefer VBOs for large meshes - if (aBuffer->vertexCount() > 100 && GLEW_ARB_vertex_buffer_object) + if (aBuffer->vertexCount() > 50 && GLEW_ARB_vertex_buffer_object) return IMeshPtr(new VBOMesh(aBuffer)); else return IMeshPtr(new VertexArrayMesh(aBuffer)); diff --git a/src/Model.cpp b/src/Model.cpp index c604611..6a0385c 100644 --- a/src/Model.cpp +++ b/src/Model.cpp @@ -47,7 +47,7 @@ namespace { // Abstracts a WaveFront material file class MaterialFile { public: - MaterialFile(IResource::Handle aHandle); + MaterialFile(const string& aFileName, IResourcePtr aRes); ~MaterialFile() {} const Material& get(const string& aName) const; @@ -58,11 +58,13 @@ private: typedef tr1::shared_ptr MaterialFilePtr; -MaterialFile::MaterialFile(IResource::Handle aHandle) +MaterialFile::MaterialFile(const string& aFileName, IResourcePtr aRes) { - log() << "Loading materials from " << aHandle.fileName(); + IResource::Handle h = aRes->openFile(aFileName); + + log() << "Loading materials from " << h.fileName(); - istream& is = aHandle.rstream(); + istream& is = h.rstream(); string activeMaterial; while (!is.eof()) { @@ -81,7 +83,7 @@ MaterialFile::MaterialFile(IResource::Handle aHandle) else if (word == "map_Kd") { // Texture is >> word; - myMaterials[activeMaterial].texture = loadTexture(word); + myMaterials[activeMaterial].texture = loadTexture(aRes, word); } else if (word == "Kd") { // Diffuse colour @@ -194,7 +196,7 @@ IModelPtr loadModel(IResourcePtr aRes, const string& aFileName, float aScale) f >> fileName; materialFile = - MaterialFilePtr(new MaterialFile(aRes->openFile(fileName))); + MaterialFilePtr(new MaterialFile(fileName, aRes)); } else if (first == "v") { // Vertex diff --git a/src/ModelViewer.cpp b/src/ModelViewer.cpp index 85c74a8..4f3a40d 100644 --- a/src/ModelViewer.cpp +++ b/src/ModelViewer.cpp @@ -76,3 +76,10 @@ int ModelViewer::handle(int anEvent) { return Fl_Gl_Window::handle(anEvent); } + +void ModelViewer::setModel(IModelPtr aModel) +{ + myModel = aModel; + + Fl_Gl_Window::redraw(); +} diff --git a/src/Texture.cpp b/src/Texture.cpp index 2b7567c..af2beab 100644 --- a/src/Texture.cpp +++ b/src/Texture.cpp @@ -69,6 +69,20 @@ ITexturePtr loadTexture(const string& aFileName) } } +ITexturePtr loadTexture(IResourcePtr aRes, const string& aFileName) +{ + // Hack alert! Just use the handle to find out the file name + // This should be replaced with a solution where all textures come + // from resources... + string realFileName; + { + IResource::Handle h = aRes->openFile(aFileName); + realFileName = h.fileName(); + } // Handle closed here + + return loadTexture(realFileName); +} + Texture::Texture(const string &file) { SDL_Surface *surface = IMG_Load(file.c_str()); -- 2.39.2