Advertisement
Guest User

Untitled

a guest
Jan 17th, 2014
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 20.90 KB | None | 0 0
  1. /** Copyright (C) 2008-2013 Robert B. Colton, Adriano Tumminelli
  2. ***
  3. *** This file is a part of the ENIGMA Development Environment.
  4. ***
  5. *** ENIGMA is free software: you can redistribute it and/or modify it under the
  6. *** terms of the GNU General Public License as published by the Free Software
  7. *** Foundation, version 3 of the license or any later version.
  8. ***
  9. *** This application and its source code is distributed AS-IS, WITHOUT ANY
  10. *** WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  11. *** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  12. *** details.
  13. ***
  14. *** You should have received a copy of the GNU General Public License along
  15. *** with this code. If not, see <http://www.gnu.org/licenses/>
  16. **/
  17. #include "../General/OpenGLHeaders.h"
  18. #include "../General/GSd3d.h"
  19. #include "../General/GSprimitives.h"
  20. #include "Universal_System/var4.h"
  21. #include "Universal_System/roomsystem.h"
  22. #include <math.h>
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25.  
  26. using namespace std;
  27.  
  28. #define __GETR(x) (x & 0x0000FF)
  29. #define __GETG(x) ((x & 0x00FF00)>>8)
  30. #define __GETB(x) ((x & 0xFF0000)>>16)
  31.  
  32. #include <iostream>
  33. #include <map>
  34. #include <list>
  35. #include "Universal_System/fileio.h"
  36. #include "Universal_System/estring.h"
  37.  
  38. #include <vector>
  39. using std::vector;
  40.  
  41. unsigned get_texture(int texid);
  42.  
  43. extern GLenum ptypes_by_id[16];
  44. namespace enigma {
  45.   extern unsigned char currentcolor[4];
  46.  
  47.   //split a string and convert to float
  48.   vector<float> float_split(const string& str, const char& ch) {
  49.     string next;
  50.     vector<float> result;
  51.  
  52.     for (string::const_iterator it = str.begin(); it != str.end(); it++)
  53.     {
  54.         if (*it == ch)
  55.         {
  56.             if (!next.empty())
  57.             {
  58.                 result.push_back(atof(next.c_str()));
  59.                 next.clear();
  60.             }
  61.         } else {
  62.             next += *it;
  63.         }
  64.     }
  65.     if (!next.empty())
  66.          result.push_back(atof(next.c_str()));
  67.     return result;
  68.   }
  69.  
  70.   //obj model parsing functions
  71.   void string_parse( string *s )
  72.   {
  73.     size_t spaces = 0;
  74.     bool trimmed = false;
  75.     bool checknormal = false;
  76.     for (unsigned int i = 0; i < s->size() ; i++)
  77.     {
  78.         //comment
  79.         if ((*s)[i] == '#')
  80.         {
  81.             s->erase(i, s->length() - i);
  82.             break;
  83.         }
  84.         else if((*s)[i] == ' ')
  85.         {
  86.             if (!trimmed)
  87.             {
  88.                 s->erase(i,1);
  89.                 i--;
  90.             }
  91.             else
  92.             {
  93.                 if (spaces >= 1)
  94.                 {
  95.                     s->erase(i,1);
  96.                     i--;
  97.                 }
  98.                 spaces++;
  99.             }
  100.         }
  101.         else
  102.         {
  103.             if((*s)[i] == '/')
  104.             {
  105.                 (*s)[i] = ' ';
  106.                 if(checknormal)
  107.                 {
  108.                     s->erase(i, 1);
  109.                     checknormal = false;
  110.                 }
  111.                 else
  112.                     checknormal = true;
  113.             }
  114.             else
  115.                 checknormal = false;
  116.             spaces = 0;
  117.             trimmed = true;
  118.         }
  119.     }
  120.     //end trim
  121.     if (s->size() > 0) {
  122.         if ((*s)[s->size()-1] == ' ')
  123.         {
  124.             s->erase(s->size()-1, 1);
  125.         }
  126.     }
  127.   }
  128. }
  129.  
  130. union VertexElement {
  131.     unsigned long d;
  132.     gs_scalar f;
  133.  
  134.     VertexElement(gs_scalar v): f(v) {}
  135.     VertexElement(unsigned long v): d(v) {}
  136. };
  137.  
  138. //NOTE: This class handles batching, indexing, and other optimization for you and is very very efficient.
  139. class Mesh
  140. {
  141.   public:
  142.   unsigned currentPrimitive; //The type of the current primitive being added to the model
  143.  
  144.   vector<VertexElement> vertices; // Temporary vertices container for the current primitive until they are batched
  145.   vector<GLuint> indices; // Temporary indices that can optionally be supplied, otherwise they will get generated by the batcher.
  146.   vector<VertexElement> triangleVertices; // The vertices added to triangle primitives batched into a single triangle list to be buffered to the GPU
  147.   vector<VertexElement> triangleIndexedVertices; // The vertices added to indexed triangle primitives batched into a single triangle list to be buffered to the GPU
  148.   vector<GLuint> triangleIndices; // The triangle indices either concatenated by batching or supplied in the temporary container.
  149.   vector<VertexElement> lineVertices; // The vertices added to line primitives batched into a single line list to be buffered to the GPU
  150.   vector<VertexElement> lineIndexedVertices; // The vertices added to indexed line primitives batched into a single line list to be buffered to the GPU
  151.   vector<GLuint> lineIndices; // The line indices either concatenated by batching or supplied in the temporary container.
  152.   vector<VertexElement> pointVertices; // The vertices added to point primitives batched into a single point list to be buffered to the GPU
  153.   vector<VertexElement> pointIndexedVertices; // The vertices added to indexed point primitives batched into a single point list to be buffered to the GPU
  154.   vector<GLuint> pointIndices; // The point indices either concatenated by batching or supplied in the temporary container.
  155.  
  156.   unsigned vertexStride; // whether the vertices are 2D or 3D
  157.   bool useColors; // If colors have been added to the model
  158.   bool useTextures; // If texture coordinates have been added
  159.   bool useNormals; // If normals have been added
  160.  
  161.   unsigned pointCount; // The number of vertices in the point buffer
  162.   unsigned triangleCount; // The number of vertices in the triangle buffer
  163.   unsigned lineCount; // The number of vertices in the line buffer
  164.  
  165.   unsigned indexedoffset; // The number of indexed vertices
  166.   unsigned pointIndexedCount; // The number of point indices
  167.   unsigned triangleIndexedCount; // The number of triangle indices
  168.   unsigned lineIndexedCount; // The number of line indices
  169.  
  170.   // Indexed primitives are first since the indices must be offset, and keeps them as small as possible.
  171.   // INDEXEDTRIANGLES|INDEXEDLINES|INDEXEDPOINTS|TRIANGLES|LINES|POINTS
  172.   GLuint vertexBuffer; // Interleaved vertex buffer object with triangles first since they are most likely to be used
  173.   GLuint indexBuffer; // Interleaved index buffer object with triangles first since they are most likely to be used
  174.  
  175.   bool vbodynamic; // Whether or not the buffer should be prepared for dynamic memory usage, eg. constantly changing vertex data
  176.   bool ibogenerated;
  177.   bool vbogenerated;
  178.   bool vbobuffered; // Whether or not the buffer objects have been generated
  179.   bool vboindexed; // Whether or not the model contains any indexed primitives or just regular lists
  180.  
  181.   Mesh (bool dynamic)
  182.   {
  183.     triangleIndexedVertices.reserve(64000);
  184.     pointIndexedVertices.reserve(64000);
  185.     lineIndexedVertices.reserve(64000);
  186.     pointVertices.reserve(64000);
  187.     pointIndices.reserve(64000);
  188.     lineVertices.reserve(64000);
  189.     lineIndices.reserve(64000);
  190.     triangleVertices.reserve(64000);
  191.     triangleIndices.reserve(64000);
  192.     vertices.reserve(64000);
  193.     indices.reserve(64000);
  194.  
  195.     vbodynamic = false;
  196.     ibogenerated = false;
  197.     vbogenerated = false;
  198.     vbobuffered = false;
  199.     vboindexed = false;
  200.  
  201.     vertexStride = 0;
  202.     useColors = false;
  203.     useTextures = false;
  204.     useNormals = false;
  205.  
  206.     pointCount = 0;
  207.     triangleCount = 0;
  208.     lineCount = 0;
  209.  
  210.     indexedoffset = 0;
  211.     pointIndexedCount = 0;
  212.     triangleIndexedCount = 0;
  213.     lineIndexedCount = 0;
  214.  
  215.     currentPrimitive = 0;
  216.   }
  217.  
  218.   ~Mesh()
  219.   {
  220.     glDeleteBuffersARB(1, &vertexBuffer);
  221.     glDeleteBuffersARB(1, &indexBuffer);
  222.   }
  223.  
  224.   void ClearData()
  225.   {
  226.     triangleVertices.clear();
  227.     pointVertices.clear();
  228.     lineVertices.clear();
  229.     triangleIndexedVertices.clear();
  230.     pointIndexedVertices.clear();
  231.     lineIndexedVertices.clear();
  232.     triangleIndices.clear();
  233.     pointIndices.clear();
  234.     lineIndices.clear();
  235.     vertices.clear();
  236.     indices.clear();
  237.   }
  238.  
  239.   void Clear()
  240.   {
  241.     ClearData();
  242.  
  243.     triangleIndexedVertices.reserve(64000);
  244.     pointIndexedVertices.reserve(64000);
  245.     lineIndexedVertices.reserve(64000);
  246.     pointVertices.reserve(64000);
  247.     pointIndices.reserve(64000);
  248.     lineVertices.reserve(64000);
  249.     lineIndices.reserve(64000);
  250.     triangleVertices.reserve(64000);
  251.     triangleIndices.reserve(64000);
  252.     vertices.reserve(64000);
  253.     indices.reserve(64000);
  254.  
  255.     vbobuffered = false;
  256.     vboindexed = false;
  257.  
  258.     vertexStride = 0;
  259.     useColors = false;
  260.     useTextures = false;
  261.     useNormals = false;
  262.  
  263.     pointCount = 0;
  264.     triangleCount = 0;
  265.     lineCount = 0;
  266.     indexedoffset = 0;
  267.     pointIndexedCount = 0;
  268.     triangleIndexedCount = 0;
  269.     lineIndexedCount = 0;
  270.   }
  271.  
  272.   unsigned GetStride() {
  273.     unsigned stride = vertexStride;
  274.     if (useNormals) stride += 3;
  275.     if (useTextures) stride += 2;
  276.     if (useColors) stride += 1;
  277.     return stride;
  278.   }
  279.  
  280.   void Begin(int pt)
  281.   {
  282.     vbobuffered = false;
  283.     currentPrimitive = pt;
  284.   }
  285.  
  286.   void AddVertex(gs_scalar x, gs_scalar y)
  287.   {
  288.     vertices.push_back(x); vertices.push_back(y);
  289.     vertexStride = 2;
  290.   }
  291.  
  292.   void AddVertex(gs_scalar x, gs_scalar y, gs_scalar z)
  293.   {
  294.     vertices.push_back(x); vertices.push_back(y); vertices.push_back(z);
  295.     vertexStride = 3;
  296.   }
  297.  
  298.   void AddIndex(unsigned ind)
  299.   {
  300.     indices.push_back(ind);
  301.   }
  302.  
  303.   void AddNormal(gs_scalar nx, gs_scalar ny, gs_scalar nz)
  304.   {
  305.     vertices.push_back(nx); vertices.push_back(ny); vertices.push_back(nz);
  306.     useNormals = true;
  307.   }
  308.  
  309.   void AddTexture(gs_scalar tx, gs_scalar ty)
  310.   {
  311.     vertices.push_back(tx); vertices.push_back(ty);
  312.     useTextures = true;
  313.   }
  314.  
  315.   void AddColor(int col, double alpha)
  316.   {
  317.     unsigned long final = col + ((unsigned char)(alpha*255) << 24);
  318.     vertices.push_back(final);
  319.     useColors = true;
  320.   }
  321.  
  322.   void End()
  323.   {
  324.     //NOTE: This batching only checks for degenerate primitives on triangle strips and fans since the GPU does not render triangles where the two
  325.     //vertices are exactly the same, triangle lists could also check for degenerates, it is unknown whether the GPU will render a degenerative
  326.     //in a line strip primitive.
  327.  
  328.     unsigned stride = GetStride();
  329.  
  330.     // Primitive has ended so now we need to batch the vertices that were given into single lists, eg. line list, triangle list, point list
  331.     // Indices are optionally supplied, model functions can also be added for the end user to supply the indexing themselves for each primitive
  332.     // but the batching system does not care either way if they are not supplied it will automatically generate them.
  333.     switch (currentPrimitive) {
  334.         case enigma_user::pr_pointlist:
  335.             if (indices.size() > 0) {
  336.                 pointIndexedVertices.insert(pointIndexedVertices.end(), vertices.begin(), vertices.end());
  337.                 for (std::vector<GLuint>::iterator it = indices.begin(); it != indices.end(); ++it) { *it += pointIndexedCount; }
  338.                 pointIndices.insert(pointIndices.end(), indices.begin(), indices.end());
  339.             } else {
  340.                 pointVertices.insert(pointVertices.end(), vertices.begin(), vertices.end());
  341.                 pointCount += vertices.size() / stride;
  342.             }
  343.             break;
  344.         case enigma_user::pr_linelist:
  345.             if (indices.size() > 0) {
  346.                 lineIndexedVertices.insert(lineIndexedVertices.end(), vertices.begin(), vertices.end());
  347.                 for (std::vector<GLuint>::iterator it = indices.begin(); it != indices.end(); ++it) { *it += lineIndexedCount; }
  348.                 lineIndices.insert(lineIndices.end(), indices.begin(), indices.end());
  349.             } else {
  350.                 lineVertices.insert(lineVertices.end(), vertices.begin(), vertices.end());
  351.                 lineCount += vertices.size() / stride;
  352.             }
  353.             break;
  354.         case enigma_user::pr_linestrip:
  355.             lineIndexedVertices.insert(lineIndexedVertices.end(), vertices.begin(), vertices.end());
  356.             if (indices.size() > 0) {
  357.                 for (std::vector<GLuint>::iterator it = indices.begin(); it != indices.end(); ++it) { *it += lineIndexedCount; }
  358.                 for (unsigned i = 0; i < indices.size() - 2; i++) {
  359.                     lineIndices.push_back(indices[i]);
  360.                     lineIndices.push_back(indices[i + 1]);
  361.                 }
  362.             } else {
  363.                 unsigned offset = (lineIndexedVertices.size() - vertices.size()) / stride;
  364.                 for (unsigned i = 0; i < vertices.size() / stride - 1; i++) {
  365.                     lineIndices.push_back(offset + i);
  366.                     lineIndices.push_back(offset + i + 1);
  367.                 }
  368.             }
  369.             break;
  370.         case enigma_user::pr_trianglelist:
  371.             if (indices.size() > 0) {
  372.                 triangleIndexedVertices.insert(triangleIndexedVertices.end(), vertices.begin(), vertices.end());
  373.                 for (std::vector<GLuint>::iterator it = indices.begin(); it != indices.end(); ++it) { *it += triangleIndexedCount; }
  374.                 triangleIndices.insert(triangleIndices.end(), indices.begin(), indices.end());
  375.             } else {
  376.                 triangleVertices.insert(triangleVertices.end(), vertices.begin(), vertices.end());
  377.                 triangleCount += vertices.size() / stride;
  378.             }
  379.             break;
  380.         case enigma_user::pr_trianglestrip:
  381.             triangleIndexedVertices.insert(triangleIndexedVertices.end(), vertices.begin(), vertices.end());
  382.             if (indices.size() > 0) {
  383.                 for (std::vector<GLuint>::iterator it = indices.begin(); it != indices.end(); ++it) { *it += triangleIndexedCount; }
  384.                 for (unsigned i = 0; i < indices.size() - 2; i++) {
  385.                     // check for and continue if indexed triangle is degenerate, because the GPU won't render it anyway
  386.                     if (indices[i] == indices[i + 1] || indices[i] == indices[i + 2]  || indices[i + 1] == indices[i + 2] ) { continue; }
  387.                     triangleIndices.push_back(indices[i]);
  388.                     triangleIndices.push_back(indices[i+1]);
  389.                     triangleIndices.push_back(indices[i+2]);
  390.                 }
  391.             } else {
  392.                 unsigned offset = (triangleIndexedVertices.size() - vertices.size()) / stride;
  393.                 for (unsigned i = 0; i < vertices.size() / stride - 2; i++) {
  394.                     if (i % 2) {
  395.                         triangleIndices.push_back(offset + i + 2);
  396.                         triangleIndices.push_back(offset + i + 1);
  397.                         triangleIndices.push_back(offset + i);
  398.                     } else {
  399.                         triangleIndices.push_back(offset + i);
  400.                         triangleIndices.push_back(offset + i + 1);
  401.                         triangleIndices.push_back(offset + i + 2);
  402.                     }
  403.                 }
  404.             }
  405.             break;
  406.         case enigma_user::pr_trianglefan:
  407.             triangleIndexedVertices.insert(triangleIndexedVertices.end(), vertices.begin(), vertices.end());
  408.             if (indices.size() > 0) {
  409.                 for (std::vector<GLuint>::iterator it = indices.begin(); it != indices.end(); ++it) { *it += triangleIndexedCount; }
  410.                 for (unsigned i = 1; i < indices.size() - 1; i++) {
  411.                     // check for and continue if indexed triangle is degenerate, because the GPU won't render it anyway
  412.                     if (indices[0] == indices[i] || indices[0] == indices[i + 1]  || indices[i] == indices[i + 1] ) { continue; }
  413.                     triangleIndices.push_back(indices[0]);
  414.                     triangleIndices.push_back(indices[i]);
  415.                     triangleIndices.push_back(indices[i + 1]);
  416.                 }
  417.             } else {
  418.                 unsigned offset = (triangleIndexedVertices.size() - vertices.size()) / stride;
  419.                 for (unsigned i = 1; i < vertices.size() / stride - 1; i++) {
  420.                     triangleIndices.push_back(offset);
  421.                     triangleIndices.push_back(offset + i);
  422.                     triangleIndices.push_back(offset + i + 1);
  423.                 }
  424.             }
  425.             break;
  426.     }
  427.  
  428.     // Clean up the temporary vertex and index containers now that they have been batched efficiently
  429.     vertices.clear();
  430.     indices.clear();
  431.   }
  432.  
  433.   void BufferGenerate()
  434.   {
  435.     vector<VertexElement> vdata;
  436.     vector<GLuint> idata;
  437.  
  438.     vdata.reserve(triangleVertices.size() + lineVertices.size() + pointVertices.size() + triangleIndexedVertices.size() + lineIndexedVertices.size() + pointIndexedVertices.size());
  439.     idata.reserve(triangleIndices.size() + lineIndices.size() + pointIndices.size());
  440.  
  441.     unsigned interleave = 0;
  442.  
  443.     triangleIndexedCount = triangleIndices.size();
  444.     if (triangleIndexedCount > 0) {
  445.         vdata.insert(vdata.end(), triangleIndexedVertices.begin(), triangleIndexedVertices.end());
  446.         idata.insert(idata.end(), triangleIndices.begin(), triangleIndices.end());
  447.         interleave += triangleIndexedVertices.size()/GetStride();
  448.     }
  449.  
  450.     lineIndexedCount = lineIndices.size();
  451.     if (lineIndexedCount > 0) {
  452.         vdata.insert(vdata.end(), lineIndexedVertices.begin(), lineIndexedVertices.end());
  453.         for (std::vector<GLuint>::iterator it = lineIndices.begin(); it != lineIndices.end(); ++it) { *it += interleave; }
  454.         idata.insert(idata.end(), lineIndices.begin(), lineIndices.end());
  455.         interleave += lineIndexedVertices.size()/GetStride();
  456.     }
  457.  
  458.     pointIndexedCount = pointIndices.size();
  459.     if (pointIndexedCount > 0) {
  460.         vdata.insert(vdata.end(), pointIndexedVertices.begin(), pointIndexedVertices.end());
  461.         for (std::vector<GLuint>::iterator it = lineIndices.begin(); it != lineIndices.end(); ++it) { *it += interleave; }
  462.         idata.insert(idata.end(), pointIndices.begin(), pointIndices.end());
  463.     }
  464.  
  465.     if (idata.size() > 0) {
  466.         vboindexed = true;
  467.         indexedoffset += vdata.size();
  468.  
  469.         if (!ibogenerated) {
  470.             glGenBuffersARB( 1, &indexBuffer );
  471.             ibogenerated = true;
  472.             glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER, indexBuffer );
  473.             glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER, idata.size() * sizeof(GLuint), &idata[0], vbodynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW );
  474.         } else {
  475.             glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER, indexBuffer );
  476.  
  477.             GLint nBufferSize = 0;
  478.             glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &nBufferSize);
  479.             if (idata.size() * sizeof(GLuint) / nBufferSize > 0.5 ) {
  480.                 glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER, idata.size() * sizeof(GLuint), &idata[0], vbodynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW );
  481.             } else {
  482.                 glBufferSubDataARB( GL_ELEMENT_ARRAY_BUFFER, 0, idata.size() * sizeof(GLuint), &idata[0]);
  483.             }
  484.         }
  485.  
  486.         // Unbind the buffer we do not need anymore
  487.         glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER, 0 );
  488.         // Clean up temporary interleaved data
  489.         idata.clear();
  490.     } else {
  491.         vboindexed = false;
  492.     }
  493.  
  494.     if (triangleCount > 0) {
  495.         vdata.insert(vdata.end(), triangleVertices.begin(), triangleVertices.end());
  496.     }
  497.  
  498.     if (lineCount > 0) {
  499.         vdata.insert(vdata.end(), lineVertices.begin(), lineVertices.end());
  500.     }
  501.  
  502.     if (pointCount > 0) {
  503.         vdata.insert(vdata.end(), pointVertices.begin(), pointVertices.end());
  504.     }
  505.  
  506.     if (!vbogenerated) {
  507.         glGenBuffersARB( 1, &vertexBuffer );
  508.         vbogenerated = true;
  509.         glBindBufferARB( GL_ARRAY_BUFFER, vertexBuffer );
  510.         glBufferDataARB( GL_ARRAY_BUFFER, vdata.size() * sizeof(VertexElement), &vdata[0], vbodynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW );
  511.     } else {
  512.         glBindBufferARB( GL_ARRAY_BUFFER, vertexBuffer );
  513.  
  514.         GLint nBufferSize = 0;
  515.         glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &nBufferSize);
  516.         if (vdata.size() * sizeof(VertexElement) / nBufferSize > 0.5 ) {
  517.             glBufferDataARB( GL_ARRAY_BUFFER, vdata.size() * sizeof(VertexElement), &vdata[0], vbodynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW );
  518.         } else {
  519.             glBufferSubDataARB( GL_ARRAY_BUFFER, 0, vdata.size() * sizeof(VertexElement), &vdata[0]);
  520.         }
  521.     }
  522.  
  523.     // Unbind the buffer we do not need anymore
  524.     glBindBufferARB( GL_ARRAY_BUFFER, 0 );
  525.     // Clean up temporary interleaved data
  526.     vdata.clear();
  527.  
  528.     // Clean up the data from RAM it is now safe on VRAM
  529.     ClearData();
  530.   }
  531.  
  532.   void Draw(int vertex_start = 0, int vertex_count = -1)
  533.   {
  534.     if (!GetStride()) { return; }
  535.     if (!vbogenerated || !vbobuffered) {
  536.       vbobuffered = true;
  537.       BufferGenerate();
  538.     }
  539.  
  540.     GLsizei stride = GetStride();
  541.  
  542.     #define OFFSET( P )  ( ( const GLvoid * ) ( sizeof(VertexElement) * ( P         ) ) )
  543.     GLsizei STRIDE = stride * sizeof(VertexElement);
  544.  
  545.     // Enable vertex array's for fast vertex processing
  546.     glBindBufferARB( GL_ARRAY_BUFFER, vertexBuffer );
  547.     if (vboindexed) {
  548.         glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER, indexBuffer );
  549.     }
  550.  
  551.     glEnableClientState(GL_VERTEX_ARRAY);
  552.     unsigned offset = 0;
  553.     glVertexPointer( vertexStride, GL_FLOAT, STRIDE, OFFSET(offset) ); // Set the vertex pointer to the offset in the buffer
  554.     offset += vertexStride;
  555.  
  556.     if (useNormals){
  557.         glEnableClientState(GL_NORMAL_ARRAY);
  558.         glNormalPointer( GL_FLOAT, STRIDE, OFFSET(offset) ); // Set the normal pointer to the offset in the buffer
  559.         offset += 3;
  560.     }
  561.  
  562.     if (useTextures){
  563.         glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  564.         glTexCoordPointer( 2, GL_FLOAT, STRIDE, OFFSET(offset) ); // Set the texture pointer to the offset in the buffer
  565.         offset += 2;
  566.     }
  567.  
  568.     if (useColors){
  569.         glEnableClientState(GL_COLOR_ARRAY);
  570.         glColorPointer( 4, GL_UNSIGNED_BYTE, STRIDE, OFFSET(offset)); // Set The Color Pointer To The Color Buffer
  571.     }
  572.  
  573.     #define OFFSETE( P )  ( ( const GLvoid * ) ( sizeof( GLuint ) * ( P         ) ) )
  574.     offset = vertex_start;
  575.  
  576.     // Draw the indexed primitives
  577.     if (triangleIndexedCount > 0) {
  578.         glDrawElements(GL_TRIANGLES, (vertex_count==-1?triangleIndexedCount:vertex_count), GL_UNSIGNED_INT, OFFSETE(offset));
  579.         offset += triangleIndexedCount;
  580.     }
  581.     if (lineIndexedCount > 0) {
  582.         glDrawElements(GL_LINES, lineIndexedCount, GL_UNSIGNED_INT, OFFSETE(offset));
  583.         offset += lineIndexedCount;
  584.     }
  585.     if (pointIndexedCount > 0) {
  586.         glDrawElements(GL_POINTS, pointIndexedCount, GL_UNSIGNED_INT, OFFSETE(offset));
  587.     }
  588.  
  589.     offset = indexedoffset/stride;
  590.  
  591.     // Draw the unindexed primitives
  592.     if (triangleCount > 0) {
  593.         glDrawArrays(GL_TRIANGLES, (vertex_start==0?offset:vertex_start), (vertex_count==-1?triangleCount:vertex_count));
  594.         offset += triangleCount;
  595.     }
  596.     if (lineCount > 0) {
  597.         glDrawArrays(GL_LINES, offset, lineCount);
  598.         offset += lineCount;
  599.     }
  600.     if (pointCount > 0) {
  601.         glDrawArrays(GL_POINTS, offset, pointCount);
  602.     }
  603.  
  604.     glBindBufferARB( GL_ARRAY_BUFFER, 0 );
  605.     if (vboindexed) {
  606.         glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER, 0 );
  607.     }
  608.  
  609.     glDisableClientState(GL_VERTEX_ARRAY);
  610.     if (useTextures) glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  611.     if (useNormals) glDisableClientState(GL_NORMAL_ARRAY);
  612.     if (useColors) glDisableClientState(GL_COLOR_ARRAY);
  613.   }
  614. };
  615.  
  616. extern vector<Mesh*> meshes;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement