浏览代码

Implement wireframe support (#448)

Pavel Alexandrov 7 年之前
父节点
当前提交
a920b57cac
共有 5 个文件被更改,包括 45 次插入10 次删除
  1. 8 3
      h3d/impl/DirectXDriver.hx
  2. 4 0
      h3d/impl/Driver.hx
  3. 27 7
      h3d/impl/GlDriver.hx
  4. 1 0
      h3d/mat/Pass.hx
  5. 5 0
      samples/Base3D.hx

+ 8 - 3
h3d/impl/DirectXDriver.hx

@@ -625,12 +625,17 @@ class DirectXDriver extends h3d.impl.Driver {
 			#end
 			#end
 		}
 		}
 
 
-		var rasterBits = bits & (Pass.culling_mask | SCISSOR_BIT);
+		var rasterBits = bits & (Pass.culling_mask | SCISSOR_BIT | Pass.wireframe_mask);
 		var raster = rasterStates.get(rasterBits);
 		var raster = rasterStates.get(rasterBits);
 		if( raster == null ) {
 		if( raster == null ) {
 			var desc = new RasterizerDesc();
 			var desc = new RasterizerDesc();
-			desc.fillMode = Solid;
-			desc.cullMode = CULL[Pass.getCulling(bits)];
+			if ( pass.wireframe ) {
+				desc.fillMode = WireFrame;
+				desc.cullMode = None;
+			} else {
+				desc.fillMode = Solid;
+				desc.cullMode = CULL[Pass.getCulling(bits)];
+			}
 			desc.depthClipEnable = true;
 			desc.depthClipEnable = true;
 			desc.scissorEnable = bits & SCISSOR_BIT != 0;
 			desc.scissorEnable = bits & SCISSOR_BIT != 0;
 			raster = Driver.createRasterizerState(desc);
 			raster = Driver.createRasterizerState(desc);

+ 4 - 0
h3d/impl/Driver.hx

@@ -101,6 +101,10 @@ enum Feature {
 		Tells if the driver uses bottom-left coordinates for textures.
 		Tells if the driver uses bottom-left coordinates for textures.
 	*/
 	*/
 	BottomLeftCoords;
 	BottomLeftCoords;
+	/*
+		Supports rendering in wireframe mode.
+	*/
+	Wireframe;
 }
 }
 
 
 enum QueryKind {
 enum QueryKind {

+ 27 - 7
h3d/impl/GlDriver.hx

@@ -186,6 +186,8 @@ class GlDriver extends Driver {
 	var firstShader = true;
 	var firstShader = true;
 	var rightHanded = false;
 	var rightHanded = false;
 	var hasMultiIndirect = false;
 	var hasMultiIndirect = false;
+	
+	var drawMode : Int;
 
 
 	public function new(antiAlias=0) {
 	public function new(antiAlias=0) {
 		#if js
 		#if js
@@ -233,6 +235,8 @@ class GlDriver extends Driver {
 			shaderVersion = Math.round( Std.parseFloat(reg.matched(0)) * 100 );
 			shaderVersion = Math.round( Std.parseFloat(reg.matched(0)) * 100 );
 		}
 		}
 
 
+		drawMode = GL.TRIANGLES;
+
 		#if js
 		#if js
 		// make sure to enable extensions
 		// make sure to enable extensions
 		makeFeatures();
 		makeFeatures();
@@ -597,6 +601,22 @@ class GlDriver extends Driver {
 		if( curMatBits < 0 ) diff = -1;
 		if( curMatBits < 0 ) diff = -1;
 		if( diff == 0 )
 		if( diff == 0 )
 			return;
 			return;
+
+		var wireframe = bits & Pass.wireframe_mask != 0;
+		#if hlsdl
+		if ( wireframe ) {
+			gl.polygonMode(GL.FRONT_AND_BACK, GL.LINE);
+			// Force set to cull = None
+			bits = (bits & ~Pass.culling_mask);
+			diff |= Pass.culling_mask;
+		} else {
+			gl.polygonMode(GL.FRONT_AND_BACK, GL.FILL);
+		}
+		#else
+		// Not entirely accurate wireframe, but the best possible on WebGL.
+		drawMode = wireframe ? GL.LINE_STRIP : GL.TRIANGLES;
+		#end
+		
 		if( diff & Pass.culling_mask != 0 ) {
 		if( diff & Pass.culling_mask != 0 ) {
 			var cull = Pass.getCulling(bits);
 			var cull = Pass.getCulling(bits);
 			if( cull == 0 )
 			if( cull == 0 )
@@ -1248,9 +1268,9 @@ class GlDriver extends Driver {
 			gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, ibuf.b);
 			gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, ibuf.b);
 		}
 		}
 		if( ibuf.is32 )
 		if( ibuf.is32 )
-			gl.drawElements(GL.TRIANGLES, ntriangles * 3, GL.UNSIGNED_INT, startIndex * 4);
+			gl.drawElements(drawMode, ntriangles * 3, GL.UNSIGNED_INT, startIndex * 4);
 		else
 		else
-			gl.drawElements(GL.TRIANGLES, ntriangles * 3, GL.UNSIGNED_SHORT, startIndex * 2);
+			gl.drawElements(drawMode, ntriangles * 3, GL.UNSIGNED_SHORT, startIndex * 2);
 	}
 	}
 
 
 	override function allocInstanceBuffer( b : InstanceBuffer, bytes : haxe.io.Bytes ) {
 	override function allocInstanceBuffer( b : InstanceBuffer, bytes : haxe.io.Bytes ) {
@@ -1294,9 +1314,9 @@ class GlDriver extends Driver {
 		if( hasMultiIndirect ) {
 		if( hasMultiIndirect ) {
 			gl.bindBuffer(GL2.DRAW_INDIRECT_BUFFER, commands.data);
 			gl.bindBuffer(GL2.DRAW_INDIRECT_BUFFER, commands.data);
 			if( ibuf.is32 )
 			if( ibuf.is32 )
-				gl.multiDrawElementsIndirect(GL.TRIANGLES, GL.UNSIGNED_INT, null, commands.commandCount, 0);
+				gl.multiDrawElementsIndirect(drawMode, GL.UNSIGNED_INT, null, commands.commandCount, 0);
 			else
 			else
-				gl.multiDrawElementsIndirect(GL.TRIANGLES, GL.UNSIGNED_SHORT, null, commands.commandCount, 0);
+				gl.multiDrawElementsIndirect(drawMode, GL.UNSIGNED_SHORT, null, commands.commandCount, 0);
 			gl.bindBuffer(GL2.DRAW_INDIRECT_BUFFER, null);
 			gl.bindBuffer(GL2.DRAW_INDIRECT_BUFFER, null);
 			return;
 			return;
 		}
 		}
@@ -1305,9 +1325,9 @@ class GlDriver extends Driver {
 		var p = 0;
 		var p = 0;
 		for( i in 0...Std.int(args.length/3) )
 		for( i in 0...Std.int(args.length/3) )
 			if( ibuf.is32 )
 			if( ibuf.is32 )
-				gl.drawElementsInstanced(GL.TRIANGLES, args[p++], GL.UNSIGNED_INT, args[p++], args[p++]);
+				gl.drawElementsInstanced(drawMode, args[p++], GL.UNSIGNED_INT, args[p++], args[p++]);
 			else
 			else
-				gl.drawElementsInstanced(GL.TRIANGLES, args[p++], GL.UNSIGNED_SHORT, args[p++], args[p++]);
+				gl.drawElementsInstanced(drawMode, args[p++], GL.UNSIGNED_SHORT, args[p++], args[p++]);
 	}
 	}
 
 
 	override function end() {
 	override function end() {
@@ -1503,7 +1523,7 @@ class GlDriver extends Driver {
 	function checkFeature( f : Feature ) {
 	function checkFeature( f : Feature ) {
 		return switch( f ) {
 		return switch( f ) {
 
 
-		case HardwareAccelerated, AllocDepthBuffer, BottomLeftCoords:
+		case HardwareAccelerated, AllocDepthBuffer, BottomLeftCoords, Wireframe:
 			true;
 			true;
 
 
 		case StandardDerivatives, MultipleRenderTargets, SRGBTextures if( glES >= 3 ):
 		case StandardDerivatives, MultipleRenderTargets, SRGBTextures if( glES >= 3 ):

+ 1 - 0
h3d/mat/Pass.hx

@@ -37,6 +37,7 @@ class Pass implements hxd.impl.Serializable {
 	@:bits(bits) public var blendAlphaDst : Blend;
 	@:bits(bits) public var blendAlphaDst : Blend;
 	@:bits(bits) public var blendOp : Operation;
 	@:bits(bits) public var blendOp : Operation;
 	@:bits(bits) public var blendAlphaOp : Operation;
 	@:bits(bits) public var blendAlphaOp : Operation;
+	@:bits(bits) public var wireframe : Bool;
 	public var colorMask : Int;
 	public var colorMask : Int;
 
 
 	@:s public var stencil : Stencil;
 	@:s public var stencil : Stencil;

+ 5 - 0
samples/Base3D.hx

@@ -7,6 +7,7 @@ class Base3D extends SampleApp {
 	var obj2 : Mesh;
 	var obj2 : Mesh;
 
 
 	override function init() {
 	override function init() {
+		super.init();
 
 
 		// creates a new unit cube
 		// creates a new unit cube
 		var prim = new h3d.prim.Cube();
 		var prim = new h3d.prim.Cube();
@@ -54,6 +55,10 @@ class Base3D extends SampleApp {
 		// disable shadows
 		// disable shadows
 		obj1.material.shadows = false;
 		obj1.material.shadows = false;
 		obj2.material.shadows = false;
 		obj2.material.shadows = false;
+		
+		if (engine.driver.hasFeature(Wireframe)) {
+			addCheck("Wireframe", function() { return obj2.material.mainPass.wireframe; }, function(v) { obj2.material.mainPass.wireframe = v; });
+		}
 	}
 	}
 
 
 	override function update( dt : Float ) {
 	override function update( dt : Float ) {