{"id":742,"date":"2026-04-08T22:55:05","date_gmt":"2026-04-08T22:55:05","guid":{"rendered":"https:\/\/hackcuba.net\/?p=742"},"modified":"2026-04-08T23:02:20","modified_gmt":"2026-04-08T23:02:20","slug":"libreria-para-3ds-en-opengl","status":"publish","type":"post","link":"https:\/\/hackcuba.net\/?p=742","title":{"rendered":"Librer\u00eda para 3DS en OpenGL"},"content":{"rendered":"\n<p>T3DSModel.cpp es una librer\u00eda cuyo objetivo es brindar una interfaz lo m\u00e1s sencilla posible para cargar<br>y dibujar archivos 3DS, de modo que con solo llamar las funciones Open3DS() y Draw() podremos estar<br>dibujando modelos complejos con alto nivel poligonal sin tener que preocuparnos en cargar texturas,<br>calcular normales, etc. Claro que a mayor abstracci\u00f3n menor control, no obstante es muy c\u00f3modo<br>exportar tus modelos previamente hechos en 3D Studio y luego cargarlos en tu aplicaci\u00f3n como escenarios,<br>personajes, etc.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>T3DSModel.cpp trabaja sobre la librer\u00eda 3ds.cpp de DigiBen para crear una interface de f\u00e1cil uso a la hora<br>de cargar y dibujar un 3DS.Tambi\u00e9n me he tomando la libertad de hacerle algunos cambios a la librer\u00eda de<br>DigiBen para agregar nuevas funcionalidades que quiz\u00e1s no sean b\u00e1sicas pero si importantes. Mis cambios<br>agregan: soporte para lightmaps, soporte para reflectionmaps, transparencia de materiales y CullMode establecido por el material.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\nT3DSModel.cpp\n\n\/*\n*\n* Nombre: T3DSModel\n* Autor: h0aX\n* Fecha: 10\/febrero\/2006\n* Descripcion: Trabaja sobre la librer\u00eda 3ds.cpp de\n* DigiBen para crear una interface de f\u00e1cil\n* uso a la hora de cargar y dibujar un 3DS\n*\n*\/\n\/\/---------------------------------------------------------------------------\n#include &lt;float.h&gt;\n#include &lt;gl.h&gt;\n#include &lt;glu.h&gt;\n#include &lt;.\\Libs3DS\\multitexture.h&gt;\n#include &quot;T3DSModel.h&quot;\n#pragma hdrstop\n#pragma package(smart_init)\n\/\/---------------------------------------------------------------------------\nT3DSModel::T3DSModel()\n{\n  _control87(MCW_EM, MCW_EM);\n  CanDraw = TRUE;\n}\n\/\/---------------------------------------------------------------------------\nvoid T3DSModel::Open3DS(char *fichero)\n{\n  BOOL bMultitexture;\n  bMultitexture = FALSE;\n\/\/importa estructura de datos del 3ds\n  g_Load3ds.Import3DS(&amp;g_3DModel, fichero);\n\/\/inicia la carga de texturas\n  for(int i = 0; i &lt; g_3DModel.numOfMaterials; i++)\n  {\n    if(strlen(g_3DModel.pMaterials&#x5B;i].strFile) &gt; 0)\n    {\n      \/\/carga textura del material\n      CreateTexture(g_Texture, g_3DModel.pMaterials&#x5B;i].strFile, i);\n      \/\/si usa lightmap activa multitexturas y carga el lightmap\n      if (g_3DModel.pMaterials&#x5B;i].bUseLightmap)\n      {\n        if (!bMultitexture)\n        {\n          InitMultiTexture();\n          bMultitexture = true;\n        }\n        CreateTexture(g_Lightmaps, g_3DModel.pMaterials&#x5B;i].strLightmapFile, i);\n      }\n      \/\/si usa reflexi\u00f3n activa multitexturas y carga la textura de reflexi\u00f3n\n      if (g_3DModel.pMaterials&#x5B;i].bUseReflection)\n      {\n        if (!bMultitexture)\n        {\n          InitMultiTexture();\n          bMultitexture = true;\n        }\n        CreateTexture(g_Reflections, g_3DModel.pMaterials&#x5B;i].strReflectionFile, i);\n      }\n    }\n    g_3DModel.pMaterials&#x5B;i].texureId = i;\n  }\n  glEnable(GL_LIGHT0);\n  glEnable(GL_LIGHTING);\n  glEnable(GL_COLOR_MATERIAL);\n}\n\/\/---------------------------------------------------------------------------\nint T3DSModel::GetPolygonsCount()\n{\n  int result = 0;\n  for(int i = 0; i &lt; g_3DModel.numOfObjects; i++)\n  {\n    if(g_3DModel.pObject.size() &lt;= 0)\n    break;\n    t3DObject *pObject = &amp;g_3DModel.pObject&#x5B;i];\n    for(int j = 0; j &lt; pObject-&gt;numOfFaces; j++)\n    {\n      result++;\n    }\n  }\n  result = result \/ 2;\n  return result;\n}\n\/\/---------------------------------------------------------------------------\nvoid T3DSModel::Draw()\n{\n  float fTransp;\n  if (CanDraw)\n  {\n    for(int i = 0; i &lt; g_3DModel.numOfObjects; i++)\n    {\n      if(g_3DModel.pObject.size() &lt;= 0) break;\n      t3DObject *pObject = &amp;g_3DModel.pObject&#x5B;i];\n\n      \/*  \n      ** Aqui comienza la carga del material\n      *\/\n\n      \/\/chequea si el material actual usa dos caras\n      if (g_3DModel.pMaterials&#x5B;pObject-&gt;materialID].bTwoSides)\n      {\n        glDisable(GL_CULL_FACE);\n      }\n      else\n      {\n        glEnable(GL_CULL_FACE);\n      }\n      \/\/chequea si el material usa texturas\n      if(pObject-&gt;bHasTexture)\n      {\n        glEnable(GL_TEXTURE_2D);\n        \/\/carga la opacidad del material\n        fTransp = g_3DModel.pMaterials&#x5B;pObject-&gt;materialID].fTransp;\n        \/\/si la opacidad es menor de 1.0 activa la transparencia\n        if (fTransp &lt; 1.0)\n        {\n          glEnable(GL_BLEND);\n          glColor4f(1.0,1.0,1.0,fTransp);\n        }\n        \/\/Si el material actual usa lightmaps activa la textura actual\n        \/\/junto con el lightmap usando multitexturas, sino solo activa\n        \/\/la textura normal\n        if ( g_3DModel.pMaterials&#x5B;pObject-&gt;materialID].bUseLightmap )\n        {\n          Bind2Textures(g_Texture&#x5B;pObject-&gt;materialID],g_Lightmaps&#x5B;pObject-&gt;materialID]);\n        }\n        else\n        {\n          glBindTexture(GL_TEXTURE_2D, g_Texture&#x5B;pObject-&gt;materialID]);\n        }\n        \/\/Si el material actual usa reflexi\u00f3n activa textura normal y la textura\n        \/\/de reflexi\u00f3n usando multitexturas y luego le da reflexi\u00f3n esf\u00e9rica a la\n        \/\/\u00faltima\n        if ( g_3DModel.pMaterials&#x5B;pObject-&gt;materialID].bUseReflection )\n        {\n          Bind2Textures(g_Texture&#x5B;pObject-&gt;materialID],g_Reflections&#x5B;pObject-&gt;materialID]);\n          glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);\n          glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);\n          glEnable(GL_TEXTURE_GEN_S);\n          glEnable(GL_TEXTURE_GEN_T);\n        }\n        \/\/Caso que usen ambos, reflexi\u00f3n y lightmaps en un mismo material se activan las\n        \/\/tres juntas con multitextura, Normal + Lightmap + Reflexi\u00f3n\n        if ( (g_3DModel.pMaterials&#x5B;pObject-&gt;materialID].bUseLightmap) &amp;&amp;\n        (g_3DModel.pMaterials&#x5B;pObject-&gt;materialID].bUseReflection) )\n        {\n          glActiveTextureARB(GL_TEXTURE0_ARB);\n          glEnable(GL_TEXTURE_2D);\n          glBindTexture(GL_TEXTURE_2D, g_Texture&#x5B;pObject-&gt;materialID]);\n          glActiveTextureARB(GL_TEXTURE1_ARB);\n          glEnable(GL_TEXTURE_2D);\n          glBindTexture(GL_TEXTURE_2D, g_Lightmaps&#x5B;pObject-&gt;materialID]);\n          glDisable(GL_TEXTURE_GEN_S);\n          glDisable(GL_TEXTURE_GEN_T);\n          glActiveTextureARB(GL_TEXTURE2_ARB);\n          glEnable(GL_TEXTURE_2D);\n          glBindTexture(GL_TEXTURE_2D, g_Reflections&#x5B;pObject-&gt;materialID]);\n          glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);\n          glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);\n          glEnable(GL_TEXTURE_GEN_S);\n          glEnable(GL_TEXTURE_GEN_T);\n        }\n      }\n      else\n      {\n        \/\/si el material no usa una textura se\n        \/\/deshabilitan las texturas y se usa un\n        \/\/color.\n        glDisable(GL_TEXTURE_2D);\n        glColor3b(g_3DModel.pMaterials&#x5B;pObject-&gt;materialID].color&#x5B;0],         g_3DModel.pMaterials&#x5B;pObject-&gt;materialID].color&#x5B;1],         g_3DModel.pMaterials&#x5B;pObject-&gt;materialID].color&#x5B;2]);\n      }\n\n      \/*\n      ** Aqui comienza el dibujado\n      *\/\n\n      glBegin(GL_TRIANGLES);\n      \/\/se recorren todas las caras\n      for(int j = 0; j &lt; pObject-&gt;numOfFaces; j++)\n      {\n        \/\/se recorre cada v\u00e9rtice de cada cara\n        for(int whichVertex = 0; whichVertex &lt; 3; whichVertex++)\n        {\n          int index = pObject-&gt;pFaces&#x5B;j].vertIndex&#x5B;whichVertex];\n          \/\/normales\n          glNormal3f(pObject-&gt;pNormals&#x5B; index ].x, pObject-&gt;pNormals&#x5B; index ].y,           pObject-&gt;pNormals&#x5B; index ].z);\n          \/\/si usa texturas se definen las coordenadas de mapeado\n          if(pObject-&gt;bHasTexture)\n          {\n            if(pObject-&gt;pTexVerts)\n            {\n              \/\/coordenadas de mapeado para los lightmaps\n              if ( g_3DModel.pMaterials&#x5B;pObject-&gt;materialID].bUseLightmap )\n              {\n                glMultiTexCoord2fARB(GL_TEXTURE0_ARB,pObject-&gt;pTexVerts&#x5B; index ].x,                 pObject-&gt;pTexVerts&#x5B; index ].y);\n                glMultiTexCoord2fARB(GL_TEXTURE1_ARB,pObject-&gt;pTexVerts&#x5B; index ].x,                 pObject-&gt;pTexVerts&#x5B; index ].y);\n              }\n              else\n              {\n                \/\/coordenadas de mapeado de textura normal\n                glTexCoord2f(pObject-&gt;pTexVerts&#x5B;index].x, pObject-&gt;pTexVerts&#x5B;index ].y);\n              }\n            }\n          }\n          else\n          {\n            \/\/si no usa textura se le asigna un color al v\u00e9rtice\n            if(g_3DModel.pMaterials.size() &amp;&amp; pObject-&gt;materialID &gt;= 0)\n            {\n              BYTE *pColor = g_3DModel.pMaterials&#x5B;pObject-&gt;materialID].color;\n              glColor3ub(pColor&#x5B;0], pColor&#x5B;1], pColor&#x5B;2]);\n            }\n          }\n          \/\/dibuja el v\u00e9rtice\n          glVertex3f(pObject-&gt;pVerts&#x5B; index ].x, pObject-&gt;pVerts&#x5B; index ].y, pObject-&gt;pVerts&#x5B; index ].z);\n          }\n        }\n        glEnd();\n\n        \/\/si la transparencia esta activada se desactiva\n        if (fTransp &lt; 1.0)\n        {\n          glDisable(GL_BLEND);\n        }\n\n        \/\/si se activaron las multitexturas se desactivan aqui\n        if ( (g_3DModel.pMaterials&#x5B;pObject-&gt;materialID].bUseLightmap) ||\n        (g_3DModel.pMaterials&#x5B;pObject-&gt;materialID].bUseReflection))\n        {\n          glActiveTextureARB(GL_TEXTURE2_ARB);\n          glDisable(GL_TEXTURE_GEN_S);\n          glDisable(GL_TEXTURE_GEN_T);\n          glDisable(GL_TEXTURE_2D);\n          glDisable(GL_TEXTURE_GEN_S);\n          glDisable(GL_TEXTURE_GEN_T);\n          glDisable(GL_TEXTURE_2D);\n          glActiveTextureARB(GL_TEXTURE1_ARB);\n          glDisable(GL_TEXTURE_GEN_S);\n          glDisable(GL_TEXTURE_GEN_T);\n          glDisable(GL_TEXTURE_2D);\n          glDisable(GL_TEXTURE_GEN_S);\n          glDisable(GL_TEXTURE_GEN_T);\n          glDisable(GL_TEXTURE_2D);\n          glActiveTextureARB(GL_TEXTURE0_ARB);\n          glEnable(GL_TEXTURE_2D);\n        }\n      }\n    }\n  }\n\/\/---------------------------------------------------------------------------\nT3DSModel::~T3DSModel()\n{\n  for(int i = 0; i &lt; g_3DModel.numOfObjects; i++)\n  {\n    delete&#x5B;] g_3DModel.pObject&#x5B;i].pFaces;\n    delete&#x5B;] g_3DModel.pObject&#x5B;i].pNormals;\n    delete&#x5B;] g_3DModel.pObject&#x5B;i].pVerts;\n    delete&#x5B;] g_3DModel.pObject&#x5B;i].pTexVerts;\n  }\n}\n\/\/---------------------------------------------------------------------------\nvoid T3DSModel::Reset()\n{\n  \/\/esto falta\n}\n\/\/---------------------------------------------------------------------------\n<\/pre><\/div>\n\n\n<div class=\"wp-block-file\"><a id=\"wp-block-file--media-a08202e1-e811-4ba7-ae2a-82502b9f3977\" href=\"https:\/\/hackcuba.net\/wp-content\/uploads\/2026\/04\/Libs3DS.zip\">Libs3DS<\/a><a href=\"https:\/\/hackcuba.net\/wp-content\/uploads\/2026\/04\/Libs3DS.zip\" class=\"wp-block-file__button wp-element-button\" download aria-describedby=\"wp-block-file--media-a08202e1-e811-4ba7-ae2a-82502b9f3977\">Descarga<\/a><\/div>\n\n\n\n<p>Escrito por H0aX [hoax_ws@yahoo.es]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>T3DSModel.cpp es una librer\u00eda cuyo objetivo es brindar una interfaz lo m\u00e1s sencilla posible para cargary dibujar archivos<\/p>\n","protected":false},"author":2,"featured_media":354,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[59,36],"tags":[227,88,226,38],"class_list":["post-742","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-codigos","category-proyecto-blackhat","tag-3ds","tag-codigos","tag-opengl","tag-proyecto-blackhat"],"_links":{"self":[{"href":"https:\/\/hackcuba.net\/index.php?rest_route=\/wp\/v2\/posts\/742","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hackcuba.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hackcuba.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hackcuba.net\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/hackcuba.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=742"}],"version-history":[{"count":2,"href":"https:\/\/hackcuba.net\/index.php?rest_route=\/wp\/v2\/posts\/742\/revisions"}],"predecessor-version":[{"id":749,"href":"https:\/\/hackcuba.net\/index.php?rest_route=\/wp\/v2\/posts\/742\/revisions\/749"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/hackcuba.net\/index.php?rest_route=\/wp\/v2\/media\/354"}],"wp:attachment":[{"href":"https:\/\/hackcuba.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=742"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hackcuba.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=742"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hackcuba.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=742"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}