Example #1
0
void OpenGLMeshPrivate::vertexAttribPointer(int location, int elements, int count, OpenGLElementType type, bool normalized, int stride, int offset)
{
  for (int i = 0; i < count; ++i)
  {
    vertexAttribPointer(location + i, elements, type, normalized, stride, static_cast<int>(offset + i * elements * OpenGLElementSize(type)));
  }
}
Example #2
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();
}
Example #3
0
void OpenGLMeshPrivate::vertexAttribPointerDivisor(int location, int elements, OpenGLElementType type, bool normalized, int stride, int offset, int divisor)
{
  vertexAttribPointer(location, elements, type, normalized, stride, offset);
  GL::glVertexAttribDivisor(location, divisor);
}
Example #4
0
// Leaves mVAO bound
void VertBatch::setupBuffers()
{
	auto ctx = gl::context();
	
	auto glslProg = ctx->getGlslProg();
	if( ! glslProg )
		return;

	const size_t verticesSizeBytes = mVertices.size() * sizeof(vec4);
	const size_t normalsSizeBytes = mNormals.size() * sizeof(vec3);
	const size_t colorsSizeBytes = mColors.size() * sizeof(ColorAf);
	const size_t texCoordsSizeBytes = mTexCoords.size() * sizeof(vec4);
	size_t totalSizeBytes = verticesSizeBytes + normalsSizeBytes + colorsSizeBytes + texCoordsSizeBytes;

	// allocate the VBO if we don't have one yet (which implies we're not using the context defaults)
	bool forceUpload = false;
	if( ! mVbo ) {
		// allocate the VBO and upload the data
		mVbo = gl::Vbo::create( GL_ARRAY_BUFFER, totalSizeBytes );
		forceUpload = true;
	}
	
	ScopedBuffer ScopedBuffer( mVbo );
	// if this VBO was freshly made, or we don't own the buffer because we use the context defaults
	if( ( forceUpload || ( ! mOwnsBuffers ) ) && ( ! mVertices.empty() ) ) {
		mVbo->ensureMinimumSize( totalSizeBytes );
		
		// upload positions
		GLintptr offset = 0;
		mVbo->bufferSubData( offset, verticesSizeBytes, &mVertices[0] );
		offset += verticesSizeBytes;
		
		// upload normals
		if( ! mNormals.empty() ) {
			mVbo->bufferSubData( offset, normalsSizeBytes, &mNormals[0] );
			offset += normalsSizeBytes;
		}

		// upload colors
		if( ! mColors.empty() ) {
			mVbo->bufferSubData( offset, colorsSizeBytes, &mColors[0] );
			offset += colorsSizeBytes;
		}

		// upload texCoords
		if( ! mTexCoords.empty() ) {
			mVbo->bufferSubData( offset, texCoordsSizeBytes, &mTexCoords[0] );
			offset += texCoordsSizeBytes;
		}
	}

	// Setup the VAO
	ctx->pushVao(); // this will be popped by draw()
	if( ! mOwnsBuffers )
		mVao->replacementBindBegin();
	else {
		mVaoStorage = gl::Vao::create();
		mVao = mVaoStorage.get();
		mVao->bind();
	}

	gl::ScopedBuffer vboScope( mVbo );
	size_t offset = 0;
	if( glslProg->hasAttribSemantic( geom::Attrib::POSITION ) ) {
		int loc = glslProg->getAttribSemanticLocation( geom::Attrib::POSITION );
		ctx->enableVertexAttribArray( loc );
		ctx->vertexAttribPointer( loc, 4, GL_FLOAT, false, 0, (const GLvoid*)offset );
		offset += verticesSizeBytes;
	}

	if( glslProg->hasAttribSemantic( geom::Attrib::NORMAL ) && ( ! mNormals.empty() ) ) {
		int loc = glslProg->getAttribSemanticLocation( geom::Attrib::NORMAL );
		ctx->enableVertexAttribArray( loc );
		ctx->vertexAttribPointer( loc, 3, GL_FLOAT, false, 0, (const GLvoid*)offset );
		offset += normalsSizeBytes;
	}

	if( glslProg->hasAttribSemantic( geom::Attrib::COLOR ) && ( ! mColors.empty() ) ) {
		int loc = glslProg->getAttribSemanticLocation( geom::Attrib::COLOR );
		ctx->enableVertexAttribArray( loc );
		ctx->vertexAttribPointer( loc, 4, GL_FLOAT, false, 0, (const GLvoid*)offset );
		offset += colorsSizeBytes;
	}

	if( glslProg->hasAttribSemantic( geom::Attrib::TEX_COORD_0 ) && ( ! mTexCoords.empty() ) ) {
		int loc = glslProg->getAttribSemanticLocation( geom::Attrib::TEX_COORD_0 );
		ctx->enableVertexAttribArray( loc );
		ctx->vertexAttribPointer( loc, 4, GL_FLOAT, false, 0, (const GLvoid*)offset );
	}
	
	if( ! mOwnsBuffers )
		mVao->replacementBindEnd();
	ctx->popVao();
}