void TopazSample::draw() { nv::matrix4f projection = nv::perspective(projection, 45.f * NV_PI / 180.f, m_width / float(m_height), 0.1f, 10.f); sceneData.sceneDepthId64 = texturesAddress64.sceneDepth; sceneData.modelViewProjection = projection * m_transformer->getModelViewMat(); sceneData.depthScale = oit->getWeightParameter(); glNamedBufferSubDataEXT(ubos.sceneUbo, 0, sizeof(SceneData), &sceneData); glBindFramebuffer(GL_FRAMEBUFFER, fbos.scene); glViewport(0, 0, m_width, m_height); glClearColor(sceneBackgroundColor.x, sceneBackgroundColor.y, sceneBackgroundColor.z, sceneBackgroundColor.w); glClearDepthf(1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if (cmdlist.state != cmdlist.captured) { updateCommandListState(); } if (drawMode == DRAW_STANDARD) { drawStandard(); } else if (drawMode == DRAW_TOKEN_LIST) { glCallCommandListNV(cmdlist.tokenCmdList); } else if (drawMode == DRAW_WEIGHT_BLENDED_STANDARD) { renderStandartWeightedBlendedOIT(); } else if (drawMode == DRAW_WEIGHT_BLENDED_TOKEN_LIST) { for (auto model = models.begin() + 1; model != models.end(); model++) { objectData.objectColor = nv::vec4f(1.0f, 1.0f, 1.0f, oit->getOpacity()); glNamedBufferSubDataEXT((*model)->getBufferID("ubo"), 0, sizeof(ObjectData), &objectData); objectData.objectColor = nv::vec4f(1.0f, 0.0f, 0.0f, oit->getOpacity()); glNamedBufferSubDataEXT((*model)->getCornerBufferID("ubo"), 0, sizeof(ObjectData), &objectData); } glBindFramebuffer(GL_FRAMEBUFFER, fbos.scene); glCallCommandListNV(cmdlist.tokenCmdListWeightBlended); } glBindFramebuffer(GL_READ_FRAMEBUFFER, fbos.scene); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glBlitFramebuffer(0, 0, m_width, m_height, 0, 0, m_width, m_height, GL_COLOR_BUFFER_BIT, GL_NEAREST); }
//------------------------------------------------------------------------------ // //------------------------------------------------------------------------------ void RendererStandard::displayGrid(const InertiaCamera& camera, const mat4f projection) { // // Update what is inside buffers // g_globalMatrices.mVP = projection * camera.m4_view; g_globalMatrices.mW = mat4f(array16_id); glNamedBufferSubDataEXT(g_uboMatrix.Id, 0, sizeof(g_globalMatrices), &g_globalMatrices); // // The cross vertex change is an example on how command-list are compatible with changing // what is inside the vertex buffers. VBOs are outside of the token buffers... // const vec3f& p = camera.curFocusPos; vec3f crossVtx[6] = { vec3f(p.x - CROSSSZ, p.y, p.z), vec3f(p.x + CROSSSZ, p.y, p.z), vec3f(p.x, p.y - CROSSSZ, p.z), vec3f(p.x, p.y + CROSSSZ, p.z), vec3f(p.x, p.y, p.z - CROSSSZ), vec3f(p.x, p.y, p.z + CROSSSZ), }; glNamedBufferSubDataEXT(s_vboCross, 0, sizeof(vec3f)* 6, crossVtx); // ------------------------------------------------------------------------------------------ // Case of regular rendering // s_shaderGrid.bindShader(); glEnableVertexAttribArray(0); glDisableVertexAttribArray(1); // -------------------------------------------------------------------------------------- // Using regular VBO // glBindBufferBase(GL_UNIFORM_BUFFER, UBO_MATRIX, g_uboMatrix.Id); glBindVertexBuffer(0, s_vboGrid, 0, sizeof(vec3f)); glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0); // // Draw! // glDrawArrays(GL_LINES, 0, GRIDDEF * 4); glBindVertexBuffer(0, s_vboCross, 0, sizeof(vec3f)); glDrawArrays(GL_LINES, 0, 6); glDisableVertexAttribArray(0); //s_shaderGrid.unbindShader(); }
//[-------------------------------------------------------] //[ Public virtual Renderer::ITextureBuffer methods ] //[-------------------------------------------------------] void TextureBufferDsa::copyDataFrom(uint32_t numberOfBytes, const void *data) { if (static_cast<OpenGLRenderer&>(getRenderer()).getExtensions().isGL_ARB_direct_state_access()) { // Upload the data glNamedBufferSubData(mOpenGLTextureBuffer, 0, static_cast<GLsizeiptr>(numberOfBytes), data); } else { // Upload the data glNamedBufferSubDataEXT(mOpenGLTextureBuffer, 0, static_cast<GLsizeiptr>(numberOfBytes), data); } }
void Buffer::setSubData(GLintptr offset, GLsizeiptr size, const GLvoid* data) { if (m_directStateAccess) { glNamedBufferSubDataEXT(m_id, offset, size, data); CheckGLError(); } else { bind(); glBufferSubData(m_target, offset, size, data); CheckGLError(); } }
void BufferImplementation_DirectStateAccessEXT::setSubData(const Buffer * buffer, GLintptr offset, GLsizeiptr size, const GLvoid * data) const { glNamedBufferSubDataEXT(buffer->id(), offset, size, data); }
//////////////////////////////////////////////////////////////////////////////// // // Method: BindlessApp::draw() // // Performs the actual rendering // //////////////////////////////////////////////////////////////////////////////// void BindlessApp::draw(void) { nv::matrix4f modelviewMatrix; glClearColor( 0.5, 0.5, 0.5, 1.0); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); // Enable the vertex and pixel shader m_shader->enable(); if (m_useBindlessTextures) { GLuint samplersLocation(m_shader->getUniformLocation("samplers")); glUniform1ui64vNV(samplersLocation, m_numTextures, m_textureHandles); } GLuint bBindlessTexture(m_shader->getUniformLocation("useBindless")); glUniform1i(bBindlessTexture, m_useBindlessTextures); GLuint currentTexture(m_shader->getUniformLocation("currentFrame")); glUniform1i(currentTexture, m_currentFrame); // Set up the transformation matices up modelviewMatrix = m_transformer->getModelViewMat(); m_transformUniformsData.ModelView = modelviewMatrix; m_transformUniformsData.ModelViewProjection= m_projectionMatrix * modelviewMatrix; m_transformUniformsData.UseBindlessUniforms = m_useBindlessUniforms; glBindBufferBase(GL_UNIFORM_BUFFER, 2, m_transformUniforms); glNamedBufferSubDataEXT(m_transformUniforms, 0, sizeof(TransformUniforms), &m_transformUniformsData); // If we are going to update the uniforms every frame, do it now if(m_updateUniformsEveryFrame == true) { float deltaTime; float dt; deltaTime = getFrameDeltaTime(); if(deltaTime < m_minimumFrameDeltaTime) { m_minimumFrameDeltaTime = deltaTime; } dt = std::min(0.00005f / m_minimumFrameDeltaTime, .01f); m_t += dt * (float)Mesh::m_drawCallsPerState; updatePerMeshUniforms(m_t); } // Set up default per mesh uniforms. These may be changed on a per mesh basis in the rendering loop below if(m_useBindlessUniforms == true) { // *** INTERESTING *** // Pass a GPU pointer to the vertex shader for the per mesh uniform data via a vertex attribute glVertexAttribI2i(m_bindlessPerMeshUniformsPtrAttribLocation, (int)(m_perMeshUniformsGPUPtr & 0xFFFFFFFF), (int)((m_perMeshUniformsGPUPtr >> 32) & 0xFFFFFFFF)); }
void Buffer::BufferSubData(GLintptr offset, GLsizeiptr size, const GLvoid* data) { Generate(); glNamedBufferSubDataEXT(m_handle, offset, size, data); }
//------------------------------------------------------------------------------ // Really dumb display loop: cycling in meshes and primitive groups as they come //------------------------------------------------------------------------------ void Bk3dModelStandard::displayObject(Renderer *pRenderer, const mat4f& cameraView, const mat4f projection, GLuint fboMSAA8x, unsigned char topologies) { NXPROFILEFUNC(__FUNCTION__); g_globalMatrices.mVP = projection * cameraView; g_globalMatrices.mW = mat4f(array16_id); cameraView.get_translation(g_globalMatrices.eyePos); //g_globalMatrices.mW.rotate(nv_to_rad*180.0f, vec3f(0,1,0)); g_globalMatrices.mW.rotate(-nv_to_rad*90.0f, vec3f(1,0,0)); g_globalMatrices.mW.translate(-m_pGenericModel->m_posOffset); g_globalMatrices.mW.scale(m_pGenericModel->m_scale); glNamedBufferSubDataEXT(g_uboMatrix.Id, 0, sizeof(g_globalMatrices), &g_globalMatrices); if(m_pGenericModel->m_meshFile) { GLuint curMaterial = 0; GLuint curTransf = 0; glBindBufferBase(GL_UNIFORM_BUFFER, UBO_MATRIX, g_uboMatrix.Id); glBindBufferBase(GL_UNIFORM_BUFFER, UBO_LIGHT, g_uboLight.Id); glBindBufferBase(GL_UNIFORM_BUFFER, UBO_MATRIXOBJ, m_uboObjectMatrices.Id); // // Loop 2 times: for filled topologies, then for lines // ideally, the models should be pre-sorted by shaders... // Alternating from one shader to the other is very expensive // so it is better to do all geometries for one dedicated shader/material // #define LINES 1 #define POLYS 2 for(int s=LINES; s<POLYS+1; s++) { if(s == POLYS) { if((topologies & 0x1C) == 0) continue; glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(1.0, 1.0); // no issue with redundant call here: the state capture will just deal with simplifying things s_shaderMesh.bindShader(); } else { if((topologies & 3) == 0) continue; glDisable(GL_POLYGON_OFFSET_FILL); s_shaderMeshLine.bindShader(); } for(int m=1; m< m_pGenericModel->m_meshFile->pMeshes->n;m++)//m_pGenericModel->m_meshFile->pMeshes->n; m++) { bk3d::Mesh *pMesh = m_pGenericModel->m_meshFile->pMeshes->p[m]; // // First filter to eliminate meshes that aren't relevant for the pass // char bPrimType = 0; for(int pg=0; pg<pMesh->pPrimGroups->n; pg++) { bk3d::PrimGroup* pPG = pMesh->pPrimGroups->p[pg]; switch(pPG->topologyGL) { case GL_LINES: case GL_LINE_STRIP: bPrimType |= LINES; break; default: bPrimType |= POLYS; break; } } // skip is exclusively for primitives out of the scope of this loop if((s == POLYS) && (bPrimType == LINES)) continue; if((s == LINES) && (bPrimType == POLYS)) continue; if(pMesh->pTransforms && (pMesh->pTransforms->n>0)) { bk3d::Bone *pTransf = pMesh->pTransforms->p[0]; if(pTransf && (curTransf != pTransf->ID)) { curTransf = pTransf->ID; glBindBufferRange(GL_UNIFORM_BUFFER, UBO_MATRIXOBJ, m_uboObjectMatrices.Id, curTransf * sizeof(MatrixBufferObject), sizeof(MatrixBufferObject) ); } } int n = pMesh->pSlots->n; // let's make it simple: for now we assume pos and normal come first: // 0: vertex // 1: normal // the file could give any arbitrary kind of attributes. Normally, we should check the attribute type and make them match with the shader expectation int bindingIndex = 0; for(int s=0; s<n; s++) { bk3d::Slot* pS = pMesh->pSlots->p[s]; glBindBuffer(GL_ARRAY_BUFFER, pS->userData); for(int a=0; a<pS->pAttributes->n; a++) { glEnableVertexAttribArray(bindingIndex); bk3d::Attribute* pAttr = pS->pAttributes->p[a]; //pAttr->name would give the attribute name... assuming we are right, here. //glBindVertexBuffer(bindingIndex, pS->userData, pAttr->dataOffsetBytes, pAttr->strideBytes); glVertexAttribPointer(bindingIndex, pAttr->numComp, pAttr->formatGL, GL_FALSE, pAttr->strideBytes, (const void*)pAttr->dataOffsetBytes); bindingIndex++; } } // disable other attributes... we never know for(int j=bindingIndex; j<=3/*15*/;j++) glDisableVertexAttribArray(bindingIndex); //====> render primitive groups for(int pg=0; pg<pMesh->pPrimGroups->n; pg++) { bk3d::PrimGroup* pPG = pMesh->pPrimGroups->p[pg]; switch(pPG->topologyGL) { case GL_LINES: if(!(topologies & 0x01)) continue; break; case GL_LINE_STRIP: if(!(topologies & 0x02)) continue; break; case GL_TRIANGLES: if(!(topologies & 0x04)) continue; break; case GL_TRIANGLE_STRIP: if(!(topologies & 0x08)) continue; break; case GL_TRIANGLE_FAN: if(!(topologies & 0x10)) continue; break; } // // Material: point to the right one in the table // bk3d::Material *pMat = pPG->pMaterial; if(pMat && (curMaterial != pMat->ID)) { curMaterial = pMat->ID; glBindBufferRange(GL_UNIFORM_BUFFER, UBO_MATERIAL, m_uboMaterial.Id, (curMaterial * sizeof(MaterialBuffer)), sizeof(MaterialBuffer)); } if(pPG->pTransforms->n>0) { bk3d::Bone *pTransf = pPG->pTransforms->p[0]; if(pTransf && (curTransf != pTransf->ID)) { curTransf = pTransf->ID; glBindBufferRange(GL_UNIFORM_BUFFER, UBO_MATRIXOBJ, m_uboObjectMatrices.Id, (curTransf * sizeof(MatrixBufferObject)), sizeof(MatrixBufferObject)); } } if(pPG->pIndexBufferData) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, (unsigned long)pPG->userPtr); glDrawElements( pPG->topologyGL, pPG->indexCount, pPG->indexFormatGL, (const void*)pPG->indexArrayByteOffset); } else { glDrawArrays( pPG->topologyGL, 0, pPG->indexCount); } } } // for(int m=1; m< m_pGenericModel->m_meshFile->pMeshes->n;m++) } // for(int s=0; s<2; s++) // normally we should diable what was really used... simplification for the sample... glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); } }
//------------------------------------------------------------------------------ // It is possible to create one VBO for one Mesh; and one EBO for each primitive group // however, for this sample, we will create only one VBO for all and one EBO // meshes and primitive groups will have an offset in these buffers //------------------------------------------------------------------------------ bool Bk3dModelStandard::initResourcesObject() { LOGFLUSH(); SHOWPROGRESS("Init resources") //m_pGenericModel->m_meshFile->pMeshes->n = 60000; // // create Buffer Object for materials // if(m_pGenericModel->m_meshFile->pMaterials && m_pGenericModel->m_meshFile->pMaterials->nMaterials ) { // // Material UBO: *TABLE* of multiple materials // Then offset in it for various drawcalls // if(m_uboMaterial.Id == 0) glGenBuffers(1, &m_uboMaterial.Id); m_uboMaterial.Sz = sizeof(MaterialBuffer) * m_pGenericModel->m_materialNItems; glNamedBufferDataEXT(m_uboMaterial.Id, m_uboMaterial.Sz, m_pGenericModel->m_material, GL_STATIC_DRAW); glBindBufferBase(GL_UNIFORM_BUFFER,UBO_MATERIAL, m_uboMaterial.Id); LOGI("%d materials stored in %d Kb\n", m_pGenericModel->m_meshFile->pMaterials->nMaterials, (m_uboMaterial.Sz+512)/1024); LOGFLUSH(); } // // create Buffer Object for Object-matrices // if(m_pGenericModel->m_meshFile->pTransforms && m_pGenericModel->m_meshFile->pTransforms->nBones) { // // Transformation UBO: *TABLE* of multiple transformations // Then offset in it for various drawcalls // if(m_uboObjectMatrices.Id == 0) glGenBuffers(1, &m_uboObjectMatrices.Id); m_uboObjectMatrices.Sz = sizeof(MatrixBufferObject) * m_pGenericModel->m_objectMatricesNItems; glNamedBufferDataEXT(m_uboObjectMatrices.Id, m_uboObjectMatrices.Sz, m_pGenericModel->m_objectMatrices, GL_STATIC_DRAW); glBindBufferBase(GL_UNIFORM_BUFFER,UBO_MATRIXOBJ, m_uboObjectMatrices.Id); LOGI("%d matrices stored in %d Kb\n", m_pGenericModel->m_meshFile->pTransforms->nBones, (m_uboObjectMatrices.Sz + 512)/1024); LOGFLUSH(); } // // First pass: evaluate the size of the single VBO // and store offset to where we'll find data back // bk3d::Mesh *pMesh = NULL; for(int i=0; i< m_pGenericModel->m_meshFile->pMeshes->n; i++) { SETPROGRESSVAL(100.0f*(float)i/(float)m_pGenericModel->m_meshFile->pMeshes->n); pMesh = m_pGenericModel->m_meshFile->pMeshes->p[i]; // // Slots: buffers for vertices // int n = pMesh->pSlots->n; for(int s=0; s<n; s++) { bk3d::Slot* pS = pMesh->pSlots->p[s]; GLuint id; glGenBuffers(1, &id); // Buffer Object directly kept in the Slot pS->userData = id; #if 1 glNamedBufferDataEXT(id, pS->vtxBufferSizeBytes, NULL, GL_STATIC_DRAW); #else glNamedBufferStorageEXT(id, pS->vtxBufferSizeBytes, NULL, 0); // Not working with NSight !!! https://www.opengl.org/registry/specs/ARB/buffer_storage.txt #endif glNamedBufferSubDataEXT(id, 0, pS->vtxBufferSizeBytes, pS->pVtxBufferData); } // // Primitive groups // for(int pg=0; pg<pMesh->pPrimGroups->n; pg++) { bk3d::PrimGroup* pPG = pMesh->pPrimGroups->p[pg]; if(pPG->indexArrayByteSize > 0) { if((pPG->pOwnerOfIB == pPG)||(pPG->pOwnerOfIB == NULL)) // this primitive group doesn't use other's buffer { GLuint id; glGenBuffers(1, &id); pPG->userPtr = (int*)id; #if 1 glNamedBufferDataEXT(id, pPG->indexArrayByteSize, NULL, GL_STATIC_DRAW); #else glNamedBufferStorageEXT(id, pPG->indexArrayByteSize, NULL, 0); // Not working with NSight !!! https://www.opengl.org/registry/specs/ARB/buffer_storage.txt #endif glNamedBufferSubDataEXT(id, pPG->indexArrayByteOffset, pPG->indexArrayByteSize, pPG->pIndexBufferData); } else { pPG->userPtr = pPG->pOwnerOfIB->userPtr; } } else { pPG->userPtr = NULL; } } } //LOGI("meshes: %d in :%d VBOs (%f Mb) and %d EBOs (%f Mb) \n", m_pGenericModel->m_meshFile->pMeshes->n, .size(), (float)totalVBOSz/(float)(1024*1024), m_ObjEBOs.size(), (float)totalEBOSz/(float)(1024*1024)); LOGFLUSH(); HIDEPROGRESS() return true; }
void TopazSample::renderStandartWeightedBlendedOIT() { glEnable(GL_DEPTH_TEST); glDisable(GL_POLYGON_OFFSET_FILL); glBindBufferBase(GL_UNIFORM_BUFFER, UBO_SCENE, ubos.sceneUbo); glBindBufferBase(GL_UNIFORM_BUFFER, UBO_IDENTITY, ubos.identityUbo); glBindFramebuffer(GL_FRAMEBUFFER, fbos.scene); drawModel(GL_TRIANGLES, *shaderPrograms["draw"], *models.at(0)); glBindFramebuffer(GL_FRAMEBUFFER, 0); /* first pass oit */ glDisable(GL_DEPTH_TEST); // TODO : change on transparent list of models for (auto model = models.begin() + 1; model != models.end(); model++) { /* geometry pass */ { glBindFramebuffer(GL_FRAMEBUFFER, oit->getFramebufferID()); const GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }; glDrawBuffers(2, drawBuffers); GLfloat clearColorZero[4] = { 0.0f }; GLfloat clearColorOne[4] = { 1.0f }; glClearBufferfv(GL_COLOR, 0, clearColorZero); glClearBufferfv(GL_COLOR, 1, clearColorOne); glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); glBlendFunci(0, GL_ONE, GL_ONE); glBlendFunci(1, GL_ZERO, GL_ONE_MINUS_SRC_COLOR); objectData.objectColor = nv::vec4f(1.0f, 1.0f, 1.0f, oit->getOpacity()); glNamedBufferSubDataEXT((*model)->getBufferID("ubo"), 0, sizeof(ObjectData), &objectData); objectData.objectColor = nv::vec4f(1.0f, 0.0f, 0.0f, oit->getOpacity()); glNamedBufferSubDataEXT((*model)->getCornerBufferID("ubo"), 0, sizeof(ObjectData), &objectData); drawModel(GL_TRIANGLES, *shaderPrograms["weightBlended"], **model); glDisable(GL_BLEND); CHECK_GL_ERROR(); } /* composition pass */ { glBindFramebuffer(GL_FRAMEBUFFER, fbos.scene); glBindBufferRange(GL_UNIFORM_BUFFER, UBO_OIT, ubos.weightBlendedUbo, 0, sizeof(WeightBlendedData)); // check uniform buffer offset { const char* uniformNames[] = { "weightBlendedData.background", "weightBlendedData.colorTex0", "weightBlendedData.colorTex1" }; std::unique_ptr<GLint> parameters(new GLint[3]); std::unique_ptr<GLuint> uniformIndices(new GLuint[3]); glGetUniformIndices(shaderPrograms["weightBlendedFinal"]->getProgram(), 3, uniformNames, uniformIndices.get()); glGetActiveUniformsiv(shaderPrograms["weightBlendedFinal"]->getProgram(), 3, uniformIndices.get(), GL_UNIFORM_OFFSET, parameters.get()); GLint* offset = parameters.get(); } { shaderPrograms["weightBlendedFinal"]->enable(); glVertexAttribFormat(VERTEX_POS, 3, GL_FLOAT, GL_FALSE, 0); glVertexAttribBinding(VERTEX_POS, 0); glEnableVertexAttribArray(VERTEX_POS); glBindVertexBuffer(0, fullScreenRectangle.vboFullScreen, 0, sizeof(nv::vec3f)); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); shaderPrograms["weightBlendedFinal"]->disable(); } CHECK_GL_ERROR(); } } }
void ParameterRendererBufferDSA::render( void const* cache ) { glNamedBufferSubDataEXT( m_ubo->getGLId(), m_uboOffset, m_uboBlockSize, cache ); }