Guest User

Untitled

a guest
Jan 17th, 2014
51
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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 GetVertexStride() {
  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.   unsigned GetVertexSize() {
  281.     unsigned size = vertexStride;
  282.     if (useNormals) size += 3;
  283.     if (useTextures) size += 2;
  284.     size *= sizeof(gs_scalar);
  285.     if (useColors) size += sizeof(unsigned long);
  286.     return size;
  287.   }
  288.  
  289.   void Begin(int pt)
  290.   {
  291.     vbobuffered = false;
  292.     currentPrimitive = pt;
  293.   }
  294.  
  295.   void AddVertex(gs_scalar x, gs_scalar y)
  296.   {
  297.     vertices.push_back(x); vertices.push_back(y);
  298.     vertexStride = 2;
  299.   }
  300.  
  301.   void AddVertex(gs_scalar x, gs_scalar y, gs_scalar z)
  302.   {
  303.     vertices.push_back(x); vertices.push_back(y); vertices.push_back(z);
  304.     vertexStride = 3;
  305.   }
  306.  
  307.   void AddIndex(unsigned ind)
  308.   {
  309.     indices.push_back(ind);
  310.   }
  311.  
  312.   void AddNormal(gs_scalar nx, gs_scalar ny, gs_scalar nz)
  313.   {
  314.     vertices.push_back(nx); vertices.push_back(ny); vertices.push_back(nz);
  315.     useNormals = true;
  316.   }
  317.  
  318.   void AddTexture(gs_scalar tx, gs_scalar ty)
  319.   {
  320.     vertices.push_back(tx); vertices.push_back(ty);
  321.     useTextures = true;
  322.   }
  323.  
  324.   void AddColor(int col, double alpha)
  325.   {
  326.     unsigned long final = col + ((unsigned char)(alpha*255) << 24);
  327.     vertices.push_back(final);
  328.     useColors = true;
  329.   }
  330.  
  331.   void End()
  332.   {
  333.     //NOTE: This batching only checks for degenerate primitives on triangle strips and fans since the GPU does not render triangles where the two
  334.     //vertices are exactly the same, triangle lists could also check for degenerates, it is unknown whether the GPU will render a degenerative
  335.     //in a line strip primitive.
  336.  
  337.     unsigned stride = GetVertexStride();
  338.  
  339.     // Primitive has ended so now we need to batch the vertices that were given into single lists, eg. line list, triangle list, point list
  340.     // Indices are optionally supplied, model functions can also be added for the end user to supply the indexing themselves for each primitive
  341.     // but the batching system does not care either way if they are not supplied it will automatically generate them.
  342.     switch (currentPrimitive) {
  343.         case enigma_user::pr_pointlist:
  344.             if (indices.size() > 0) {
  345.                 pointIndexedVertices.insert(pointIndexedVertices.end(), vertices.begin(), vertices.end());
  346.                 for (std::vector<GLuint>::iterator it = indices.begin(); it != indices.end(); ++it) { *it += pointIndexedCount; }
  347.                 pointIndices.insert(pointIndices.end(), indices.begin(), indices.end());
  348.             } else {
  349.                 pointVertices.insert(pointVertices.end(), vertices.begin(), vertices.end());
  350.                 pointCount += vertices.size() / stride;
  351.             }
  352.             break;
  353.         case enigma_user::pr_linelist:
  354.             if (indices.size() > 0) {
  355.                 lineIndexedVertices.insert(lineIndexedVertices.end(), vertices.begin(), vertices.end());
  356.                 for (std::vector<GLuint>::iterator it = indices.begin(); it != indices.end(); ++it) { *it += lineIndexedCount; }
  357.                 lineIndices.insert(lineIndices.end(), indices.begin(), indices.end());
  358.             } else {
  359.                 lineVertices.insert(lineVertices.end(), vertices.begin(), vertices.end());
  360.                 lineCount += vertices.size() / stride;
  361.             }
  362.             break;
  363.         case enigma_user::pr_linestrip:
  364.             lineIndexedVertices.insert(lineIndexedVertices.end(), vertices.begin(), vertices.end());
  365.             if (indices.size() > 0) {
  366.                 for (std::vector<GLuint>::iterator it = indices.begin(); it != indices.end(); ++it) { *it += lineIndexedCount; }
  367.                 for (unsigned i = 0; i < indices.size() - 2; i++) {
  368.                     lineIndices.push_back(indices[i]);
  369.                     lineIndices.push_back(indices[i + 1]);
  370.                 }
  371.             } else {
  372.                 unsigned offset = (lineIndexedVertices.size() - vertices.size()) / stride;
  373.                 for (unsigned i = 0; i < vertices.size() / stride - 1; i++) {
  374.                     lineIndices.push_back(offset + i);
  375.                     lineIndices.push_back(offset + i + 1);
  376.                 }
  377.             }
  378.             break;
  379.         case enigma_user::pr_trianglelist:
  380.             if (indices.size() > 0) {
  381.                 triangleIndexedVertices.insert(triangleIndexedVertices.end(), vertices.begin(), vertices.end());
  382.                 for (std::vector<GLuint>::iterator it = indices.begin(); it != indices.end(); ++it) { *it += triangleIndexedCount; }
  383.                 triangleIndices.insert(triangleIndices.end(), indices.begin(), indices.end());
  384.             } else {
  385.                 triangleVertices.insert(triangleVertices.end(), vertices.begin(), vertices.end());
  386.                 triangleCount += vertices.size() / stride;
  387.             }
  388.             break;
  389.         case enigma_user::pr_trianglestrip:
  390.             triangleIndexedVertices.insert(triangleIndexedVertices.end(), vertices.begin(), vertices.end());
  391.             if (indices.size() > 0) {
  392.                 for (std::vector<GLuint>::iterator it = indices.begin(); it != indices.end(); ++it) { *it += triangleIndexedCount; }
  393.                 for (unsigned i = 0; i < indices.size() - 2; i++) {
  394.                     // check for and continue if indexed triangle is degenerate, because the GPU won't render it anyway
  395.                     if (indices[i] == indices[i + 1] || indices[i] == indices[i + 2]  || indices[i + 1] == indices[i + 2] ) { continue; }
  396.                     triangleIndices.push_back(indices[i]);
  397.                     triangleIndices.push_back(indices[i+1]);
  398.                     triangleIndices.push_back(indices[i+2]);
  399.                 }
  400.             } else {
  401.                 unsigned offset = (triangleIndexedVertices.size() - vertices.size()) / stride;
  402.                 for (unsigned i = 0; i < vertices.size() / stride - 2; i++) {
  403.                     if (i % 2) {
  404.                         triangleIndices.push_back(offset + i + 2);
  405.                         triangleIndices.push_back(offset + i + 1);
  406.                         triangleIndices.push_back(offset + i);
  407.                     } else {
  408.                         triangleIndices.push_back(offset + i);
  409.                         triangleIndices.push_back(offset + i + 1);
  410.                         triangleIndices.push_back(offset + i + 2);
  411.                     }
  412.                 }
  413.             }
  414.             break;
  415.         case enigma_user::pr_trianglefan:
  416.             triangleIndexedVertices.insert(triangleIndexedVertices.end(), vertices.begin(), vertices.end());
  417.             if (indices.size() > 0) {
  418.                 for (std::vector<GLuint>::iterator it = indices.begin(); it != indices.end(); ++it) { *it += triangleIndexedCount; }
  419.                 for (unsigned i = 1; i < indices.size() - 1; i++) {
  420.                     // check for and continue if indexed triangle is degenerate, because the GPU won't render it anyway
  421.                     if (indices[0] == indices[i] || indices[0] == indices[i + 1]  || indices[i] == indices[i + 1] ) { continue; }
  422.                     triangleIndices.push_back(indices[0]);
  423.                     triangleIndices.push_back(indices[i]);
  424.                     triangleIndices.push_back(indices[i + 1]);
  425.                 }
  426.             } else {
  427.                 unsigned offset = (triangleIndexedVertices.size() - vertices.size()) / stride;
  428.                 for (unsigned i = 1; i < vertices.size() / stride - 1; i++) {
  429.                     triangleIndices.push_back(offset);
  430.                     triangleIndices.push_back(offset + i);
  431.                     triangleIndices.push_back(offset + i + 1);
  432.                 }
  433.             }
  434.             break;
  435.     }
  436.  
  437.     // Clean up the temporary vertex and index containers now that they have been batched efficiently
  438.     vertices.clear();
  439.     indices.clear();
  440.   }
  441.  
  442.   void BufferGenerate()
  443.   {
  444.     vector<VertexElement> vdata;
  445.     vector<GLuint> idata;
  446.  
  447.     vdata.reserve(triangleVertices.size() + lineVertices.size() + pointVertices.size() + triangleIndexedVertices.size() + lineIndexedVertices.size() + pointIndexedVertices.size());
  448.     idata.reserve(triangleIndices.size() + lineIndices.size() + pointIndices.size());
  449.  
  450.     unsigned interleave = 0;
  451.  
  452.     triangleIndexedCount = triangleIndices.size();
  453.     if (triangleIndexedCount > 0) {
  454.         vdata.insert(vdata.end(), triangleIndexedVertices.begin(), triangleIndexedVertices.end());
  455.         idata.insert(idata.end(), triangleIndices.begin(), triangleIndices.end());
  456.         interleave += triangleIndexedVertices.size()/GetVertexStride();
  457.     }
  458.  
  459.     lineIndexedCount = lineIndices.size();
  460.     if (lineIndexedCount > 0) {
  461.         vdata.insert(vdata.end(), lineIndexedVertices.begin(), lineIndexedVertices.end());
  462.         for (std::vector<GLuint>::iterator it = lineIndices.begin(); it != lineIndices.end(); ++it) { *it += interleave; }
  463.         idata.insert(idata.end(), lineIndices.begin(), lineIndices.end());
  464.         interleave += lineIndexedVertices.size()/GetVertexStride();
  465.     }
  466.  
  467.     pointIndexedCount = pointIndices.size();
  468.     if (pointIndexedCount > 0) {
  469.         vdata.insert(vdata.end(), pointIndexedVertices.begin(), pointIndexedVertices.end());
  470.         for (std::vector<GLuint>::iterator it = lineIndices.begin(); it != lineIndices.end(); ++it) { *it += interleave; }
  471.         idata.insert(idata.end(), pointIndices.begin(), pointIndices.end());
  472.     }
  473.  
  474.     if (idata.size() > 0) {
  475.         vboindexed = true;
  476.         indexedoffset += vdata.size();
  477.  
  478.         if (!ibogenerated) {
  479.             glGenBuffersARB( 1, &indexBuffer );
  480.             ibogenerated = true;
  481.             glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER, indexBuffer );
  482.             glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER, idata.size() * sizeof(GLuint), &idata[0], vbodynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW );
  483.         } else {
  484.             glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER, indexBuffer );
  485.  
  486.             GLint nBufferSize = 0;
  487.             glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &nBufferSize);
  488.             if (idata.size() * sizeof(GLuint) / nBufferSize > 0.5 ) {
  489.                 glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER, idata.size() * sizeof(GLuint), &idata[0], vbodynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW );
  490.             } else {
  491.                 glBufferSubDataARB( GL_ELEMENT_ARRAY_BUFFER, 0, idata.size() * sizeof(GLuint), &idata[0]);
  492.             }
  493.         }
  494.  
  495.         // Unbind the buffer we do not need anymore
  496.         glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER, 0 );
  497.         // Clean up temporary interleaved data
  498.         idata.clear();
  499.     } else {
  500.         vboindexed = false;
  501.     }
  502.  
  503.     if (triangleCount > 0) {
  504.         vdata.insert(vdata.end(), triangleVertices.begin(), triangleVertices.end());
  505.     }
  506.  
  507.     if (lineCount > 0) {
  508.         vdata.insert(vdata.end(), lineVertices.begin(), lineVertices.end());
  509.     }
  510.  
  511.     if (pointCount > 0) {
  512.         vdata.insert(vdata.end(), pointVertices.begin(), pointVertices.end());
  513.     }
  514.  
  515.     GLsizei buffsize = GetVertexSize() * vdata.size();
  516.    
  517.     if (!vbogenerated) {
  518.         glGenBuffersARB( 1, &vertexBuffer );
  519.         vbogenerated = true;
  520.         glBindBufferARB( GL_ARRAY_BUFFER, vertexBuffer );
  521.         glBufferDataARB( GL_ARRAY_BUFFER, buffsize, &vdata[0], vbodynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW );
  522.     } else {
  523.         glBindBufferARB( GL_ARRAY_BUFFER, vertexBuffer );
  524.  
  525.         GLint nBufferSize = 0;
  526.         glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &nBufferSize);
  527.         if (buffsize / nBufferSize > 0.5 ) {
  528.             glBufferDataARB( GL_ARRAY_BUFFER, buffsize, &vdata[0], vbodynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW );
  529.         } else {
  530.             glBufferSubDataARB( GL_ARRAY_BUFFER, 0, buffsize, &vdata[0]);
  531.         }
  532.     }
  533.  
  534.     // Unbind the buffer we do not need anymore
  535.     glBindBufferARB( GL_ARRAY_BUFFER, 0 );
  536.     // Clean up temporary interleaved data
  537.     vdata.clear();
  538.  
  539.     // Clean up the data from RAM it is now safe on VRAM
  540.     ClearData();
  541.   }
  542.  
  543.   void Draw(int vertex_start = 0, int vertex_count = -1)
  544.   {
  545.     GLsizei stride = GetVertexSize();
  546.     if (!stride) { return; }
  547.     if (!vbogenerated || !vbobuffered) {
  548.       vbobuffered = true;
  549.       BufferGenerate();
  550.     }
  551.  
  552.     #define OFFSET( P )  ( ( const GLvoid * ) ( sizeof(gs_scalar) * ( P         ) ) )
  553.  
  554.     // Enable vertex array's for fast vertex processing
  555.     glBindBufferARB( GL_ARRAY_BUFFER, vertexBuffer );
  556.     if (vboindexed) {
  557.         glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER, indexBuffer );
  558.     }
  559.  
  560.     glEnableClientState(GL_VERTEX_ARRAY);
  561.     unsigned offset = 0;
  562.     glVertexPointer( vertexStride, GL_FLOAT, stride, OFFSET(offset) ); // Set the vertex pointer to the offset in the buffer
  563.     offset += vertexStride;
  564.  
  565.     if (useNormals){
  566.         glEnableClientState(GL_NORMAL_ARRAY);
  567.         glNormalPointer( GL_FLOAT, stride, OFFSET(offset) ); // Set the normal pointer to the offset in the buffer
  568.         offset += 3;
  569.     }
  570.  
  571.     if (useTextures){
  572.         glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  573.         glTexCoordPointer( 2, GL_FLOAT, stride, OFFSET(offset) ); // Set the texture pointer to the offset in the buffer
  574.         offset += 2;
  575.     }
  576.  
  577.     if (useColors){
  578.         glEnableClientState(GL_COLOR_ARRAY);
  579.         glColorPointer( 4, GL_UNSIGNED_BYTE, stride, OFFSET(offset)); // Set The Color Pointer To The Color Buffer
  580.     }
  581.  
  582.     #define OFFSETE( P )  ( ( const GLvoid * ) ( sizeof( GLuint ) * ( P         ) ) )
  583.     offset = vertex_start;
  584.  
  585.     // Draw the indexed primitives
  586.     if (triangleIndexedCount > 0) {
  587.         glDrawElements(GL_TRIANGLES, (vertex_count==-1?triangleIndexedCount:vertex_count), GL_UNSIGNED_INT, OFFSETE(offset));
  588.         offset += triangleIndexedCount;
  589.     }
  590.     if (lineIndexedCount > 0) {
  591.         glDrawElements(GL_LINES, lineIndexedCount, GL_UNSIGNED_INT, OFFSETE(offset));
  592.         offset += lineIndexedCount;
  593.     }
  594.     if (pointIndexedCount > 0) {
  595.         glDrawElements(GL_POINTS, pointIndexedCount, GL_UNSIGNED_INT, OFFSETE(offset));
  596.     }
  597.  
  598.     offset = indexedoffset/GetVertexStride();
  599.  
  600.     // Draw the unindexed primitives
  601.     if (triangleCount > 0) {
  602.         glDrawArrays(GL_TRIANGLES, (vertex_start==0?offset:vertex_start), (vertex_count==-1?triangleCount:vertex_count));
  603.         offset += triangleCount;
  604.     }
  605.     if (lineCount > 0) {
  606.         glDrawArrays(GL_LINES, offset, lineCount);
  607.         offset += lineCount;
  608.     }
  609.     if (pointCount > 0) {
  610.         glDrawArrays(GL_POINTS, offset, pointCount);
  611.     }
  612.  
  613.     glBindBufferARB( GL_ARRAY_BUFFER, 0 );
  614.     if (vboindexed) {
  615.         glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER, 0 );
  616.     }
  617.  
  618.     glDisableClientState(GL_VERTEX_ARRAY);
  619.     if (useTextures) glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  620.     if (useNormals) glDisableClientState(GL_NORMAL_ARRAY);
  621.     if (useColors) glDisableClientState(GL_COLOR_ARRAY);
  622.   }
  623. };
  624.  
  625. extern vector<Mesh*> meshes;
RAW Paste Data