void Context::close() { #if _FLEXCL_DEBUG_SWITCH_ == 1 cout << "OpenCL::Context::close()" << endl; #endif // The cleaning sequence matters. Remember that the programs will do a cleanup as well // removing their associated memory buffers. This MUST take place before removing the remaining // memory objects for(vector<Program*>::iterator it = programs.begin(); it != programs.end(); ++it) delete *it; programs.clear(); // Clear shared OpenGL/OpenCL buffers #if _FLEXCL_OPENGL_SUPPORT_ == 1 for(vector<OpenGLBuffer*>::iterator it = openglBuffers.begin(); it != openglBuffers.end(); ++it) { OpenGLBuffer *buffer = *it; buffer->close(); delete buffer; } openglBuffers.clear(); #endif for(vector<cl_mem>::iterator it = buffers.begin(); it != buffers.end(); ++it) clReleaseMemObject(*it); buffers.clear(); deleteCommandQueue(); if (memobj != NULL) clReleaseMemObject(memobj); memobj = NULL; if (command_queue != NULL) clReleaseCommandQueue(command_queue); command_queue = NULL; if (context != NULL) clReleaseContext(context); context = NULL; }
void OpenGLVertexDeclaration::CreateVertexArrayOGL( const RenderOperation& operation, const Shader& vertexShader ) { glGenVertexArrays(1, &mVertexArrayOGL); glBindVertexArray(mVertexArrayOGL); OpenGLVertexDeclaration* vertexDeclOGL = static_cast_checked<OpenGLVertexDeclaration*>(operation.VertexDecl.get()); GLuint vertexSlotBind = -1; for (GLuint attribIndex = 0; attribIndex < vertexDeclOGL->mVertexElemets.size(); ++attribIndex) { const VertexElement& attribute = vertexDeclOGL->mVertexElemets[attribIndex]; // Bind vertex stream to slot if (attribute.InputSlot != vertexSlotBind) { OpenGLBuffer* bufferOGL = static_cast_checked<OpenGLBuffer*>(operation.VertexStreams[attribute.InputSlot].get()); glBindBuffer(GL_ARRAY_BUFFER, bufferOGL->GetBufferOGL()); vertexSlotBind = attribute.InputSlot; } GLenum type = OpenGLMapping::Mapping(attribute.Type); uint32_t size = VertexElementUtil::GetElementComponentCount(attribute); uint32_t stride = vertexDeclOGL->GetStreamStride(attribute.InputSlot); uint32_t offset = attribute.Offset; bool isMatchVertexShader = true; if (isMatchVertexShader) { glEnableVertexAttribArray(attribIndex); if (OpenGLMapping::IsIntegerType(type)) glVertexAttribIPointer(attribIndex, size, type, stride, BUFFER_OFFSET(offset)); else glVertexAttribPointer(attribIndex, size, type, false, stride, BUFFER_OFFSET(offset)); if (attribute.InstanceStepRate > 0) glVertexAttribDivisor(attribIndex, attribute.InstanceStepRate); } else glDisableVertexAttribArray(attribIndex); } glBindVertexArray(0); }
/****************************************************************************** * Allocates a particle buffer with the given number of elements. ******************************************************************************/ void OpenGLArrowPrimitive::startSetElements(int elementCount) { OVITO_ASSERT(elementCount >= 0); OVITO_ASSERT(QOpenGLContextGroup::currentContextGroup() == _contextGroup); OVITO_ASSERT(_mappedChunkIndex == -1); _verticesWithNormals.clear(); _verticesWithElementInfo.clear(); _elementCount = elementCount; bool renderMesh = true; int stripsPerElement; int fansPerElement; int verticesPerStrip; int verticesPerFan; if(shadingMode() == NormalShading) { verticesPerStrip = _cylinderSegments * 2 + 2; verticesPerFan = _cylinderSegments; if(shape() == ArrowShape) { stripsPerElement = 2; fansPerElement = 2; } else { stripsPerElement = 1; fansPerElement = 2; if(renderingQuality() == HighQuality) { if(_usingGeometryShader) { verticesPerStrip = 1; stripsPerElement = 1; } else { verticesPerStrip = 14; } fansPerElement = verticesPerFan = 0; renderMesh = false; } } } else if(shadingMode() == FlatShading) { fansPerElement = 1; stripsPerElement = 0; verticesPerStrip = 0; if(shape() == ArrowShape) verticesPerFan = 7; else verticesPerFan = 4; if(_usingGeometryShader && shape() == CylinderShape) { verticesPerFan = 1; } renderMesh = false; } else OVITO_ASSERT(false); // Determine the VBO chunk size. _verticesPerElement = stripsPerElement * verticesPerStrip + fansPerElement * verticesPerFan; int bytesPerVertex = renderMesh ? sizeof(VertexWithNormal) : sizeof(VertexWithElementInfo); _chunkSize = std::min(_maxVBOSize / _verticesPerElement / bytesPerVertex, _elementCount); // Allocate VBOs. for(int i = _elementCount; i > 0; i -= _chunkSize) { if(renderMesh) { OpenGLBuffer<VertexWithNormal> buffer; buffer.create(QOpenGLBuffer::StaticDraw, std::min(i, _chunkSize), _verticesPerElement); _verticesWithNormals.push_back(buffer); } else { OpenGLBuffer<VertexWithElementInfo> buffer; buffer.create(QOpenGLBuffer::StaticDraw, std::min(i, _chunkSize), _verticesPerElement); _verticesWithElementInfo.push_back(buffer); } } OVITO_REPORT_OPENGL_ERRORS(); // Prepare arrays to be passed to the glMultiDrawArrays() function. _stripPrimitiveVertexStarts.resize(_chunkSize * stripsPerElement); _stripPrimitiveVertexCounts.resize(_chunkSize * stripsPerElement); _fanPrimitiveVertexStarts.resize(_chunkSize * fansPerElement); _fanPrimitiveVertexCounts.resize(_chunkSize * fansPerElement); std::fill(_stripPrimitiveVertexCounts.begin(), _stripPrimitiveVertexCounts.end(), verticesPerStrip); std::fill(_fanPrimitiveVertexCounts.begin(), _fanPrimitiveVertexCounts.end(), verticesPerFan); auto ps_strip = _stripPrimitiveVertexStarts.begin(); auto ps_fan = _fanPrimitiveVertexStarts.begin(); for(GLint index = 0, baseIndex = 0; index < _chunkSize; index++) { for(int p = 0; p < stripsPerElement; p++, baseIndex += verticesPerStrip) *ps_strip++ = baseIndex; for(int p = 0; p < fansPerElement; p++, baseIndex += verticesPerFan) *ps_fan++ = baseIndex; } // Precompute cos() and sin() functions. if(shadingMode() == NormalShading) { _cosTable.resize(_cylinderSegments+1); _sinTable.resize(_cylinderSegments+1); for(int i = 0; i <= _cylinderSegments; i++) { float angle = (FLOATTYPE_PI * 2 / _cylinderSegments) * i; _cosTable[i] = std::cos(angle); _sinTable[i] = std::sin(angle); } } }
void OpenGLMeshPrivate::create(const KHalfEdgeMesh &mesh) { // Helpers m_aabb = KAabbBoundingVolume(mesh.aabb()); KHalfEdgeMesh::FaceContainer const &faces = mesh.faces(); KHalfEdgeMesh::VertexContainer const &vertices = mesh.vertices(); size_t verticesSize = sizeof(KVertex) * vertices.size(); size_t indicesCount = faces.size() * 3; size_t indicesSize = sizeof(uint32_t) * indicesCount; OpenGLBuffer::RangeAccessFlags flags = OpenGLBuffer::RangeInvalidate | OpenGLBuffer::RangeUnsynchronized | OpenGLBuffer::RangeWrite; // Create Buffers m_elementCount = static_cast<GLsizei>(indicesCount); m_vertexArrayObject.create(); m_vertexBuffer.create(); m_indexBuffer.create(); // Bind mesh m_vertexArrayObject.bind(); m_vertexBuffer.bind(); m_indexBuffer.bind(); // Allocate Mesh m_vertexBuffer.allocate(verticesSize); m_indexBuffer.allocate(indicesSize); KVertex *vertDest = (KVertex*)m_vertexBuffer.mapRange(0, verticesSize, flags); uint32_t *indDest = (uint32_t*)m_indexBuffer.mapRange(0, indicesSize, flags); // Iterators uint32_t *baseIndDest; const KHalfEdgeMesh::HalfEdge *halfEdge; // Construct Mesh for (size_t i = 0; i < vertices.size(); ++i) { vertDest[i] = KVertex(vertices[i].position, vertices[i].normal); } for (size_t i = 0; i < faces.size(); ++i) { baseIndDest = &indDest[3 * i]; halfEdge = mesh.halfEdge(faces[i].first); baseIndDest[0] = halfEdge->to - 1; halfEdge = mesh.halfEdge(halfEdge->next); baseIndDest[1] = halfEdge->to - 1; halfEdge = mesh.halfEdge(halfEdge->next); baseIndDest[2] = halfEdge->to - 1; } // Setup Vertex Pointers vertexAttribPointer(0, KVertex::PositionTupleSize, OpenGLElementType::Float, false, KVertex::stride(), KVertex::positionOffset()); vertexAttribPointer(1, KVertex::NormalTupleSize, OpenGLElementType::Float, true, KVertex::stride(), KVertex::normalOffset()); // Finalize Construction m_indexBuffer.unmap(); m_vertexBuffer.unmap(); m_vertexArrayObject.release(); }