Beispiel #1
0
bool HSCCSprite::ContainsTouchLocation( CCTouch* touch )
{
	CCSize s = getTexture()->getContentSize();
	CCRect r = CCRectMake(-s.width / 2, -s.height / 2, s.width, s.height);
	return r.containsPoint(convertTouchToNodeSpaceAR(touch));
}
Beispiel #2
0
//----------------------------------------------------------
void ofFbo::setAnchorPoint(float x, float y){
	getTexture().setAnchorPoint(x, y);
}
Beispiel #3
0
//----------------------------------------------------------
void ofFbo::draw(float x, float y, float width, float height) const{
	if(!bIsAllocated) return;
    getTexture().draw(x, y, width, height);
}
Beispiel #4
0
//----------------------------------------------------------
const ofTexture& ofFbo::getTextureReference() const{
	return getTexture();
}
Beispiel #5
0
//----------------------------------------------------------
const ofTexture& ofFbo::getTexture() const{
	return getTexture(defaultTextureIndex);
}
Beispiel #6
0
// -------------------------------------------------------------------
//  Loads the material description
void ObjFileMtlImporter::load()
{
    if ( m_DataIt == m_DataItEnd )
        return;

    while ( m_DataIt != m_DataItEnd )
    {
        switch (*m_DataIt)
        {
        case 'k':
        case 'K':
            {
                ++m_DataIt;
                if (*m_DataIt == 'a') // Ambient color
                {
                    ++m_DataIt;
                    getColorRGBA( &m_pModel->m_pCurrentMaterial->ambient );
                }
                else if (*m_DataIt == 'd')  // Diffuse color
                {
                    ++m_DataIt;
                    getColorRGBA( &m_pModel->m_pCurrentMaterial->diffuse );
                }
                else if (*m_DataIt == 's')
                {
                    ++m_DataIt;
                    getColorRGBA( &m_pModel->m_pCurrentMaterial->specular );
                }
                else if (*m_DataIt == 'e')
                {
                    ++m_DataIt;
                    getColorRGBA( &m_pModel->m_pCurrentMaterial->emissive );
                }
                m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
            }
            break;

        case 'd':   
            {
                if( *(m_DataIt+1) == 'i' && *( m_DataIt + 2 ) == 's' && *( m_DataIt + 3 ) == 'p' ) {
                    // A displacement map
                    getTexture();
                } else {
                    // Alpha value
                    ++m_DataIt;
                    getFloatValue( m_pModel->m_pCurrentMaterial->alpha );
                    m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
                }
            }
            break;

        case 'N':
        case 'n':
            {
                ++m_DataIt;
                switch(*m_DataIt)
                {
                case 's':   // Specular exponent
                    ++m_DataIt;
                    getFloatValue(m_pModel->m_pCurrentMaterial->shineness);
                    break;
                case 'i':   // Index Of refraction
                    ++m_DataIt;
                    getFloatValue(m_pModel->m_pCurrentMaterial->ior);
                    break;
                case 'e':   // New material
                    createMaterial();
                    break;
                }
                m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
            }
            break;

        case 'm':   // Texture
        case 'b':   // quick'n'dirty - for 'bump' sections
            {
                getTexture();
                m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
            }
            break;

        case 'i':   // Illumination model
            {
                m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
                getIlluminationModel( m_pModel->m_pCurrentMaterial->illumination_model );
                m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
            }
            break;

        default:
            {
                m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
            }
            break;
        }
    }
}
Beispiel #7
0
Rect FramePart::getRect()
{
    auto s = getTexture()->getContentSize();
    return Rect(-s.width / 2, -s.height / 2, s.width, s.height);
}
Beispiel #8
0
CCRect Paddle::rect()
{
    CCSize s = getTexture()->getContentSize();
    return CCRectMake(-s.width / 2, -s.height / 2, s.width, s.height);
}
Beispiel #9
0
float Ball::radius()
{
    return getTexture()->getContentSize().width / 2;
}
Beispiel #10
0
void Manager::_parseMaterial(Material* material, io::IReader* stream)
{
    static std::map<std::string, bool RenderState::*>   stateCommands;
    static std::map<std::string, DepthFn>               depthFnLiterals;
    static std::map<std::string, BlendFn::Factor>       blendFnLiterals;

    if (stateCommands.empty())
    {
        stateCommands["depthtest"]     = &RenderState::depthTest;
        stateCommands["depthwrite"]    = &RenderState::depthWrite;
        stateCommands["alphatest"]     = &RenderState::alphaTest;
        stateCommands["blend"]         = &RenderState::blend;
        stateCommands["cullface"]      = &RenderState::cullFace;
        stateCommands["polygonoffset"] = &RenderState::polygonOffset;
    }

    if (depthFnLiterals.empty())
    {
        depthFnLiterals["never"]    = DepthFn::Never;
        depthFnLiterals["less"]     = DepthFn::Less;
        depthFnLiterals["equal"]    = DepthFn::Equal;
        depthFnLiterals["lequal"]   = DepthFn::LEqual;
        depthFnLiterals["greater"]  = DepthFn::Greater;
        depthFnLiterals["notequal"] = DepthFn::NotEqual;
        depthFnLiterals["gequal"]   = DepthFn::GEqual;
        depthFnLiterals["always"]   = DepthFn::Always;
    }

    if (blendFnLiterals.empty())
    {
        blendFnLiterals["one"]               = BlendFn::One;
        blendFnLiterals["zero"]              = BlendFn::Zero;
        blendFnLiterals["srccolor"]          = BlendFn::SrcColor;
        blendFnLiterals["oneminussrccolor"]  = BlendFn::OneMinusSrcColor;
        blendFnLiterals["srcalpha"]          = BlendFn::SrcAlpha;
        blendFnLiterals["oneminussrcalpha"]  = BlendFn::OneMinusSrcAlpha;
        blendFnLiterals["dstalpha"]          = BlendFn::DstAlpha;
        blendFnLiterals["oneminusdstalpha"]  = BlendFn::OneMinusDstAlpha;
        blendFnLiterals["dstcolor"]          = BlendFn::DstColor;
        blendFnLiterals["oneminusdstcolor"]  = BlendFn::OneMinusDstColor;
        blendFnLiterals["srcalphasaturate"]  = BlendFn::SrcAlphaSaturate;
    }

    enum {States, Textures, Shaders} mode = States;

    RenderState renderState;
    ShaderList shaders;
    std::vector<std::string> textures;

    char key[64] = {}, value[256] = {};
    int tokens = 0;

    for (io::LineParser parser(stream); parser.readLine();)
    {
        if (!parser.indent())
            mode = States;

        switch (mode)
        {
        case States:
            tokens = std::sscanf(parser.line().c_str(), "%63[^:] : %255s", key, value);
            if (tokens == 2)
            {
                for (auto str = key; *str; ++str)
                    *str = ::tolower(*str);

                for (auto str = value; *str; ++str)
                    *str = ::tolower(*str);

                auto stateCmdIt = stateCommands.find(key);
                if (stateCmdIt != stateCommands.end())
                    renderState.*stateCmdIt->second = strcmp(value, "true") == 0;

                else if (strcmp(key, "depthfunc") == 0)
                {
                    auto depthFnIt = depthFnLiterals.find(value);
                    if (depthFnIt != depthFnLiterals.end())
                        renderState.depthFunc = depthFnIt->second;
                }
                else if (strcmp(key, "blendfunc") == 0)
                {
                    char srcFactor[32], dstFactor[32];
                    if (std::sscanf("[ %31[^ 0xa0\t,] , %31[^ 0xa0\t\\] ]", srcFactor, dstFactor) == 2)
                    {
                        auto blendFnIt = blendFnLiterals.find(srcFactor);
                        if (blendFnIt != blendFnLiterals.end())
                            renderState.blendFunc.srcFactor = blendFnIt->second;

                        blendFnIt = blendFnLiterals.find(dstFactor);
                        if (blendFnIt != blendFnLiterals.end())
                            renderState.blendFunc.dstFactor = blendFnIt->second;
                    }
                }
                else if (strcmp(key, "passhint") == 0)
                    material->setPassHint(atoi(value));
            }
            else if (tokens == 1)
            {
                for (auto str = key; *str; ++str)
                    *str = ::tolower(*str);

                if (strcmp(key, "shaders") == 0)
                    mode = Shaders;

                else if (strcmp(key, "textures") == 0)
                    mode = Textures;
            }
            break;

        case Shaders:
            if (std::sscanf(parser.line().c_str(), " - %255s", value) == 1)
                shaders.add(getShader(value));
            break;

        case Textures:
            if (std::sscanf(parser.line().c_str(), " - %255s", value) == 1)
                textures.push_back(value);
            break;
        }
    }

    material->setRenderState(renderState);
    material->setShaders(shaders);

    auto maxTextures = std::min<std::size_t>(material->numTextures(), textures.size());

    for (std::size_t i = 0; i < maxTextures; ++i)
        material->setTexture(i, getTexture(textures[i]));
}
Beispiel #11
0
const ofTexture & ofImage_<PixelType>::getTextureReference() const{
	return getTexture();
}
Beispiel #12
0
//------------------------------------
const ofTexture& ofxKinect::getTextureReference() const{
	return getTexture();
}
Beispiel #13
0
	bool initWithFileEx(const char *filename,
		const Format::Texture &t,
		const Format::TextureFragment &f,
		const Format::BitmapEx &bx)
	{
		if (!cocos2d::Sprite::initWithFile(filename))
			return false;

		bool hasPremultipliedAlpha = getTexture()->hasPremultipliedAlpha() ||
			t.format == Format::TEXTUREFORMAT_PREMULTIPLIEDALPHA;
		m_baseBlendFunc = {(GLenum)(hasPremultipliedAlpha ?
			GL_ONE : GL_SRC_ALPHA), GL_ONE_MINUS_SRC_ALPHA};

		float tw = (float)t.width;
		float th = (float)t.height;

		float x = (float)f.x;
		float y = (float)f.y;
		float u = (float)f.u;
		float v = (float)f.v;
		float w = (float)f.w;
		float h = (float)f.h;

		float bu = bx.u * w;
		float bv = bx.v * h;
		float bw = bx.w;
		float bh = bx.h;

		x += bu;
		y += bv;
		u += bu;
		v += bv;
		w *= bw;
		h *= bh;

		float x0 = x / t.scale;
		float y0 = y / t.scale;
		float x1 = (x + w) / t.scale;
		float y1 = (y + h) / t.scale;

		m_quad.bl.vertices = cocos2d::Vertex3F(x1, y1, 0);
		m_quad.br.vertices = cocos2d::Vertex3F(x0, y1, 0);
		m_quad.tl.vertices = cocos2d::Vertex3F(x1, y0, 0);
		m_quad.tr.vertices = cocos2d::Vertex3F(x0, y0, 0);

		if (f.rotated == 0) {
			float u0 = u / tw;
			float v0 = v / th;
			float u1 = (u + w) / tw;
			float v1 = (v + h) / th;
			m_quad.bl.texCoords.u = u1;
			m_quad.bl.texCoords.v = v1;
			m_quad.br.texCoords.u = u0;
			m_quad.br.texCoords.v = v1;
			m_quad.tl.texCoords.u = u1;
			m_quad.tl.texCoords.v = v0;
			m_quad.tr.texCoords.u = u0;
			m_quad.tr.texCoords.v = v0;
		} else {
			float u0 = u / tw;
			float v0 = v / th;
			float u1 = (u + h) / tw;
			float v1 = (v + w) / th;
			m_quad.bl.texCoords.u = u0;
			m_quad.bl.texCoords.v = v1;
			m_quad.br.texCoords.u = u0;
			m_quad.br.texCoords.v = v0;
			m_quad.tl.texCoords.u = u1;
			m_quad.tl.texCoords.v = v1;
			m_quad.tr.texCoords.u = u1;
			m_quad.tr.texCoords.v = v0;
		}

		_quad = m_quad;

		return true;
	}
LLDrawPoolTerrain::~LLDrawPoolTerrain()
{
	llassert( gPipeline.findPool( getType(), getTexture() ) == NULL );
}
// slightly different format than the 
void Cavern::loadLevel( const char *levelFile, std::vector<Shape*> &shapeList )
{
	TiXmlDocument *xmlDoc = new TiXmlDocument( levelFile );

	if (!xmlDoc->LoadFile() ) {
		printf("ERR! Can't load %s\n", levelFile );
	}

	TiXmlElement *xCavern, *xShape;
	//TiXmlNode *xText;

	xCavern = xmlDoc->FirstChildElement( "Cavern" );
	assert( xCavern );

	m_mapSize = vec2f( atof( xCavern->Attribute("width") ),
					   atof( xCavern->Attribute("height") ) );

	sscanf( xCavern->Attribute("spawnPoint"), "%f,%f",
				&(m_spawnPoint.x), &(m_spawnPoint.y) );

	xShape = xCavern->FirstChildElement( "Shape" );
	while (xShape) 
	{
		Shape *shp = new Shape();
		
		shp->name = xShape->Attribute("name");
		shp->mapname = xShape->Attribute("mapname");
		shp->m_collide = (!stricmp( xShape->Attribute("collide"), "true" ));
		shp->m_pattern = (!stricmp( xShape->Attribute("pattern"), "true" ));

		const char *blend = xShape->Attribute("blendMode");
		for (int i=0; i< 3; i++)
		{
			if (!stricmp( blend, BlendModeNames[i]) ) shp->blendMode = i;
		}
		
		shp->angle = atof( xShape->Attribute("angle") );
		shp->sortNum = atoi( xShape->Attribute("sortNum") );
		
		//sscanf( xShape->Attribute("sts"), "%f,%f,%f,%f",
		//		&(shp->st0.x), &(shp->st0.y),
		//		&(shp->st1.x), &(shp->st1.y) );

		sscanf( xShape->Attribute("pos"), "%f,%f",
				&(shp->pos.x), &(shp->pos.y) );

		sscanf( xShape->Attribute("size"), "%f,%f",
				&(shp->m_size.x), &(shp->m_size.y) );

		//sscanf( xShape->Attribute("origSize"), "%f,%f",
		//		&(shp->m_origSize.x), &(shp->m_origSize.y) );

		// Get sts and origSize from the shape List in case these
		// changed
		bool found = false;
		for (int i=0; i < shapeList.size(); ++i)
		{
			if (shp->name == shapeList[i]->name)
			{
				shp->m_origSize = shapeList[i]->m_origSize;
				shp->st0 = shapeList[i]->st0;
				shp->st1 = shapeList[i]->st1;
				shp->m_relief = shapeList[i]->m_relief;

				found = true;
				break;
			}
		}
		if (!found)
		{
			printf("WARNING: Couldn't find shape %s\n", shp->name.c_str() );
			delete shp;
		}
		else
		{
			// Load the map
			shp->m_texId = getTexture( shp->mapname, NULL, NULL );
			m_shapes.push_back( shp );
		}
		xShape = xShape->NextSiblingElement( "Shape" );
	}

	TiXmlElement *xSegment = xCavern->FirstChildElement( "Segment" );
	while (xSegment) 
	{
		vec2f a, b;
		sscanf( xSegment->Attribute( "start" ), "%f,%f", &(a.x), &(a.y) );
		sscanf( xSegment->Attribute( "end" ), "%f,%f", &(b.x), &(b.y) );
		const char *szType = xSegment->Attribute("type");
		if (!szType) szType = "collide";

		int type = SegType_COLLIDE;
		for (int i=SegType_COLLIDE; i < SegType_LAST; ++i )
		{
			if (!stricmp( SegTypeNames[i], szType ))
			{
				type = i;
				break;
			}
		}

		addSegment( a, b, type );

		// next segment
		xSegment = xSegment->NextSiblingElement( "Segment" );
	}

	// sort
	sortShapes();

	// done
	xmlDoc->Clear();
	delete xmlDoc;
}
Beispiel #16
0
	bool initWithFileEx(Bitmap *bitmap, BitmapEx *bitmapEx,
		const char *filename, const Format::Texture &t,
		const Format::TextureFragment &f, const Format::BitmapEx &bx,
		bool flippedX, bool flippedY)
	{
		cocos2d::LWFResourceCache *cache =
			cocos2d::LWFResourceCache::sharedLWFResourceCache();
		cocos2d::Texture2D *texture = cache->addImage(filename);
		if (texture == 0 || !cocos2d::Sprite::initWithTexture(texture))
			return false;

		m_hasPremultipliedAlpha = getTexture()->hasPremultipliedAlpha() ||
			t.format == Format::TEXTUREFORMAT_PREMULTIPLIEDALPHA;
		m_baseBlendFunc = {(GLenum)(m_hasPremultipliedAlpha ?
			GL_ONE : GL_SRC_ALPHA), GL_ONE_MINUS_SRC_ALPHA};

		float tw = (float)t.width;
		float th = (float)t.height;

		float x = (float)f.x;
		float y = (float)f.y;
		float u = (float)f.u;
		float v = (float)f.v;
		float w = (float)f.w;
		float h = (float)f.h;

		float bu = bx.u * w;
		float bv = bx.v * h;
		float bw = bx.w;
		float bh = bx.h;

		x += bu;
		y += bv;
		u += bu;
		v += bv;
		w *= bw;
		h *= bh;

		float x0 = x / t.scale;
		float y0 = y / t.scale;
		float x1 = (x + w) / t.scale;
		float y1 = (y + h) / t.scale;

		m_quad.bl.vertices = cocos2d::Vec3(x1, y1, 0);
		m_quad.br.vertices = cocos2d::Vec3(x0, y1, 0);
		m_quad.tl.vertices = cocos2d::Vec3(x1, y0, 0);
		m_quad.tr.vertices = cocos2d::Vec3(x0, y0, 0);

		if (f.rotated == 0) {
			float u0 = u / tw;
			float v0 = v / th;
			float u1 = (u + w) / tw;
			float v1 = (v + h) / th;
			if (flippedX)
				std::swap(u1, u0);
			if (flippedY)
				std::swap(v1, v0);
			m_quad.bl.texCoords.u = u1;
			m_quad.bl.texCoords.v = v1;
			m_quad.br.texCoords.u = u0;
			m_quad.br.texCoords.v = v1;
			m_quad.tl.texCoords.u = u1;
			m_quad.tl.texCoords.v = v0;
			m_quad.tr.texCoords.u = u0;
			m_quad.tr.texCoords.v = v0;
		} else {
			float u0 = u / tw;
			float v0 = v / th;
			float u1 = (u + h) / tw;
			float v1 = (v + w) / th;
			m_quad.bl.texCoords.u = u0;
			m_quad.bl.texCoords.v = v1;
			m_quad.br.texCoords.u = u0;
			m_quad.br.texCoords.v = v0;
			m_quad.tl.texCoords.u = u1;
			m_quad.tl.texCoords.v = v1;
			m_quad.tr.texCoords.u = u1;
			m_quad.tr.texCoords.v = v0;
		}

		_quad = m_quad;

		m_bitmap = bitmap;
		m_bitmapEx = bitmapEx;

		return true;
	}
Beispiel #17
0
	void Asset::drawTexture(const std::string & name, const mat3 &m)
	{
		sfw::drawTextureMatrix(getTexture(name)._handle, 0, WHITE, mat3to4(m.m, 0).m);
	}
Beispiel #18
0
void GameObject::draw(vec2 cam, int drawAngle)
{
	sfw::drawTexture(getTexture(textureName), pos.x - cam.x, pos.y - cam.y, dim.x, dim.y, angle - drawAngle, true);	
}
Beispiel #19
0
void ofFbo::draw(float x, float y, float width, float height) {
	getTexture(0).draw(x, y, width, height);
}
Beispiel #20
0
GLTexture* MapTextureManager::getFlat(string name, bool mixed)
{
	// Get flat matching name
	map_tex_t& mtex = flats[name.Upper()];

	// Get desired filter type
	int filter = 1;
	if (map_tex_filter == 0)
		filter = GLTexture::NEAREST_LINEAR_MIN;
	else if (map_tex_filter == 1)
		filter = GLTexture::LINEAR;
	else if (map_tex_filter == 2)
		filter = GLTexture::LINEAR_MIPMAP;
	else if (map_tex_filter == 3)
		filter = GLTexture::NEAREST_MIPMAP;

	// If the texture is loaded
	if (mtex.texture)
	{
		// If the texture filter matches the desired one, return it
		if (mtex.texture->getFilter() == filter)
			return mtex.texture;
		else
		{
			// Otherwise, reload the texture
			if (mtex.texture != &(GLTexture::missingTex())) delete mtex.texture;
			mtex.texture = NULL;
		}
	}

	// Flat not found, look for it
	Palette8bit* pal = getResourcePalette();
	if (!mtex.texture)
	{
		ArchiveEntry* entry = theResourceManager->getTextureEntry(name, "hires", archive);
		if (entry == NULL)
			entry = theResourceManager->getTextureEntry(name, "flats", archive);
		if (entry == NULL)
			entry = theResourceManager->getFlatEntry(name, archive);
		if (entry)
		{
			SImage image;
			if (Misc::loadImageFromEntry(&image, entry))
			{
				mtex.texture = new GLTexture(false);
				mtex.texture->setFilter(filter);
				mtex.texture->loadImage(&image, pal);
			}
		}
	}

	/*
	// Try composite textures then
	if (!mtex.texture) {
		CTexture* ctex = theResourceManager->getTexture(name, archive);
		if (ctex) {
			SImage image;
			if (ctex->toImage(image, archive, pal)) {
				mtex.texture = new GLTexture(false);
				mtex.texture->setFilter(filter);
				mtex.texture->loadImage(&image, pal);
			}
		}
	}
	*/

	// Not found
	if (!mtex.texture)
	{
		// Try textures if mixed
		if (mixed)
			return getTexture(name, false);

		// Otherwise use missing texture
		else
			mtex.texture = &(GLTexture::missingTex());
	}

	return mtex.texture;
}
Beispiel #21
0
//----------------------------------------------------------
ofTexture& ofFbo::getTextureReference(){
	return getTexture();
}
//------------------------------------
const ofTexture & ofVideoGrabber::getTextureReference() const{
	return getTexture();
}
Beispiel #23
0
//----------------------------------------------------------
const ofTexture& ofFbo::getTextureReference(int attachmentPoint) const{
	return getTexture(attachmentPoint);
}
//----------------------------------------------------------
void ofVideoGrabber::setAnchorPercent(float xPct, float yPct){
	getTexture().setAnchorPercent(xPct, yPct);
}
Beispiel #25
0
//----------------------------------------------------------
void ofFbo::setAnchorPercent(float xPct, float yPct){
	getTexture().setAnchorPercent(xPct, yPct);
}
//----------------------------------------------------------
void ofVideoGrabber::setAnchorPoint(float x, float y){
	getTexture().setAnchorPoint(x, y);
}
Beispiel #27
0
//----------------------------------------------------------
void ofFbo::resetAnchor(){
	getTexture().resetAnchor();
}
//----------------------------------------------------------
void ofVideoGrabber::resetAnchor(){
	getTexture().resetAnchor();
}
Beispiel #29
0
const Texture* TextureManager::getTexture(const std::string& filename) const
{
    unsigned int textureFileNameHash = hashString(filename);
    return getTexture(textureFileNameHash);
}
Beispiel #30
0
static void loadBspGeometry(Bsp *bsp, void *faceData, int32_t faceSize, void *edgeData, int32_t edgeSize,
		void *ledgeData, int32_t ledgeSize){

	bsp->numFaces = faceSize / sizeof(FaceDef);
	bsp->faces = malloc(sizeof(Face)*bsp->numFaces);
	FaceDef *faces = malloc(faceSize);
	memcpy(faces, faceData, faceSize);

	EdgeDef *edges = malloc(edgeSize);
	memcpy(edges, edgeData, edgeSize);

	int32_t *ledges = malloc(ledgeSize);
	memcpy(ledges, ledgeData, ledgeSize);

	for(int i=0; i < bsp->numFaces; i++){
		// Read all verts from edge data into a vert data structure
		// that is more suitable for GL rendering
		Face *face = &bsp->faces[i];
		face->numVerts = faces[i].edgeNum;
		face->verts = malloc(sizeof(Vert)*face->numVerts);
		TexInfoDef *texInfo = getTexInfo(bsp, faces[i].texinfoId);
		face->texture = getTexture(bsp, texInfo->texId);
		face->glId = 0;
		// If face is a trigger or clip skip loading it's verts
		// TODO make somekind of stack or vector to store faces so we don't bother
		// allocating useless memory
		if(strcmp("trigger", getTexName(face->texture)) == 0 || strcmp("clip", getTexName(face->texture)) == 0){
			continue;
		}
		for(int edge=0; edge < faces[i].edgeNum; edge++){
			int32_t edgeIndex = ledges[edge+faces[i].edgeId];
			vec3Float verts[2];
			// if edgeIndex is negative flip v0 and v1
			if(edgeIndex < 0){
				edgeIndex = -edgeIndex;
				verts[0] = getVert(bsp, edges[edgeIndex].vert1);
				verts[1] = getVert(bsp, edges[edgeIndex].vert0);
			} else {
				verts[0] = getVert(bsp, edges[edgeIndex].vert0);
				verts[1] = getVert(bsp, edges[edgeIndex].vert1);
			}

			face->verts[edge].normal = getPlane(bsp, faces[i].planeId)->normal;

			// Negate y and flip y & z so it's oriented properly
			face->verts[edge].position.x = verts[0].x;
			face->verts[edge].position.y = verts[0].z;
			face->verts[edge].position.z = -verts[0].y;

			// compute s and t coordinate for texture mapping
			face->verts[edge].texCoord.x = (vec3FDot(&verts[0], &texInfo->vecS) + texInfo->distS) / getTexWidth(face->texture);
			face->verts[edge].texCoord.y = (vec3FDot(&verts[0], &texInfo->vecT) + texInfo->distT) / getTexHeight(face->texture);
		}

		// Now that we have loaded all vertex data for this face
		// We can generate a vbo for it
		glGenBuffers(1, &face->glId);
		glBindBuffer(GL_ARRAY_BUFFER, face->glId);
		glBufferData(GL_ARRAY_BUFFER, sizeof(Vert)*face->numVerts, &face->verts[0], GL_STATIC_DRAW);
	}

	free(faces);
	free(edges);
	free(ledges);
}