void PassForward_Generic::draw() { if(m_commands.empty()) { return; } ++m_frame; static const VBO_RID s_vboids[] = {VBO_GENERIC_PARAMS1, VBO_GENERIC_PARAMS2}; i3d::DeviceContext *dc = atmGetGLDeviceContext(); RenderTarget *rt = atmGetBackRenderTarget(); Buffer *vbo_params = atmGetVertexBuffer(s_vboids[m_frame%2]); rt->setDepthStencilBuffer(atmGetRenderTarget(RT_GBUFFER)->getDepthStencilBuffer()); dc->setBlendState(atmGetBlendState(BS_BLEND_ALPHA)); dc->setDepthStencilState(atmGetDepthStencilState(DS_DEPTH_ENABLED)); dc->setRenderTarget(rt); for(auto si=m_commands.begin(); si!=m_commands.end(); ++si) { const ModelParamCont &mm = si->second; for(auto mi=mm.begin(); mi!=mm.end(); ++mi) { m_params.insert(m_params.end(), mi->second.begin(), mi->second.end()); } } if(!m_params.empty()) { size_t capacity = vbo_params->getDesc().size; size_t size_byte = sizeof(InstanceParams)*m_params.size(); istAssert(size_byte < capacity); MapAndWrite(dc, vbo_params, &m_params[0], std::min<size_t>(size_byte, capacity)); m_params.clear(); static const VertexDesc transform_descs[] = { {GLSL_INSTANCE_TRANSFORM1, I3D_FLOAT32,4, 0, false, 1}, {GLSL_INSTANCE_TRANSFORM2, I3D_FLOAT32,4, 16, false, 1}, {GLSL_INSTANCE_TRANSFORM3, I3D_FLOAT32,4, 32, false, 1}, {GLSL_INSTANCE_TRANSFORM4, I3D_FLOAT32,4, 48, false, 1}, {GLSL_INSTANCE_PARAM1, I3D_FLOAT32,4, 64, false, 1}, {GLSL_INSTANCE_PARAM2, I3D_FLOAT32,4, 80, false, 1}, {GLSL_INSTANCE_PARAM3, I3D_FLOAT32,4, 96, false, 1}, {GLSL_INSTANCE_PARAM4, I3D_FLOAT32,4,112, false, 1}, }; size_t params_offset = 0; for(auto si=m_commands.begin(); si!=m_commands.end(); ++si) { const ModelParamCont &mm = si->second; AtomicShader *sh = atmGetShader(si->first); sh->bind(); for(auto mi=mm.begin(); mi!=mm.end(); ++mi) { if(mi->second.empty()) { continue; } const ModelInfo &model = *atmGetModelInfo(mi->first); const ParamCont ¶ms = mi->second; VertexArray *va = atmGetVertexArray(model.vertices); Buffer *ibo = atmGetIndexBuffer(model.indices); dc->setIndexBuffer(ibo, 0, I3D_UINT32); va->setAttributes(1, vbo_params, sizeof(InstanceParams)*params_offset, sizeof(InstanceParams), transform_descs, _countof(transform_descs)); dc->setVertexArray(va); if(ibo) { dc->drawIndexedInstanced(model.topology, 0, model.num_indices, params.size()); } else { dc->drawInstanced(model.topology, 0, model.num_indices, params.size()); } dc->setIndexBuffer(nullptr, 0, I3D_UINT32); dc->setVertexArray(nullptr); params_offset += params.size(); } sh->unbind(); } } dc->setDepthStencilState(atmGetDepthStencilState(DS_NO_DEPTH_NO_STENCIL)); dc->setBlendState(atmGetBlendState(BS_NO_BLEND)); rt->setDepthStencilBuffer(nullptr); }