2014-05-03 15:18:28 -07:00
/*
2016-01-01 00:11:04 -08:00
* Copyright 2011 - 2016 Branimir Karadzic . All rights reserved .
* License : https : //github.com/bkaradzic/bgfx#license-bsd-2-clause
2014-05-03 15:18:28 -07:00
*/
2014-10-17 09:45:45 -07:00
# include <string.h> // strlen
2015-01-21 18:01:32 +01:00
# include "common.h"
2014-10-17 09:45:45 -07:00
# include <tinystl/allocator.h>
# include <tinystl/vector.h>
# include <tinystl/string.h>
namespace stl = tinystl ;
2014-05-03 15:18:28 -07:00
2015-09-18 20:16:24 -07:00
# include <bgfx/bgfx.h>
2015-10-23 20:57:04 -07:00
# include <bx/commandline.h>
2014-05-26 19:31:37 -07:00
# include <bx/fpumath.h>
2015-10-23 20:57:04 -07:00
# include <bx/readerwriter.h>
2015-05-13 22:54:52 -07:00
# include <bx/string.h>
2014-05-03 15:18:28 -07:00
# include "entry/entry.h"
2014-12-31 16:11:07 -08:00
# include <ib-compress/indexbufferdecompression.h>
2014-05-03 15:18:28 -07:00
2015-01-07 22:36:36 -08:00
# include "bgfx_utils.h"
2015-11-06 22:03:06 -08:00
void * load ( bx : : FileReaderI * _reader , bx : : AllocatorI * _allocator , const char * _filePath , uint32_t * _size )
2014-05-03 15:18:28 -07:00
{
2016-01-31 16:00:02 -08:00
if ( bx : : open ( _reader , _filePath ) )
2014-05-03 15:18:28 -07:00
{
uint32_t size = ( uint32_t ) bx : : getSize ( _reader ) ;
2015-06-01 17:45:40 -07:00
void * data = BX_ALLOC ( _allocator , size ) ;
2014-05-03 15:18:28 -07:00
bx : : read ( _reader , data , size ) ;
bx : : close ( _reader ) ;
2015-01-22 21:01:09 -08:00
if ( NULL ! = _size )
{
* _size = size ;
}
2014-05-03 15:18:28 -07:00
return data ;
}
2015-12-08 20:34:31 -08:00
else
{
DBG ( " Failed to open: %s. " , _filePath ) ;
}
2014-05-03 15:18:28 -07:00
2015-01-22 21:01:09 -08:00
if ( NULL ! = _size )
{
* _size = 0 ;
}
2016-01-31 16:00:02 -08:00
2014-05-03 15:18:28 -07:00
return NULL ;
}
2015-01-22 21:01:09 -08:00
void * load ( const char * _filePath , uint32_t * _size )
2014-05-03 15:18:28 -07:00
{
2015-06-01 17:45:40 -07:00
return load ( entry : : getFileReader ( ) , entry : : getAllocator ( ) , _filePath , _size ) ;
}
void unload ( void * _ptr )
{
BX_FREE ( entry : : getAllocator ( ) , _ptr ) ;
2014-05-03 15:18:28 -07:00
}
static const bgfx : : Memory * loadMem ( bx : : FileReaderI * _reader , const char * _filePath )
{
2016-01-31 16:00:02 -08:00
if ( bx : : open ( _reader , _filePath ) )
2014-05-03 15:18:28 -07:00
{
uint32_t size = ( uint32_t ) bx : : getSize ( _reader ) ;
const bgfx : : Memory * mem = bgfx : : alloc ( size + 1 ) ;
bx : : read ( _reader , mem - > data , size ) ;
bx : : close ( _reader ) ;
mem - > data [ mem - > size - 1 ] = ' \0 ' ;
return mem ;
}
2015-12-08 20:34:31 -08:00
DBG ( " Failed to load %s. " , _filePath ) ;
2014-05-03 15:18:28 -07:00
return NULL ;
}
2015-11-06 22:03:06 -08:00
static void * loadMem ( bx : : FileReaderI * _reader , bx : : AllocatorI * _allocator , const char * _filePath , uint32_t * _size )
2015-05-13 22:54:52 -07:00
{
2016-01-31 16:00:02 -08:00
if ( bx : : open ( _reader , _filePath ) )
2015-05-13 22:54:52 -07:00
{
uint32_t size = ( uint32_t ) bx : : getSize ( _reader ) ;
void * data = BX_ALLOC ( _allocator , size ) ;
bx : : read ( _reader , data , size ) ;
bx : : close ( _reader ) ;
if ( NULL ! = _size )
{
* _size = size ;
}
return data ;
}
2015-12-08 20:34:31 -08:00
DBG ( " Failed to load %s. " , _filePath ) ;
2015-05-13 22:54:52 -07:00
return NULL ;
}
2014-05-10 20:51:44 -07:00
static bgfx : : ShaderHandle loadShader ( bx : : FileReaderI * _reader , const char * _name )
2014-05-03 15:18:28 -07:00
{
char filePath [ 512 ] ;
const char * shaderPath = " shaders/dx9/ " ;
switch ( bgfx : : getRendererType ( ) )
{
case bgfx : : RendererType : : Direct3D11 :
2015-02-16 21:58:13 -08:00
case bgfx : : RendererType : : Direct3D12 :
2014-05-03 15:18:28 -07:00
shaderPath = " shaders/dx11/ " ;
break ;
case bgfx : : RendererType : : OpenGL :
shaderPath = " shaders/glsl/ " ;
break ;
2015-08-14 15:12:44 +02:00
case bgfx : : RendererType : : Metal :
shaderPath = " shaders/metal/ " ;
break ;
2015-08-21 20:08:03 -07:00
2014-05-03 15:18:28 -07:00
case bgfx : : RendererType : : OpenGLES :
shaderPath = " shaders/gles/ " ;
break ;
default :
break ;
}
strcpy ( filePath , shaderPath ) ;
strcat ( filePath , _name ) ;
strcat ( filePath , " .bin " ) ;
2014-05-10 20:51:44 -07:00
return bgfx : : createShader ( loadMem ( _reader , filePath ) ) ;
2014-05-03 15:18:28 -07:00
}
2014-05-10 20:51:44 -07:00
bgfx : : ShaderHandle loadShader ( const char * _name )
2014-05-03 15:18:28 -07:00
{
2014-05-10 20:51:44 -07:00
return loadShader ( entry : : getFileReader ( ) , _name ) ;
}
2014-05-03 15:18:28 -07:00
2014-05-10 20:51:44 -07:00
bgfx : : ProgramHandle loadProgram ( bx : : FileReaderI * _reader , const char * _vsName , const char * _fsName )
{
bgfx : : ShaderHandle vsh = loadShader ( _reader , _vsName ) ;
2015-08-15 18:07:43 -07:00
bgfx : : ShaderHandle fsh = BGFX_INVALID_HANDLE ;
if ( NULL ! = _fsName )
{
fsh = loadShader ( _reader , _fsName ) ;
}
2014-05-03 15:18:28 -07:00
return bgfx : : createProgram ( vsh , fsh , true /* destroy shaders when program is destroyed */ ) ;
}
bgfx : : ProgramHandle loadProgram ( const char * _vsName , const char * _fsName )
{
return loadProgram ( entry : : getFileReader ( ) , _vsName , _fsName ) ;
}
2015-05-13 22:54:52 -07:00
typedef unsigned char stbi_uc ;
extern " C " stbi_uc * stbi_load_from_memory ( stbi_uc const * buffer , int len , int * x , int * y , int * comp , int req_comp ) ;
2014-05-03 15:18:28 -07:00
bgfx : : TextureHandle loadTexture ( bx : : FileReaderI * _reader , const char * _name , uint32_t _flags , uint8_t _skip , bgfx : : TextureInfo * _info )
{
2015-05-24 10:25:47 -07:00
char filePath [ 512 ] = { ' \0 ' } ;
if ( NULL = = strchr ( _name , ' / ' ) )
{
strcpy ( filePath , " textures/ " ) ;
}
2014-05-03 15:18:28 -07:00
strcat ( filePath , _name ) ;
2015-05-13 22:54:52 -07:00
if ( NULL ! = bx : : stristr ( _name , " .dds " )
| | NULL ! = bx : : stristr ( _name , " .pvr " )
| | NULL ! = bx : : stristr ( _name , " .ktx " ) )
{
const bgfx : : Memory * mem = loadMem ( _reader , filePath ) ;
2015-05-24 10:25:47 -07:00
if ( NULL ! = mem )
{
return bgfx : : createTexture ( mem , _flags , _skip , _info ) ;
}
bgfx : : TextureHandle handle = BGFX_INVALID_HANDLE ;
DBG ( " Failed to load %s. " , filePath ) ;
return handle ;
2015-05-13 22:54:52 -07:00
}
2015-05-24 10:25:47 -07:00
bgfx : : TextureHandle handle = BGFX_INVALID_HANDLE ;
2015-11-06 22:03:06 -08:00
bx : : AllocatorI * allocator = entry : : getAllocator ( ) ;
2015-05-13 22:54:52 -07:00
2015-05-14 19:05:59 -07:00
uint32_t size = 0 ;
2015-05-13 22:54:52 -07:00
void * data = loadMem ( _reader , allocator , filePath , & size ) ;
2015-05-24 10:25:47 -07:00
if ( NULL ! = data )
{
int width = 0 ;
int height = 0 ;
int comp = 0 ;
2015-05-13 22:54:52 -07:00
2015-05-24 10:25:47 -07:00
uint8_t * img = NULL ;
img = stbi_load_from_memory ( ( uint8_t * ) data , size , & width , & height , & comp , 4 ) ;
2015-05-13 22:54:52 -07:00
2015-05-24 10:25:47 -07:00
BX_FREE ( allocator , data ) ;
2015-05-13 22:54:52 -07:00
2015-05-27 21:18:43 -07:00
if ( NULL ! = img )
2015-05-24 10:25:47 -07:00
{
2015-05-27 21:18:43 -07:00
handle = bgfx : : createTexture2D ( uint16_t ( width ) , uint16_t ( height ) , 1
, bgfx : : TextureFormat : : RGBA8
, _flags
, bgfx : : copy ( img , width * height * 4 )
) ;
free ( img ) ;
if ( NULL ! = _info )
{
bgfx : : calcTextureSize ( * _info
, uint16_t ( width )
, uint16_t ( height )
, 0
, false
, 1
, bgfx : : TextureFormat : : RGBA8
) ;
}
2015-05-24 10:25:47 -07:00
}
}
else
2015-05-13 22:54:52 -07:00
{
2015-05-24 10:25:47 -07:00
DBG ( " Failed to load %s. " , filePath ) ;
2015-05-13 22:54:52 -07:00
}
2014-05-03 15:18:28 -07:00
2015-05-13 22:54:52 -07:00
return handle ;
2014-05-03 15:18:28 -07:00
}
bgfx : : TextureHandle loadTexture ( const char * _name , uint32_t _flags , uint8_t _skip , bgfx : : TextureInfo * _info )
{
return loadTexture ( entry : : getFileReader ( ) , _name , _flags , _skip , _info ) ;
}
void calcTangents ( void * _vertices , uint16_t _numVertices , bgfx : : VertexDecl _decl , const uint16_t * _indices , uint32_t _numIndices )
{
struct PosTexcoord
{
float m_x ;
float m_y ;
float m_z ;
float m_pad0 ;
float m_u ;
float m_v ;
float m_pad1 ;
float m_pad2 ;
} ;
float * tangents = new float [ 6 * _numVertices ] ;
memset ( tangents , 0 , 6 * _numVertices * sizeof ( float ) ) ;
PosTexcoord v0 ;
PosTexcoord v1 ;
PosTexcoord v2 ;
for ( uint32_t ii = 0 , num = _numIndices / 3 ; ii < num ; + + ii )
{
const uint16_t * indices = & _indices [ ii * 3 ] ;
uint32_t i0 = indices [ 0 ] ;
uint32_t i1 = indices [ 1 ] ;
uint32_t i2 = indices [ 2 ] ;
bgfx : : vertexUnpack ( & v0 . m_x , bgfx : : Attrib : : Position , _decl , _vertices , i0 ) ;
bgfx : : vertexUnpack ( & v0 . m_u , bgfx : : Attrib : : TexCoord0 , _decl , _vertices , i0 ) ;
bgfx : : vertexUnpack ( & v1 . m_x , bgfx : : Attrib : : Position , _decl , _vertices , i1 ) ;
bgfx : : vertexUnpack ( & v1 . m_u , bgfx : : Attrib : : TexCoord0 , _decl , _vertices , i1 ) ;
bgfx : : vertexUnpack ( & v2 . m_x , bgfx : : Attrib : : Position , _decl , _vertices , i2 ) ;
bgfx : : vertexUnpack ( & v2 . m_u , bgfx : : Attrib : : TexCoord0 , _decl , _vertices , i2 ) ;
const float bax = v1 . m_x - v0 . m_x ;
const float bay = v1 . m_y - v0 . m_y ;
const float baz = v1 . m_z - v0 . m_z ;
const float bau = v1 . m_u - v0 . m_u ;
const float bav = v1 . m_v - v0 . m_v ;
const float cax = v2 . m_x - v0 . m_x ;
const float cay = v2 . m_y - v0 . m_y ;
const float caz = v2 . m_z - v0 . m_z ;
const float cau = v2 . m_u - v0 . m_u ;
const float cav = v2 . m_v - v0 . m_v ;
const float det = ( bau * cav - bav * cau ) ;
const float invDet = 1.0f / det ;
const float tx = ( bax * cav - cax * bav ) * invDet ;
const float ty = ( bay * cav - cay * bav ) * invDet ;
const float tz = ( baz * cav - caz * bav ) * invDet ;
const float bx = ( cax * bau - bax * cau ) * invDet ;
const float by = ( cay * bau - bay * cau ) * invDet ;
const float bz = ( caz * bau - baz * cau ) * invDet ;
for ( uint32_t jj = 0 ; jj < 3 ; + + jj )
{
float * tanu = & tangents [ indices [ jj ] * 6 ] ;
float * tanv = & tanu [ 3 ] ;
tanu [ 0 ] + = tx ;
tanu [ 1 ] + = ty ;
tanu [ 2 ] + = tz ;
tanv [ 0 ] + = bx ;
tanv [ 1 ] + = by ;
tanv [ 2 ] + = bz ;
}
}
for ( uint32_t ii = 0 ; ii < _numVertices ; + + ii )
{
const float * tanu = & tangents [ ii * 6 ] ;
const float * tanv = & tangents [ ii * 6 + 3 ] ;
float normal [ 4 ] ;
bgfx : : vertexUnpack ( normal , bgfx : : Attrib : : Normal , _decl , _vertices , ii ) ;
2014-05-26 19:31:37 -07:00
float ndt = bx : : vec3Dot ( normal , tanu ) ;
2014-05-03 15:18:28 -07:00
float nxt [ 3 ] ;
2014-05-26 19:31:37 -07:00
bx : : vec3Cross ( nxt , normal , tanu ) ;
2014-05-03 15:18:28 -07:00
float tmp [ 3 ] ;
tmp [ 0 ] = tanu [ 0 ] - normal [ 0 ] * ndt ;
tmp [ 1 ] = tanu [ 1 ] - normal [ 1 ] * ndt ;
tmp [ 2 ] = tanu [ 2 ] - normal [ 2 ] * ndt ;
float tangent [ 4 ] ;
2014-05-26 19:31:37 -07:00
bx : : vec3Norm ( tangent , tmp ) ;
2014-05-03 15:18:28 -07:00
2014-05-26 19:31:37 -07:00
tangent [ 3 ] = bx : : vec3Dot ( nxt , tanv ) < 0.0f ? - 1.0f : 1.0f ;
2014-05-03 15:18:28 -07:00
bgfx : : vertexPack ( tangent , true , bgfx : : Attrib : : Tangent , _decl , _vertices , ii ) ;
}
delete [ ] tangents ;
2015-01-07 22:36:36 -08:00
}
2014-05-03 15:18:28 -07:00
struct Aabb
{
float m_min [ 3 ] ;
float m_max [ 3 ] ;
} ;
struct Obb
{
float m_mtx [ 16 ] ;
} ;
struct Sphere
{
float m_center [ 3 ] ;
float m_radius ;
} ;
struct Primitive
{
uint32_t m_startIndex ;
uint32_t m_numIndices ;
uint32_t m_startVertex ;
uint32_t m_numVertices ;
Sphere m_sphere ;
Aabb m_aabb ;
Obb m_obb ;
} ;
2014-10-17 09:45:45 -07:00
typedef stl : : vector < Primitive > PrimitiveArray ;
2014-05-03 15:18:28 -07:00
struct Group
{
Group ( )
{
reset ( ) ;
}
void reset ( )
{
m_vbh . idx = bgfx : : invalidHandle ;
m_ibh . idx = bgfx : : invalidHandle ;
m_prims . clear ( ) ;
}
bgfx : : VertexBufferHandle m_vbh ;
bgfx : : IndexBufferHandle m_ibh ;
Sphere m_sphere ;
Aabb m_aabb ;
Obb m_obb ;
PrimitiveArray m_prims ;
} ;
2014-08-17 17:20:15 -07:00
namespace bgfx
{
2016-03-06 14:56:09 -08:00
int32_t read ( bx : : ReaderI * _reader , bgfx : : VertexDecl & _decl , bx : : Error * _err = NULL ) ;
2014-08-17 17:20:15 -07:00
}
2014-05-03 15:18:28 -07:00
struct Mesh
{
void load ( bx : : ReaderSeekerI * _reader )
{
2014-08-17 17:20:15 -07:00
# define BGFX_CHUNK_MAGIC_VB BX_MAKEFOURCC('V', 'B', ' ', 0x1)
# define BGFX_CHUNK_MAGIC_IB BX_MAKEFOURCC('I', 'B', ' ', 0x0)
2014-12-31 16:11:07 -08:00
# define BGFX_CHUNK_MAGIC_IBC BX_MAKEFOURCC('I', 'B', 'C', 0x0)
2014-05-03 15:18:28 -07:00
# define BGFX_CHUNK_MAGIC_PRI BX_MAKEFOURCC('P', 'R', 'I', 0x0)
2014-08-17 17:20:15 -07:00
using namespace bx ;
using namespace bgfx ;
2014-05-03 15:18:28 -07:00
Group group ;
2015-11-06 22:03:06 -08:00
bx : : AllocatorI * allocator = entry : : getAllocator ( ) ;
2015-01-07 22:36:36 -08:00
2014-05-03 15:18:28 -07:00
uint32_t chunk ;
2016-02-06 13:41:58 -08:00
bx : : Error err ;
while ( 4 = = bx : : read ( _reader , chunk , & err )
& & err . isOk ( ) )
2014-05-03 15:18:28 -07:00
{
switch ( chunk )
{
case BGFX_CHUNK_MAGIC_VB :
{
2014-08-17 17:20:15 -07:00
read ( _reader , group . m_sphere ) ;
read ( _reader , group . m_aabb ) ;
read ( _reader , group . m_obb ) ;
read ( _reader , m_decl ) ;
2014-05-03 15:18:28 -07:00
uint16_t stride = m_decl . getStride ( ) ;
uint16_t numVertices ;
2014-08-17 17:20:15 -07:00
read ( _reader , numVertices ) ;
2014-05-03 15:18:28 -07:00
const bgfx : : Memory * mem = bgfx : : alloc ( numVertices * stride ) ;
2014-08-17 17:20:15 -07:00
read ( _reader , mem - > data , mem - > size ) ;
2014-05-03 15:18:28 -07:00
group . m_vbh = bgfx : : createVertexBuffer ( mem , m_decl ) ;
}
break ;
case BGFX_CHUNK_MAGIC_IB :
{
uint32_t numIndices ;
2014-08-17 17:20:15 -07:00
read ( _reader , numIndices ) ;
2014-05-03 15:18:28 -07:00
const bgfx : : Memory * mem = bgfx : : alloc ( numIndices * 2 ) ;
2014-08-17 17:20:15 -07:00
read ( _reader , mem - > data , mem - > size ) ;
2014-05-03 15:18:28 -07:00
group . m_ibh = bgfx : : createIndexBuffer ( mem ) ;
}
break ;
2014-12-31 16:11:07 -08:00
case BGFX_CHUNK_MAGIC_IBC :
{
uint32_t numIndices ;
bx : : read ( _reader , numIndices ) ;
const bgfx : : Memory * mem = bgfx : : alloc ( numIndices * 2 ) ;
uint32_t compressedSize ;
bx : : read ( _reader , compressedSize ) ;
2015-01-07 22:36:36 -08:00
void * compressedIndices = BX_ALLOC ( allocator , compressedSize ) ;
2014-12-31 16:11:07 -08:00
bx : : read ( _reader , compressedIndices , compressedSize ) ;
ReadBitstream rbs ( ( const uint8_t * ) compressedIndices , compressedSize ) ;
DecompressIndexBuffer ( ( uint16_t * ) mem - > data , numIndices / 3 , rbs ) ;
2015-01-07 22:36:36 -08:00
BX_FREE ( allocator , compressedIndices ) ;
2014-12-31 16:11:07 -08:00
group . m_ibh = bgfx : : createIndexBuffer ( mem ) ;
}
break ;
2014-05-03 15:18:28 -07:00
case BGFX_CHUNK_MAGIC_PRI :
{
uint16_t len ;
2014-08-17 17:20:15 -07:00
read ( _reader , len ) ;
2014-05-03 15:18:28 -07:00
2014-10-17 09:45:45 -07:00
stl : : string material ;
2014-05-03 15:18:28 -07:00
material . resize ( len ) ;
2014-08-17 17:20:15 -07:00
read ( _reader , const_cast < char * > ( material . c_str ( ) ) , len ) ;
2014-05-03 15:18:28 -07:00
uint16_t num ;
2014-08-17 17:20:15 -07:00
read ( _reader , num ) ;
2014-05-03 15:18:28 -07:00
for ( uint32_t ii = 0 ; ii < num ; + + ii )
{
2014-08-17 17:20:15 -07:00
read ( _reader , len ) ;
2014-05-03 15:18:28 -07:00
2014-10-17 09:45:45 -07:00
stl : : string name ;
2014-05-03 15:18:28 -07:00
name . resize ( len ) ;
2014-08-17 17:20:15 -07:00
read ( _reader , const_cast < char * > ( name . c_str ( ) ) , len ) ;
2014-05-03 15:18:28 -07:00
Primitive prim ;
2014-08-17 17:20:15 -07:00
read ( _reader , prim . m_startIndex ) ;
read ( _reader , prim . m_numIndices ) ;
read ( _reader , prim . m_startVertex ) ;
read ( _reader , prim . m_numVertices ) ;
read ( _reader , prim . m_sphere ) ;
read ( _reader , prim . m_aabb ) ;
read ( _reader , prim . m_obb ) ;
2014-05-03 15:18:28 -07:00
group . m_prims . push_back ( prim ) ;
}
m_groups . push_back ( group ) ;
group . reset ( ) ;
}
break ;
default :
DBG ( " %08x at %d " , chunk , bx : : skip ( _reader , 0 ) ) ;
break ;
}
}
}
void unload ( )
{
for ( GroupArray : : const_iterator it = m_groups . begin ( ) , itEnd = m_groups . end ( ) ; it ! = itEnd ; + + it )
{
const Group & group = * it ;
bgfx : : destroyVertexBuffer ( group . m_vbh ) ;
if ( bgfx : : isValid ( group . m_ibh ) )
{
bgfx : : destroyIndexBuffer ( group . m_ibh ) ;
}
}
m_groups . clear ( ) ;
}
2015-01-07 22:36:36 -08:00
void submit ( uint8_t _id , bgfx : : ProgramHandle _program , const float * _mtx , uint64_t _state ) const
2014-05-03 15:18:28 -07:00
{
2014-05-20 21:15:48 -07:00
if ( BGFX_STATE_MASK = = _state )
{
_state = 0
| BGFX_STATE_RGB_WRITE
| BGFX_STATE_ALPHA_WRITE
| BGFX_STATE_DEPTH_WRITE
| BGFX_STATE_DEPTH_TEST_LESS
| BGFX_STATE_CULL_CCW
| BGFX_STATE_MSAA
;
}
2016-02-29 11:24:14 -08:00
bgfx : : setTransform ( _mtx ) ;
bgfx : : setState ( _state ) ;
2015-01-07 22:36:36 -08:00
2014-05-03 15:18:28 -07:00
for ( GroupArray : : const_iterator it = m_groups . begin ( ) , itEnd = m_groups . end ( ) ; it ! = itEnd ; + + it )
{
const Group & group = * it ;
bgfx : : setIndexBuffer ( group . m_ibh ) ;
bgfx : : setVertexBuffer ( group . m_vbh ) ;
2016-02-29 11:24:14 -08:00
bgfx : : submit ( _id , _program , 0 , it ! = itEnd - 1 ) ;
2014-05-03 15:18:28 -07:00
}
}
2015-01-07 22:36:36 -08:00
void submit ( const MeshState * const * _state , uint8_t _numPasses , const float * _mtx , uint16_t _numMatrices ) const
{
uint32_t cached = bgfx : : setTransform ( _mtx , _numMatrices ) ;
for ( uint32_t pass = 0 ; pass < _numPasses ; + + pass )
{
2016-02-29 11:24:14 -08:00
bgfx : : setTransform ( cached , _numMatrices ) ;
2015-01-07 22:36:36 -08:00
const MeshState & state = * _state [ pass ] ;
2016-02-29 11:24:14 -08:00
bgfx : : setState ( state . m_state ) ;
for ( uint8_t tex = 0 ; tex < state . m_numTextures ; + + tex )
{
const MeshState : : Texture & texture = state . m_textures [ tex ] ;
bgfx : : setTexture ( texture . m_stage
, texture . m_sampler
, texture . m_texture
, texture . m_flags
) ;
}
2015-01-07 22:36:36 -08:00
for ( GroupArray : : const_iterator it = m_groups . begin ( ) , itEnd = m_groups . end ( ) ; it ! = itEnd ; + + it )
{
const Group & group = * it ;
bgfx : : setIndexBuffer ( group . m_ibh ) ;
bgfx : : setVertexBuffer ( group . m_vbh ) ;
2016-02-29 11:24:14 -08:00
bgfx : : submit ( state . m_viewId , state . m_program , 0 , it ! = itEnd - 1 ) ;
2015-01-07 22:36:36 -08:00
}
}
}
2014-05-03 15:18:28 -07:00
bgfx : : VertexDecl m_decl ;
2014-10-17 09:45:45 -07:00
typedef stl : : vector < Group > GroupArray ;
2014-05-03 15:18:28 -07:00
GroupArray m_groups ;
} ;
Mesh * meshLoad ( bx : : ReaderSeekerI * _reader )
{
Mesh * mesh = new Mesh ;
mesh - > load ( _reader ) ;
return mesh ;
}
Mesh * meshLoad ( const char * _filePath )
{
bx : : FileReaderI * reader = entry : : getFileReader ( ) ;
2016-01-31 16:00:02 -08:00
if ( bx : : open ( reader , _filePath ) )
{
Mesh * mesh = meshLoad ( reader ) ;
bx : : close ( reader ) ;
return mesh ;
}
return NULL ;
2014-05-03 15:18:28 -07:00
}
void meshUnload ( Mesh * _mesh )
{
_mesh - > unload ( ) ;
delete _mesh ;
}
2015-01-07 22:36:36 -08:00
MeshState * meshStateCreate ( )
{
MeshState * state = ( MeshState * ) BX_ALLOC ( entry : : getAllocator ( ) , sizeof ( MeshState ) ) ;
return state ;
}
void meshStateDestroy ( MeshState * _meshState )
{
BX_FREE ( entry : : getAllocator ( ) , _meshState ) ;
}
void meshSubmit ( const Mesh * _mesh , uint8_t _id , bgfx : : ProgramHandle _program , const float * _mtx , uint64_t _state )
2014-05-03 15:18:28 -07:00
{
2014-05-20 21:15:48 -07:00
_mesh - > submit ( _id , _program , _mtx , _state ) ;
2014-05-03 15:18:28 -07:00
}
2015-01-07 22:36:36 -08:00
void meshSubmit ( const Mesh * _mesh , const MeshState * const * _state , uint8_t _numPasses , const float * _mtx , uint16_t _numMatrices )
{
_mesh - > submit ( _state , _numPasses , _mtx , _numMatrices ) ;
}
2015-10-23 20:57:04 -07:00
Args : : Args ( int _argc , char * * _argv )
: m_type ( bgfx : : RendererType : : Count )
, m_pciId ( BGFX_PCI_ID_NONE )
{
bx : : CommandLine cmdLine ( _argc , ( const char * * ) _argv ) ;
if ( cmdLine . hasArg ( " gl " ) )
{
m_type = bgfx : : RendererType : : OpenGL ;
}
2016-02-16 20:38:59 -08:00
else if ( cmdLine . hasArg ( " vk " ) )
2015-10-23 20:57:04 -07:00
{
2016-02-16 20:38:59 -08:00
m_type = bgfx : : RendererType : : Vulkan ;
}
else if ( cmdLine . hasArg ( " noop " ) )
{
m_type = bgfx : : RendererType : : Null ;
2015-10-23 20:57:04 -07:00
}
else if ( BX_ENABLED ( BX_PLATFORM_WINDOWS ) )
{
if ( cmdLine . hasArg ( " d3d9 " ) )
{
m_type = bgfx : : RendererType : : Direct3D9 ;
}
else if ( cmdLine . hasArg ( " d3d11 " ) )
{
m_type = bgfx : : RendererType : : Direct3D11 ;
}
else if ( cmdLine . hasArg ( " d3d12 " ) )
{
m_type = bgfx : : RendererType : : Direct3D12 ;
}
}
else if ( BX_ENABLED ( BX_PLATFORM_OSX ) )
{
if ( cmdLine . hasArg ( " mtl " ) )
{
m_type = bgfx : : RendererType : : Metal ;
}
}
if ( cmdLine . hasArg ( " amd " ) )
{
m_pciId = BGFX_PCI_ID_AMD ;
}
else if ( cmdLine . hasArg ( " nvidia " ) )
{
m_pciId = BGFX_PCI_ID_NVIDIA ;
}
else if ( cmdLine . hasArg ( " intel " ) )
{
m_pciId = BGFX_PCI_ID_INTEL ;
}
else if ( cmdLine . hasArg ( " sw " ) )
{
m_pciId = BGFX_PCI_ID_SOFTWARE_RASTERIZER ;
}
}