Exemple #1
0
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);
		}
	}
}
Exemple #4
0
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();
}