Compare commits

..

46 Commits

Author SHA1 Message Date
Josh Holtrop
e6a41718b7 copy m_aabb in copy constructor 2011-07-15 13:49:41 -04:00
Josh Holtrop
9a483990a2 read the GL uniform locations 2011-07-15 12:42:16 -04:00
Josh Holtrop
eed74a64f3 fix logic error unbinding shader program in the middle of an object 2011-07-15 12:25:56 -04:00
Josh Holtrop
d043cf999c fix obj shader to remove uniforms 2011-07-15 12:25:18 -04:00
Josh Holtrop
9d33fa3c79 fix boxarena test object to specify materials for all surfaces 2011-05-27 16:26:05 -04:00
Josh Holtrop
943ef698dd update wfobj 2011-05-27 15:40:42 -04:00
Josh Holtrop
6952d2f9c0 locateResource() checks for full path already 2011-05-26 23:08:34 -04:00
Josh Holtrop
2f57e27988 remove executable bit from models 2011-05-26 22:57:40 -04:00
Josh Holtrop
7c8d754c53 disable program after using it 2011-05-26 22:39:29 -04:00
Josh Holtrop
da09c3f3ba bind texture when switching material 2011-05-26 22:20:01 -04:00
Josh Holtrop
3209ec83c5 make sure to call obj.bindBuffers() for WFObj objects 2011-05-26 22:17:46 -04:00
Josh Holtrop
9caaa66a45 reset shader when using old display list 2011-05-26 22:05:32 -04:00
Josh Holtrop
73d418b35c build mipmaps for textures 2011-05-26 21:18:17 -04:00
Josh Holtrop
d7dfddda4e update glslUtil 2011-05-25 20:09:33 -04:00
Josh Holtrop
b7a0867fc2 update glslUtil 2011-05-25 17:09:46 -04:00
Josh Holtrop
9c2f883b31 fix loadTexture to use locateResource() 2011-05-25 16:17:25 -04:00
Josh Holtrop
0c361d3d5a fix shader source file name 2011-05-25 16:14:30 -04:00
Josh Holtrop
36fc988fa2 update glslUtil 2011-05-25 16:13:08 -04:00
Josh Holtrop
8094d60ac8 update TextureCache 2011-05-25 16:11:12 -04:00
Josh Holtrop
a33a2c1ba3 remove unnecessary WFObj include from ag.cc 2011-05-25 16:08:43 -04:00
Josh Holtrop
9fc482dbcc pass Engine ref to Engine::Object for accessing program data 2011-05-25 16:08:02 -04:00
Josh Holtrop
be307c2c32 draw model-based objects using shaders 2011-05-25 15:53:43 -04:00
Josh Holtrop
6e5eafb8d9 add GL_GLEXT_PROTOTYPES to CPPFLAGS 2011-05-25 15:53:25 -04:00
Josh Holtrop
7b497c73c5 remove static loadFile() 2011-05-25 09:26:24 -04:00
Josh Holtrop
96e4a66c2c create "obj" and "obj_tex" shader programs 2011-05-25 09:26:02 -04:00
Josh Holtrop
3b940aa140 update glslUtil 2011-05-25 08:41:24 -04:00
Josh Holtrop
e5c1a3075e update glslUtil 2011-05-23 15:53:46 -04:00
Josh Holtrop
00c28804f6 add glslUtil submodule 2011-05-23 11:24:44 -04:00
Josh Holtrop
826a57107e fix CFS source list: glob everything under shaders/ 2011-05-23 10:21:49 -04:00
Josh Holtrop
c710dee00c add textured object shader; update names 2011-05-22 22:59:01 -04:00
Josh Holtrop
be15f95560 PhyObj::load() takes const ptr 2011-05-21 23:45:13 -04:00
Josh Holtrop
5a0eea19f5 fix qualifiers again 2011-05-21 23:43:49 -04:00
Josh Holtrop
07f4162581 fix some qualifiers dealing with loadFile() 2011-05-21 23:42:52 -04:00
Josh Holtrop
15c30e0d00 fix Engine::validatePath() to accept a const ref 2011-05-21 23:40:44 -04:00
Josh Holtrop
67010e02c2 add Engine::loadWFObjFile() 2011-05-21 23:33:28 -04:00
Josh Holtrop
278867b3c8 AV::Sound copies sound buffer to avoid memory leak 2011-05-21 23:20:50 -04:00
Josh Holtrop
8f1329fed8 fix a few compilation issues 2011-05-20 13:27:40 -04:00
Josh Holtrop
af88db267f fix loadSound() 2011-05-20 07:44:53 -04:00
Josh Holtrop
f78c42c8c8 update WFObj construction, loadFile()/loadTexture() 2011-05-19 23:14:10 -04:00
Josh Holtrop
f1bc763be2 update loadPhy() interface 2011-05-19 22:59:04 -04:00
Josh Holtrop
08dbe60b7b remove Engine::FileLoader 2011-05-19 22:55:09 -04:00
Josh Holtrop
89d98be780 remove FileLoader from PhyObj 2011-05-19 22:30:58 -04:00
Josh Holtrop
e40a79435d update AV to remove FileLoader 2011-05-19 17:14:00 -04:00
Josh Holtrop
6e29f8adf6 update TextureCache submodule 2011-05-19 16:55:17 -04:00
Josh Holtrop
b4cacbd05d fix getFile() usage 2011-05-19 16:46:24 -04:00
Josh Holtrop
8028654ff2 beginning migrate to shaders
add a few submodules
generate C file store with cfs_gen
remove FileLoader/TextureLoader
add initial color shaders for wfobj objects
2011-05-18 17:17:06 -04:00
40 changed files with 703 additions and 1608 deletions

3
.gitignore vendored
View File

@ -9,7 +9,8 @@
/stderr.txt /stderr.txt
/sdl_keymap.h /sdl_keymap.h
/sdl_keymap.cc /sdl_keymap.cc
/ag_lua.cc /cfs.cc
/cfs.h
# /libsrc/ # /libsrc/
/libsrc/*.blend1 /libsrc/*.blend1

15
.gitmodules vendored Normal file
View File

@ -0,0 +1,15 @@
[submodule "cfs_gen"]
path = cfs_gen
url = ../util/cfs_gen.git
[submodule "wfobj"]
path = wfobj
url = ../util/wfobj.git
[submodule "refptr"]
path = refptr
url = ../util/refptr.git
[submodule "TextureCache"]
path = TextureCache
url = ../util/TextureCache.git
[submodule "glslUtil"]
path = glslUtil
url = ../util/glslUtil.git

View File

@ -1,88 +0,0 @@
#ifndef FILELOADER_H
#define FILELOADER_H FILELOADER_H
#include <string>
#include <iostream>
class FileLoader
{
public:
class Path
{
public:
std::string fullPath;
std::string shortPath;
Path() { }
Path(const std::string & full_path,
const std::string & short_path)
: fullPath(full_path), shortPath(short_path) { }
std::string toString() const
{
std::string ret;
if (shortPath != "")
ret += shortPath + ",";
if (fullPath != "")
ret += fullPath;
return ret;
}
};
class Buffer
{
public:
char * data;
int size;
Buffer(int sz)
{
size = sz;
data = new char[size];
_refcnt = new int;
*_refcnt = 1;
m_alloced = true;
}
Buffer(char * data, int sz)
{
size = sz;
this->data = data;
m_alloced = false;
}
void copy(const Buffer & other)
{
data = other.data;
size = other.size;
m_alloced = other.m_alloced;
if (m_alloced)
{
_refcnt = other._refcnt;
(*_refcnt)++;
}
}
Buffer(const Buffer & other) { copy(other); }
Buffer & operator=(const Buffer & other)
{
copy(other);
return *this;
}
~Buffer()
{
if (m_alloced)
{
(*_refcnt)--;
if (*_refcnt < 1)
{
delete _refcnt;
delete data;
}
}
}
protected:
int * _refcnt;
bool m_alloced;
};
virtual int getSize(const Path & path) = 0;
virtual Buffer load(const Path & path) = 0;
};
#endif

View File

@ -41,12 +41,9 @@ PhyObj::Geom::Geom(PhyObj::GeomType type, refptr< vector<float> > args)
/********** PhyObj functions **********/ /********** PhyObj functions **********/
void PhyObj::load(FileLoader * fileLoader, const FileLoader::Path & path) void PhyObj::load(const unsigned char *data, unsigned int size)
{ {
FileLoader::Buffer buff = fileLoader->load(path); string str((char *) data, size);
if (buff.size <= 0)
return;
string str(buff.data, buff.size);
stringstream istr(str, ios_base::in); stringstream istr(str, ios_base::in);
while (!istr.eof()) while (!istr.eof())
{ {

View File

@ -3,7 +3,6 @@
#define PHYOBJ_H #define PHYOBJ_H
#include "refptr/refptr.h" #include "refptr/refptr.h"
#include "FileLoader/FileLoader.h"
#include <vector> #include <vector>
class PhyObj class PhyObj
@ -29,7 +28,7 @@ class PhyObj
}; };
/* Methods */ /* Methods */
void load(FileLoader * fileLoader, const FileLoader::Path & path); void load(const unsigned char *data, unsigned int size);
size_t getNumGeoms() { return m_geoms.size(); } size_t getNumGeoms() { return m_geoms.size(); }
refptr<Geom> getGeom(int i) { return m_geoms[i]; } refptr<Geom> getGeom(int i) { return m_geoms[i]; }

View File

@ -16,7 +16,6 @@ if os.sep == '\\':
platform = 'PLATFORM_WINDOWS' platform = 'PLATFORM_WINDOWS'
else: else:
platform = 'PLATFORM_LINUX' platform = 'PLATFORM_LINUX'
subdirs = ['WFObj', 'PhyObj', 'TextureCache', 'OdeWorld']
env = Environment() env = Environment()
env.ParseConfig('pkg-config --cflags --libs lua5.1') env.ParseConfig('pkg-config --cflags --libs lua5.1')
@ -31,44 +30,46 @@ if platform == 'PLATFORM_WINDOWS':
if platform == 'PLATFORM_LINUX': if platform == 'PLATFORM_LINUX':
env.Append(LIBS = ['GL', 'GLU']) env.Append(LIBS = ['GL', 'GLU'])
env.Append(CPPFLAGS = ['-D'+platform, '-I.']) env.Append(CPPFLAGS = ['-D'+platform, '-I.', '-DGL_GLEXT_PROTOTYPES'])
env.Append(LIBS = ['SDL_image', 'SDL_sound', 'vorbisfile']) env.Append(LIBS = ['SDL_image', 'SDL_sound', 'vorbisfile'])
env.Append(CCFLAGS = ['-O2', '-Wall']) env.Append(CCFLAGS = ['-O2', '-Wall'])
if DEBUG: if DEBUG:
env.Append(CCFLAGS = ['-g']) env.Append(CCFLAGS = ['-g'])
sources = [Glob('src/*.cc'), 'ag_lua.cc', 'sdl_keymap.cc'] sources = [
for sd in subdirs: 'cfs.cc',
sources += [Glob(sd + '/*.c'), Glob(sd + '/*.cc')] 'sdl_keymap.cc',
Glob('src/*.cc'),
'OdeWorld/OdeWorld.cc',
'PhyObj/PhyObj.cc',
'TextureCache/TextureCache.cc',
'wfobj/WFObj.cc',
'glslUtil/glslUtil.c',
]
def F2C(target, source, env): def CFS(target, source, env):
f = open(str(target[0]), 'w') source_list = []
for s in source: for s in source:
c_name = re.sub(r'\W', '_', str(s).split('/')[-1]) source_list.append(str(s))
f.write('unsigned char %s[] = {' % c_name) Popen(['./cfs_gen/cfs_gen.py', str(target[0])] + source_list).wait()
src = open(str(s), 'r')
s_len = 0
while 1:
if s_len % 12 == 0:
f.write('\n ')
ch = src.read(1)
if len(ch) < 1:
break
s_len += 1
f.write('0x%02x, ' % ord(ch))
f.write('0x00\n')
src.close()
f.write('};\n')
f.write('unsigned int %s_len = %d;\n' % (c_name, s_len))
f.close()
return None return None
def CFS_emitter(target, source, env):
target.append(re.sub(r'\.cc?', '.h', str(target[0])))
return target, source
def bt(cmd): def bt(cmd):
return Popen(cmd, shell = True, stdout = PIPE).communicate()[0] return Popen(cmd, shell = True, stdout = PIPE).communicate()[0]
env.Append(BUILDERS = {'F2C' : Builder(action = F2C)}) env.Append(BUILDERS = {'CFS' : Builder(action = CFS, emitter = CFS_emitter)})
env.F2C('ag_lua.cc', 'src/ag.lua') cfs_sources = [
'src/ag.lua',
Glob('shaders/*'),
]
env.CFS('cfs.cc', cfs_sources)
env.Depends('cfs.cc', 'cfs_gen/cfs_gen.py')
env.Command('sdl_keymap.cc', 'gen-sdl-keymap.pl', 'perl gen-sdl-keymap.pl') env.Command('sdl_keymap.cc', 'gen-sdl-keymap.pl', 'perl gen-sdl-keymap.pl')
env.Program(target, sources) env.Program(target, sources)

1
TextureCache Submodule

@ -0,0 +1 @@
Subproject commit 60b16263424cd3828db389e1730eae87439cfe03

View File

@ -1,12 +0,0 @@
TARGET := TextureCache.o
SOURCES := $(wildcard *.cc)
HEADERS := $(wildcard *.h)
all: $(TARGET)
$(TARGET): $(SOURCES) $(HEADERS)
$(CXX) -c -o $@ $(CXXFLAGS) $(SOURCES)
clean:
-rm -f *~ *.o

View File

@ -1,143 +0,0 @@
#include <SDL.h>
#include <SDL_image.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <iostream>
#include "TextureCache.h"
#include "TextureLoader/TextureLoader.h"
#include "FileLoader/FileLoader.h"
using namespace std;
//#define DEBUG_GL_ERROR
#ifdef DEBUG_GL_ERROR
#define checkGLError() checkGLErrorLine(__FUNCTION__, __LINE__)
static void checkGLErrorLine(const char * function, int line)
{
GLenum err = glGetError();
if (err != 0)
{
cerr << "gl error in " << function
<< ": " << err << " (0x" << hex << err << ") at line "
<< dec << line << endl;
}
}
#else
#define checkGLError()
#endif
TextureCache::~TextureCache()
{
}
GLuint TextureCache::load(const FileLoader::Path & path,
FileLoader & fileLoader, bool mipmaps,
int mode, int quality)
{
string filename = path.shortPath;
if (filename == "")
filename = path.fullPath;
if (filename == "")
return 0;
map<string,GLuint>::iterator it = m_cache.find(filename);
if (it != m_cache.end())
{
return it->second;
}
GLuint tex = loadTexture(path, fileLoader, mipmaps, mode, quality);
if (tex > 0)
{
m_cache[filename] = tex;
}
return tex;
}
GLuint TextureCache::loadTexture(const FileLoader::Path & path,
FileLoader & fileLoader, bool mipmaps,
int mode, int quality)
{
checkGLError();
GLuint texture;
FileLoader::Buffer buff = fileLoader.load(path);
if (buff.size <= 0)
return 0;
SDL_RWops * ops = SDL_RWFromMem(buff.data, buff.size);
SDL_Surface * temp = IMG_Load_RW(ops, true);
if (!temp)
{
cerr << "Failed to load image ('" << path.fullPath << "', '"
<< path.shortPath << "'): " << IMG_GetError() << endl;
return 0;
}
SDL_PixelFormat fmt;
fmt.palette = NULL;
fmt.BitsPerPixel = 32;
fmt.BytesPerPixel = 4;
fmt.Rmask = 0x000000FF;
fmt.Gmask = 0x0000FF00;
fmt.Bmask = 0x00FF0000;
fmt.Amask = 0xFF000000;
fmt.Rshift = 0;
fmt.Gshift = 8;
fmt.Bshift = 16;
fmt.Ashift = 24;
SDL_Surface * texsurf = SDL_ConvertSurface(temp, &fmt, SDL_SWSURFACE);
SDL_FreeSurface(temp);
if (!texsurf)
{
cerr << "Image was not converted properly!" << endl;
return 0;
}
unsigned int * pixels = new unsigned int[texsurf->w * texsurf->h];
int y;
unsigned int dstOffset = texsurf->w * (texsurf->h - 1);
unsigned int srcOffset = 0;
for (y = 0; y < texsurf->h; y++)
{
memcpy(pixels + dstOffset,
((unsigned int *)texsurf->pixels) + srcOffset,
texsurf->w << 2);
dstOffset -= texsurf->w;
srcOffset += texsurf->w;
}
glGenTextures(1, &texture);
checkGLError();
glBindTexture(GL_TEXTURE_2D, texture);
checkGLError();
glTexImage2D(GL_TEXTURE_2D, 0, 4, texsurf->w, texsurf->h, 0,
GL_RGBA, GL_UNSIGNED_BYTE, pixels);
if (quality > 0)
{
checkGLError();
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
mipmaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR);
checkGLError();
}
else
{
checkGLError();
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
mipmaps ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST);
checkGLError();
}
checkGLError();
if (mipmaps)
{
checkGLError();
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA,
texsurf->w, texsurf->h, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
checkGLError();
}
SDL_FreeSurface(texsurf);
delete[] pixels;
checkGLError();
return texture;
}

View File

@ -1,30 +0,0 @@
#ifndef TEXTURECACHE_H
#define TEXTURECACHE_H TEXTURECACHE_H
#include <SDL.h>
#include <GL/gl.h>
#include <map>
#include <string>
#include "TextureLoader/TextureLoader.h"
#include "FileLoader/FileLoader.h"
class TextureCache : public TextureLoader
{
public:
virtual ~TextureCache();
virtual GLuint load(const FileLoader::Path & path,
FileLoader & fileLoader, bool mipmaps = true,
int mode = GL_DECAL, int quality = 1);
protected:
/* methods */
GLuint loadTexture(const FileLoader::Path & path,
FileLoader & fileLoader, bool mipmaps,
int mode, int quality);
/* data */
std::map< std::string, GLuint > m_cache;
};
#endif

View File

@ -1,18 +0,0 @@
#ifndef TEXTURELOADER_H
#define TEXTURELOADER_H TEXTURELOADER_H
#include <string>
#include <GL/gl.h>
#include "FileLoader/FileLoader.h"
class TextureLoader
{
public:
virtual GLuint load(
const FileLoader::Path & path,
FileLoader & fileLoader, bool mipmaps = true,
int mode = GL_DECAL, int quality = 1) = 0;
};
#endif

View File

@ -1,10 +0,0 @@
TARGET := WFObj.o
all: $(TARGET)
%.o: %.cc
$(CXX) -c -o $@ $(CPPFLAGS) $(CXXFLAGS) $<
clean:
-rm -f *~ *.o

View File

@ -1,18 +0,0 @@
CXX := g++
CXXFLAGS := -O2
SOURCE := WFObj.cc driver.cc
OBJS := $(SOURCE:.cc=.o)
LDFLAGS := -lGL
TARGET := driver
all: $(TARGET)
$(TARGET): $(OBJS)
$(CXX) -o $@ $^ $(LDFLAGS)
%.o: %.cc %.hh
$(CXX) -c -o $@ $< $(CXXFLAGS)
clean:
-rm -f *~ *.o $(TARGET)

View File

@ -1,703 +0,0 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <ctype.h> // isspace()
#include <string.h> // strlen()
#include <GL/gl.h>
#include <vector>
#include <string>
#include <map>
#include <iostream>
#include <fstream>
#include <sstream>
#include "WFObj.h"
using namespace std;
#define WHITESPACE " \n\r\t\v"
//#define DEBUGGL
/****** static functions ******/
static string trimString(string s)
{
size_t lastpos = s.find_last_not_of(WHITESPACE);
if (lastpos == string::npos)
return "";
s.erase(lastpos + 1);
s.erase(0, s.find_first_not_of(WHITESPACE));
return s;
}
static string stripFirstToken(string & input)
{
size_t firstnonspace = input.find_first_not_of(WHITESPACE);
if (firstnonspace == string::npos)
return "";
size_t spaceafter = input.find_first_of(WHITESPACE, firstnonspace);
string token = input.substr(firstnonspace, spaceafter - firstnonspace);
input.erase(0, spaceafter);
return token;
}
static vector<string> splitString(const string & str, char delim)
{
vector<string> ret;
string s = str;
size_t pos;
while ( (pos = s.find(delim)) != string::npos )
{
string t = s.substr(0, pos);
ret.push_back(t);
s.erase(0, pos + 1);
}
if (s != "")
ret.push_back(s);
return ret;
}
static string basePath(const string & str)
{
string path = str;
size_t pos;
if ( (pos = path.find_last_of("/\\")) != string::npos )
{
path.erase(pos + 1);
return path;
}
return "";
}
//#define DEBUG_GL_ERROR
#ifdef DEBUG_GL_ERROR
#define checkGLError() checkGLErrorLine(__FUNCTION__, __LINE__)
static void checkGLErrorLine(const char * function, int line)
{
GLenum err = glGetError();
if (err != 0)
{
cerr << "gl error in " << function
<< ": " << err << " (0x" << hex << err << ") at line "
<< dec << line << endl;
}
}
#else
#define checkGLError()
#endif
/****** WFObj functions ******/
WFObj::WFObj()
{
init();
}
WFObj::WFObj(FileLoader & fileLoader)
{
init(&fileLoader);
}
WFObj::WFObj(TextureLoader & textureLoader)
{
init(NULL, &textureLoader);
}
WFObj::WFObj(FileLoader & fileLoader, TextureLoader & textureLoader)
{
init(&fileLoader, &textureLoader);
}
void WFObj::init (FileLoader * fileLoader,
TextureLoader * textureLoader)
{
m_fileLoader = fileLoader;
if (m_fileLoader == NULL)
{
m_fileLoader = new WFFileLoader();
m_iCreatedFileLoader = true;
}
else
{
m_iCreatedFileLoader = false;
}
m_textureLoader = textureLoader;
}
WFObj::~WFObj()
{
if (m_iCreatedFileLoader)
delete m_fileLoader;
}
void WFObj::clear()
{
m_data = std::vector< std::vector<std::string> >();
m_loadedVertex = false;
}
bool WFObj::load(const FileLoader::Path & path)
{
clear();
FileLoader::Buffer buff = m_fileLoader->load(path);
if (buff.size <= 0)
return false;
m_path = path;
string str(buff.data, buff.size);
stringstream istr(str, ios_base::in);
load(istr, buff.size);
return true;
}
bool WFObj::load(std::istream & istr, unsigned int size)
{
char buf[size+1];
string buildup;
while (istr.good())
{
istr.getline(buf, size+1);
string input = trimString(buf);
int sz = input.size();
if (sz == 0 || input[0] == '#')
continue;
if (input[sz-1] == '\\')
{
input[sz-1] = ' ';
buildup = input;
continue;
}
if (buildup != "")
input = buildup + input;
buildup = "";
processInputLine(input);
}
return true;
}
void WFObj::processInputLine(const std::string & input)
{
string line = input;
vector<string> lineParts;
for (;;)
{
string token = stripFirstToken(line);
if (token == "")
break;
lineParts.push_back(token);
}
if (lineParts.size() > 0)
m_data.push_back(lineParts);
}
GLuint WFObj::render(bool doTextureInfo, bool enableBlending)
{
checkGLError();
GLuint list = glGenLists(1);
glNewList(list, GL_COMPILE);
int len = m_data.size();
enum { VERTEX, VERTEX_TEXTURE, VERTEX_NORMAL, VERTEX_TYPES };
vector<Vertex> vertices[VERTEX_TYPES];
int numVertsLast = 0;
bool inFace = false;
bool inMaterial = false;
string currentMaterialName;
WFMtl material(this);
for (int i = 0; i < len; i++)
{
string type = m_data[i][0];
if (type == "v")
{
Vertex v = readVertex(m_data[i]);
updateAABB(v.getData());
vertices[VERTEX].push_back(v);
}
else if (type == "vt")
vertices[VERTEX_TEXTURE].push_back(readVertex(m_data[i]));
else if (type == "vn")
vertices[VERTEX_NORMAL].push_back(readVertex(m_data[i]));
else if (type == "f")
{
int numVerts = m_data[i].size() - 1;
if (inFace && (numVerts != numVertsLast || numVertsLast > 4))
{
#ifdef DEBUGGL
cout << "glEnd()" << endl;
#endif
glEnd();
inFace = false;
}
if (!inFace)
{
if (numVerts == 3)
{
#ifdef DEBUGGL
cout << "glBegin(GL_TRIANGLES)" << endl;
#endif
glBegin(GL_TRIANGLES);
}
else if (numVerts == 4)
{
#ifdef DEBUGGL
cout << "glBegin(GL_QUADS)" << endl;
#endif
glBegin(GL_QUADS);
}
else
{
#ifdef DEBUGGL
cout << "glBegin(GL_POLYGON)" << endl;
#endif
glBegin(GL_POLYGON);
}
inFace = true;
}
for (int v = 1; v <= numVerts; v++)
{
int vertexIndices[3] = {0, 0, 0};
parseVertexIndices(m_data[i][v], vertexIndices);
for (int j = 0; j < 3; j++)
{
if (vertexIndices[j] < 0)
vertexIndices[j] += vertices[j].size() + 1;
}
bool valid = true;
for (int j = 0; j < 3; j++)
{
if (vertexIndices[j] > (int) vertices[j].size())
{
valid = false;
break;
}
}
if (vertexIndices[VERTEX] <= 0)
valid = false;
if (!valid)
continue;
if (vertexIndices[VERTEX_NORMAL] != 0)
{
/* a normal is present */
#ifdef DEBUGGL
cout << " glNormal3f(" <<
vertices[VERTEX_NORMAL][vertexIndices[VERTEX_NORMAL]-1]
[0] << ", " <<
vertices[VERTEX_NORMAL][vertexIndices[VERTEX_NORMAL]-1]
[1] << ", " <<
vertices[VERTEX_NORMAL][vertexIndices[VERTEX_NORMAL]-1]
[2] << ")" << endl;
#endif
glNormal3fv(vertices[VERTEX_NORMAL]
[vertexIndices[VERTEX_NORMAL]-1].getData());
}
if (vertexIndices[VERTEX_TEXTURE] != 0)
{
/* a texture coordinate is present */
#ifdef DEBUGGL
cout << " glTexCoord2f(" <<
vertices[VERTEX_TEXTURE][vertexIndices[VERTEX_TEXTURE]-1]
[0] << ", " <<
vertices[VERTEX_TEXTURE][vertexIndices[VERTEX_TEXTURE]-1]
[1] << ')' << endl;
#endif
glTexCoord2fv(vertices[VERTEX_TEXTURE]
[vertexIndices[VERTEX_TEXTURE]-1].getData());
}
#ifdef DEBUGGL
cout << " glVertex3f(" <<
vertices[VERTEX][vertexIndices[VERTEX]-1][0] << ", " <<
vertices[VERTEX][vertexIndices[VERTEX]-1][1] << ", " <<
vertices[VERTEX][vertexIndices[VERTEX]-1][2] << ")" <<
" [" << vertexIndices[VERTEX] << "]" << endl;
#endif
glVertex3fv(vertices[VERTEX][vertexIndices[VERTEX]-1].getData());
}
numVertsLast = numVerts;
}
else if (type == "usemtl")
{
if (inFace)
{
#ifdef DEBUGGL
cout << "glEnd()" << endl;
#endif
glEnd();
inFace = false;
}
if (inMaterial)
{
material.renderEnd(currentMaterialName, doTextureInfo,
enableBlending);
inMaterial = false;
}
if (m_data[i].size() >= 2)
{
currentMaterialName = m_data[i][1];
material.renderBegin(currentMaterialName, doTextureInfo,
enableBlending);
inMaterial = true;
}
}
else if (type == "mtllib")
{
if (m_data[i].size() >= 2)
{
FileLoader::Path path(
basePath(m_path.fullPath) + m_data[i][1],
m_data[i][1]);
material.load(path);
}
}
}
if (inFace)
{
#ifdef DEBUGGL
cout << "glEnd()" << endl;
#endif
glEnd();
inFace = false;
}
if (inMaterial)
{
material.renderEnd(currentMaterialName, doTextureInfo, enableBlending);
inMaterial = false;
}
glEndList();
checkGLError();
return list;
}
void WFObj::updateAABB(const float * const vertex)
{
if (m_loadedVertex)
{
if (vertex[0] < m_aabb[0])
m_aabb[0] = vertex[0];
else if (vertex[0] > m_aabb[3])
m_aabb[3] = vertex[0];
if (vertex[1] < m_aabb[1])
m_aabb[1] = vertex[1];
else if (vertex[1] > m_aabb[4])
m_aabb[4] = vertex[1];
if (vertex[2] < m_aabb[2])
m_aabb[2] = vertex[2];
else if (vertex[2] > m_aabb[5])
m_aabb[5] = vertex[2];
}
else
{
m_aabb[0] = m_aabb[3] = vertex[0];
m_aabb[1] = m_aabb[4] = vertex[1];
m_aabb[2] = m_aabb[5] = vertex[2];
m_loadedVertex = true;
}
}
WFObj::Vertex WFObj::readVertex(const vector<string> & parts)
{
int partslen = parts.size();
Vertex v;
for (int i = 1; i < partslen && i <= 4; i++)
{
sscanf(parts[i].c_str(), "%f", &v[i - 1]);
}
return v;
}
void WFObj::parseVertexIndices(const string & vtxref, int * ret)
{
vector<string> parts = splitString(vtxref, '/');
int num = parts.size();
for (int i = 0; i < num && i < 3; i++)
sscanf(parts[i].c_str(), "%d", ret + i);
}
/****** WFMtl functions ******/
void WFObj::WFMtl::clear()
{
m_data = map< string, vector< vector<string> > >();
m_currentMaterialName = "";
m_attributesPushed = false;
}
bool WFObj::WFMtl::load(const FileLoader::Path & path)
{
clear();
FileLoader::Buffer buff = m_obj->m_fileLoader->load(path);
if (buff.size <= 0)
return false;
m_path = path;
string str(buff.data, buff.size);
stringstream istr(str, ios_base::in);
load(istr, buff.size);
return true;
}
bool WFObj::WFMtl::load(std::istream & istr, unsigned int size)
{
char buf[size+1];
string buildup;
while (istr.good())
{
istr.getline(buf, size+1);
string input = trimString(buf);
int sz = input.size();
if (sz == 0 || input[0] == '#')
continue;
if (input[sz-1] == '\\')
{
input[sz-1] = ' ';
buildup = input;
continue;
}
if (buildup != "")
input = buildup + input;
buildup = "";
processInputLine(input);
}
return true;
}
void WFObj::WFMtl::processInputLine(const std::string & input)
{
string line = input;
vector<string> lineParts;
for (;;)
{
string token = stripFirstToken(line);
if (token == "")
break;
lineParts.push_back(token);
}
if (lineParts.size() > 0)
{
if ( (lineParts.size() >= 2) && (lineParts[0] == "newmtl") )
{
m_currentMaterialName = lineParts[1];
}
else if (m_currentMaterialName != "")
{
m_data[m_currentMaterialName].push_back(lineParts);
}
}
}
void WFObj::WFMtl::renderBegin(const string & mtlname, bool doTextureInfo,
bool enableBlending)
{
map< string, vector< vector<string> > >::iterator it = m_data.find(mtlname);
if (it == m_data.end())
return;
vector< vector<string> > & stmts = it->second;
int num_stmts = stmts.size();
bool foundTexture = false;
bool didSomething = false;
checkGLError();
for (int i = 0; i < num_stmts; i++)
{
string & type = stmts[i][0];
if (type == "Ka") /* set ambient color */
{
if ( (stmts[i].size() == 4) && (stmts[i][1] != "spectral") )
{
pushAttributes();
float mat[4] = {0.0f, 0.0f, 0.0f, 1.0f};
for (int j = 0; j < 3; j++)
sscanf(stmts[i][j+1].c_str(), "%f", &mat[j]);
#ifdef DEBUGGL
cout << " glMaterialfv(GL_FRONT, GL_AMBIENT, {";
for (int j = 0; j < 4; j++)
cout << mat[j] << (j < 3 ? ", " : "})");
cout << endl;
#endif
glMaterialfv(GL_FRONT, GL_AMBIENT, mat);
didSomething = true;
}
}
else if (type == "Kd") /* set diffuse color */
{
if ( (stmts[i].size() == 4) && (stmts[i][1] != "spectral") )
{
pushAttributes();
float mat[4] = {0.0f, 0.0f, 0.0f, 1.0f};
for (int j = 0; j < 3; j++)
sscanf(stmts[i][j+1].c_str(), "%f", &mat[j]);
#ifdef DEBUGGL
cout << " glMaterialfv(GL_FRONT, GL_DIFFUSE, {";
for (int j = 0; j < 4; j++)
cout << mat[j] << (j < 3 ? ", " : "})");
cout << endl;
#endif
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat);
didSomething = true;
}
}
else if (type == "Ks") /* set specular color */
{
if ( (stmts[i].size() == 4) && (stmts[i][1] != "spectral") )
{
pushAttributes();
float mat[4] = {0.0f, 0.0f, 0.0f, 1.0f};
for (int j = 0; j < 3; j++)
sscanf(stmts[i][j+1].c_str(), "%f", &mat[j]);
#ifdef DEBUGGL
cout << " glMaterialfv(GL_FRONT, GL_SPECULAR, {";
for (int j = 0; j < 4; j++)
cout << mat[j] << (j < 3 ? ", " : "})");
cout << endl;
#endif
glMaterialfv(GL_FRONT, GL_SPECULAR, mat);
didSomething = true;
}
}
else if (type == "Ns") /* set shininess */
{
if (stmts[i].size() == 2)
{
pushAttributes();
GLfloat shininess = 0.0f;
sscanf(stmts[i][1].c_str(), "%f", &shininess);
#ifdef DEBUGGL
cout << " glMaterialf(GL_FRONT, GL_SHININESS, "
<< shininess << ")" << endl;
#endif
glMaterialf(GL_FRONT, GL_SHININESS, shininess);
didSomething = true;
}
}
else if (type == "map_Kd") /* load a diffuse texture */
{
if (doTextureInfo)
{
if (stmts[i].size() == 2)
{
if (m_obj->m_textureLoader != NULL)
{
FileLoader::Path path(
basePath(m_path.fullPath + stmts[i][1]),
stmts[i][1]);
GLuint tex = m_obj->m_textureLoader->load(path,
*m_obj->m_fileLoader);
if (tex > 0)
{
pushAttributes(); /* jh 2009-11-16 */
#ifdef DEBUGGL
cout << " glBindTexture(GL_TEXTURE_2D, " << tex << ")" << endl;
#endif
glBindTexture(GL_TEXTURE_2D, tex);
foundTexture = true;
didSomething = true;
}
}
}
}
}
}
checkGLError();
if (didSomething)
{
pushAttributes();
if (doTextureInfo)
{
if (enableBlending)
{
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
}
if (foundTexture)
{
#ifdef DEBUGGL
cout << " glEnable(GL_TEXTURE_2D)" << endl;
#endif
glEnable(GL_TEXTURE_2D);
}
else
{
#ifdef DEBUGGL
cout << " glDisable(GL_TEXTURE_2D)" << endl;
#endif
glDisable(GL_TEXTURE_2D);
}
}
}
checkGLError();
}
void WFObj::WFMtl::pushAttributes()
{
if (m_attributesPushed)
return;
m_attributesPushed = true;
#ifdef DEBUGGL
cout << " glPushAttrib(GL_LIGHTING_BIT | GL_TEXTURE_BIT | GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT)"
<< endl;
#endif
checkGLError();
glPushAttrib(GL_LIGHTING_BIT | GL_TEXTURE_BIT | GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT);
checkGLError();
}
void WFObj::WFMtl::renderEnd(const string & mtlname, bool doTextureInfo,
bool enableBlending)
{
map< string, vector< vector<string> > >::iterator it = m_data.find(mtlname);
if (it == m_data.end())
return;
if (m_attributesPushed)
{
#ifdef DEBUGGL
cout << " glPopAttrib()" << endl;
#endif
checkGLError();
glPopAttrib();
checkGLError();
m_attributesPushed = false;
}
}
/****** WFFileLoader functions ******/
int WFObj::WFFileLoader::getSize(const Path & path)
{
struct stat st;
if (path.fullPath == "")
return -1;
if (stat(path.fullPath.c_str(), &st))
return -2;
return st.st_size;
}
FileLoader::Buffer WFObj::WFFileLoader::load(const Path & path)
{
int size = getSize(path);
if (size > 0)
{
int fd = open(path.fullPath.c_str(), O_RDONLY);
if (fd > 0)
{
Buffer buf(size);
int num_read = read(fd, buf.data, size);
close(fd);
if (num_read > 0)
return buf;
}
}
return Buffer(0);
}

View File

@ -1,92 +0,0 @@
#ifndef WFOBJ_H
#define WFOBJ_H
#include "FileLoader/FileLoader.h"
#include "TextureLoader/TextureLoader.h"
#include <GL/gl.h>
#include <vector>
#include <string>
#include <map>
class WFObj
{
public:
WFObj();
WFObj(FileLoader & fileLoader);
WFObj(TextureLoader & textureLoader);
WFObj(FileLoader & fileLoader, TextureLoader & textureLoader);
~WFObj();
class WFMtl
{
public:
WFMtl(WFObj * obj) { m_obj = obj; }
bool load(const FileLoader::Path & path);
void renderBegin(const std::string & mtlname,
bool doTextureInfo = true,
bool enableBlending = false);
void renderEnd(const std::string & mtlname,
bool doTextureInfo = true,
bool enableBlending = false);
protected:
/* methods */
void clear();
void processInputLine(const std::string & input);
void pushAttributes();
bool load(std::istream & istr, unsigned int size);
/* variables */
std::map< std::string, std::vector< std::vector<std::string> > > m_data;
std::string m_currentMaterialName;
bool m_attributesPushed;
FileLoader::Path m_path;
WFObj * m_obj;
};
class WFFileLoader : public FileLoader
{
public:
virtual int getSize(const Path & path);
virtual Buffer load(const Path & path);
};
bool load(const FileLoader::Path & path);
GLuint render(bool doTextureInfo = true,
bool enableBlending = false);
const float * const getAABB() { return m_aabb; }
protected:
/* types */
class Vertex
{
public:
float operator[](int idx) const { return data[idx]; }
float & operator[](int idx) { return data[idx]; }
float * getData() { return data; }
private:
float data[4];
};
/* methods */
void init(FileLoader * fileLoader = NULL,
TextureLoader * textureLoader = NULL);
void clear();
void processInputLine(const std::string & input);
Vertex readVertex(const std::vector<std::string> & parts);
void parseVertexIndices(const std::string & vtxref, int * ret);
void updateAABB(const float * const vertex);
bool load(std::istream & istr, unsigned int size);
/* variables */
std::vector< std::vector<std::string> > m_data;
FileLoader::Path m_path;
float m_aabb[6];
bool m_loadedVertex;
FileLoader * m_fileLoader;
TextureLoader * m_textureLoader;
bool m_iCreatedFileLoader;
};
#endif

1
cfs_gen Submodule

@ -0,0 +1 @@
Subproject commit 6954147f53d57724b7666bf4a1226e17ca64f734

1
glslUtil Submodule

@ -0,0 +1 @@
Subproject commit 0d78e3cf4f606953087cdccae989f805e07ac0e3

0
lib/dwlogo.mtl Executable file → Normal file
View File

0
lib/dwlogo.obj Executable file → Normal file
View File

0
lib/dwlogo.phy Executable file → Normal file
View File

0
libsrc/dwlogo.blend Executable file → Normal file
View File

0
libsrc/dwlogo_phy.blend Executable file → Normal file
View File

1
refptr Submodule

@ -0,0 +1 @@
Subproject commit d5c4876ff8bd674c9d788dfa58eeae35249f3edc

View File

@ -1,99 +0,0 @@
#ifndef REFPTR_H
#define REFPTR_H REFPTR_H
/* Author: Josh Holtrop
* Purpose: Provide a reference-counting pointer-like first order
* C++ object that will free the object it is pointing to when
* all references to it have been destroyed.
* This implementation does not solve the circular reference problem.
* I was not concerned with that when developing this class.
*/
#include <stdlib.h> /* NULL */
template <typename T>
class refptr
{
public:
refptr<T>();
refptr<T>(T * ptr);
refptr<T>(const refptr<T> & orig);
refptr<T> & operator=(const refptr<T> & orig);
refptr<T> & operator=(T * ptr);
~refptr<T>();
T & operator*() const { return *m_ptr; }
T * operator->() const { return m_ptr; }
bool isNull() const { return m_ptr == NULL; }
private:
void cloneFrom(const refptr<T> & orig);
void destroy();
T * m_ptr;
int * m_refCount;
};
template <typename T> refptr<T>::refptr()
{
m_ptr = NULL;
m_refCount = NULL;
}
template <typename T> refptr<T>::refptr(T * ptr)
{
m_ptr = ptr;
m_refCount = new int;
*m_refCount = 1;
}
template <typename T> refptr<T>::refptr(const refptr<T> & orig)
{
cloneFrom(orig);
}
template <typename T> refptr<T> & refptr<T>::operator=(const refptr<T> & orig)
{
destroy();
cloneFrom(orig);
return *this;
}
template <typename T> refptr<T> & refptr<T>::operator=(T * ptr)
{
destroy();
m_ptr = ptr;
m_refCount = new int;
*m_refCount = 1;
return *this;
}
template <typename T> void refptr<T>::cloneFrom(const refptr<T> & orig)
{
this->m_ptr = orig.m_ptr;
this->m_refCount = orig.m_refCount;
if (m_refCount != NULL)
(*m_refCount)++;
}
template <typename T> refptr<T>::~refptr()
{
destroy();
}
template <typename T> void refptr<T>::destroy()
{
if (m_refCount != NULL)
{
if (*m_refCount <= 1)
{
delete m_ptr;
delete m_refCount;
}
else
{
(*m_refCount)--;
}
}
}
#endif

39
shaders/obj.fp Normal file
View File

@ -0,0 +1,39 @@
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
uniform vec4 ambient, diffuse, specular;
uniform float shininess;
varying vec3 pos_i;
varying vec3 normal_i;
void main(void)
{
vec3 n, lightDir;
vec4 color;
float NdotL, RdotEye;
lightDir = normalize(vec3(-0.4, 0, -0.9));
color = vec4(0.2, 0.2, 0.2, 1.0) * ambient; /* ambient light */
n = normalize(normal_i);
NdotL = max(dot(n, -lightDir), 0.0);
if (NdotL > 0.0)
{
/* diffuse component */
color += diffuse * NdotL;
/* specular component */
RdotEye = dot(normalize(-pos_i), normalize(reflect(-lightDir, n)));
if (RdotEye > 0.0)
{
color += clamp(specular * pow(RdotEye, shininess), 0.0, 1.0);
}
}
gl_FragColor = color;
}

13
shaders/obj.vp Normal file
View File

@ -0,0 +1,13 @@
attribute vec3 pos;
attribute vec3 normal;
varying vec3 pos_i;
varying vec3 normal_i;
void main(void)
{
gl_Position = gl_ModelViewProjectionMatrix * vec4(pos, 1);
pos_i = gl_Position.xyz;
normal_i = gl_NormalMatrix * normal;
}

41
shaders/obj_tex.fp Normal file
View File

@ -0,0 +1,41 @@
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
uniform vec4 ambient, specular;
uniform float shininess;
uniform sampler2D tex;
varying vec3 pos_i;
varying vec3 normal_i;
varying vec2 tex_coord_i;
void main(void)
{
vec3 n, lightDir;
vec4 color;
float NdotL, RdotEye;
lightDir = normalize(vec3(-0.1, 0, -0.9));
color = vec4(0.2, 0.2, 0.2, 1.0) * ambient; /* ambient light */
n = normalize(normal_i);
NdotL = max(dot(n, -lightDir), 0.0);
if (NdotL > 0.0)
{
/* diffuse component */
color += texture2D(tex, tex_coord_i) * NdotL;
/* specular component */
RdotEye = dot(normalize(-pos_i), normalize(reflect(-lightDir, n)));
if (RdotEye > 0.0)
{
color += clamp(specular * pow(RdotEye, shininess), 0.0, 1.0);
}
}
gl_FragColor = color;
}

16
shaders/obj_tex.vp Normal file
View File

@ -0,0 +1,16 @@
attribute vec3 pos;
attribute vec3 normal;
attribute vec2 tex_coord;
varying vec3 pos_i;
varying vec3 normal_i;
varying vec2 tex_coord_i;
void main(void)
{
gl_Position = gl_ModelViewProjectionMatrix * vec4(pos, 1);
pos_i = gl_Position.xyz;
tex_coord_i = tex_coord;
normal_i = gl_NormalMatrix * normal;
}

View File

@ -238,13 +238,13 @@ void AV::playCallback(Uint8 * stream, int len)
/******************** AV::Sound ********************/ /******************** AV::Sound ********************/
AV::Sound::Sound(AV & av) AV::Sound::Sound(AV & av)
: m_av(av), : m_av(av)
m_buff(1)
{ {
m_rwops = NULL; m_rwops = NULL;
m_ss = NULL; m_ss = NULL;
m_buff_bytes_left = 0; m_buff_bytes_left = 0;
m_volume = 1.0f; m_volume = 1.0f;
m_data = NULL;
} }
AV::Sound::~Sound() AV::Sound::~Sound()
@ -253,31 +253,28 @@ AV::Sound::~Sound()
{ {
Sound_FreeSample(m_ss); Sound_FreeSample(m_ss);
} }
if (m_data != NULL)
{
delete[] m_data;
}
} }
bool AV::Sound::load(FileLoader & fileLoader, const FileLoader::Path & path) bool AV::Sound::load(const unsigned char *data, unsigned int size)
{ {
m_buff = fileLoader.load(path); m_data = new unsigned char[size];
if (m_buff.size > 0) memcpy(m_data, data, size);
m_rwops = SDL_RWFromMem(m_data, size);
Sound_AudioInfo desired;
desired.channels = CHANNELS;
desired.format = AUDIO_S16SYS;
desired.rate = SOUND_RATE;
m_ss = Sound_NewSample(m_rwops, NULL, &desired,
CALLBACK_SAMPLES * BYTES_PER_SAMPLE);
if (m_ss != NULL)
{ {
m_rwops = SDL_RWFromMem(m_buff.data, m_buff.size); return true;
Sound_AudioInfo desired;
desired.channels = CHANNELS;
desired.format = AUDIO_S16SYS;
desired.rate = SOUND_RATE;
m_ss = Sound_NewSample(m_rwops, NULL, &desired,
CALLBACK_SAMPLES * BYTES_PER_SAMPLE);
if (m_ss != NULL)
{
return true;
}
else
{
cerr << "Error loading sound " << path.toString() << ": "
<< Sound_GetError() << endl;
m_rwops = NULL;
}
} }
m_rwops = NULL;
return false; return false;
} }

View File

@ -8,7 +8,6 @@
#include <set> #include <set>
#include "FileLoader/FileLoader.h"
#include "refptr/refptr.h" #include "refptr/refptr.h"
#define AV_SOUND_FORMAT AUDIO_S16SYS #define AV_SOUND_FORMAT AUDIO_S16SYS
@ -28,8 +27,7 @@ class AV
public: public:
Sound(AV & av); Sound(AV & av);
~Sound(); ~Sound();
bool load(FileLoader & fileLoader, bool load(const unsigned char *data, unsigned int size);
const FileLoader::Path & path);
void play(); void play();
void resume(); void resume();
void stop(); void stop();
@ -40,9 +38,9 @@ class AV
void setVolume(float v); void setVolume(float v);
protected: protected:
AV & m_av; AV & m_av;
unsigned char *m_data;
SDL_RWops * m_rwops; SDL_RWops * m_rwops;
Sound_Sample * m_ss; Sound_Sample * m_ss;
FileLoader::Buffer m_buff;
int m_loop_count; int m_loop_count;
int m_buff_bytes_left; int m_buff_bytes_left;
float m_volume; float m_volume;

View File

@ -20,6 +20,8 @@
#include "AV.h" #include "AV.h"
#include "PhyObj/PhyObj.h" #include "PhyObj/PhyObj.h"
#include "sdl_keymap.h" #include "sdl_keymap.h"
#include "cfs.h"
#include "glslUtil/glslUtil.h"
using namespace std; using namespace std;
@ -96,6 +98,16 @@ static vector<string> split(const string & str, char delim)
return ret; return ret;
} }
static bool loadWFObjFile(const char *fname, WFObj::Buffer & buff)
{
return g_engine->loadWFObjFile(fname, buff);
}
static GLuint loadTexture(const char *fname)
{
return g_engine->loadTexture(fname);
}
/******** Engine functions ********/ /******** Engine functions ********/
@ -116,7 +128,6 @@ Engine::Engine(const string & path, AV & av)
m_autoStartFrame = true; m_autoStartFrame = true;
m_autoEndFrame = true; m_autoEndFrame = true;
m_autoDrawObjects = true; m_autoDrawObjects = true;
m_fileLoader = new EngineFileLoader(this);
m_event_time = 0; m_event_time = 0;
m_font = NULL; m_font = NULL;
m_engine_cursor_visible = m_av.getCursorVisible(); m_engine_cursor_visible = m_av.getCursorVisible();
@ -146,6 +157,64 @@ Engine::Engine(const string & path, AV & av)
m_luaState = lua_open(); m_luaState = lua_open();
registerLibraries(); registerLibraries();
{
const char *obj_v_src = (const char *) getFile("shaders/obj.vp", NULL);
const char *obj_f_src = (const char *) getFile("shaders/obj.fp", NULL);
const static guAttribBinding obj_bindings[] = {
{ATTRIBUTE_OBJ_POS, "pos"},
{ATTRIBUTE_OBJ_NORMAL, "normal"},
{0, NULL}
};
if (obj_v_src != NULL && obj_f_src != NULL)
{
m_programs[PROG_OBJ] = guMakeProgramFromSource(obj_v_src, obj_f_src,
obj_bindings);
}
else
{
m_programs[PROG_OBJ] = 0;
cerr << "Error: Could not obtain 'obj' shader sources" << endl;
}
guUniformLocation uniforms_obj[] = {
{&m_uniforms_obj[UNIFORM_OBJ_AMBIENT], "ambient"},
{&m_uniforms_obj[UNIFORM_OBJ_DIFFUSE], "diffuse"},
{&m_uniforms_obj[UNIFORM_OBJ_SPECULAR], "specular"},
{&m_uniforms_obj[UNIFORM_OBJ_SHININESS], "shininess"},
{NULL, NULL}
};
guGetUniformLocations(m_programs[PROG_OBJ], uniforms_obj);
}
{
const char *obj_tex_v_src =
(const char *) getFile("shaders/obj_tex.vp", NULL);
const char *obj_tex_f_src =
(const char *) getFile("shaders/obj_tex.fp", NULL);
const static guAttribBinding obj_tex_bindings[] = {
{ATTRIBUTE_OBJ_TEX_POS, "pos"},
{ATTRIBUTE_OBJ_TEX_NORMAL, "normal"},
{ATTRIBUTE_OBJ_TEX_TEX_COORD, "tex_coord"},
{0, NULL}
};
if (obj_tex_v_src != NULL && obj_tex_f_src != NULL)
{
m_programs[PROG_OBJ_TEX] = guMakeProgramFromSource(obj_tex_v_src,
obj_tex_f_src, obj_tex_bindings);
}
else
{
m_programs[PROG_OBJ_TEX] = 0;
cerr << "Error: Could not obtain 'obj_tex' shader sources" << endl;
}
guUniformLocation uniforms_obj_tex[] = {
{&m_uniforms_obj_tex[UNIFORM_OBJ_TEX_AMBIENT], "ambient"},
{&m_uniforms_obj_tex[UNIFORM_OBJ_TEX_SPECULAR], "specular"},
{&m_uniforms_obj_tex[UNIFORM_OBJ_TEX_SHININESS], "shininess"},
{NULL, NULL}
};
guGetUniformLocations(m_programs[PROG_OBJ_TEX], uniforms_obj_tex);
}
} }
Engine::~Engine() Engine::~Engine()
@ -157,7 +226,6 @@ Engine::~Engine()
{ {
delete it->second; delete it->second;
} }
delete m_fileLoader;
if (m_font != NULL) if (m_font != NULL)
delete m_font; delete m_font;
} }
@ -236,24 +304,17 @@ void Engine::checkForAllHandlerFunctions()
checkForFunction("mouse_motion_event", mouse_motion); checkForFunction("mouse_motion_event", mouse_motion);
} }
bool Engine::validatePath(string & path) bool Engine::validatePath(const string & path)
{ {
if (path.find_first_not_of(FILENAME_SAFE_CHARS) != string::npos) if (path[0] == '/')
return false; return false;
if (path[0] == ':') vector<string> parts = split(path, '/');
return false;
vector<string> parts = split(path, ':');
path = "";
bool multiple = false;
for (int i = 0, sz = parts.size(); i < sz; i++) for (int i = 0, sz = parts.size(); i < sz; i++)
{ {
if (parts[i].find_first_not_of(".") != string::npos) if (parts[i].find_first_not_of(FILENAME_SAFE_CHARS) != string::npos)
{ return false;
if (multiple) if (parts[i].find_first_not_of(".") == string::npos)
path += "/"; return false;
path += parts[i];
multiple = true;
}
} }
return true; return true;
} }
@ -286,7 +347,9 @@ void Engine::registerLibraries()
string Engine::locateResource(const string & shortname) string Engine::locateResource(const string & shortname)
{ {
string try_path; string try_path = shortname;
if (fileExists(try_path))
return try_path;
/* look for the resource relative to the loaded script's directory */ /* look for the resource relative to the loaded script's directory */
try_path = m_program_directory + "/" + shortname; try_path = m_program_directory + "/" + shortname;
@ -315,7 +378,7 @@ int Engine::addObject(WFObj * obj, bool is_static, bool is_reference,
bool enable_blending, float scale) bool enable_blending, float scale)
{ {
Object * o = new Object(is_static, is_reference, enable_blending, Object * o = new Object(is_static, is_reference, enable_blending,
m_world, obj, scale); m_world, *this, obj, scale);
int id = m_objects.add(o); int id = m_objects.add(o);
o->setID(id); o->setID(id);
return id; return id;
@ -325,7 +388,7 @@ int Engine::addObject(bool is_static, bool is_reference, bool enable_blending,
OdeWorld::GeomType geom_type, refptr< vector<float> > args) OdeWorld::GeomType geom_type, refptr< vector<float> > args)
{ {
Object * o = new Object(is_static, is_reference, enable_blending, Object * o = new Object(is_static, is_reference, enable_blending,
m_world, geom_type, args); m_world, *this, geom_type, args);
int id = m_objects.add(o); int id = m_objects.add(o);
o->setID(id); o->setID(id);
return id; return id;
@ -592,19 +655,23 @@ int Engine::loadModel(const string & name, bool is_static, bool is_reference,
string path = name; string path = name;
if (validatePath(path)) if (validatePath(path))
{ {
FileLoader::Path model_path("", path + ".obj"); string model_path = path + ".obj";
FileLoader::Path phys_path("", path + ".phy"); string phys_path = path + ".phy";
WFObj * obj = new WFObj(*m_fileLoader, m_textureCache); WFObj * obj = new WFObj();
if (obj->load(model_path)) if (obj->load(model_path.c_str(), &::loadWFObjFile, &::loadTexture))
{ {
int id = addObject(obj, is_static, is_reference, enable_blending, int id = addObject(obj, is_static, is_reference, enable_blending,
scale); scale);
Engine::Object * engine_obj = getObject(id); Engine::Object * engine_obj = getObject(id);
if (engine_obj != NULL) if (engine_obj != NULL)
{ {
engine_obj->loadPhy(m_fileLoader, phys_path); unsigned int size;
const unsigned char *phy_data =
loadFile(phys_path.c_str(), &size);
engine_obj->loadPhy(phy_data, size);
free((void *) phy_data);
} }
return id; return id;
} }
@ -619,21 +686,22 @@ int Engine::loadModel(const string & name, bool is_static, bool is_reference,
int Engine::loadSound(const string & name) int Engine::loadSound(const string & name)
{ {
string nm = name; if (validatePath(name))
if (validatePath(nm))
{ {
FileLoader::Path path("", nm); string nm = locateResource(name.c_str());
refptr<AV::Sound> avs = m_av.createSound(); refptr<AV::Sound> avs = m_av.createSound();
if (avs->load(*m_fileLoader, path)) unsigned int size;
const unsigned char *data = loadFile(nm.c_str(), &size);
if (data != NULL)
{ {
return addSound(avs); bool loaded = avs->load(data, size);
} delete[] data;
else if (loaded)
{ return addSound(avs);
cerr << "error loading sound '" << name << "'" << endl;
} }
cerr << "error loading sound '" << name << "'" << endl;
} }
return 0; return 0;
} }
@ -679,12 +747,6 @@ bool Engine::importFullPath(const char * path)
return false; return false;
} }
GLuint Engine::loadTexture(const char * name)
{
FileLoader::Path path("", name);
return m_textureCache.load(path, *m_fileLoader);
}
GLuint Engine::startList() GLuint Engine::startList()
{ {
GLuint list = glGenLists(1); GLuint list = glGenLists(1);
@ -1260,54 +1322,73 @@ void Engine::drawObjects()
} }
} }
/******** Engine::EngineFileLoader functions ********/ int Engine::getFileSize(const char *fname)
Engine::EngineFileLoader::EngineFileLoader(Engine * engine)
{
m_engine = engine;
}
int Engine::EngineFileLoader::getSize(const Path & path)
{ {
struct stat st; struct stat st;
string file_path = resolvePath(path);
if (file_path == "") if (stat(fname, &st))
return -1;
if (stat(file_path.c_str(), &st))
return -2; return -2;
return st.st_size; return st.st_size;
} }
FileLoader::Buffer Engine::EngineFileLoader::load(const Path & path) const unsigned char *Engine::loadFile(const char *fname, unsigned int *len)
{ {
string file_path = resolvePath(path); string file_path = locateResource(fname);
int size = getSize(path); unsigned int size = getFileSize(file_path.c_str());
if (size > 0) if (size > 0)
{ {
FILE * fp = fopen(file_path.c_str(), "rb"); FILE * fp = fopen(file_path.c_str(), "rb");
if (fp != NULL) if (fp != NULL)
{ {
Buffer buf(size); unsigned char *data = new unsigned char[size];
int num_read = fread(buf.data, size, 1, fp); int num_read = fread(data, size, 1, fp);
fclose(fp); fclose(fp);
if (num_read > 0) if (num_read > 0)
{ {
return buf; if (len != NULL)
*len = size;
return data;
} }
} }
} }
return Buffer(0); return NULL;
} }
string Engine::EngineFileLoader::resolvePath(const Path & path) bool Engine::loadWFObjFile(const char *fname, WFObj::Buffer & buff)
{ {
string file_path = m_engine->locateResource(path.shortPath); unsigned int size;
if (file_path == "") const unsigned char *data = loadFile(fname, &size);
file_path = path.fullPath; if (data != NULL)
return file_path; {
buff.alloc(size);
memcpy(buff.data, data, size);
delete[] data;
return true;
}
return false;
} }
GLuint Engine::loadTexture(const char *fname)
{
string path = locateResource(fname);
GLuint id = m_textureCache.load(path.c_str());
if (id != 0)
{
int width, height;
glBindTexture(GL_TEXTURE_2D, id);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height);
char *data = (char *) malloc(4 * width * height);
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, width, height, GL_RGBA,
GL_UNSIGNED_BYTE, data);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR_MIPMAP_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
free(data);
}
return id;
}
/******** Engine::PickedObject functions ********/ /******** Engine::PickedObject functions ********/

View File

@ -9,8 +9,7 @@
#include <SDL.h> #include <SDL.h>
#include "OdeWorld/OdeWorld.h" #include "OdeWorld/OdeWorld.h"
#include "TextureCache/TextureCache.h" #include "TextureCache/TextureCache.h"
#include "FileLoader/FileLoader.h" #include "wfobj/WFObj.h"
#include "WFObj/WFObj.h"
#include "AV.h" #include "AV.h"
#include "refptr/refptr.h" #include "refptr/refptr.h"
#include "ftgl.h" #include "ftgl.h"
@ -24,17 +23,18 @@ class Engine
{ {
public: public:
Object(bool is_static, bool is_reference, bool enable_blending, Object(bool is_static, bool is_reference, bool enable_blending,
OdeWorld & world, WFObj * wfobj, OdeWorld & world, Engine & e, WFObj * wfobj,
float scale = 1.0f); float scale = 1.0f);
Object(bool is_static, bool is_reference, bool enable_blending, Object(bool is_static, bool is_reference, bool enable_blending,
OdeWorld & world, OdeWorld::GeomType geom_type, OdeWorld & world, Engine & e,
OdeWorld::GeomType geom_type,
refptr< std::vector<float> > args); refptr< std::vector<float> > args);
Object(const Object & orig); Object(const Object & orig);
~Object(); ~Object();
void setPosition(double x, double y, double z); void setPosition(double x, double y, double z);
void getPosition(double * x, double * y, double * z); void getPosition(double * x, double * y, double * z);
void loadPhy(FileLoader * fl, const FileLoader::Path & path); void loadPhy(const unsigned char *data, unsigned int size);
void instantiatePhy(); void instantiatePhy();
void setVisible(bool visible) { m_is_visible = visible; } void setVisible(bool visible) { m_is_visible = visible; }
bool getVisible() { return m_is_visible; } bool getVisible() { return m_is_visible; }
@ -103,6 +103,7 @@ class Engine
void createManagedObject(); void createManagedObject();
void render(); void render();
Engine & m_engine;
OdeWorld::Object * m_ode_object; OdeWorld::Object * m_ode_object;
GLuint m_display_list; GLuint m_display_list;
bool m_is_visible; bool m_is_visible;
@ -121,7 +122,8 @@ class Engine
bool m_enable_blending; bool m_enable_blending;
/* for "pre-loaded" objects */ /* for "pre-loaded" objects */
int * m_display_list_refcnt; WFObj * m_obj;
int * m_obj_refcnt;
/* for "managed" objects */ /* for "managed" objects */
OdeWorld::GeomType m_geom_type; OdeWorld::GeomType m_geom_type;
@ -131,17 +133,6 @@ class Engine
float m_texture_scale; float m_texture_scale;
}; };
class EngineFileLoader : public FileLoader
{
public:
EngineFileLoader(Engine * engine);
virtual int getSize(const Path & path);
virtual Buffer load(const Path & path);
protected:
std::string resolvePath(const Path & path);
Engine * m_engine;
};
class PickedObject class PickedObject
{ {
public: public:
@ -264,6 +255,8 @@ class Engine
void exit(); void exit();
bool import(const char * name); bool import(const char * name);
bool importFullPath(const char * path); bool importFullPath(const char * path);
const unsigned char *loadFile(const char *fname, unsigned int *len);
bool loadWFObjFile(const char *fname, WFObj::Buffer & buff);
GLuint loadTexture(const char * name); GLuint loadTexture(const char * name);
void debug_hook(lua_Debug * debug); void debug_hook(lua_Debug * debug);
void setGravity(float gx, float gy, float gz) void setGravity(float gx, float gy, float gz)
@ -334,14 +327,14 @@ class Engine
m_av.setCursorVisible( m_av.setCursorVisible(
m_engine_cursor_visible || m_script_cursor_visible); m_engine_cursor_visible || m_script_cursor_visible);
} }
bool validatePath(std::string & path); bool validatePath(const std::string & path);
int getFileSize(const char *fname);
AV & m_av; AV & m_av;
bool m_engine_cursor_visible; bool m_engine_cursor_visible;
bool m_script_cursor_visible; bool m_script_cursor_visible;
bool m_input_grabbed; bool m_input_grabbed;
TextureCache m_textureCache; TextureCache m_textureCache;
EngineFileLoader * m_fileLoader;
lua_State * m_luaState; lua_State * m_luaState;
std::string m_program_path; std::string m_program_path;
std::string m_program_directory; std::string m_program_directory;
@ -375,6 +368,35 @@ class Engine
bool m_event_mousebutton_down_present; bool m_event_mousebutton_down_present;
bool m_event_mousebutton_up_present; bool m_event_mousebutton_up_present;
bool m_event_mouse_motion_present; bool m_event_mouse_motion_present;
enum { PROG_OBJ, PROG_OBJ_TEX, PROG_COUNT };
GLuint m_programs[PROG_COUNT];
enum {
UNIFORM_OBJ_AMBIENT,
UNIFORM_OBJ_DIFFUSE,
UNIFORM_OBJ_SPECULAR,
UNIFORM_OBJ_SHININESS,
UNIFORM_OBJ_COUNT
};
enum {
ATTRIBUTE_OBJ_POS,
ATTRIBUTE_OBJ_NORMAL,
ATTRIBUTE_OBJ_COUNT
};
GLint m_uniforms_obj[UNIFORM_OBJ_COUNT];
enum {
UNIFORM_OBJ_TEX_AMBIENT,
UNIFORM_OBJ_TEX_SPECULAR,
UNIFORM_OBJ_TEX_SHININESS,
UNIFORM_OBJ_TEX_COUNT
};
enum {
ATTRIBUTE_OBJ_TEX_POS,
ATTRIBUTE_OBJ_TEX_NORMAL,
ATTRIBUTE_OBJ_TEX_TEX_COORD,
ATTRIBUTE_OBJ_TEX_COUNT
};
GLint m_uniforms_obj_tex[UNIFORM_OBJ_TEX_COUNT];
}; };
extern Engine * g_engine; extern Engine * g_engine;

View File

@ -27,8 +27,8 @@ static void checkGLErrorLine(const char * function, int line)
/* used for objects loaded directly from model files */ /* used for objects loaded directly from model files */
Engine::Object::Object(bool is_static, bool is_reference, bool enable_blending, Engine::Object::Object(bool is_static, bool is_reference, bool enable_blending,
OdeWorld & world, WFObj * obj, float scale) OdeWorld & world, Engine & e, WFObj * obj, float scale)
: m_world(world) : m_engine(e), m_world(world)
{ {
m_is_reference = is_reference; m_is_reference = is_reference;
if (m_is_reference) if (m_is_reference)
@ -42,26 +42,28 @@ Engine::Object::Object(bool is_static, bool is_reference, bool enable_blending,
} }
m_is_static = is_static; m_is_static = is_static;
m_enable_blending = enable_blending; m_enable_blending = enable_blending;
m_display_list = obj->render(true, enable_blending);
const float * obj_aabb = obj->getAABB(); const float * obj_aabb = obj->getAABB();
for (int i = 0; i < 6; i++) for (int i = 0; i < 6; i++)
m_aabb[i] = scale * obj_aabb[i]; m_aabb[i] = scale * obj_aabb[i];
m_display_list_refcnt = new int;
*m_display_list_refcnt = 1;
m_is_visible = true; m_is_visible = true;
m_scale = scale; m_scale = scale;
m_is_scaled = ! (fabs(scale - 1.0) < 0.0001); m_is_scaled = ! (fabs(scale - 1.0) < 0.0001);
m_display_list = 0;
m_is_managed = false; m_is_managed = false;
m_mass = 0.0; m_mass = 0.0;
m_mass_is_set = false; m_mass_is_set = false;
m_gravity_mode = true; m_gravity_mode = true;
m_obj = obj;
m_obj_refcnt = new int;
*m_obj_refcnt = 1;
} }
/* used for "managed" objects with one geom */ /* used for "managed" objects with one geom */
Engine::Object::Object(bool is_static, bool is_reference, bool enable_blending, Engine::Object::Object(bool is_static, bool is_reference, bool enable_blending,
OdeWorld & world, OdeWorld::GeomType geom_type, OdeWorld & world, Engine & e,
OdeWorld::GeomType geom_type,
refptr< std::vector<float> > args) refptr< std::vector<float> > args)
: m_world(world) : m_engine(e), m_world(world)
{ {
m_is_reference = is_reference; m_is_reference = is_reference;
m_enable_blending = enable_blending; m_enable_blending = enable_blending;
@ -70,7 +72,6 @@ Engine::Object::Object(bool is_static, bool is_reference, bool enable_blending,
m_scale = 1.0f; m_scale = 1.0f;
m_is_scaled = false; m_is_scaled = false;
m_display_list = 0; m_display_list = 0;
m_display_list_refcnt = NULL;
if (m_is_reference) if (m_is_reference)
{ {
m_ode_object = NULL; m_ode_object = NULL;
@ -92,11 +93,13 @@ Engine::Object::Object(bool is_static, bool is_reference, bool enable_blending,
m_mass = 0.0; m_mass = 0.0;
m_mass_is_set = false; m_mass_is_set = false;
m_gravity_mode = true; m_gravity_mode = true;
m_obj = NULL;
m_obj_refcnt = NULL;
} }
/* used to clone objects */ /* used to clone objects */
Engine::Object::Object(const Engine::Object & orig) Engine::Object::Object(const Engine::Object & orig)
: m_world(orig.m_world) : m_engine(orig.m_engine), m_world(orig.m_world)
{ {
m_is_reference = false; m_is_reference = false;
m_is_visible = orig.m_is_visible; m_is_visible = orig.m_is_visible;
@ -106,13 +109,7 @@ Engine::Object::Object(const Engine::Object & orig)
m_is_scaled = orig.m_is_scaled; m_is_scaled = orig.m_is_scaled;
m_phy = orig.m_phy; m_phy = orig.m_phy;
m_is_managed = orig.m_is_managed; m_is_managed = orig.m_is_managed;
if (m_is_managed) m_display_list = 0;
m_display_list = 0;
else
m_display_list = orig.m_display_list;
m_display_list_refcnt = orig.m_display_list_refcnt;
if (m_display_list_refcnt != NULL)
(*m_display_list_refcnt)++;
m_geom_type = orig.m_geom_type; m_geom_type = orig.m_geom_type;
m_args = orig.m_args; m_args = orig.m_args;
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
@ -142,26 +139,27 @@ Engine::Object::Object(const Engine::Object & orig)
} }
m_gravity_mode = orig.m_gravity_mode; m_gravity_mode = orig.m_gravity_mode;
setGravityMode(m_gravity_mode); setGravityMode(m_gravity_mode);
m_obj = orig.m_obj;
m_obj_refcnt = orig.m_obj_refcnt;
if (m_obj_refcnt)
(*m_obj_refcnt)++;
memcpy(m_aabb, orig.m_aabb, sizeof(m_aabb));
} }
Engine::Object::~Object() Engine::Object::~Object()
{ {
if (m_ode_object != NULL) if (m_ode_object != NULL)
delete m_ode_object; delete m_ode_object;
if (m_display_list_refcnt != NULL) if (m_display_list != 0)
{
(*m_display_list_refcnt)--;
if (*m_display_list_refcnt < 1)
{
/* we hold the last reference to the OpenGL display list */
delete m_display_list_refcnt;
glDeleteLists(m_display_list, 1);
}
}
else
{ {
glDeleteLists(m_display_list, 1); glDeleteLists(m_display_list, 1);
} }
if (m_obj_refcnt != NULL)
{
(*m_obj_refcnt)--;
if (*m_obj_refcnt < 1)
delete m_obj;
}
} }
void Engine::Object::createManagedObject() void Engine::Object::createManagedObject()
@ -454,10 +452,10 @@ void Engine::Object::getPosition(double * x, double * y, double * z)
*x = *y = *z = 0.0; *x = *y = *z = 0.0;
} }
void Engine::Object::loadPhy(FileLoader * fl, const FileLoader::Path & path) void Engine::Object::loadPhy(const unsigned char *data, unsigned int size)
{ {
m_phy = new PhyObj(); m_phy = new PhyObj();
m_phy->load(fl, path); m_phy->load(data, size);
if (!m_is_managed) if (!m_is_managed)
instantiatePhy(); instantiatePhy();
} }
@ -522,7 +520,104 @@ void Engine::Object::draw()
} }
checkGLError(); checkGLError();
glCallList(m_display_list);
if (m_is_managed)
{
glCallList(m_display_list);
}
else
{
m_obj->bindBuffers();
GLuint program = m_engine.m_programs[PROG_OBJ];
glUseProgram(program);
glEnableVertexAttribArray(ATTRIBUTE_OBJ_POS);
glEnableVertexAttribArray(ATTRIBUTE_OBJ_NORMAL);
int stride = m_obj->getStride();
glVertexAttribPointer(ATTRIBUTE_OBJ_POS, 3, GL_FLOAT, GL_FALSE,
stride, (GLvoid *) m_obj->getVertexOffset());
glVertexAttribPointer(ATTRIBUTE_OBJ_NORMAL, 3, GL_FLOAT, GL_FALSE,
stride, (GLvoid *) m_obj->getNormalOffset());
if (m_obj->doTextures())
{
glVertexAttribPointer(ATTRIBUTE_OBJ_TEX_TEX_COORD,
2, GL_FLOAT, GL_FALSE,
stride, (GLvoid *) m_obj->getTextureCoordOffset());
}
for (map<string, WFObj::Material>::iterator it =
m_obj->getMaterials().begin();
it != m_obj->getMaterials().end();
it++)
{
WFObj::Material & m = it->second;
if (m.flags & WFObj::Material::TEXTURE_BIT)
{
glBindTexture(GL_TEXTURE_2D, m.texture);
if (program != m_engine.m_programs[PROG_OBJ_TEX])
{
program = m_engine.m_programs[PROG_OBJ_TEX];
glUseProgram(program);
glEnableVertexAttribArray(ATTRIBUTE_OBJ_TEX_TEX_COORD);
}
}
else
{
if (program != m_engine.m_programs[PROG_OBJ])
{
program = m_engine.m_programs[PROG_OBJ];
glUseProgram(program);
glDisableVertexAttribArray(ATTRIBUTE_OBJ_TEX_TEX_COORD);
}
}
if (m.flags & WFObj::Material::SHININESS_BIT)
{
if (program == m_engine.m_programs[PROG_OBJ_TEX])
glUniform1f(m_engine.m_uniforms_obj_tex[
UNIFORM_OBJ_TEX_SHININESS],
m.shininess);
else
glUniform1f(m_engine.m_uniforms_obj[
UNIFORM_OBJ_SHININESS],
m.shininess);
}
if (m.flags & WFObj::Material::AMBIENT_BIT)
{
if (program == m_engine.m_programs[PROG_OBJ_TEX])
glUniform4fv(m_engine.m_uniforms_obj_tex[
UNIFORM_OBJ_TEX_AMBIENT],
1, &m.ambient[0]);
else
glUniform4fv(m_engine.m_uniforms_obj[
UNIFORM_OBJ_AMBIENT],
1, &m.ambient[0]);
}
if (m.flags & WFObj::Material::DIFFUSE_BIT)
{
if (program != m_engine.m_programs[PROG_OBJ_TEX])
glUniform4fv(m_engine.m_uniforms_obj[
UNIFORM_OBJ_DIFFUSE],
1, &m.diffuse[0]);
}
if (m.flags & WFObj::Material::SPECULAR_BIT)
{
if (program == m_engine.m_programs[PROG_OBJ_TEX])
glUniform4fv(m_engine.m_uniforms_obj_tex[
UNIFORM_OBJ_TEX_SPECULAR],
1, &m.specular[0]);
else
glUniform4fv(m_engine.m_uniforms_obj[
UNIFORM_OBJ_SPECULAR],
1, &m.specular[0]);
}
glDrawElements(GL_TRIANGLES, m.num_vertices,
GL_UNSIGNED_SHORT,
(GLvoid *) (sizeof(GLushort) * m.first_vertex));
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glUseProgram(0);
}
checkGLError(); checkGLError();
if (m_is_scaled) if (m_is_scaled)

View File

@ -13,10 +13,9 @@
#include <string> #include <string>
#include "ag.h" #include "ag.h"
#include "ag_lua.h" #include "cfs.h"
#include "anaglym.h" #include "anaglym.h"
#include "Engine.h" #include "Engine.h"
#include "WFObj/WFObj.h"
#include "AV.h" #include "AV.h"
using namespace std; using namespace std;
@ -86,8 +85,7 @@ namespace ag
}; };
luaL_register(L, "ag", functions); luaL_register(L, "ag", functions);
ag_lua[ag_lua_len - 1] = '\0'; luaL_loadstring(L, (const char *) getFile("src/ag.lua", NULL));
luaL_loadstring(L, (const char *) ag_lua);
lua_pcall(L, 0, 0, 0); lua_pcall(L, 0, 0, 0);
} }

View File

@ -1,8 +0,0 @@
#ifndef AG_LUA_H
#define AG_LUA_H
extern unsigned char ag_lua[];
extern unsigned int ag_lua_len;
#endif

View File

@ -6,7 +6,6 @@
#include <stdlib.h> /* exit(), srand() */ #include <stdlib.h> /* exit(), srand() */
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <unistd.h>
using namespace std; using namespace std;
static void usage(); static void usage();

BIN
tests/boxarena.blend Executable file → Normal file

Binary file not shown.

View File

@ -1,12 +1,12 @@
# Blender3D MTL File: boxarena.blend # Blender3D MTL File: boxarena.blend
# Material Count: 1 # Material Count: 1
newmtl Material newmtl Material
Ns 96.078431 Ns 96.078431
Ka 0.000000 0.000000 0.000000 Ka 0.000000 0.000000 0.000000
Kd 0.640000 0.640000 0.640000 Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000 Ks 0.500000 0.500000 0.500000
Ni 1.000000 Ni 1.000000
d 1.000000 d 1.000000
illum 2 illum 2

View File

@ -1,198 +1,197 @@
# Blender3D v248 OBJ File: boxarena.blend # Blender3D v249 OBJ File: boxarena.blend
# www.blender3d.org # www.blender3d.org
mtllib boxarena.mtl mtllib boxarena.mtl
v 0.000000 10.000000 8.000000 v 0.000000 10.000000 8.000000
v 0.000000 8.000000 8.000000 v 0.000000 8.000000 8.000000
v -10.000001 8.000000 8.000000 v -10.000000 8.000000 8.000000
v -9.999998 10.000000 8.000000 v -9.999998 10.000000 8.000000
v 0.000002 9.999999 10.000000 v 0.000002 9.999999 10.000000
v -0.000003 8.000000 10.000000 v -0.000003 8.000000 10.000000
v -10.000002 8.000000 10.000000 v -10.000002 8.000000 10.000000
v -10.000000 10.000000 10.000000 v -10.000000 10.000000 10.000000
vn 0.000000 0.000000 -1.000000 vn 0.000000 0.000000 -1.000000
vn 0.000000 0.000000 1.000000 vn 0.000000 -0.000000 1.000000
vn 1.000000 -0.000001 0.000000 vn 1.000000 -0.000001 0.000000
vn -0.000000 -1.000000 -0.000000 vn -0.000000 -1.000000 -0.000000
vn -1.000000 0.000001 -0.000001 vn -1.000000 0.000001 -0.000001
vn 0.000000 1.000000 0.000000 vn 0.000000 1.000000 0.000000
usemtl (null) usemtl Material
s off s off
f 1//1 2//1 3//1 4//1 f 1//1 2//1 3//1 4//1
f 5//2 8//2 7//2 6//2 f 5//2 8//2 7//2 6//2
f 1//3 5//3 6//3 2//3 f 1//3 5//3 6//3 2//3
f 2//4 6//4 7//4 3//4 f 2//4 6//4 7//4 3//4
f 3//5 7//5 8//5 4//5 f 3//5 7//5 8//5 4//5
f 5//6 1//6 4//6 8//6 f 5//6 1//6 4//6 8//6
v 0.000000 10.000000 6.000000 v 0.000000 10.000000 6.000000
v 0.000000 6.000000 6.000000 v 0.000000 6.000000 6.000000
v -10.000001 6.000000 6.000000 v -10.000000 6.000000 6.000000
v -9.999998 10.000001 6.000000 v -9.999998 10.000001 6.000000
v 0.000002 9.999999 8.000000 v 0.000002 9.999999 8.000000
v -0.000003 5.999999 8.000000 v -0.000003 5.999999 8.000000
v -10.000002 6.000001 8.000000 v -10.000002 6.000001 8.000000
v -10.000000 10.000000 8.000000 v -10.000000 10.000000 8.000000
usemtl (null) vn -1.000000 0.000000 -0.000001
s off usemtl Material
f 9//1 10//1 11//1 12//1 s off
f 13//2 16//2 15//2 14//2 f 9//1 10//1 11//1 12//1
f 9//3 13//3 14//3 10//3 f 13//2 16//2 15//2 14//2
f 10//4 14//4 15//4 11//4 f 9//3 13//3 14//3 10//3
f 11//5 15//5 16//5 12//5 f 10//4 14//4 15//4 11//4
f 13//6 9//6 12//6 16//6 f 11//7 15//7 16//7 12//7
v 0.000000 10.000000 4.000000 f 13//6 9//6 12//6 16//6
v 0.000000 4.000000 4.000000 v 0.000000 10.000000 4.000000
v -10.000001 4.000000 4.000000 v 0.000000 4.000000 4.000000
v -9.999998 10.000001 4.000000 v -10.000000 4.000000 4.000000
v 0.000002 9.999998 6.000000 v -9.999998 10.000001 4.000000
v -0.000003 3.999998 6.000000 v 0.000002 9.999998 6.000000
v -10.000002 4.000001 6.000000 v -0.000003 3.999998 6.000000
v -10.000000 10.000000 6.000000 v -10.000002 4.000001 6.000000
vn 1.000000 -0.000000 0.000000 v -10.000000 10.000000 6.000000
vn -1.000000 0.000000 -0.000001 vn 1.000000 -0.000000 0.000000
vn 0.000000 1.000000 0.000001 vn 0.000000 1.000000 0.000001
usemtl (null) usemtl Material
s off s off
f 17//1 18//1 19//1 20//1 f 17//1 18//1 19//1 20//1
f 21//2 24//2 23//2 22//2 f 21//2 24//2 23//2 22//2
f 17//7 21//7 22//7 18//7 f 17//8 21//8 22//8 18//8
f 18//4 22//4 23//4 19//4 f 18//4 22//4 23//4 19//4
f 19//8 23//8 24//8 20//8 f 19//7 23//7 24//7 20//7
f 21//9 17//9 20//9 24//9 f 21//9 17//9 20//9 24//9
v 0.000000 10.000000 2.000000 v 0.000000 10.000000 2.000000
v 0.000000 2.000000 2.000000 v 0.000000 2.000000 2.000000
v -10.000001 2.000001 2.000000 v -10.000000 2.000001 2.000000
v -9.999998 10.000002 2.000000 v -9.999998 10.000002 2.000000
v 0.000002 9.999998 4.000000 v 0.000002 9.999998 4.000000
v -0.000003 1.999998 4.000000 v -0.000003 1.999998 4.000000
v -10.000002 2.000001 4.000000 v -10.000002 2.000001 4.000000
v -10.000000 10.000000 4.000000 v -10.000000 10.000000 4.000000
usemtl (null) usemtl Material
s off s off
f 25//1 26//1 27//1 28//1 f 25//1 26//1 27//1 28//1
f 29//2 32//2 31//2 30//2 f 29//2 32//2 31//2 30//2
f 25//7 29//7 30//7 26//7 f 25//8 29//8 30//8 26//8
f 26//4 30//4 31//4 27//4 f 26//4 30//4 31//4 27//4
f 27//8 31//8 32//8 28//8 f 27//7 31//7 32//7 28//7
f 29//9 25//9 28//9 32//9 f 29//9 25//9 28//9 32//9
v 0.000000 10.000000 0.000000 v 0.000000 10.000000 0.000000
v 0.000000 0.000000 0.000000 v 0.000000 0.000000 0.000000
v -10.000001 0.000001 0.000000 v -10.000000 0.000001 0.000000
v -9.999998 10.000002 0.000000 v -9.999998 10.000002 0.000000
v 0.000002 9.999997 2.000000 v 0.000002 9.999997 2.000000
v -0.000003 -0.000003 2.000000 v -0.000003 -0.000003 2.000000
v -10.000002 0.000002 2.000000 v -10.000002 0.000002 2.000000
v -10.000000 10.000000 2.000000 v -10.000000 10.000000 2.000000
vn -0.000000 -1.000000 -0.000001 usemtl Material
usemtl (null) s off
s off f 33//1 34//1 35//1 36//1
f 33//1 34//1 35//1 36//1 f 37//2 40//2 39//2 38//2
f 37//2 40//2 39//2 38//2 f 33//8 37//8 38//8 34//8
f 33//7 37//7 38//7 34//7 f 34//4 38//4 39//4 35//4
f 34//10 38//10 39//10 35//10 f 35//7 39//7 40//7 36//7
f 35//8 39//8 40//8 36//8 f 37//9 33//9 36//9 40//9
f 37//9 33//9 36//9 40//9 v 10.000000 9.999999 20.000000
v 10.000000 9.999999 20.000000 v 10.000000 -10.000000 20.000000
v 10.000000 -10.000000 20.000000 v -10.000001 -9.999998 20.000000
v -10.000001 -9.999998 20.000000 v -9.999996 10.000004 20.000000
v -9.999996 10.000004 20.000000 v 10.000005 9.999994 21.000000
v 10.000005 9.999994 21.000000 v 9.999993 -10.000006 21.000000
v 9.999993 -10.000006 21.000000 v -10.000004 -9.999996 21.000000
v -10.000004 -9.999996 21.000000 v -9.999999 10.000000 21.000000
v -9.999999 10.000000 21.000000 vn 1.000000 -0.000000 0.000001
vn 1.000000 -0.000000 0.000001 vn -0.000000 -1.000000 -0.000002
vn -0.000000 -1.000000 -0.000002 vn -1.000000 0.000000 -0.000003
vn -1.000000 0.000000 -0.000003 vn 0.000000 1.000000 0.000004
vn 0.000000 1.000000 0.000004 usemtl Material
usemtl Material s off
s off f 41//1 42//1 43//1 44//1
f 41//1 42//1 43//1 44//1 f 45//2 48//2 47//2 46//2
f 45//2 48//2 47//2 46//2 f 41//10 45//10 46//10 42//10
f 41//11 45//11 46//11 42//11 f 42//11 46//11 47//11 43//11
f 42//12 46//12 47//12 43//12 f 43//12 47//12 48//12 44//12
f 43//13 47//13 48//13 44//13 f 45//13 41//13 44//13 48//13
f 45//14 41//14 44//14 48//14 v 9.999999 -11.000000 0.000000
v 9.999999 -11.000000 0.000000 v -10.000000 -11.000000 0.000000
v -10.000000 -11.000000 0.000000 v -9.999998 -10.000000 0.000000
v -9.999998 -9.999999 0.000000 v 10.000004 -10.000001 0.000000
v 10.000004 -10.000001 0.000000 v 9.999994 -11.000001 20.000000
v 9.999994 -11.000001 20.000000 v -10.000006 -10.999999 20.000000
v -10.000006 -10.999999 20.000000 v -9.999996 -9.999999 20.000000
v -9.999996 -9.999999 20.000000 v 10.000000 -10.000000 20.000000
v 10.000000 -10.000000 20.000000 vn -1.000000 0.000006 -0.000000
vn -1.000000 0.000006 -0.000000 vn 1.000000 -0.000005 0.000000
vn 1.000000 -0.000005 0.000000 usemtl Material
usemtl Material s off
s off f 49//1 50//1 51//1 52//1
f 49//1 50//1 51//1 52//1 f 53//2 56//2 55//2 54//2
f 53//2 56//2 55//2 54//2 f 49//4 53//4 54//4 50//4
f 49//4 53//4 54//4 50//4 f 50//14 54//14 55//14 51//14
f 50//15 54//15 55//15 51//15 f 51//6 55//6 56//6 52//6
f 51//6 55//6 56//6 52//6 f 53//15 49//15 52//15 56//15
f 53//16 49//16 52//16 56//16 v 9.999999 10.000000 0.000000
v 9.999999 10.000000 0.000000 v -10.000000 10.000000 0.000000
v -10.000000 10.000000 0.000000 v -9.999998 11.000000 0.000000
v -9.999998 11.000001 0.000000 v 10.000004 10.999999 0.000000
v 10.000004 10.999999 0.000000 v 9.999994 9.999999 20.000000
v 9.999994 9.999999 20.000000 v -10.000006 10.000001 20.000000
v -10.000006 10.000001 20.000000 v -9.999996 11.000001 20.000000
v -9.999996 11.000001 20.000000 v 10.000000 11.000000 20.000000
v 10.000000 11.000000 20.000000 usemtl Material
usemtl Material s off
s off f 57//1 58//1 59//1 60//1
f 57//1 58//1 59//1 60//1 f 61//2 64//2 63//2 62//2
f 61//2 64//2 63//2 62//2 f 57//4 61//4 62//4 58//4
f 57//4 61//4 62//4 58//4 f 58//14 62//14 63//14 59//14
f 58//15 62//15 63//15 59//15 f 59//6 63//6 64//6 60//6
f 59//6 63//6 64//6 60//6 f 61//15 57//15 60//15 64//15
f 61//16 57//16 60//16 64//16 v 11.000000 9.999999 0.000000
v 11.000000 9.999999 0.000000 v 11.000000 -10.000000 0.000000
v 11.000000 -10.000000 0.000000 v 10.000000 -9.999998 0.000000
v 10.000000 -9.999998 0.000000 v 10.000000 10.000004 0.000000
v 10.000000 10.000004 0.000000 v 11.000000 9.999994 20.000000
v 11.000000 9.999994 20.000000 v 11.000000 -10.000006 20.000000
v 11.000000 -10.000006 20.000000 v 10.000000 -9.999996 20.000000
v 10.000000 -9.999996 20.000000 v 10.000000 10.000000 20.000000
v 10.000000 10.000000 20.000000 vn -0.000006 -1.000000 -0.000000
vn -0.000006 -1.000000 -0.000000 vn -1.000000 -0.000000 0.000000
vn -1.000000 0.000000 0.000000 vn 0.000005 1.000000 0.000000
vn 0.000005 1.000000 0.000000 usemtl Material
usemtl Material s off
s off f 65//1 66//1 67//1 68//1
f 65//1 66//1 67//1 68//1 f 69//2 72//2 71//2 70//2
f 69//2 72//2 71//2 70//2 f 65//8 69//8 70//8 66//8
f 65//7 69//7 70//7 66//7 f 66//16 70//16 71//16 67//16
f 66//17 70//17 71//17 67//17 f 67//17 71//17 72//17 68//17
f 67//18 71//18 72//18 68//18 f 69//18 65//18 68//18 72//18
f 69//19 65//19 68//19 72//19 v -10.000000 9.999999 0.000000
v -10.000000 9.999999 0.000000 v -10.000000 -10.000000 0.000000
v -10.000000 -10.000000 0.000000 v -11.000000 -9.999998 0.000000
v -11.000000 -9.999998 0.000000 v -11.000000 10.000004 0.000000
v -11.000000 10.000004 0.000000 v -10.000000 9.999994 20.000000
v -10.000000 9.999994 20.000000 v -10.000000 -10.000006 20.000000
v -10.000000 -10.000006 20.000000 v -11.000000 -9.999996 20.000000
v -11.000000 -9.999996 20.000000 v -11.000000 10.000000 20.000000
v -11.000000 10.000000 20.000000 usemtl Material
usemtl Material s off
s off f 73//1 74//1 75//1 76//1
f 73//1 74//1 75//1 76//1 f 77//2 80//2 79//2 78//2
f 77//2 80//2 79//2 78//2 f 73//8 77//8 78//8 74//8
f 73//7 77//7 78//7 74//7 f 74//16 78//16 79//16 75//16
f 74//17 78//17 79//17 75//17 f 75//17 79//17 80//17 76//17
f 75//18 79//18 80//18 76//18 f 77//18 73//18 76//18 80//18
f 77//19 73//19 76//19 80//19 v 10.000000 9.999999 -1.000000
v 10.000000 9.999999 -1.000000 v 10.000000 -10.000000 -1.000000
v 10.000000 -10.000000 -1.000000 v -10.000001 -9.999998 -1.000000
v -10.000001 -9.999998 -1.000000 v -9.999996 10.000004 -1.000000
v -9.999996 10.000004 -1.000000 v 10.000005 9.999994 0.000000
v 10.000005 9.999994 0.000000 v 9.999993 -10.000006 0.000000
v 9.999993 -10.000006 0.000000 v -10.000004 -9.999996 0.000000
v -10.000004 -9.999996 0.000000 v -9.999999 10.000000 0.000000
v -9.999999 10.000000 0.000000 usemtl Material
usemtl Material s off
s off f 81//1 82//1 83//1 84//1
f 81//1 82//1 83//1 84//1 f 85//2 88//2 87//2 86//2
f 85//2 88//2 87//2 86//2 f 81//10 85//10 86//10 82//10
f 81//11 85//11 86//11 82//11 f 82//11 86//11 87//11 83//11
f 82//12 86//12 87//12 83//12 f 83//12 87//12 88//12 84//12
f 83//13 87//13 88//13 84//13 f 85//13 81//13 84//13 88//13
f 85//14 81//14 84//14 88//14

1
wfobj Submodule

@ -0,0 +1 @@
Subproject commit e4dc0f4d3627ab08e20d1be2dce41981e5771cca