void InstancingApp::initPerInstancePositions( int32_t sceneIndex, float* pHwInstanceData ) { // init positional offsets for all instances if( sceneIndex == BOXES_SCENE ) // boxes scene { for( int32_t z = 0; z < GRID_SIZE; ++z ) { for( int32_t y = 0; y < GRID_SIZE; ++y ) { for( int32_t x = 0; x < GRID_SIZE; ++x ) { int32_t i = 3 * ( z * GRID_SIZE * GRID_SIZE + y * GRID_SIZE + x ); m_instanceOffsets[sceneIndex][ i + 0 ] = - 10.0f + float( x ) * 1.1f + (isMobilePlatform() ? -5.0f : 0.0f); m_instanceOffsets[sceneIndex][ i + 1 ] = - 10.0f + float( y ) * 1.1f; m_instanceOffsets[sceneIndex][ i + 2 ] = - 10.0f + float( z ) * 1.1f; int32_t j = 6 * ( z * GRID_SIZE * GRID_SIZE + y * GRID_SIZE + x ); pHwInstanceData[ j + 0 ] = m_instanceOffsets[sceneIndex][ i + 0 ]; pHwInstanceData[ j + 1 ] = m_instanceOffsets[sceneIndex][ i + 1 ]; pHwInstanceData[ j + 2 ] = m_instanceOffsets[sceneIndex][ i + 2 ]; } } } } else // grass scene { const static int32_t MAX_GRASS_SIZE = int32_t( sqrt( float(MAX_OBJECTS) ) ); for( int32_t y = 0; y < MAX_GRASS_SIZE; ++y ) { for( int32_t x = 0; x < MAX_GRASS_SIZE; ++x ) { int32_t i = ( y * MAX_GRASS_SIZE + x ); if( i < MAX_OBJECTS ) { i *= 3; m_instanceOffsets[sceneIndex][ i + 0 ] = -10.0f + float( x ) * 0.25f + ( ( float( rand() ) / float( RAND_MAX ) ) - 0.5f ) * 0.08f - (isMobilePlatform() ? 10.0f : 20.0f); m_instanceOffsets[sceneIndex][ i + 1 ] = isMobilePlatform() ? 10.0f : 40.0f; m_instanceOffsets[sceneIndex][ i + 2 ] = -10.0f + float( y ) * 0.25f + ( ( float( rand() ) / float( RAND_MAX ) ) - 0.5f ) * 0.08f; int32_t j = 6 * ( y * MAX_GRASS_SIZE + x ); pHwInstanceData[ j + 0 ] = m_instanceOffsets[sceneIndex][ i + 0 ]; pHwInstanceData[ j + 1 ] = m_instanceOffsets[sceneIndex][ i + 1 ]; pHwInstanceData[ j + 2 ] = m_instanceOffsets[sceneIndex][ i + 2 ]; } } } } }
void MultiDrawIndirect::initUI() { if (mTweakBar) { mTweakBar->addPadding(); if (isMobilePlatform()) { mTweakBar->addValue("Grid Size (n x n) :", m_GridSize, MIN_MOBILE_GRID_SIZE, MAX_MOBILE_GRID_SIZE, 1); } else { mTweakBar->addValue("Grid Size (n x n) :", m_GridSize, MIN_GRID_SIZE, MAX_GRID_SIZE, 1); } NvTweakEnum<uint32_t> callModes[] = { {"Use Multidraw", USE_MULTIDRAWINDIRECT}, {"Use Individual Draw Calls", NO_MULTIDRAWINDIRECT}, }; mTweakBar->addEnum("Instancing Mode:", m_DrawInstanceMode, callModes, TWEAKENUM_ARRAYSIZE(callModes)); } // UI elements for displaying triangle statistics if (mFPSText) { NvUIRect tr; mFPSText->GetScreenRect(tr); // base off of fps element. m_timingStats = new NvUIText("Multi\nLine\nString", NvUIFontFamily::SANS, (mFPSText->GetFontSize()*2)/3, NvUITextAlign::RIGHT); m_timingStats->SetColor(NV_PACKED_COLOR(0x30,0xD0,0xD0,0xB0)); m_timingStats->SetShadow(); mUIWindow->Add(m_timingStats, tr.left, tr.top+tr.height+8); } }
void InstancedTessellation::draw(void) { //matrices for translation and rotation glClearColor(0.2f, 0.2f, 0.2f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if (isMobilePlatform()) { nv::matrix4f translation; m_viewMatrix = m_transformer->getModelViewMat() * m_ModelMatrix[ m_modelIndex ] ; //note: there is no m_pModel matrix as the m_pModel is always at origin(0,0,0) in the world-space m_normalMatrixHandle = nv::inverse(m_viewMatrix); m_normalMatrixHandle = nv::transpose(m_normalMatrixHandle); m_lightPositionEye = nv::vec4f(m_lightPosition.x, m_lightPosition.y, m_lightPosition.z, m_lightType); drawModelLit(); } else { for( int x = -1; x <= 1; ++x ) { for( int y = 0; y <= 0; ++y ) { for( int z = 0; z <= 3; ++z ) { nv::matrix4f translation = nv::translation( translation, 20.0f * float(x), 18.0f * float(y), -18.0f * float( z ) ); m_viewMatrix = m_transformer->getModelViewMat() * translation * m_ModelMatrix[ m_modelIndex ] ; //note: there is no m_pModel matrix as the m_pModel is always at origin(0,0,0) in the world-space m_normalMatrixHandle = nv::inverse(m_viewMatrix); m_normalMatrixHandle = nv::transpose(m_normalMatrixHandle); m_lightPositionEye = nv::vec4f(m_lightPosition.x, m_lightPosition.y, m_lightPosition.z, m_lightType); drawModelLit(); } } } } }
void MultiDrawIndirect::initRendering(void) { NV_APP_BASE_SHARED_INIT(); bool MultidrawAvailable; m_GPUTimer.init(); m_CPUTimer.init(); MultidrawAvailable = requireExtension("GL_ARB_multi_draw_indirect", false); if (MultidrawAvailable == false) { errorExit("The current system does not appear to support the extension GL_ARB_multi_draw_indirect, which is required by the sample.\n\nThis is likely because the systems GPU or driver does not support the extension. Please see the samples source code for details"); return; } if (isMobilePlatform()) { m_GridSize = DEFAULT_MOBILE_GRID_SIZE; m_MaxGridSize = MAX_MOBILE_GRID_SIZE; m_MaxModelInstances = MAX_MODEL_INSTANCES; } else { m_GridSize = DEFAULT_GRID_SIZE; m_MaxGridSize = MAX_GRID_SIZE; m_MaxModelInstances = MAX_MODEL_INSTANCES; } glClearColor(0.0f, 0.0f, 0.0f, 1.0f); NvAssetLoaderAddSearchPath("gl4-kepler/MultiDrawIndirect"); CleanRendering(); Startup(); }
void InstancingApp::initRendering(void) { m_transformer->setTranslationVec(isMobilePlatform() ? nv::vec3f(0.0f, 0.0f, -40.0f) : nv::vec3f(-20.0f, 0.0f, -100.0f)); if( requireMinAPIVersion(NvGLAPIVersionES3(), false) ) { m_hwInstancing = true; glDrawElementsInstancedInternal = (PFNDrawElementsInstanced)getGLContext()->getGLProcAddress("glDrawElementsInstanced"); glVertexAttribDivisorInternal = (PFNVertexAttribDivisor)getGLContext()->getGLProcAddress("glVertexAttribDivisor"); } else { // We need at least _one_ of these two extensions if (!requireExtension("GL_ARB_instanced_arrays", false) && !requireExtension("GL_NV_draw_instanced", false)) { m_hwInstancing = false; m_instancingOptions = SHADER_INSTANCING; } else { m_hwInstancing = true; if (requireExtension("GL_ARB_instanced_arrays", false) ) { glDrawElementsInstancedInternal = (PFNDrawElementsInstanced)getGLContext()->getGLProcAddress("glDrawElementsInstancedARB"); glVertexAttribDivisorInternal = (PFNVertexAttribDivisor)getGLContext()->getGLProcAddress("glVertexAttribDivisorARB"); } else { glDrawElementsInstancedInternal = (PFNDrawElementsInstanced)getGLContext()->getGLProcAddress("glDrawElementsInstancedNV"); glVertexAttribDivisorInternal = (PFNVertexAttribDivisor)getGLContext()->getGLProcAddress("glVertexAttribDivisorNV"); } } } if( m_hwInstancing == false ) { m_instancingOptions = SHADER_INSTANCING; } NvAssetLoaderAddSearchPath("es2-aurora/InstancingApp"); LOGI("Hardware Instancing %s\n", m_hwInstancing ? "Available" : "Not available" ); if (getGLContext()->getConfiguration().apiVer.api == NvGLAPI::GL) { NvGLSLProgram::setGlobalShaderHeader("#version 130\n"); } else { NvGLSLProgram::setGlobalShaderHeader("#version 300 es\n"); } //init the shaders m_shaders[0] = NvGLSLProgram::createFromFiles("shaders/boxes.vert", "shaders/boxes.frag"); m_shaders[1] = NvGLSLProgram::createFromFiles("shaders/grass.vert", "shaders/grass.frag"); m_shaders[2] = NvGLSLProgram::createFromFiles("shaders/boxes_instanced.vert", "shaders/boxes.frag"); m_shaders[3] = NvGLSLProgram::createFromFiles("shaders/grass_instanced.vert", "shaders/grass.frag"); NvGLSLProgram::setGlobalShaderHeader(NULL); initShaders(); CHECK_GL_ERROR(); //load g_pModel loadModelFromFile("models/cube.obj", 0); loadModelFromFile("models/grass.obj", 1); CHECK_GL_ERROR(); GLuint texID; NvImage::VerticalFlip(false); CHECK_GL_ERROR(); texID = NvImageGL::UploadTextureFromDDSFile("images/rock.dds"); if( texID > 0) { configTexture( texID, 0 ); configTexture( texID, 2 ); } CHECK_GL_ERROR(); texID = NvImageGL::UploadTextureFromDDSFile( "images/grass.dds" ); if( texID > 0) { configTexture( texID, 1 ); configTexture( texID, 3 ); } CHECK_GL_ERROR(); texID = NvImageGL::UploadTextureFromDDSFile( "images/rock.dds" ); if( texID > 0) configTexture( texID, 2 ); CHECK_GL_ERROR(); texID = NvImageGL::UploadTextureFromDDSFile( "images/grass.dds" ); if( texID > 0) configTexture( texID, 3 ); CHECK_GL_ERROR(); NvImage::VerticalFlip(false); glClearColor(0.0, 0.0, 0.0, 1.0); CHECK_GL_ERROR(); }