Compare commits
No commits in common. "master" and "v2.0" have entirely different histories.
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
# vim:filetype=python
|
# vim:filetype=python
|
||||||
|
|
||||||
env = Environment(LIBS = ['GL'], CXXFLAGS = ['-Wall', '-DGL_GLEXT_PROTOTYPES'])
|
env = Environment(LIBS = ['GL'])
|
||||||
|
|
||||||
env.Program('driver', Glob('*.cc'))
|
env.Program('driver', Glob('*.cc'))
|
||||||
|
107
WFObj.cc
107
WFObj.cc
@ -1,4 +1,6 @@
|
|||||||
|
|
||||||
|
#define GL_GLEXT_PROTOTYPES
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@ -6,6 +8,7 @@
|
|||||||
#include <ctype.h> /* isspace() */
|
#include <ctype.h> /* isspace() */
|
||||||
#include <string.h> /* strlen() */
|
#include <string.h> /* strlen() */
|
||||||
#include <stdlib.h> /* atoi */
|
#include <stdlib.h> /* atoi */
|
||||||
|
#include <GL/gl.h>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -97,8 +100,14 @@ static void checkGLErrorLine(const char * function, int line)
|
|||||||
|
|
||||||
/****** WFObj functions ******/
|
/****** WFObj functions ******/
|
||||||
|
|
||||||
WFObj::WFObj()
|
WFObj::WFObj(loadfile_t lf, loadtexture_t lt)
|
||||||
{
|
{
|
||||||
|
m_loadfile = lf;
|
||||||
|
m_loadtexture = lt;
|
||||||
|
if (m_loadfile == NULL)
|
||||||
|
{
|
||||||
|
m_loadfile = loadfile;
|
||||||
|
}
|
||||||
if (m_valid)
|
if (m_valid)
|
||||||
{
|
{
|
||||||
glDeleteBuffers(1, &m_data_vbo);
|
glDeleteBuffers(1, &m_data_vbo);
|
||||||
@ -114,24 +123,18 @@ WFObj::~WFObj()
|
|||||||
|
|
||||||
void WFObj::clear()
|
void WFObj::clear()
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < sizeof(m_vertices)/sizeof(m_vertices[0]); i++)
|
for (int i = 0; i < sizeof(m_vertices)/sizeof(m_vertices[0]); i++)
|
||||||
m_vertices[i].clear();
|
m_vertices[i].clear();
|
||||||
m_faces.clear();
|
m_faces.clear();
|
||||||
|
m_face_indices.clear();
|
||||||
m_materials.clear();
|
m_materials.clear();
|
||||||
m_valid = false;
|
m_valid = false;
|
||||||
m_path = "";
|
m_path = "";
|
||||||
m_current_material_name = "";
|
m_current_material_name = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WFObj::load(const char *fname, loadfile_t lf, loadtexture_t lt)
|
bool WFObj::load(const char *fname)
|
||||||
{
|
{
|
||||||
m_loadfile = lf;
|
|
||||||
m_loadtexture = lt;
|
|
||||||
if (m_loadfile == NULL)
|
|
||||||
{
|
|
||||||
m_loadfile = loadfile;
|
|
||||||
}
|
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
Buffer buff;
|
Buffer buff;
|
||||||
@ -214,10 +217,7 @@ void WFObj::processInputLine(const std::string & input)
|
|||||||
else if (type == "f")
|
else if (type == "f")
|
||||||
{
|
{
|
||||||
if (m_faces.find(m_current_material_name) == m_faces.end())
|
if (m_faces.find(m_current_material_name) == m_faces.end())
|
||||||
{
|
|
||||||
m_faces[m_current_material_name] = vector<Face>();
|
m_faces[m_current_material_name] = vector<Face>();
|
||||||
m_num_materials = m_faces.size();
|
|
||||||
}
|
|
||||||
vector<Face> faces = readFaces(tokens);
|
vector<Face> faces = readFaces(tokens);
|
||||||
for (vector<Face>::iterator it = faces.begin(); it != faces.end(); it++)
|
for (vector<Face>::iterator it = faces.begin(); it != faces.end(); it++)
|
||||||
m_faces[m_current_material_name].push_back(*it);
|
m_faces[m_current_material_name].push_back(*it);
|
||||||
@ -339,7 +339,7 @@ WFObj::VertexRef WFObj::readVertexRef(const std::string ref)
|
|||||||
void WFObj::loadMaterial(const std::string & name)
|
void WFObj::loadMaterial(const std::string & name)
|
||||||
{
|
{
|
||||||
Buffer buff;
|
Buffer buff;
|
||||||
string path = resolvePath(name);
|
string path = (name[0] != '/') ? basePath(m_path) + name : name;
|
||||||
if (!m_loadfile(path.c_str(), buff))
|
if (!m_loadfile(path.c_str(), buff))
|
||||||
{
|
{
|
||||||
cerr << "WFObj: error: couldn't open material file '" << path << "'"
|
cerr << "WFObj: error: couldn't open material file '" << path << "'"
|
||||||
@ -370,7 +370,7 @@ void WFObj::loadMaterial(const std::string & name)
|
|||||||
else if (tokens[0] == "Ns")
|
else if (tokens[0] == "Ns")
|
||||||
{
|
{
|
||||||
m_materials[mat_name].shininess = atof(tokens[1].c_str());
|
m_materials[mat_name].shininess = atof(tokens[1].c_str());
|
||||||
m_materials[mat_name].flags |= Material::SHININESS_BIT;
|
m_materials[mat_name].flags |= Material::MAT_SHININESS;
|
||||||
}
|
}
|
||||||
else if (tokens[0] == "Ka")
|
else if (tokens[0] == "Ka")
|
||||||
{
|
{
|
||||||
@ -380,7 +380,7 @@ void WFObj::loadMaterial(const std::string & name)
|
|||||||
m_materials[mat_name].ambient[i] =
|
m_materials[mat_name].ambient[i] =
|
||||||
atof(tokens[i + 1].c_str());
|
atof(tokens[i + 1].c_str());
|
||||||
m_materials[mat_name].ambient[3] = 1.0;
|
m_materials[mat_name].ambient[3] = 1.0;
|
||||||
m_materials[mat_name].flags |= Material::AMBIENT_BIT;
|
m_materials[mat_name].flags |= Material::MAT_AMBIENT;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
cerr << "WFObj: error: 'Ka' material directive requires"
|
cerr << "WFObj: error: 'Ka' material directive requires"
|
||||||
@ -394,7 +394,7 @@ void WFObj::loadMaterial(const std::string & name)
|
|||||||
m_materials[mat_name].diffuse[i] =
|
m_materials[mat_name].diffuse[i] =
|
||||||
atof(tokens[i + 1].c_str());
|
atof(tokens[i + 1].c_str());
|
||||||
m_materials[mat_name].diffuse[3] = 1.0;
|
m_materials[mat_name].diffuse[3] = 1.0;
|
||||||
m_materials[mat_name].flags |= Material::DIFFUSE_BIT;
|
m_materials[mat_name].flags |= Material::MAT_DIFFUSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
cerr << "WFObj: error: 'Kd' material directive requires"
|
cerr << "WFObj: error: 'Kd' material directive requires"
|
||||||
@ -408,7 +408,7 @@ void WFObj::loadMaterial(const std::string & name)
|
|||||||
m_materials[mat_name].specular[i] =
|
m_materials[mat_name].specular[i] =
|
||||||
atof(tokens[i + 1].c_str());
|
atof(tokens[i + 1].c_str());
|
||||||
m_materials[mat_name].specular[3] = 1.0;
|
m_materials[mat_name].specular[3] = 1.0;
|
||||||
m_materials[mat_name].flags |= Material::SPECULAR_BIT;
|
m_materials[mat_name].flags |= Material::MAT_SPECULAR;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
cerr << "WFObj: error: 'Ks' material directive requires"
|
cerr << "WFObj: error: 'Ks' material directive requires"
|
||||||
@ -418,15 +418,9 @@ void WFObj::loadMaterial(const std::string & name)
|
|||||||
{
|
{
|
||||||
/* ignore these parameters */
|
/* ignore these parameters */
|
||||||
}
|
}
|
||||||
else if (tokens[0] == "map_Kd")
|
|
||||||
{
|
|
||||||
m_materials[mat_name].texture = loadTexture(resolvePath(tokens[1]));
|
|
||||||
if (m_materials[mat_name].texture != 0)
|
|
||||||
m_materials[mat_name].flags |= Material::TEXTURE_BIT;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cerr << "WFObj: warning: unrecognized material directive: '"
|
cerr << "WFObj: error: unrecognized material directive: '"
|
||||||
<< tokens[0] << "'" << endl;
|
<< tokens[0] << "'" << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -462,12 +456,6 @@ bool WFObj::buildVBO()
|
|||||||
it != m_faces.end();
|
it != m_faces.end();
|
||||||
it++)
|
it++)
|
||||||
{
|
{
|
||||||
if (m_materials.find(it->first) == m_materials.end())
|
|
||||||
{
|
|
||||||
cerr << "Material '" << it->first << "' referenced in '"
|
|
||||||
<< m_path << "' is not defined." << endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for (vector<Face>::iterator fit = it->second.begin();
|
for (vector<Face>::iterator fit = it->second.begin();
|
||||||
fit != it->second.end();
|
fit != it->second.end();
|
||||||
fit++)
|
fit++)
|
||||||
@ -541,8 +529,7 @@ bool WFObj::buildVBO()
|
|||||||
vid++;
|
vid++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_materials[it->first].first_vertex = first;
|
m_face_indices[it->first] = make_pair(first, vid - first);
|
||||||
m_materials[it->first].num_vertices = vid - first;
|
|
||||||
}
|
}
|
||||||
glGenBuffers(1, &m_data_vbo);
|
glGenBuffers(1, &m_data_vbo);
|
||||||
glGenBuffers(1, &m_index_vbo);
|
glGenBuffers(1, &m_index_vbo);
|
||||||
@ -558,26 +545,52 @@ bool WFObj::buildVBO()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WFObj::bindBuffers()
|
void WFObj::draw()
|
||||||
{
|
{
|
||||||
|
if (!m_valid)
|
||||||
|
return;
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, m_data_vbo);
|
glBindBuffer(GL_ARRAY_BUFFER, m_data_vbo);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_vbo);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_vbo);
|
||||||
|
glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
|
||||||
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glEnableClientState(GL_NORMAL_ARRAY);
|
||||||
|
size_t stride = sizeof(GLfloat) * m_n_floats_per_vref;
|
||||||
|
glVertexPointer(3, GL_FLOAT, stride, NULL);
|
||||||
|
glNormalPointer(GL_FLOAT, stride, (GLvoid *) (sizeof(GLfloat) * 3));
|
||||||
|
if (m_do_textures)
|
||||||
|
{
|
||||||
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
glTexCoordPointer(2, GL_FLOAT, stride,
|
||||||
|
(GLvoid *) (sizeof(GLfloat) * 6));
|
||||||
|
}
|
||||||
|
for (map<string, vector<Face> >::iterator it = m_faces.begin();
|
||||||
|
it != m_faces.end();
|
||||||
|
it++)
|
||||||
|
{
|
||||||
|
glPushAttrib(GL_LIGHTING_BIT);
|
||||||
|
renderMaterial(m_materials[it->first]);
|
||||||
|
glDrawElements(GL_TRIANGLES, m_face_indices[it->first].second,
|
||||||
|
GL_UNSIGNED_SHORT,
|
||||||
|
(GLvoid *) (sizeof(GLshort) * m_face_indices[it->first].first));
|
||||||
|
glPopAttrib();
|
||||||
|
}
|
||||||
|
glPopClientAttrib();
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint WFObj::loadTexture(const std::string & path)
|
void WFObj::renderMaterial(const WFObj::Material & m)
|
||||||
{
|
{
|
||||||
if (m_loadtexture == NULL)
|
if (m.flags & Material::MAT_SHININESS)
|
||||||
return 0;
|
glMaterialf(GL_FRONT, GL_SHININESS, m.shininess);
|
||||||
if (m_textures.find(path) != m_textures.end())
|
if (m.flags & Material::MAT_AMBIENT)
|
||||||
return m_textures[path];
|
glMaterialfv(GL_FRONT, GL_AMBIENT, &m.ambient[0]);
|
||||||
GLuint id = m_loadtexture(path.c_str());
|
if (m.flags & Material::MAT_DIFFUSE)
|
||||||
m_textures[path] = id;
|
glMaterialfv(GL_FRONT, GL_DIFFUSE, &m.diffuse[0]);
|
||||||
return id;
|
if (m.flags & Material::MAT_SPECULAR)
|
||||||
}
|
glMaterialfv(GL_FRONT, GL_SPECULAR, &m.specular[0]);
|
||||||
|
if (m.flags & Material::MAT_TEXTURE)
|
||||||
string WFObj::resolvePath(const string & name)
|
{
|
||||||
{
|
cerr << "WFObj: error: textured materials not implemented yet" << endl;
|
||||||
return (name[0] != '/') ? basePath(m_path) + name : name;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WFObj::VertexRef::operator<(const VertexRef & other) const
|
bool WFObj::VertexRef::operator<(const VertexRef & other) const
|
||||||
|
72
WFObj.h
72
WFObj.h
@ -2,12 +2,7 @@
|
|||||||
#ifndef WFOBJ_H
|
#ifndef WFOBJ_H
|
||||||
#define WFOBJ_H
|
#define WFOBJ_H
|
||||||
|
|
||||||
#ifdef GL_INCLUDE_FILE
|
|
||||||
#include GL_INCLUDE_FILE
|
|
||||||
#else
|
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
@ -19,7 +14,7 @@ public:
|
|||||||
class Buffer
|
class Buffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Buffer() : m_alloc(false) {data = NULL; length = 0;}
|
Buffer() : m_alloc(false) {}
|
||||||
~Buffer() { if (m_alloc) delete data; }
|
~Buffer() { if (m_alloc) delete data; }
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
size_t length;
|
size_t length;
|
||||||
@ -33,48 +28,20 @@ public:
|
|||||||
bool m_alloc;
|
bool m_alloc;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Material
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum {
|
|
||||||
SHININESS_BIT = 0x01,
|
|
||||||
AMBIENT_BIT = 0x02,
|
|
||||||
DIFFUSE_BIT = 0x04,
|
|
||||||
SPECULAR_BIT = 0x08,
|
|
||||||
TEXTURE_BIT = 0x10
|
|
||||||
};
|
|
||||||
Material() : flags(0) {}
|
|
||||||
GLfloat shininess;
|
|
||||||
GLfloat ambient[4];
|
|
||||||
GLfloat diffuse[4];
|
|
||||||
GLfloat specular[4];
|
|
||||||
GLuint texture;
|
|
||||||
int flags;
|
|
||||||
int first_vertex;
|
|
||||||
int num_vertices;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef bool (*loadfile_t)(const char *fname, Buffer & buff);
|
typedef bool (*loadfile_t)(const char *fname, Buffer & buff);
|
||||||
typedef GLuint (*loadtexture_t)(const char *fname);
|
typedef GLuint (*loadtexture_t)(const char *fname);
|
||||||
|
|
||||||
enum { VERTEX, VERTEX_TEXTURE, VERTEX_NORMAL, VERTEX_TYPES };
|
enum { VERTEX, VERTEX_TEXTURE, VERTEX_NORMAL, VERTEX_TYPES };
|
||||||
|
|
||||||
/* constructors */
|
/* constructors */
|
||||||
WFObj();
|
WFObj(loadfile_t lf = NULL, loadtexture_t lt = NULL);
|
||||||
~WFObj();
|
~WFObj();
|
||||||
|
|
||||||
/* methods */
|
/* methods */
|
||||||
bool load(const char *fname, loadfile_t lf = NULL, loadtexture_t lt = NULL);
|
bool load(const char *fname);
|
||||||
bool load(const Buffer &buff);
|
bool load(const Buffer &buff);
|
||||||
const float * const getAABB() { return m_aabb; }
|
const float * const getAABB() { return m_aabb; }
|
||||||
size_t getStride() { return sizeof(GLfloat) * m_n_floats_per_vref; }
|
void draw();
|
||||||
size_t getVertexOffset() { return 0; }
|
|
||||||
size_t getNormalOffset() { return 3 * sizeof(GLfloat); }
|
|
||||||
size_t getTextureCoordOffset() { return 6 * sizeof(GLfloat); }
|
|
||||||
void bindBuffers();
|
|
||||||
size_t getNumMaterials() { return m_num_materials; }
|
|
||||||
std::map<std::string, Material> & getMaterials() { return m_materials; }
|
|
||||||
bool doTextures() { return m_do_textures; }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/* types */
|
/* types */
|
||||||
@ -92,9 +59,9 @@ protected:
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
VertexRef() : vertex(0), texture(0), normal(0) {}
|
VertexRef() : vertex(0), texture(0), normal(0) {}
|
||||||
size_t vertex;
|
int vertex;
|
||||||
size_t texture;
|
int texture;
|
||||||
size_t normal;
|
int normal;
|
||||||
bool operator<(const VertexRef & other) const;
|
bool operator<(const VertexRef & other) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -104,6 +71,25 @@ protected:
|
|||||||
VertexRef vertices[3];
|
VertexRef vertices[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Material
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
MAT_SHININESS = 0x01,
|
||||||
|
MAT_AMBIENT = 0x02,
|
||||||
|
MAT_DIFFUSE = 0x04,
|
||||||
|
MAT_SPECULAR = 0x08,
|
||||||
|
MAT_TEXTURE = 0x10
|
||||||
|
};
|
||||||
|
Material() : flags(0) {}
|
||||||
|
GLfloat shininess;
|
||||||
|
GLfloat ambient[4];
|
||||||
|
GLfloat diffuse[4];
|
||||||
|
GLfloat specular[4];
|
||||||
|
std::string texture;
|
||||||
|
int flags;
|
||||||
|
};
|
||||||
|
|
||||||
/* methods */
|
/* methods */
|
||||||
void clear();
|
void clear();
|
||||||
void processInputLine(const std::string & input);
|
void processInputLine(const std::string & input);
|
||||||
@ -115,12 +101,12 @@ protected:
|
|||||||
std::string getLine(const Buffer & buff, size_t idx, size_t *update_idx);
|
std::string getLine(const Buffer & buff, size_t idx, size_t *update_idx);
|
||||||
void loadMaterial(const std::string & name);
|
void loadMaterial(const std::string & name);
|
||||||
bool buildVBO();
|
bool buildVBO();
|
||||||
GLuint loadTexture(const std::string & path);
|
void renderMaterial(const Material & m);
|
||||||
std::string resolvePath(const std::string & name);
|
|
||||||
|
|
||||||
/* variables */
|
/* variables */
|
||||||
std::vector<Vertex> m_vertices[VERTEX_TYPES];
|
std::vector<Vertex> m_vertices[VERTEX_TYPES];
|
||||||
std::map< std::string, std::vector< Face > > m_faces;
|
std::map< std::string, std::vector< Face > > m_faces;
|
||||||
|
std::map< std::string, std::pair<int, int> > m_face_indices;
|
||||||
std::map< std::string, Material > m_materials;
|
std::map< std::string, Material > m_materials;
|
||||||
float m_aabb[6];
|
float m_aabb[6];
|
||||||
std::string m_path;
|
std::string m_path;
|
||||||
@ -131,8 +117,6 @@ protected:
|
|||||||
GLuint m_data_vbo, m_index_vbo;
|
GLuint m_data_vbo, m_index_vbo;
|
||||||
bool m_do_textures;
|
bool m_do_textures;
|
||||||
size_t m_n_floats_per_vref;
|
size_t m_n_floats_per_vref;
|
||||||
size_t m_num_materials;
|
|
||||||
std::map<std::string, GLuint> m_textures;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user