Override primitive drawing type for Batch or VboMesh?

Hi there, I’d like to force a Batch (or VboMesh) to draw using a different primitive type, such as GL_LINE_STRIP or GL_TRIANGLE_FAN (even if it “doesn’t make sense,” it’s more to draw the same data with a glitchy effect). I don’t want to just change the PolygonMode (which would be okay for point mode, but the effect of drawing with polygon mode GL_LINE is not the same as using the line primitive types…it just outlines the triangles).

There seems to be no setter for the primitive mode (VboMesh does have a getter, at least, getGlPrimitive(), but no setter).

Any suggestions, or should I just make a subclass (or add the functionality)? I thought about maybe using a VertBatch for the data instead, but that doesn’t have a drawInstanced() method, which I also want. (-;


The actual meat of VboMesh::drawImpl is a single draw call to glDrawElements or glDrawArrays depending in if it’s indexed or not. It’s trivial to reimplement using your own primitive type rather than the private member variable. Same deal with Batch::draw.

namespace glx
	void DrawWithPrimitive ( const gl::BatchRef& batch, GLenum primitive, GLint first = 0, GLsizei count = -1 )
		auto ctx = gl::context();
		gl::ScopedGlslProg ScopedGlslProg( batch->getGlslProg() );
		gl::ScopedVao ScopedVao( batch->getVao() );
		DrawWithPrimitive ( batch->getVboMesh(), primitive, first, count )

	void DrawWithPrimitive ( const gl::VboMeshRef& mesh, GLenum primitive, GLint first = 0, GLsizei count = -1 )
		if( mesh->getIndexVbo() ) 
			auto indexType = mesh->getIndexDataType();
			auto numIndices = mesh->getNumIndices();
			size_t firstByteOffset = first;
			if( indexType == GL_UNSIGNED_INT ) firstByteOffset *= 4;
			else if( indexType == GL_UNSIGNED_SHORT ) firstByteOffset *= 2;
			glDrawElements( primitive, ( count < 0 ) ? ( numIndices - first ) : count, indexType, (GLvoid*)( firstByteOffset ) );
			glDrawArrays( primitive, first, ( count < 0 ) ? ( mesh->getNumVertices() - first ) : count );


glx::DrawWithPrimitive ( batch, GL_LINE_LOOP );

Written inline and not tested but should basically work. Instancing should be a similar implementation.

1 Like

Thanks, that does just what I want. I will make the instanced version I need, but the basic idea here works just fine.