Skip to content

Instantly share code, notes, and snippets.

@HybridEidolon
Created March 11, 2015 00:32
Show Gist options
  • Save HybridEidolon/de04303c7e31b6df7dd5 to your computer and use it in GitHub Desktop.
Save HybridEidolon/de04303c7e31b6df7dd5 to your computer and use it in GitHub Desktop.
#include <vector>
#include <GL/gl.h>
using namespace std;
struct Vector3f
{
float x;
float y;
float z;
Vector3f(float x, float y, float z) : x(x), y(y), z(z) {}
Vector3f(const Vector3f & copy) : x(copy.x), y(copy.y), z(copy.z) {}
/* ... operator overloads for various operations ... */
/** The cross product between this vector and another vector. */
Vector3f cross(const Vector3f & r);
};
/* ... implementation details for Vector3f hidden for brevity ... */
void drawVertexArray (const vector<Vector3f> & verts, const GLenum primitiveType);
void drawVertexArray (const vector<Vector3f> & verts, const GLenum primitiveType)
{
vector<float> vertexArray;
const int componentsPerVertex = 3; // 3-dimensional vertices in this vertex array
const GLenum componentType = GL_FLOAT; // there are several component types, but we usually use float
const int stride = 0;
/* Stride is used if we are compacting more than just positions into a single array.
* You can use a single array to stuff vertex position, normal, color, etc, using
* an array offset and the stride set to the struct size of the vertex. */
// For clarity, we will map vector<Vector3f> -> vector<float>
// Note: we are using C++11 foreach syntax. Use --std=c++11 with gcc/clang to compile.
for (Vector3f v : verts)
{
vertexArray.push_back(v.x);
vertexArray.push_back(v.y);
vertexArray.push_back(v.z);
}
// First, enable the necessary client states and set the client-side vertex pointer.
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(componentsPerVertex, componentType, stride, &vertexArray[0]);
// This makes use of a clever trick allowed by the STL spec for std::vector.
// As long as vertexArray isn't resized, &vertexArray[0] is always a valid C array.
// Calling glDrawArrays will upload the arrays for drawing immediately.
// This eliminates all of the draw call overhead and constant internal array
// resizing caused by glBegin/glEnd.
glDrawArrays(primitiveType, 0, verts.size());
// Now we clean up states.
glDisableClientState(GL_VERTEX_ARRAY);
// Since vertexArray leaves scope here, the memory managed by std::vector
// is automatically freed in its deconstructor.
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment