-- $Id: Jet.lua 3171 2008-11-06 09:06:29Z det $ ----------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------- local Jet = {} Jet.__index = Jet local jitShader local tex --//screencopy local timerUniform ----------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------- function Jet.GetInfo() return { name = "Jet", backup = "", --// backup class, if this class doesn't work (old cards,ati's,etc.) desc = "", layer = 4, --// extreme simply z-ordering :x --// gfx requirement fbo = true, shader = true, distortion= true, ms = -1, intel = -1, } end Jet.Default = { layer = 4, life = math.huge, repeatEffect = true, emitVector = {0,0,-1}, pos = {0,0,0}, --// not used width = 4, length = 50, distortion = 0.02, animSpeed = 1, texture1 = "bitmaps/GPL/Lups/perlin_noise.jpg", --// noise texture texture2 = ":c:bitmaps/GPL/Lups/jet.bmp", --// jitter shape } ----------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------- local spGetGameSeconds = Spring.GetGameSeconds local glUseShader = gl.UseShader local glUniform = gl.Uniform local glTexture = gl.Texture local glCallList = gl.CallList function Jet:BeginDrawDistortion() glUseShader(jitShader) glUniform(timerUniform, spGetGameSeconds()) end function Jet:EndDrawDistortion() glUseShader(0) glTexture(1,false) glTexture(2,false) end function Jet:DrawDistortion() glTexture(1,self.texture1) glTexture(2,self.texture2) glCallList(self.dList) end ----------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------- -- used if repeatEffect=true; function Jet:ReInitialize() self.dieGameFrame = self.dieGameFrame + self.life end function Jet.Initialize() jitShader = gl.CreateShader({ vertex = [[ uniform float timer; varying float distortion; varying vec4 texCoords; const vec4 centerPos = vec4(0.0,0.0,0.0,1.0); // gl_vertex.xy := width/length // gl_vertex.zw := texcoord // gl_MultiTexCoord0.x := (quad_width) / (quad_length) (used to normalize the texcoord dimensions) // gl_MultiTexCoord0.y := distortion strength // gl_MultiTexCoord0.z := animation speed // gl_MultiTexCoord1 := emit vector void main() { texCoords.st = gl_Vertex.pq; texCoords.pq = gl_Vertex.pq; texCoords.p *= gl_MultiTexCoord0.x; texCoords.pq += timer*gl_MultiTexCoord0.z; gl_Position = gl_ModelViewMatrix * centerPos; vec3 dir3 = vec3(gl_ModelViewMatrix * gl_MultiTexCoord1) - gl_Position.xyz; vec3 v = normalize( dir3 ); vec3 w = normalize( -vec3(gl_Position) ); vec3 u = normalize( cross(w,v) ); gl_Position.xyz += gl_Vertex.x*v + gl_Vertex.y*u; gl_Position = gl_ProjectionMatrix * gl_Position; distortion = gl_MultiTexCoord0.y; } ]], fragment = [[ uniform sampler2D noiseMap; uniform sampler2D mask; varying float distortion; varying vec4 texCoords; void main(void) { float opac = texture2D(mask,texCoords.st).r; vec2 noiseVec = (texture2D(noiseMap, texCoords.pq).st - 0.5) * distortion * opac; gl_FragColor = vec4(noiseVec.xy,0.0,gl_FragCoord.z); } ]], uniformInt = { noiseMap = 1, mask = 2, }, uniform = { timer = 0, } }) if (jitShader == nil) then print(PRIO_MAJOR,"LUPS->Jet: shader error: "..gl.GetShaderLog()) return false end timerUniform = gl.GetUniformLocation(jitShader, 'timer') end function Jet:Finalize() if (gl.DeleteShader) then gl.DeleteShader(jitShader) end end ----------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------- local glMultiTexCoord = gl.MultiTexCoord local glVertex = gl.Vertex local glCreateList = gl.CreateList local glDeleteList = gl.DeleteList local glBeginEnd = gl.BeginEnd local GL_QUADS = GL.QUADS local function BeginEndDrawList(self) local ev = self.emitVector glMultiTexCoord(0,self.width/self.length,self.distortion,0.2*self.animSpeed) glMultiTexCoord(1,ev[1],ev[2],ev[3],1) --// xy = width/length ; zw = texcoord local w = self.width local l = self.length glVertex(-l,-w, 1,0) glVertex(0, -w, 1,1) glVertex(0, w, 0,1) glVertex(-l, w, 0,0) end function Jet:CreateParticle() self.dList = glCreateList(glBeginEnd,GL_QUADS, BeginEndDrawList,self) --// used for visibility check self.radius = self.length self.dieGameFrame = thisGameFrame + self.life end ----------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------- local MergeTable = MergeTable local setmetatable = setmetatable function Jet.Create(Options) local newObject = MergeTable(Options, Jet.Default) setmetatable(newObject,Jet) -- make handle lookup newObject:CreateParticle() return newObject end function Jet:Destroy() --gl.DeleteTexture(self.texture1) --gl.DeleteTexture(self.texture2) glDeleteList(self.dList) end ----------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------- return Jet