/* * Copyright 2011-2016 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause */#include"common.h"#include"bgfx_utils.h"structPosColorVertex{floatm_x;floatm_y;floatm_z;uint32_tm_abgr;staticvoidinit(){ms_decl.begin().add(bgfx::Attrib::Position,3,bgfx::AttribType::Float).add(bgfx::Attrib::Color0,4,bgfx::AttribType::Uint8,true).end();};staticbgfx::VertexDeclms_decl;};bgfx::VertexDeclPosColorVertex::ms_decl;staticPosColorVertexs_cubeVertices[8]={{-1.0f,1.0f,1.0f,0xff000000},{1.0f,1.0f,1.0f,0xff0000ff},{-1.0f,-1.0f,1.0f,0xff00ff00},{1.0f,-1.0f,1.0f,0xff00ffff},{-1.0f,1.0f,-1.0f,0xffff0000},{1.0f,1.0f,-1.0f,0xffff00ff},{-1.0f,-1.0f,-1.0f,0xffffff00},{1.0f,-1.0f,-1.0f,0xffffffff},};staticconstuint16_ts_cubeIndices[36]={0,1,2,// 01,3,2,4,6,5,// 25,6,7,0,2,4,// 44,2,6,1,5,3,// 65,7,3,0,4,1,// 84,5,1,2,3,6,// 106,3,7,};classExampleInstancing:publicentry::AppI{voidinit(int_argc,char**_argv)BX_OVERRIDE{Argsargs(_argc,_argv);m_width=1280;m_height=720;m_debug=BGFX_DEBUG_TEXT;m_reset=BGFX_RESET_VSYNC;bgfx::init(args.m_type,args.m_pciId);bgfx::reset(m_width,m_height,m_reset);// Enable debug text.bgfx::setDebug(m_debug);// Set view 0 clear state.bgfx::setViewClear(0,BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH,0x303030ff,1.0f,0);// Create vertex stream declaration.PosColorVertex::init();// Create static vertex buffer.m_vbh=bgfx::createVertexBuffer(bgfx::makeRef(s_cubeVertices,sizeof(s_cubeVertices)),PosColorVertex::ms_decl);// Create static index buffer.m_ibh=bgfx::createIndexBuffer(bgfx::makeRef(s_cubeIndices,sizeof(s_cubeIndices)));// Create program from shaders.m_program=loadProgram("vs_instancing","fs_instancing");m_timeOffset=bx::getHPCounter();}intshutdown()BX_OVERRIDE{// Cleanup.bgfx::destroyIndexBuffer(m_ibh);bgfx::destroyVertexBuffer(m_vbh);bgfx::destroyProgram(m_program);// Shutdown bgfx.bgfx::shutdown();return0;}boolupdate()BX_OVERRIDE{if(!entry::processEvents(m_width,m_height,m_debug,m_reset)){// Set view 0 default viewport.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_tnow=bx::getHPCounter();staticint64_tlast=now;constint64_tframeTime=now-last;last=now;constdoublefreq=double(bx::getHPFrequency());constdoubletoMs=1000.0/freq;floattime=(float)((now-m_timeOffset)/double(bx::getHPFrequency()));// Use debug font to print information about this example.bgfx::dbgTextClear();bgfx::dbgTextPrintf(0,1,0x4f,"bgfx/examples/05-instancing");bgfx::dbgTextPrintf(0,2,0x6f,"Description: Geometry instancing.");bgfx::dbgTextPrintf(0,3,0x0f,"Frame: % 7.3f[ms]",double(frameTime)*toMs);// Get renderer capabilities info.constbgfx::Caps*caps=bgfx::getCaps();// Check if instancing is supported.if(0==(BGFX_CAPS_INSTANCING&caps->supported)){// When instancing is not supported by GPU, implement alternative// code path that doesn't use instancing.boolblink=uint32_t(time*3.0f)&1;bgfx::dbgTextPrintf(0,5,blink?0x1f:0x01," Instancing is not supported by GPU. ");}else{floatat[3]={0.0f,0.0f,0.0f};floateye[3]={0.0f,0.0f,-35.0f};// Set view and projection matrix for view 0.constbgfx::HMD*hmd=bgfx::getHMD();if(NULL!=hmd&&0!=(hmd->flags&BGFX_HMD_RENDERING)){floatview[16];bx::mtxQuatTranslationHMD(view,hmd->eye[0].rotation,eye);floatproj[16];bx::mtxProj(proj,hmd->eye[0].fov,0.1f,100.0f);bgfx::setViewTransform(0,view,proj);// Set view 0 default viewport.//// Use HMD's width/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{floatview[16];bx::mtxLookAt(view,eye,at);floatproj[16];bx::mtxProj(proj,60.0f,float(m_width)/float(m_height),0.1f,100.0f);bgfx::setViewTransform(0,view,proj);// Set view 0 default viewport.bgfx::setViewRect(0,0,0,m_width,m_height);}constuint16_tinstanceStride=80;constbgfx::InstanceDataBuffer*idb=bgfx::allocInstanceDataBuffer(121,instanceStride);if(NULL!=idb){uint8_t*data=idb->data;// Write instance data for 11x11 cubes.for(uint32_tyy=0,numInstances=0;yy<11&&numInstances<idb->num;++yy){for(uint32_txx=0;xx<11&&numInstances<idb->num;++xx,++numInstances){float*mtx=(float*)data;bx::mtxRotateXY(mtx,time+xx*0.21f,time+yy*0.37f);mtx[12]=-15.0f+float(xx)*3.0f;mtx[13]=-15.0f+float(yy)*3.0f;mtx[14]=0.0f;float*color=(float*)&data[64];color[0]=sinf(time+float(xx)/11.0f)*0.5f+0.5f;color[1]=cosf(time+float(yy)/11.0f)*0.5f+0.5f;color[2]=sinf(time*3.0f)*0.5f+0.5f;color[3]=1.0f;data+=instanceStride;}}// Set vertex and index buffer.bgfx::setVertexBuffer(m_vbh);bgfx::setIndexBuffer(m_ibh);// Set instance data buffer.bgfx::setInstanceDataBuffer(idb);// Set render states.bgfx::setState(BGFX_STATE_DEFAULT);// Submit primitive for rendering to view 0.bgfx::submit(0,m_program);}}// Advance to next frame. Rendering thread will be kicked to// process submitted rendering primitives.bgfx::frame();returntrue;}returnfalse;}uint32_tm_width;uint32_tm_height;uint32_tm_debug;uint32_tm_reset;bgfx::VertexBufferHandlem_vbh;bgfx::IndexBufferHandlem_ibh;bgfx::ProgramHandlem_program;int64_tm_timeOffset;};ENTRY_IMPLEMENT_MAIN(ExampleInstancing);