Drawing Order - Page 4

Drawing Order

Discuss the source code and development of Spring Engine in general from a technical point of view. Patches go here too.

Moderator: Moderators

User avatar
hoijui
Former Engine Dev
Posts: 4344
Joined: 22 Sep 2007, 09:51

Re: Drawing Order

Post by hoijui »

i think everyone know you want to have it in the engine, as otherwise you would not need to do this thread and ask us to incldue it in the engine.
you didnt say if you would code it or not.
and then someone of "the others", eg jk, had to say if he would accept such a patch.
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: Drawing Order

Post by Argh »

I am looking at the problem now. I haven't figured out which part of Spring determines which Units are visible in the frustrum and submits a list to be rendered yet. Once I know where that list is being made, it should be fairly trivial to write a patch.
User avatar
jK
Spring Developer
Posts: 2299
Joined: 28 Jun 2007, 07:30

Re: Drawing Order

Post by jK »

Argh wrote:All Units we want to render must go through the UnitRendering pathway, which is locked to UnitID order. Or you can do gl.Unit, but then you don't have a TBN matrix.
TBN Matrix is saved in MultiTexcoord and is available in _all_ renderpaths (cuz it is compiled in the used DLists).
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: Drawing Order

Post by Argh »

OK. So, in theory, I can use gl.Unit then. Hmm.
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: Drawing Order

Post by Argh »

Proof of concept.

Depth-sorted translucent objects do not arbitrarily cause masking problems:

Image
Image
Image
I apologize for the surrealness of the imagery, I'm using gl.Scale to offset while testing.

The code is still extremely rough. I will release the source when I have optimized it better.
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: Drawing Order

Post by Argh »

Well, great, I've hit another wall. Seems that even if I give Units a totally transparent S3O texture, they're culling geometry.

IOW, when I quit offsetting geometry, my previously-working setup falls flat on its face, because the ARB-shaded versions are using incompatible OpenGL settings.

IIRC, we're able to manipulate that alpha-test, though. I'll try that.

Oh, never mind. I forgot ALPHA_THRESHOLD is broken and won't be fixed.

Maybe the layer assignment...
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: Drawing Order

Post by Argh »

I've tested depth-sorting multiple times now. Works quite consistently, if it's kept away from the actual location of the Unit.

But I can't eliminate drawing the Units via ARB without using DrawUnit and Spring.UnitRendering.

And that only runs in the order of UnitIDs, and doesn't allow for arbitrary re-arrangement of the rendering order.

If I draw in DrawWorldPreUnit, then it's no better. If I use invisible S3Os, it doesn't matter, the z-buffer mask is set up before it reaches the shader.

It's going to require a change to the engine.




For future reference, ARB/Khronos (OpenGL's maintainers) say this about translucency and OpenGL:
When using depth buffering in an application, you need to be careful about the order in which you render primitives. Fully opaque primitives need to be rendered first, followed by partially opaque primitives in back-to-front order. If you don't render primitives in this order, the primitives, which would otherwise be visible through a partially opaque primitive, might lose the depth test entirely.
Full text:
http://www.opengl.org/resources/faq/tec ... arency.htm

Which is pretty much exactly what I said at the start of this whole debacle.


The only thing I can think that might work... hmm... maybe turn on SUR, give the pre and post display lists a depth test that will cause them to not be able to win.

That might work. Maybe. I guess it's worth one more shot, it won't take very long.
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: Drawing Order

Post by Argh »

Nope, doesn't work. Engine's gotta change to make it work. I'm sure now.

Anyhow, here's the last version of the tests. It z-orders UnitIDs and works correctly, so long as the models aren't being masked by the invisible Unit geometry. Near the end of DrawWorld, just re-activate gl.Scale to see it in action with the test geometry of your choice.

Meanwhile, I guess I'll revert this to the previous version, it's quite a bit slower and obviously a lot messier, I didn't feel like tidying up something that can't ever work.

Code: Select all

function gadget:GetInfo()
   return {
      name      = "unit_normalmap_shader_tst.lua",
      desc      = "adds normal-mapping to S3O models",
      author    = "Kloot",
      date      = "31-1-2009",
      license   = "GPL v2",
      layer     =  -200,
      enabled   = true
   }
end

if (gadgetHandler:IsSyncedCode()) then
	function gadget:Initialize()
		-- desc      = "adds normal-mapping to S3O models (gadgetized)",
		-- author    = "Kloot",
		-- date      = "April 6, 2009",
		-- license   = "GPL v2",
	end

	function gadget:UnitGiven(unitID)
		SendToUnsynced("MyUnitCrea", unitID)
		return true
	end

	function gadget:UnitCreated(unitID)
		SendToUnsynced("MyUnitCrea", unitID)
		return true
	end

	function gadget:UnitDestroyed(unitID)
		SendToUnsynced("MyUnitDest", unitID)
		return true
	end

else

	local glLoadIdentity       = gl.LoadIdentity
	local glPushMatrix         = gl.PushMatrix
	local glPopMatrix          = gl.PopMatrix
	local glTranslate          = gl.Translate
	local glBeginEnd           = gl.BeginEnd
	local glNormal             = gl.Normal
	local glVertex             = gl.Vertex
	local glColor              = gl.Color
	local glLight              = gl.Light
	local glLighting           = gl.Lighting
	local glBlending           = gl.Blending
	local glPushAttrib         = gl.PushAttrib
	local glPopAttrib          = gl.PopAttrib

	local glCulling            = gl.Culling
	local glDepthMask          = gl.DepthMask
	local glDepthTest          = gl.DepthTest
	local glAlphaTest 	= gl.AlphaTest

	local glCreateList         = gl.CreateList
	local glDeleteList         = gl.DeleteList

	local glUnit               = gl.Unit
	local glUnitRaw            = gl.UnitRaw
	local glTexture            = gl.Texture
	local glTexCoord           = gl.TexCoord
	local glMultiTexCoord      = gl.MultiTexCoord
	local glUnitMultMatrix     = gl.UnitMultMatrix

	local glGetSun             = gl.GetSun
	local glGetShadowMapParams = gl.GetShadowMapParams
	local glGetMatrixData      = gl.GetMatrixData

	local glGetShaderLog       = gl.GetShaderLog
	local glCreateShader       = gl.CreateShader
	local glDeleteShader       = gl.DeleteShader
	local glUseShader          = gl.UseShader

	local glUniformMatrix      = gl.UniformMatrix
	local glUniformInt         = gl.UniformInt
	local glUniform            = gl.Uniform
	local glGetUniformLocation = gl.GetUniformLocation
	local glGetActiveUniforms  = gl.GetActiveUniforms

	local normalMapList = {}
	local normalMapNames      = {}
	local textureNames        = {}
	local preDisplayLists     = {}
	local pstDisplayLists     = {}
	local luaShader           = nil

	local luaShaderLocs = {
		cameraMatrixLoc     = -1,
		cameraInvMatrixLoc  = -1,
		shadowMatrixLoc     = -1,
		shadowParamsLoc     = -1,
		shadowDensityLoc    = -1,

		unitAmbientLightLoc = -1,
		unitDiffuseLightLoc = -1,

		shadowMapLoc        = -1,
		textureS3O1Loc      = -1,
		textureS3O2Loc      = -1,
		--specularMapLoc      = -1,
		reflectMapLoc       = -1,
		normalMapLoc        = -1,
	}

	local sprGetGameFrame           = Spring.GetGameFrame
	local sprGetUnitDefID           = Spring.GetUnitDefID
	local sprGetAllUnits            = Spring.GetAllUnits
	local sprGetVisibleUnits        = Spring.GetVisibleUnits
	local sprIsUnitVisible          = Spring.IsUnitVisible
	local sprGetUnitTeam            = Spring.GetUnitTeam
	local sprGetCameraPosition      = Spring.GetCameraPosition
	local sprGetTeamColor           = Spring.GetTeamColor
	local sprSetUnitNoDraw          = Spring.SetUnitNoDraw
	local sprHaveShadows            = Spring.HaveShadows
	local sprGetUnitTransformMatrix = Spring.GetUnitTransformMatrix
	local SUR                       = Spring.UnitRendering





	local function GetPreDisplayList(unitID)
		local unitTeam = sprGetUnitTeam(unitID)
		local unitDefID = sprGetUnitDefID(unitID)

		if (preDisplayLists[unitDefID] == nil) then
			preDisplayLists[unitDefID] = {}
		end

		if (preDisplayLists[unitDefID][unitTeam] == nil) then
			local sdx, sdy, sdz = glGetSun("pos")
			local tcr, tcg, tcb, tca = sprGetTeamColor(unitTeam)

			preDisplayLists[unitDefID][unitTeam] = glCreateList(
				function()
               glColor(1.0, 1.0, 1.0, 0.0)

               glLight(0, false)
               glLighting(false)

               glDepthTest(false)
               glDepthMask(false)
               glBlending(false)
				end)
		end

		return preDisplayLists[unitDefID][unitTeam]
	end

	local function GetPostDisplayList(unitID)
		local unitTeam = sprGetUnitTeam(unitID)
		local unitDefID = sprGetUnitDefID(unitID)

		if (pstDisplayLists[unitDefID] == nil) then
			pstDisplayLists[unitDefID] = {}
		end

		if (pstDisplayLists[unitDefID][unitTeam] == nil) then
			pstDisplayLists[unitDefID][unitTeam] = glCreateList(
				function()

               glColor(1.0, 1.0, 1.0, 0.0)

               glLight(0, false)
               glLighting(false)

               glDepthTest(false)
               glDepthMask(false)
               glBlending(false)

				end)
		end

		return pstDisplayLists[unitDefID][unitTeam]
	end

	local function GetUnitDefMaterial(unitDefID, preDL, pstDL)
		local matTbl = {
			--order = order,
			--[[texunits = {
				[0] = {tex = textureNames[unitDefID][1],   enable = true},
				[1] = {tex = textureNames[unitDefID][2],   enable = true},
				[2] = {tex = "$reflection",                enable = true},
				[3] = {tex = "unittextures/" .. UnitDefs[unitDefID].customParams.normalmap_name, enable = true},
				[4] = {tex = "$shadow",                    enable = true}
			},]]

			culling         = GL.FRONT_AND_BACK,
			--shader          = luaShader,
			--cameraloc       = luaShaderLocs.cameraMatrixLoc,
			--camerainvloc    = luaShaderLocs.cameraInvMatrixLoc, -- Spring 0.79
			--shadowloc       = luaShaderLocs.shadowMatrixLoc,
			--shadowparamsloc = luaShaderLocs.shadowParamsLoc,
			prelist         = preDL,
			postlist        = pstDL
		}
		return matTbl
	end


	local function MyUnitCrea(unitID,order)
		local unitDefID = sprGetUnitDefID(unitID)

		if (normalMapNames[unitDefID] ~= nil) then
			if (textureNames[unitDefID] == nil) then
				textureNames[unitDefID] = {
					[1] = '%' .. unitDefID .. ":0",
					[2] = '%' .. unitDefID .. ":1"
				}
			end

			--Spring.Echo("Found Unit",unitID)

			local preDL = GetPreDisplayList(unitID)
			local pstDL = GetPostDisplayList(unitID)

			SUR.SetLODCount(unitID, 1)
			SUR.SetMaterial(unitID, 1, "opaque", GetUnitDefMaterial(unitDefID, preDL, pstDL))
			SUR.SetUnitLuaDraw(unitID, true)

			for pieceID, pieceName in pairs(Spring.GetUnitPieceList(unitID) or {}) do
				if (pieceID ~= "n") then
					SUR.SetPieceList(unitID, 1, pieceID)
				end
			end
		end
	end

	local function MyUnitDest(unitID)
		local unitDefID = sprGetUnitDefID(unitID)

		if (normalMapNames[unitDefID] ~= nil) then
			SUR.SetUnitLuaDraw(unitID, false)
			SUR.SetLODCount(unitID, 0)
		end
	end





local function CreateShader1()
				local s = glCreateShader({
			vertex = [[

				varying vec3 lvES;
				varying vec3 hvES;
				varying vec3 nvES;

				varying mat3 tbnInvMatrix;
				varying vec3 cdES;

				uniform int haveShadows;
				uniform mat4 shadowMatrix;
				uniform vec4 shadowParams;
				uniform mat4 cameraMatrix;
				uniform mat4 cameraInvMatrix;

				void main(void) {
					mat4 modelMatrix = cameraInvMatrix * gl_ModelViewMatrix;
					mat4 modelInvMatrix = gl_ModelViewMatrixInverse * cameraMatrix;

					vec3 vpES = (gl_ModelViewMatrix * gl_Vertex).xyz;
					vec3 cpES = vec3(0.0, 0.0, 1.0);

					vec3 svOS = gl_MultiTexCoord5.xyz;
					vec3 tvOS = gl_MultiTexCoord6.xyz;
					
					//Manual transform of the matrix, for GLSL 1.X compatibility
					mat3 tbnMatrix = mat3(svOS, tvOS, gl_Normal);
					tbnInvMatrix[0].x = tbnMatrix[0].x;
					tbnInvMatrix[0].y = tbnMatrix[1].x;
					tbnInvMatrix[0].z = tbnMatrix[2].x;

					tbnInvMatrix[1].x = tbnMatrix[0].y;
					tbnInvMatrix[1].y = tbnMatrix[1].y;
					tbnInvMatrix[1].z = tbnMatrix[2].y;

					tbnInvMatrix[2].x = tbnMatrix[0].z;
					tbnInvMatrix[2].y = tbnMatrix[1].z;
					tbnInvMatrix[2].z = tbnMatrix[2].z;
						
					cdES = (vpES - cpES);

					nvES = normalize(gl_NormalMatrix * gl_Normal);
					lvES = normalize(gl_LightSource[0].position.xyz);
					hvES = normalize(gl_LightSource[0].halfVector.xyz);


					gl_FrontColor = gl_Color;
					gl_TexCoord[0].st  = gl_MultiTexCoord0.st;
					gl_Position = gl_ProjectionMatrix * cameraMatrix * modelMatrix * gl_Vertex;


					if (haveShadows != 0) {
						vec4 vpWS = (modelMatrix * gl_Vertex);
						gl_TexCoord[3] = shadowMatrix * vpWS;
						
						gl_TexCoord[3].st *= (1 / sqrt(abs(gl_TexCoord[3].st) + shadowParams.z) + shadowParams.w);
						gl_TexCoord[3].st += shadowParams.xy;
					}
				}
			]],

			fragment = [[

				varying vec3 lvES;
				varying vec3 hvES;
				varying vec3 nvES;

				varying vec3 cdES;

				uniform sampler2D textureS3O1;
				uniform sampler2D textureS3O2;

				uniform samplerCube reflectMap;
				uniform sampler2D normalMap;

				uniform sampler2D shadowMap;
				uniform int haveShadows;

				uniform vec3 unitAmbientLight;
				uniform vec3 unitDiffuseLight;

				varying mat3 tbnInvMatrix;

				void main(void) {

						//Manual transform of the matrix, for GLSL 1.X compatibility
						mat3 tbnMatrix;

						tbnMatrix[0].x = tbnInvMatrix[0].x;
						tbnMatrix[0].y = tbnInvMatrix[1].x;
						tbnMatrix[0].z = tbnInvMatrix[2].x;

						tbnMatrix[1].x = tbnInvMatrix[0].y;
						tbnMatrix[1].y = tbnInvMatrix[1].y;
						tbnMatrix[1].z = tbnInvMatrix[2].y;

						tbnMatrix[2].x = tbnInvMatrix[0].z;
						tbnMatrix[2].y = tbnInvMatrix[1].z;
						tbnMatrix[2].z = tbnInvMatrix[2].z;

					vec2 tc = vec2(gl_TexCoord[0].s, gl_TexCoord[0].t);

					vec3 nvTS = ((texture2D(normalMap, tc) * 2.0) - 1.0);

					vec4 basicColor = texture2D(textureS3O1, tc);
					vec4 extraColor = texture2D(textureS3O2, tc);

					float nvDOTlv = 0.0;
					float nvDOThv = 0.0;
					vec3 reDirES;

					vec3 nv_OS = normalize(tbnMatrix * nvTS);
					vec3 nv_ES = normalize(gl_NormalMatrix * nv_OS);

					nvDOTlv = max(nvDOTlv, dot(nv_ES, lvES));
					nvDOThv = max(nvDOThv, dot(nv_ES, hvES));
					reDirES = reflect(normalize(cdES), nv_ES);

					float shininess = extraColor.g * 4.0;

					float specPow =
						(nvDOTlv > 0.0 && nvDOThv > 0.0)?
						max(0.0, pow(nvDOThv, shininess)):
						0.0;

					if (extraColor.b > 0.0)
					{
						specPow = specPow * extraColor.b;
					}

					vec3 specColor = textureCube(reflectMap, reDirES).rgb * specPow * extraColor.g;
					vec3 reflColor = textureCube(reflectMap, reDirES).rgb;
					vec3 diffColor = (unitDiffuseLight * nvDOTlv) + unitAmbientLight * 1.25;

					reflColor = mix(diffColor, reflColor, extraColor.g);
					reflColor += extraColor.r;

					gl_FragColor = basicColor;
					gl_FragColor.rgb = mix(gl_FragColor.rgb, gl_Color.rgb, gl_FragColor.a);
					gl_FragColor.rgb = gl_FragColor.rgb * reflColor + specColor;

					if(haveShadows != 0)
					{
						vec2 tc = vec2(gl_TexCoord[3].s, gl_TexCoord[3].t);
						float depth = texture2D(shadowMap, tc).z;
						if (depth <  0.05)
						{
							gl_FragColor.rgb = gl_FragColor.rgb * vec3(extraColor.r + unitAmbientLight.r + extraColor.g, 

extraColor.r + unitAmbientLight.g + extraColor.g, extraColor.r + unitAmbientLight.b + extraColor.g);

							if (basicColor.a > 0.0)
							{
								gl_FragColor.rgb = mix(gl_FragColor.rgb, gl_Color, basicColor.a);
							}
						}						
					}

					gl_FragColor.a   = extraColor.a;
				}
			]],

			uniformInt = {
				textureS3O1 = 0,
				textureS3O2 = 1,
				reflectMap  = 2,
				normalMap   = 3,
				shadowMap   = 4,
			},
			uniform = {
				unitAmbientLight = {glGetSun("ambient", "unit")},
				unitDiffuseLight = {glGetSun("diffuse", "unit")},
			},
			uniformMatrix = {
				shadowMatrix = {glGetMatrixData("shadow")},
			}
		})

		return s
end


	local function SetShaderUniformLocations(s)
		cameraMatrixLoc     = glGetUniformLocation(s, "cameraMatrix")
		cameraInvMatrixLoc  = glGetUniformLocation(s, "cameraInvMatrix")
		shadowMatrixLoc     = glGetUniformLocation(s, "shadowMatrix")

		haveShadowsLoc      = glGetUniformLocation(luaShader, "haveShadows")
		shadowParamsLoc     = glGetUniformLocation(luaShader, "shadowParams")
		shadowDensityLoc    = glGetUniformLocation(luaShader, "shadowDensity")

		cameraMatrixLoc     = glGetUniformLocation(s, "cameraMatrix")
		cameraInvMatrixLoc  = glGetUniformLocation(s, "cameraInvMatrix")

		unitAmbientLightLoc = glGetUniformLocation(s, "unitAmbientLight")
		unitDiffuseLightLoc = glGetUniformLocation(s, "unitDiffuseLight")

		shadowMatrixLoc     = glGetUniformLocation(s, "shadowMatrix")
		shadowParamsLoc     = glGetUniformLocation(s, "shadowParams")
		shadowDensityLoc    = glGetUniformLocation(s, "shadowDensity")
		haveShadowsLoc      = glGetUniformLocation(s, "haveShadows")
		haveNormalsLoc      = glGetUniformLocation(s, "haveNormals")
		haveOffsetsLoc      = glGetUniformLocation(s, "haveOffsets")

		shadowMapLoc        = glGetUniformLocation(s, "shadowMap")
		textureS3O1Loc      = glGetUniformLocation(s, "textureS3O1")
		textureS3O2Loc      = glGetUniformLocation(s, "textureS3O2")
		reflectMapLoc       = glGetUniformLocation(s, "reflectMap")
		normalMapLoc        = glGetUniformLocation(s, "normalMap")
	end


	function gadget:Initialize()
		if (glCreateShader == nil) then
			Spring.Echo("[unit_normalmap_shader:Initialize] no shader support")
			gadgetHandler:RemoveGadget()
			return
		end

		luaShader = CreateShader1()


		if (luaShader == nil) then
			Spring.Echo("[unit_normalmap_shader:Initialize] shader1 compilation failed")
			Spring.Echo(glGetShaderLog())
			gadgetHandler:RemoveGadget()
			return
		end

		SetShaderUniformLocations(luaShader)

		for unitDefID, unitDef in pairs(UnitDefs) do
			if (unitDef.customParams.normalmaps == "yes") then
				--Spring.Echo("Found Normalmap",unitDefID)
				normalMapNames[unitDefID] = {"unittextures/" .. unitDef.customParams.normalmap_name, true, true}
				--Spring.Echo(normalMapNames[unitDefID])
				table.insert(normalMapList,unitDefID,1)
			end
		end
	end

	function gadget:Shutdown()

	end

   function gadget:RecvFromSynced(fun, unitID)
      --if (fun == "MyUnitCrea") then MyUnitCrea(unitID) return true end
      --if (fun == "MyUnitDest") then MyUnitDest(unitID) return true end
      return false
   end


	function gadget:DrawUnit(unitID, gameDrawMode)
		--[[ud = Spring.GetUnitDefID(unitID)
		if normalMapList[ud] then
			return true
		else
			return true
		end]]
		return true
	end


	local unitIDList = {}
	local tempList = {}
	function gadget:DrawWorldPreUnit()

	local frame = Spring.GetGameFrame()
	if (((frame + 5) % 15) < 0.1) then
		--Spring.Echo("updating list")
		unitIDList = Spring.GetVisibleUnits(-1)
		--cull the unitIDs that don't use SUR here
		for _,unitID in pairs(unitIDList) do
			id = Spring.GetUnitDefID(unitID)
			if normalMapList[id] == nil then
				table.remove(unitIDList,unitID)
			end
		end
		--Depth-sort them

		local tempList = {}
		if unitIDList[1] ~= nil then
			
			local camX,camY,camZ = Spring.GetCameraPosition()
			for _,unitID in ipairs (unitIDList) do
				local posX,posY,posZ = Spring.GetUnitPosition(unitID)
				--Spring.Echo(posX,posY,posZ)
				if posX ~= nil then
				local distance = math.sqrt(camX*posX + camY*posY + camZ*posZ)
				--Spring.Echo(distance)
				table.insert(tempList,#tempList+1,{unitID = unitID, dist = distance,})
				else Spring.Echo("nil posX!") end
			end
			unitIDList = tempList
			 table.sort(unitIDList, function(m1,m2) return m1.dist > m2.dist; end)
			tempList = {}
		end
	end

	if unitIDList[1] ~= nil then
		--local myOrder = 0
		for i,k in ipairs(unitIDList) do
			--myOrder = myOrder + 1

			--local blah = k.dist
			--Spring.Echo(k.unitID,"my distance is: "..blah,"myOrder = "..myOrder)
			--MyUnitCrea(k.unitID,myOrder)
			--SUR.SetUnitLuaDraw(k.unitID,true)
			--SUR.SetMaterial(k.unitID, 1, "alpha")

				local unitTeam = sprGetUnitTeam(k.unitID)
				local tcr, tcg, tcb, tca = sprGetTeamColor(unitTeam)
				local sdx, sdy, sdz = glGetSun()

				glAlphaTest(GL.GREATER,0.01)
				glBlending(GL.SRC_ALPHA, GL.ONE_MINUS_SRC_ALPHA)

				glDepthMask(true)
				glDepthTest(GL.LEQUAL)
				glCulling(GL.BACK)

				glLighting(true)
				glLight(0, true)
				glLight(1, false)
				glLight(0, GL.POSITION, sdx, sdy, sdz, 0)

				glUseShader(luaShader)
				glColor(tcr, tcg, tcb, tca)
				glUniformMatrix(cameraMatrixLoc,    glGetMatrixData("camera"))
				glUniformMatrix(cameraInvMatrixLoc, glGetMatrixData("caminv"))
				glUniformMatrix(shadowMatrixLoc,    glGetMatrixData("shadow"))

				glUniformInt(haveShadowsLoc, ((sprHaveShadows() and 1) or 0))
				glUniformInt(haveNormalsLoc, ((haveNormals and 1) or 0))
				glUniformInt(haveOffsetsLoc, ((haveOffsets and 1) or 0))

				glUniform(unitAmbientLightLoc, glGetSun("ambient", "unit"))
				glUniform(unitDiffuseLightLoc, glGetSun("diffuse", "unit"))
				glUniform(shadowDensityLoc, glGetSun("shadowDensity", "unit"))
				glUniform(shadowParamsLoc, glGetShadowMapParams())

				glUniformInt(textureS3O1Loc, 0)
				glUniformInt(textureS3O2Loc, 1)
				glUniformInt(reflectMapLoc,  2)
				glUniformInt(normalMapLoc,   3)
				glUniformInt(shadowMapLoc,   4)

				glTexture(0, 'unittextures/Bubble_Farm.dds')
				glTexture(1, 'unittextures/Bubble_Farm_ColorAlpha.dds')
				glTexture(2, "$reflection")
				glTexture(3, 'unittextures/Bubble_Farm_NormalMap.dds')
				glTexture(4, "$shadow")

			--gl.UnitMatrix(k.unitID)
			--local posX,posY,posZ = Spring.GetUnitPosition(k.unitID)
			--gl.Translate(posX,posY + 1,posZ)
			
			--gl.Color(1.0,1.0,1.0,1.0)
			--gl.Scale(1.05,1.05,1.05)
			gl.Unit(k.unitID,true)
		end

	end


	end
end
User avatar
jK
Spring Developer
Posts: 2299
Joined: 28 Jun 2007, 07:30

Re: Drawing Order

Post by jK »

Argh wrote:Nope, doesn't work. Engine's gotta change to make it work. I'm sure now.
there are min. 3 ways to do so w/o an engine change
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: Drawing Order

Post by Argh »

If you have a practical idea, let's hear it. Call me a bit doubtful atm, though. I don't think there are ways to do it, without abandoning the unit-rendering system.
User avatar
jK
Spring Developer
Posts: 2299
Joined: 28 Jun 2007, 07:30

Re: Drawing Order

Post by jK »

1. there is an order tag in SUR (ugliest and perhaps slowest method)
2. just use SUR to deactivate the engine drawing and render the whole unit yourself in DrawWorld
3. just replace the translucent model piece via SUR with an empty DList and then just render those pieces in DrawWorld (seems to be the fastest way)
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: Drawing Order

Post by Argh »

1. there is an order tag in SUR (ugliest and perhaps slowest method)
Tried that, I was hoping that would work, it was the easiest solution. It doesn't seem to do anything.
2. just use SUR to deactivate the engine drawing and render the whole unit yourself in DrawWorld
Tried that, that's pretty much what this last example does. I think that DrawWorldReflection's causing it to fail the depth-test.
3. just replace the translucent model piece via SUR with an empty DList and then just render those pieces in DrawWorld (seems to be the fastest way)
Haven't tried that, but I suspect that it'll still be masked by the passes I can't see or change.

We have three passes- reflectons, shadowmap, and diffuse. I thought shadowmap was FBO'd, so it's not causing the problem. Whenever I make the Unit geometry invisible via SUR (this last example has that) it doesn't seem to matter. Maybe I should test it and see if turning reflections off suddenly fixes it. That would be amusing.

Of course... if it works... I won't see a shadow or a reflection at all.
User avatar
jK
Spring Developer
Posts: 2299
Joined: 28 Jun 2007, 07:30

Re: Drawing Order

Post by jK »

Argh wrote:
1. there is an order tag in SUR (ugliest and perhaps slowest method)
Tried that, I was hoping that would work, it was the easiest solution. It doesn't seem to do anything.
2. just use SUR to deactivate the engine drawing and render the whole unit yourself in DrawWorld
Tried that, that's pretty much what this last example does. I think that DrawWorldReflection's causing it to fail the depth-test.
3. just replace the translucent model piece via SUR with an empty DList and then just render those pieces in DrawWorld (seems to be the fastest way)
Haven't tried that, but I suspect that it'll still be masked by the passes I can't see or change.

We have three passes- reflectons, shadowmap, and diffuse. I thought shadowmap was FBO'd, so it's not causing the problem. Whenever I make the Unit geometry invisible via SUR (this last example has that) it doesn't seem to matter. Maybe I should test it and see if turning reflections off suddenly fixes it. That would be amusing.

Of course... if it works... I won't see a shadow or a reflection at all.
sorry but everything you said doesn't make any sense.
first (1) works fine, your assumptions how it works are just wrong.
Also your assumptions of depth buffer, stencil buffer, alpha test, etc. are very broken, you should really try to read it up somewhere.
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: Drawing Order

Post by Argh »

The "order" is supposed to be the order in which it's rendered? The order of the material within the SUR rendering process?

All I know is that I treated it like it was a layer, and it doesn't work.

As for the rest of it... talk's cheap. Screens, working code, or anything else of a verifiable nature would be good.

I would have thought that last series of screenshots would have been pretty convincing, frankly- I proposed my theory, and then successfully demonstrated it.

I'm open to suggestions to try something else, but thus far it's a waste of time.
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: Drawing Order

Post by Argh »

Here's an implementation of the "order" solution. jK's comment wasn't terribly clear, so I just sent "order" the distances of the unitIDs from the POV, after applying math.floor (since it's supposed to be an int).

Code: Select all

function gadget:GetInfo()
	return {
		name	= "unit_normalmap_shader_tst.lua",
		desc	= "adds normal-mapping to S3O models",
		author	 = "Kloot",
		date	= "31-1-2009",
		license	= "GPL v2",
		layer	=  0,
		enabled	= true
	}
end

if (gadgetHandler:IsSyncedCode()) then
	function gadget:Initialize()
		-- desc	= "adds normal-mapping to S3O models (gadgetized)",
		-- author	 = "Kloot",
		-- date	= "April 6, 2009",
		-- license	= "GPL v2",
	end

	function gadget:UnitGiven(unitID)
		SendToUnsynced("MyUnitCrea", unitID)
		return true
	end

	function gadget:UnitCreated(unitID)
		SendToUnsynced("MyUnitCrea", unitID)
		return true
	end

	function gadget:UnitDestroyed(unitID)
		SendToUnsynced("MyUnitDest", unitID)
		return true
	end

else

	local glLoadIdentity	= gl.LoadIdentity
	local glPushMatrix	= gl.PushMatrix
	local glPopMatrix	= gl.PopMatrix
	local glTranslate	= gl.Translate
	local glBeginEnd	= gl.BeginEnd
	local glNormal	= gl.Normal
	local glVertex	= gl.Vertex
	local glColor	= gl.Color
	local glLight	= gl.Light
	local glLighting	= gl.Lighting
	local glBlending	= gl.Blending
	local glPushAttrib	= gl.PushAttrib
	local glPopAttrib	= gl.PopAttrib

	local glCulling	= gl.Culling
	local glDepthMask	= gl.DepthMask
	local glDepthTest	= gl.DepthTest
	local glAlphaTest	 = gl.AlphaTest

	local glCreateList	= gl.CreateList
	local glDeleteList	= gl.DeleteList

	local glUnit	= gl.Unit
	local glUnitRaw	= gl.UnitRaw
	local glTexture	= gl.Texture
	local glTexCoord	= gl.TexCoord
	local glMultiTexCoord = gl.MultiTexCoord
	local glUnitMultMatrix = gl.UnitMultMatrix

	local glGetSun	= gl.GetSun
	local glGetShadowMapParams = gl.GetShadowMapParams
	local glGetMatrixData = gl.GetMatrixData

	local glGetShaderLog	= gl.GetShaderLog
	local glCreateShader	= gl.CreateShader
	local glDeleteShader	= gl.DeleteShader
	local glUseShader		= gl.UseShader

	local glUniformMatrix = gl.UniformMatrix
	local glUniformInt = gl.UniformInt
	local glUniform = gl.Uniform
	local glGetUniformLocation = gl.GetUniformLocation
	local glGetActiveUniforms  = gl.GetActiveUniforms

	local normalMapNames = {}
	local textureNames = {}
	local preDisplayLists	= {}
	local pstDisplayLists	= {}
	local luaShader = nil

	local luaShaderLocs = {
		cameraMatrixLoc	= -1,
		cameraInvMatrixLoc  = -1,
		shadowMatrixLoc	= -1,
		shadowParamsLoc	= -1,
		shadowDensityLoc	 = -1,

		unitAmbientLightLoc = -1,
		unitDiffuseLightLoc = -1,

		shadowMapLoc = -1,
		textureS3O1Loc = -1,
		textureS3O2Loc = -1,
		--specularMapLoc = -1,
		reflectMapLoc = -1,
		normalMapLoc = -1,
	}

	local sprGetGameFrame = Spring.GetGameFrame
	local sprGetUnitDefID = Spring.GetUnitDefID
	local sprGetAllUnits	= Spring.GetAllUnits
	local sprGetVisibleUnits = Spring.GetVisibleUnits
	local sprIsUnitVisible	 = Spring.IsUnitVisible
	local sprGetUnitTeam = Spring.GetUnitTeam
	local sprGetCameraPosition = Spring.GetCameraPosition
	local sprGetTeamColor = Spring.GetTeamColor
	local sprSetUnitNoDraw = Spring.SetUnitNoDraw
	local sprHaveShadows = Spring.HaveShadows
	local sprGetUnitTransformMatrix = Spring.GetUnitTransformMatrix
	local SUR	= Spring.UnitRendering





	local function GetPreDisplayList(unitID)
		local unitTeam = sprGetUnitTeam(unitID)
		local unitDefID = sprGetUnitDefID(unitID)

		if (preDisplayLists[unitDefID] == nil) then
			preDisplayLists[unitDefID] = {}
		end

		if (preDisplayLists[unitDefID][unitTeam] == nil) then
			local sdx, sdy, sdz = glGetSun("pos")
			local tcr, tcg, tcb, tca = sprGetTeamColor(unitTeam)

			preDisplayLists[unitDefID][unitTeam] = glCreateList(
				function()
					glPushAttrib(GL_ALL_ATTRIB_BITS)
					glAlphaTest(GL.GREATER,0.01)
					glBlending(GL.SRC_ALPHA, GL.ONE_MINUS_SRC_ALPHA)
					glDepthMask(true)
					glDepthTest(GL.LEQUAL)
					glCulling(GL.BACK)

					glLighting(true)
					glLight(0, true)
					glLight(1, false)
					glLight(0, GL.POSITION, sdx, sdy, sdz, 0)

					glPushMatrix()
					glColor(tcr, tcg, tcb, tca)
					glTexture(4, normalMapNames[unitDefID][1])
				end)
		end

		return preDisplayLists[unitDefID][unitTeam]
	end

	local function GetPostDisplayList(unitID)
		local unitTeam = sprGetUnitTeam(unitID)
		local unitDefID = sprGetUnitDefID(unitID)

		if (pstDisplayLists[unitDefID] == nil) then
			pstDisplayLists[unitDefID] = {}
		end

		if (pstDisplayLists[unitDefID][unitTeam] == nil) then
			pstDisplayLists[unitDefID][unitTeam] = glCreateList(
				function()
					glTexture(4, false)
					glColor(1.0, 1.0, 1.0, 1.0)
					glPopMatrix()

					glLight(0, false)
					glLighting(false)

					glCulling(GL.FRONT)
					glDepthTest(false)
					glDepthMask(false)
					glBlending(true)
					glPopAttrib()
				end)
		end

		return pstDisplayLists[unitDefID][unitTeam]
	end

	local function GetUnitDefMaterial(unitDefID, preDL, pstDL, order)
		local matTbl = {
			order = order,
			texunits = {
				[0] = {tex = textureNames[unitDefID][1],	enable = true},
				[1] = {tex = textureNames[unitDefID][2],	enable = true},
				[2] = {tex = "$reflection",				enable = true},
				[3] = {tex = normalMapNames[unitDefID][1], enable = true},
				[4] = {tex = "$shadow",						enable = true}
			},
			culling = GL.BACK,
			shader = luaShader,
			cameraloc	= luaShaderLocs.cameraMatrixLoc,
			--camerainvloc = luaShaderLocs.cameraInvMatrixLoc, -- Spring 0.79
			shadowloc	= luaShaderLocs.shadowMatrixLoc,
			shadowparamsloc = luaShaderLocs.shadowParamsLoc,
			prelist = preDL,
			postlist = pstDL
		}
		return matTbl
	end


	local function MyUnitCrea(unitID,order)
		local unitDefID = sprGetUnitDefID(unitID)

		if (normalMapNames[unitDefID] ~= nil) then
			if (textureNames[unitDefID] == nil) then
				textureNames[unitDefID] = {
					[1] = '%' .. unitDefID .. ":0",
					[2] = '%' .. unitDefID .. ":1"
				}
			end

			--Spring.Echo("Found Unit",unitID)

			local preDL = GetPreDisplayList(unitID)
			local pstDL = GetPostDisplayList(unitID)

			SUR.SetLODCount(unitID, 1)
			SUR.SetMaterial(unitID, 1, "opaque", GetUnitDefMaterial(unitDefID, preDL, pstDL, order) )
			SUR.SetUnitLuaDraw(unitID, true)

			for pieceID, pieceName in pairs(Spring.GetUnitPieceList(unitID) or {}) do
				if (pieceID ~= "n") then
					SUR.SetPieceList(unitID, 1, pieceID)
				end
			end
		end
	end

	local function MyUnitDest(unitID)
		local unitDefID = sprGetUnitDefID(unitID)

		if (normalMapNames[unitDefID] ~= nil) then
			SUR.SetUnitLuaDraw(unitID, false)
			SUR.SetLODCount(unitID, 0)
		end
	end



	local function SetShaderUniformLocations(s)
		luaShaderLocs.cameraMatrixLoc	= glGetUniformLocation(s, "cameraMatrix")
		luaShaderLocs.cameraInvMatrixLoc  = glGetUniformLocation(s, "cameraInvMatrix")
		luaShaderLocs.shadowMatrixLoc	= glGetUniformLocation(s, "shadowMatrix")

		luaShaderLocs.haveShadowsLoc		= glGetUniformLocation(luaShader, "haveShadows")
		luaShaderLocs.shadowParamsLoc	= glGetUniformLocation(luaShader, "shadowParams")
		luaShaderLocs.shadowDensityLoc	 = glGetUniformLocation(luaShader, "shadowDensity")
	end

local function CreateShader1()
				local s = glCreateShader({
			vertex = [[
				varying vec3 lvES;
				varying vec3 hvES;
				varying vec3 nvES;

				varying mat3 tbnInvMatrix;
				varying vec3 cdES;
				//varying vec3 cdTS;

				uniform int haveShadows;
				uniform mat4 shadowMatrix;
				uniform vec4 shadowParams;
				uniform mat4 cameraMatrix;
				uniform mat4 cameraInvMatrix;

				void main(void) {

					mat4 modelMatrix = cameraInvMatrix * gl_ModelViewMatrix;
					mat4 modelInvMatrix = gl_ModelViewMatrixInverse * cameraMatrix;

					vec3 vpES = (gl_ModelViewMatrix * gl_Vertex).xyz;
					vec3 cpES = vec3(0.0, 0.0, 1.0);

					vec3 svOS = gl_MultiTexCoord5.xyz;
					vec3 tvOS = gl_MultiTexCoord6.xyz;
					
					//Manual transform of the matrix, for GLSL 1.X compatibility
					mat3 tbnMatrix = mat3(svOS, tvOS, gl_Normal);
					tbnInvMatrix[0].x = tbnMatrix[0].x;
					tbnInvMatrix[0].y = tbnMatrix[1].x;
					tbnInvMatrix[0].z = tbnMatrix[2].x;

					tbnInvMatrix[1].x = tbnMatrix[0].y;
					tbnInvMatrix[1].y = tbnMatrix[1].y;
					tbnInvMatrix[1].z = tbnMatrix[2].y;

					tbnInvMatrix[2].x = tbnMatrix[0].z;
					tbnInvMatrix[2].y = tbnMatrix[1].z;
					tbnInvMatrix[2].z = tbnMatrix[2].z;
						
					cdES = (vpES - cpES);
					//cdTS = (tbnInvMatrix * (gl_ModelViewMatrixInverse * vec4(cdES, gl_Vertex.w)).xyz);

					nvES = normalize(gl_NormalMatrix * gl_Normal);
					lvES = normalize(gl_LightSource[0].position.xyz);
					hvES = normalize(gl_LightSource[0].halfVector.xyz);


					gl_FrontColor = gl_Color;
					gl_TexCoord[0].st  = gl_MultiTexCoord0.st;
					gl_Position = gl_ProjectionMatrix * cameraMatrix * modelMatrix * gl_Vertex;

					if (haveShadows != 0) {
						vec4 vpWS = (modelMatrix * gl_Vertex);
						gl_TexCoord[3] = shadowMatrix * vpWS;
						
						gl_TexCoord[3].st *= (1 / sqrt(abs(gl_TexCoord[3].st) + shadowParams.z) + shadowParams.w);
						gl_TexCoord[3].st += shadowParams.xy;
					}
				}
			]],

			fragment = [[
				varying vec3 lvES;
				varying vec3 hvES;
				varying vec3 nvES;

				varying vec3 cdES;
				//varying vec3 cdTS;

				uniform sampler2D textureS3O1;
				uniform sampler2D textureS3O2;

				uniform samplerCube reflectMap;
				uniform sampler2D normalMap;

				uniform sampler2D shadowMap;
				uniform int haveShadows;

				uniform vec3 unitAmbientLight;
				uniform vec3 unitDiffuseLight;

				varying mat3 tbnInvMatrix;

				void main(void) {

						//Manual transform of the matrix, for GLSL 1.X compatibility
						mat3 tbnMatrix;

						tbnMatrix[0].x = tbnInvMatrix[0].x;
						tbnMatrix[0].y = tbnInvMatrix[1].x;
						tbnMatrix[0].z = tbnInvMatrix[2].x;

						tbnMatrix[1].x = tbnInvMatrix[0].y;
						tbnMatrix[1].y = tbnInvMatrix[1].y;
						tbnMatrix[1].z = tbnInvMatrix[2].y;

						tbnMatrix[2].x = tbnInvMatrix[0].z;
						tbnMatrix[2].y = tbnInvMatrix[1].z;
						tbnMatrix[2].z = tbnInvMatrix[2].z;

					vec2 tc = vec2(gl_TexCoord[0].s, gl_TexCoord[0].t);

/*vec4 normalColor = texture2D(normalMap, tc);

					vec3 cdTS = (tbnInvMatrix * (gl_ModelViewMatrixInverse * vec4(cdES,normalColor.a)).xyz);

						// parallax-mapping
						float s =  0.005;
						float b = -0.001;
						
						//float h;
						float h = (float(texture2D(normalMap, tc)) * s) + b;
						//h = (h * s) + b;

						tc += (h * (normalize(cdTS)).xy);*/



					vec3 nvTS = ((texture2D(normalMap, tc) * 2.0) - 1.0);

					vec4 basicColor = texture2D(textureS3O1, tc);
					vec4 extraColor = texture2D(textureS3O2, tc);

					float nvDOTlv = 0.0;
					float nvDOThv = 0.0;
					vec3 reDirES;

					vec3 nv_OS = normalize(tbnMatrix * nvTS);
					vec3 nv_ES = normalize(gl_NormalMatrix * nv_OS);

					nvDOTlv = max(nvDOTlv, dot(nv_ES, lvES));
					nvDOThv = max(nvDOThv, dot(nv_ES, hvES));
					reDirES = reflect(normalize(cdES), nv_ES);

					float shininess = extraColor.g * 4.0;

					float specPow =
						(nvDOTlv > 0.0 && nvDOThv > 0.0)?
						max(0.0, pow(nvDOThv, shininess)):
						0.0;

					if (extraColor.b > 0.0)
					{
						specPow = specPow * extraColor.b;
					}

					vec3 specColor = textureCube(reflectMap, reDirES).rgb * specPow * extraColor.g;
					vec3 reflColor = textureCube(reflectMap, reDirES).rgb;
					vec3 diffColor = (unitDiffuseLight * nvDOTlv) + unitAmbientLight * 1.25;

					reflColor = mix(diffColor, reflColor, extraColor.g);
					reflColor += extraColor.r;

					gl_FragColor = basicColor;
					gl_FragColor.rgb = mix(gl_FragColor.rgb, gl_Color.rgb, gl_FragColor.a);
					gl_FragColor.rgb = gl_FragColor.rgb * reflColor + specColor;

					if(haveShadows != 0)
					{
						vec2 tc = vec2(gl_TexCoord[3].s, gl_TexCoord[3].t);
						float depth = texture2D(shadowMap, tc).z;
						if (depth <  0.05)
						{
							gl_FragColor.rgb = gl_FragColor.rgb * vec3(extraColor.r + unitAmbientLight.r + extraColor.g, 

extraColor.r + unitAmbientLight.g + extraColor.g, extraColor.r + unitAmbientLight.b + extraColor.g);

							if (basicColor.a > 0.0)
							{
								gl_FragColor.rgb = mix(gl_FragColor.rgb, gl_Color, basicColor.a);
							}
						}						
					}
					gl_FragColor.a	= extraColor.a;
				}
			]],

			uniformInt = {
				textureS3O1 = 0,
				textureS3O2 = 1,
				reflectMap  = 2,
				normalMap	= 3,
				shadowMap	= 4,
			},
			uniform = {
				unitAmbientLight = {glGetSun("ambient", "unit")},
				unitDiffuseLight = {glGetSun("diffuse", "unit")},
			},
			uniformMatrix = {
				shadowMatrix = {glGetMatrixData("shadow")},
			}
		})

		return s
end


	local normalMapList = {}
	function gadget:Initialize()
		if (glCreateShader == nil) then
			Spring.Echo("[unit_normalmap_shader:Initialize] no shader support")
			gadgetHandler:RemoveGadget()
			return
		end

		luaShader = CreateShader1()


		if (luaShader == nil) then
			Spring.Echo("[unit_normalmap_shader:Initialize] shader1 compilation failed")
			Spring.Echo(glGetShaderLog())
			gadgetHandler:RemoveGadget()
			return
		end

		SetShaderUniformLocations(luaShader)

		for unitDefID, unitDef in pairs(UnitDefs) do
			if (unitDef.customParams.normalmaps == "yes") then
				--Spring.Echo("Found Normalmap",unitDefID)
				normalMapNames[unitDefID] = {"unittextures/" .. unitDef.customParams.normalmap_name, true, true}
				--Spring.Echo(normalMapNames[unitDefID])
				table.insert(normalMapList,unitDefID,1)
			end
		end
	end

	function gadget:Shutdown()
		for unitDefID, _ in pairs(UnitDefs) do
			if (preDisplayLists[unitDefID] ~= nil) then
				for i = 0, 1024 do
					if (preDisplayLists[unitDefID][i] ~= nil) then glDeleteList(preDisplayLists[unitDefID][i]) end
					if (pstDisplayLists[unitDefID][i] ~= nil) then glDeleteList(pstDisplayLists[unitDefID][i]) end
				end
			end
		end
		--glDeleteShader(luaShader or 0)
	end

	function gadget:RecvFromSynced(fun, unitID)
		if (fun == "MyUnitCrea") then MyUnitCrea(unitID,0) return true end
		if (fun == "MyUnitDest") then MyUnitDest(unitID) return true end
		return false
	end

	function gadget:DrawUnit(unitID, gameDrawMode)
		glUniformMatrix(luaShaderLocs.cameraInvMatrixLoc, glGetMatrixData("caminv")) -- Spring 0.78.2.*
		glUniformInt(luaShaderLocs.haveShadowsLoc, ((sprHaveShadows() and 1) or 0))

		if (sprHaveShadows()) then
			glUniform(luaShaderLocs.shadowParamsLoc, glGetShadowMapParams())
			glUniform(luaShaderLocs.shadowDensityLoc, glGetSun("shadowDensity", "unit"))
		end

		glUnitRaw(unitID, true)
		return true
	end

local unitIDList = {}
local tempList = {}

function gadget:DrawWorld()
	local frame = Spring.GetGameFrame()
	if (((frame + 5) % 15) < 0.1) then
		--Spring.Echo("updating list")
		unitIDList = Spring.GetVisibleUnits(-1)
		--cull the unitIDs that don't use SUR here
		for _,unitID in pairs(unitIDList) do
			id = Spring.GetUnitDefID(unitID)
			if normalMapList[id] == nil then
				table.remove(unitIDList,unitID)
			end
		end
		--Depth-sort them

		local tempList = {}
		if unitIDList[1] ~= nil then
			
			local camX,camY,camZ = Spring.GetCameraPosition()
			for _,unitID in ipairs (unitIDList) do
				local posX,posY,posZ = Spring.GetUnitPosition(unitID)
				--Spring.Echo(posX,posY,posZ)
				if posX ~= nil then
				local distance = math.sqrt(camX*posX + camY*posY + camZ*posZ)
				--Spring.Echo(distance)
				table.insert(tempList,#tempList+1,{unitID = unitID, dist = distance,})
				else Spring.Echo("nil posX!") end
			end
			unitIDList = tempList
			
			table.sort(unitIDList, function(m1,m2) return m1.dist > m2.dist; end)
			tempList = {}
			for i,k in ipairs(unitIDList) do
				MyUnitCrea(k.unitID,math.floor(k.dist))
			end
		end
	end
end

end
Unfortunately, it doesn't work as written.

Just wanted to put that out there, in case I did it wrong. I don't get any errors, the SUR works... it just doesn't use a different z-order.

jK, I tried gutting the display lists, and rendering in DrawWorld. That also doesn't work- apparently gl.Unit needs the display lists created by SUR. I see nothing at all- no shadow, no reflection, no nothing.


So... question... what are the pre and post DisplayLists? Why are there two, and what are they used for? I've tried disabling depth-testing on them- if I do it on Pre, it borks the rendering... on Post, it doesn't seem to do anything.
User avatar
jK
Spring Developer
Posts: 2299
Joined: 28 Jun 2007, 07:30

Re: Drawing Order

Post by jK »

Argh wrote:

Code: Select all

...
Unfortunately, it doesn't work as written.

Just wanted to put that out there, in case I did it wrong. I don't get any errors, the SUR works... it just doesn't use a different z-order.
As I said your assumptions are wrong!
order affects the draw order when you use SUR, but you aren't using SUR, you are using SetLuaUnitDraw! Also there isn't even a reason why to use the UnitDraw callin here.
Argh wrote:jK, I tried gutting the display lists, and rendering in DrawWorld. That also doesn't work- apparently gl.Unit needs the display lists created by SUR. I see nothing at all- no shadow, no reflection, no nothing.
already got the idea to buffer the DisplayList before, or just using a different command like those raw ones or as the wiki says use lod=-1?
Also I said you should replace the model pieces with empty displaylists, so you would have to use gl.UnitPiece ...
(option 2, didn't said anything about replacing display lists)
Argh wrote:So... question... what are the pre and post DisplayLists? Why are there two, and what are they used for? I've tried disabling depth-testing on them- if I do it on Pre, it borks the rendering... on Post, it doesn't seem to do anything.
just face palms (you should know what pre and post means and you should know what a DisplayList is)
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Re: Drawing Order

Post by Argh »

Basically, it sounds like this section's where the main problems are:

Code: Select all

local function MyUnitCrea(unitID,order)
		local unitDefID = sprGetUnitDefID(unitID)

		if (normalMapNames[unitDefID] ~= nil) then
			if (textureNames[unitDefID] == nil) then
				textureNames[unitDefID] = {
					[1] = '%' .. unitDefID .. ":0",
					[2] = '%' .. unitDefID .. ":1"
				}
			end

			--Spring.Echo("Found Unit",unitID)

			local preDL = GetPreDisplayList(unitID)
			local pstDL = GetPostDisplayList(unitID)

			SUR.SetLODCount(unitID, 1)
			SUR.SetMaterial(unitID, 1, "opaque", GetUnitDefMaterial(unitDefID, preDL, pstDL, order) )
			SUR.SetUnitLuaDraw(unitID, true)

			for pieceID, pieceName in pairs(Spring.GetUnitPieceList(unitID) or {}) do
				if (pieceID ~= "n") then
					SUR.SetPieceList(unitID, 1, pieceID)
				end
			end
		end
	end
If I comment out that SUR.SetUnitLuaDraw, then I don't see the shader at all.
order affects the draw order when you use SUR, but you aren't using SUR, you are using SetLuaUnitDraw!
It's Spring.UnitRendering.SetLuaUnitDraw... S.UR.

I'm confused. You're telling me not to use this?
already got the idea to buffer the DisplayList before, or just using a different command like those raw ones or as the wiki says use lod=-1?

Code: Select all

SUR.SetPieceList(unitID, -1, pieceID)
Results in nothing being drawn at all. No shadows, no reflectivity, nothing.

I assume that's a good idea- it means that we've side-stepped the entire Spring Unit rendering process. So... I'm going out on a limb, and assume that we can fetch that display list again somewhere else, and render it using gl.UnitPiece, in order of Pieces, and then in z-order of depth from POV in a DrawWorld loop?
Post Reply

Return to “Engine”