2013-05-18 18:41:32 +08:00
/*
* Copyright 2013 Milos Tosic . All rights reserved .
2016-01-01 00:11:04 -08:00
* License : https : //github.com/bkaradzic/bgfx#license-bsd-2-clause
2013-05-18 18:41:32 +08:00
*/
2013-05-23 22:07:54 -07:00
# include "common.h"
2014-05-03 15:18:28 -07:00
# include "bgfx_utils.h"
2013-05-23 22:07:54 -07:00
# include "imgui/imgui.h"
2013-05-18 18:41:32 +08:00
2014-05-03 15:18:28 -07:00
# include <bx/readerwriter.h>
2013-05-18 18:41:32 +08:00
struct KnightPos
{
int32_t m_x ;
int32_t m_y ;
} ;
2015-10-24 22:34:11 -07:00
static const KnightPos knightTour [ 8 * 4 ] =
2013-05-18 22:12:40 -07:00
{
2013-05-18 18:41:32 +08:00
{ 0 , 0 } , { 1 , 2 } , { 3 , 3 } , { 4 , 1 } , { 5 , 3 } , { 7 , 2 } , { 6 , 0 } , { 5 , 2 } ,
{ 7 , 3 } , { 6 , 1 } , { 4 , 0 } , { 3 , 2 } , { 2 , 0 } , { 0 , 1 } , { 1 , 3 } , { 2 , 1 } ,
{ 0 , 2 } , { 1 , 0 } , { 2 , 2 } , { 0 , 3 } , { 1 , 1 } , { 3 , 0 } , { 4 , 2 } , { 5 , 0 } ,
2015-03-30 14:38:16 -07:00
{ 7 , 1 } , { 6 , 3 } , { 5 , 1 } , { 7 , 0 } , { 6 , 2 } , { 4 , 3 } , { 3 , 1 } , { 2 , 3 } ,
2013-05-18 18:41:32 +08:00
} ;
2016-03-06 15:29:22 -08:00
class ExampleLod : public entry : : AppI
2013-05-18 18:41:32 +08:00
{
2015-10-24 22:34:11 -07:00
void init ( int _argc , char * * _argv ) BX_OVERRIDE
{
Args args ( _argc , _argv ) ;
2013-05-18 18:41:32 +08:00
2015-10-24 22:34:11 -07:00
m_width = 1280 ;
m_height = 720 ;
m_debug = BGFX_DEBUG_TEXT ;
m_reset = BGFX_RESET_VSYNC ;
2013-05-18 18:41:32 +08:00
2015-10-24 22:34:11 -07:00
bgfx : : init ( args . m_type , args . m_pciId ) ;
bgfx : : reset ( m_width , m_height , m_reset ) ;
2013-05-18 18:41:32 +08:00
2015-10-24 22:34:11 -07:00
// Enable debug text.
bgfx : : setDebug ( m_debug ) ;
2015-01-22 21:01:09 -08:00
2015-10-24 22:34:11 -07:00
// Set view 0 clear state.
bgfx : : setViewClear ( 0
, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH
, 0x303030ff
, 1.0f
, 0
) ;
2013-05-18 18:41:32 +08:00
2015-10-24 22:34:11 -07:00
s_texColor = bgfx : : createUniform ( " s_texColor " , bgfx : : UniformType : : Int1 ) ;
s_texStipple = bgfx : : createUniform ( " s_texStipple " , bgfx : : UniformType : : Int1 ) ;
u_stipple = bgfx : : createUniform ( " u_stipple " , bgfx : : UniformType : : Vec4 ) ;
2013-05-18 18:41:32 +08:00
2015-10-24 22:34:11 -07:00
m_program = loadProgram ( " vs_tree " , " fs_tree " ) ;
2013-05-18 18:41:32 +08:00
2015-10-24 22:34:11 -07:00
m_textureLeafs = loadTexture ( " leafs1.dds " ) ;
m_textureBark = loadTexture ( " bark1.dds " ) ;
2013-05-18 18:41:32 +08:00
2015-10-24 22:34:11 -07:00
const bgfx : : Memory * stippleTex = bgfx : : alloc ( 8 * 4 ) ;
memset ( stippleTex - > data , 0 , stippleTex - > size ) ;
2013-05-18 18:41:32 +08:00
2015-10-24 22:34:11 -07:00
for ( uint32_t ii = 0 ; ii < 32 ; + + ii )
{
stippleTex - > data [ knightTour [ ii ] . m_y * 8 + knightTour [ ii ] . m_x ] = ii * 4 ;
}
2015-01-22 21:01:09 -08:00
2015-10-24 22:34:11 -07:00
m_textureStipple = bgfx : : createTexture2D ( 8 , 4 , 1
2015-03-30 14:38:16 -07:00
, bgfx : : TextureFormat : : R8
, BGFX_TEXTURE_MAG_POINT | BGFX_TEXTURE_MIN_POINT
, stippleTex
) ;
2013-05-18 18:41:32 +08:00
2015-10-24 22:34:11 -07:00
m_meshTop [ 0 ] = meshLoad ( " meshes/tree1b_lod0_1.bin " ) ;
m_meshTop [ 1 ] = meshLoad ( " meshes/tree1b_lod1_1.bin " ) ;
m_meshTop [ 2 ] = meshLoad ( " meshes/tree1b_lod2_1.bin " ) ;
2015-01-22 21:01:09 -08:00
2015-10-24 22:34:11 -07:00
m_meshTrunk [ 0 ] = meshLoad ( " meshes/tree1b_lod0_2.bin " ) ;
m_meshTrunk [ 1 ] = meshLoad ( " meshes/tree1b_lod1_2.bin " ) ;
m_meshTrunk [ 2 ] = meshLoad ( " meshes/tree1b_lod2_2.bin " ) ;
2013-05-18 18:41:32 +08:00
2015-10-24 22:34:11 -07:00
// Imgui.
imguiCreate ( ) ;
2013-05-18 18:41:32 +08:00
2015-10-24 22:34:11 -07:00
m_scrollArea = 0 ;
m_transitions = true ;
m_transitionFrame = 0 ;
m_currLod = 0 ;
m_targetLod = 0 ;
}
2013-05-18 18:41:32 +08:00
2015-10-24 22:34:11 -07:00
virtual int shutdown ( ) BX_OVERRIDE
{
imguiDestroy ( ) ;
2013-05-18 18:41:32 +08:00
2015-10-24 22:34:11 -07:00
for ( uint32_t ii = 0 ; ii < BX_COUNTOF ( m_meshTop ) ; + + ii )
{
meshUnload ( m_meshTop [ ii ] ) ;
meshUnload ( m_meshTrunk [ ii ] ) ;
}
2013-05-18 18:41:32 +08:00
2015-10-24 22:34:11 -07:00
// Cleanup.
bgfx : : destroyProgram ( m_program ) ;
2013-05-18 18:41:32 +08:00
2015-10-24 22:34:11 -07:00
bgfx : : destroyUniform ( s_texColor ) ;
bgfx : : destroyUniform ( s_texStipple ) ;
bgfx : : destroyUniform ( u_stipple ) ;
2013-05-18 18:41:32 +08:00
2015-10-24 22:34:11 -07:00
bgfx : : destroyTexture ( m_textureStipple ) ;
bgfx : : destroyTexture ( m_textureLeafs ) ;
bgfx : : destroyTexture ( m_textureBark ) ;
2013-05-18 18:41:32 +08:00
2015-10-24 22:34:11 -07:00
// Shutdown bgfx.
bgfx : : shutdown ( ) ;
2013-05-18 18:41:32 +08:00
2015-10-24 22:34:11 -07:00
return 0 ;
}
2013-05-18 18:41:32 +08:00
2015-10-24 22:34:11 -07:00
bool update ( ) BX_OVERRIDE
{
if ( ! entry : : processEvents ( m_width , m_height , m_debug , m_reset , & m_mouseState ) )
2014-11-02 00:06:18 -07:00
{
2015-10-24 22:34:11 -07:00
imguiBeginFrame ( m_mouseState . m_mx
, m_mouseState . m_my
, ( m_mouseState . m_buttons [ entry : : MouseButton : : Left ] ? IMGUI_MBUT_LEFT : 0 )
| ( m_mouseState . m_buttons [ entry : : MouseButton : : Right ] ? IMGUI_MBUT_RIGHT : 0 )
| ( m_mouseState . m_buttons [ entry : : MouseButton : : Middle ] ? IMGUI_MBUT_MIDDLE : 0 )
, m_mouseState . m_mz
, m_width
, m_height
) ;
2015-10-24 22:47:24 -07:00
imguiBeginScrollArea ( " Toggle transitions " , m_width - m_width / 5 - 10 , 10 , m_width / 5 , m_height / 6 , & m_scrollArea ) ;
2015-10-24 22:34:11 -07:00
imguiSeparatorLine ( ) ;
if ( imguiButton ( m_transitions ? " ON " : " OFF " ) )
{
m_transitions = ! m_transitions ;
}
2014-11-02 00:06:18 -07:00
2015-10-24 22:34:11 -07:00
static float distance = 2.0f ;
2015-10-24 22:47:24 -07:00
imguiSlider ( " Distance " , distance , 2.0f , 6.0f , 0.01f ) ;
2014-11-02 00:06:18 -07:00
2015-10-24 22:34:11 -07:00
imguiEndScrollArea ( ) ;
imguiEndFrame ( ) ;
2014-11-02 00:06:18 -07:00
// Set view 0 default viewport.
2015-10-24 22:34:11 -07:00
bgfx : : setViewRect ( 0 , 0 , 0 , m_width , m_height ) ;
// This dummy draw call is here to make sure that view 0 is cleared
// if no other draw calls are submitted to view 0.
bgfx : : touch ( 0 ) ;
int64_t now = bx : : getHPCounter ( ) ;
static int64_t last = now ;
const int64_t frameTime = now - last ;
last = now ;
const double freq = double ( bx : : getHPFrequency ( ) ) ;
const double toMs = 1000.0 / freq ;
// Use debug font to print information about this example.
bgfx : : dbgTextClear ( ) ;
bgfx : : dbgTextPrintf ( 0 , 1 , 0x4f , " bgfx/examples/12-lod " ) ;
2015-10-24 22:47:24 -07:00
bgfx : : dbgTextPrintf ( 0 , 2 , 0x6f , " Description: Mesh LOD transitions. " ) ;
2015-10-24 22:34:11 -07:00
bgfx : : dbgTextPrintf ( 0 , 3 , 0x0f , " Frame: % 7.3f[ms] " , double ( frameTime ) * toMs ) ;
2015-10-24 22:53:26 -07:00
float at [ 3 ] = { 0.0f , 1.0f , 0.0f } ;
float eye [ 3 ] = { 0.0f , 2.0f , - distance } ;
2015-10-24 22:34:11 -07:00
// Set view and projection matrix for view 0.
const bgfx : : HMD * hmd = bgfx : : getHMD ( ) ;
if ( NULL ! = hmd & & 0 ! = ( hmd - > flags & BGFX_HMD_RENDERING ) )
{
float view [ 16 ] ;
bx : : mtxQuatTranslationHMD ( view , hmd - > eye [ 0 ] . rotation , eye ) ;
2014-11-02 00:06:18 -07:00
2015-10-24 22:34:11 -07:00
float proj [ 16 ] ;
bx : : mtxProj ( proj , hmd - > eye [ 0 ] . fov , 0.1f , 100.0f ) ;
2014-11-02 00:06:18 -07:00
2015-10-24 22:34:11 -07:00
bgfx : : setViewTransform ( 0 , view , proj ) ;
// Set view 0 default viewport.
//
// Use HMD's m_width/m_height since HMD's internal frame buffer size
// might be much larger than window size.
bgfx : : setViewRect ( 0 , 0 , 0 , hmd - > width , hmd - > height ) ;
}
else
{
float view [ 16 ] ;
bx : : mtxLookAt ( view , eye , at ) ;
2013-05-18 18:41:32 +08:00
2015-10-24 22:34:11 -07:00
float proj [ 16 ] ;
bx : : mtxProj ( proj , 60.0f , float ( m_width ) / float ( m_height ) , 0.1f , 100.0f ) ;
bgfx : : setViewTransform ( 0 , view , proj ) ;
2013-05-18 18:41:32 +08:00
2015-10-24 22:34:11 -07:00
// Set view 0 default viewport.
bgfx : : setViewRect ( 0 , 0 , 0 , m_width , m_height ) ;
}
2013-05-18 18:41:32 +08:00
2015-10-24 22:34:11 -07:00
float mtx [ 16 ] ;
bx : : mtxScale ( mtx , 0.1f , 0.1f , 0.1f ) ;
2015-01-22 21:01:09 -08:00
2015-10-24 22:34:11 -07:00
float stipple [ 3 ] ;
float stippleInv [ 3 ] ;
2015-01-22 21:01:09 -08:00
2015-10-24 22:34:11 -07:00
const int currentLODframe = m_transitions ? 32 - m_transitionFrame : 32 ;
const int mainLOD = m_transitions ? m_currLod : m_targetLod ;
2013-05-18 18:41:32 +08:00
2015-10-24 22:34:11 -07:00
stipple [ 0 ] = 0.0f ;
stipple [ 1 ] = - 1.0f ;
stipple [ 2 ] = ( float ( currentLODframe ) * 4.0f / 255.0f ) - ( 1.0f / 255.0f ) ;
2013-05-18 18:41:32 +08:00
2015-10-24 22:34:11 -07:00
stippleInv [ 0 ] = ( float ( 31 ) * 4.0f / 255.0f ) ;
stippleInv [ 1 ] = 1.0f ;
stippleInv [ 2 ] = ( float ( m_transitionFrame ) * 4.0f / 255.0f ) - ( 1.0f / 255.0f ) ;
2013-05-18 18:41:32 +08:00
2015-10-24 22:34:11 -07:00
const uint64_t stateTransparent = 0
| BGFX_STATE_RGB_WRITE
| BGFX_STATE_ALPHA_WRITE
| BGFX_STATE_DEPTH_TEST_LESS
| BGFX_STATE_CULL_CCW
| BGFX_STATE_MSAA
| BGFX_STATE_BLEND_ALPHA
;
2015-01-22 21:01:09 -08:00
2015-10-24 22:34:11 -07:00
const uint64_t stateOpaque = BGFX_STATE_DEFAULT ;
2013-05-18 09:43:57 -07:00
2015-10-24 22:34:11 -07:00
bgfx : : setTexture ( 0 , s_texColor , m_textureBark ) ;
bgfx : : setTexture ( 1 , s_texStipple , m_textureStipple ) ;
bgfx : : setUniform ( u_stipple , stipple ) ;
meshSubmit ( m_meshTrunk [ mainLOD ] , 0 , m_program , mtx , stateOpaque ) ;
2013-05-18 18:41:32 +08:00
2015-10-24 22:34:11 -07:00
bgfx : : setTexture ( 0 , s_texColor , m_textureLeafs ) ;
bgfx : : setTexture ( 1 , s_texStipple , m_textureStipple ) ;
bgfx : : setUniform ( u_stipple , stipple ) ;
meshSubmit ( m_meshTop [ mainLOD ] , 0 , m_program , mtx , stateTransparent ) ;
if ( m_transitions
& & ( m_transitionFrame ! = 0 ) )
2013-05-18 09:43:57 -07:00
{
2015-10-24 22:34:11 -07:00
bgfx : : setTexture ( 0 , s_texColor , m_textureBark ) ;
bgfx : : setTexture ( 1 , s_texStipple , m_textureStipple ) ;
bgfx : : setUniform ( u_stipple , stippleInv ) ;
meshSubmit ( m_meshTrunk [ m_targetLod ] , 0 , m_program , mtx , stateOpaque ) ;
bgfx : : setTexture ( 0 , s_texColor , m_textureLeafs ) ;
bgfx : : setTexture ( 1 , s_texStipple , m_textureStipple ) ;
bgfx : : setUniform ( u_stipple , stippleInv ) ;
meshSubmit ( m_meshTop [ m_targetLod ] , 0 , m_program , mtx , stateTransparent ) ;
2013-05-18 09:43:57 -07:00
}
2015-01-22 21:01:09 -08:00
2015-10-24 22:34:11 -07:00
int lod = 0 ;
if ( eye [ 2 ] < - 2.5f )
{
lod = 1 ;
}
2013-05-18 18:41:32 +08:00
2015-10-24 22:34:11 -07:00
if ( eye [ 2 ] < - 5.0f )
{
lod = 2 ;
}
2013-05-18 18:41:32 +08:00
2015-10-24 22:34:11 -07:00
if ( m_targetLod ! = lod )
{
if ( m_targetLod = = m_currLod )
{
m_targetLod = lod ;
}
}
2013-05-18 18:41:32 +08:00
2015-10-24 22:34:11 -07:00
if ( m_currLod ! = m_targetLod )
{
m_transitionFrame + + ;
}
2013-10-06 20:30:44 -07:00
2015-10-24 22:34:11 -07:00
if ( m_transitionFrame > 32 )
{
m_currLod = m_targetLod ;
m_transitionFrame = 0 ;
}
2013-05-18 18:41:32 +08:00
2015-10-24 22:34:11 -07:00
// Advance to next frame. Rendering thread will be kicked to
// process submitted rendering primitives.
bgfx : : frame ( ) ;
2013-05-18 18:41:32 +08:00
2015-10-24 22:34:11 -07:00
return true ;
}
2013-05-18 18:41:32 +08:00
2015-10-24 22:34:11 -07:00
return false ;
}
2015-01-22 21:01:09 -08:00
2015-10-24 22:34:11 -07:00
entry : : MouseState m_mouseState ;
uint32_t m_width ;
uint32_t m_height ;
uint32_t m_debug ;
uint32_t m_reset ;
Mesh * m_meshTop [ 3 ] ;
Mesh * m_meshTrunk [ 3 ] ;
bgfx : : ProgramHandle m_program ;
bgfx : : UniformHandle s_texColor ;
bgfx : : UniformHandle s_texStipple ;
bgfx : : UniformHandle u_stipple ;
bgfx : : TextureHandle m_textureStipple ;
bgfx : : TextureHandle m_textureLeafs ;
bgfx : : TextureHandle m_textureBark ;
int32_t m_scrollArea ;
int32_t m_transitionFrame ;
int32_t m_currLod ;
int32_t m_targetLod ;
bool m_transitions ;
} ;
2013-05-18 18:41:32 +08:00
2016-03-06 15:29:22 -08:00
ENTRY_IMPLEMENT_MAIN ( ExampleLod ) ;