Rolplay Posted March 29, 2020 Share Posted March 29, 2020 Hi! I downloaded a mod, which have working indicator textures. This is the mod: https://www.gtainside.com/en/sanandreas/cars/139425-audi-a6-avant-2019-magyar-rend-rs-g/ That have a turned on .tga file ( named "p" and "l") on the tga file. The question: how can i use them? I mean, if i click on the right, the car turn on his right indicator. Link to comment
The_GTA Posted March 29, 2020 Share Posted March 29, 2020 (edited) Hello Rolplay, I have checked out the mod with Magic.TXD and the TXD does contain the following indicator textures named "p" and "l": In order to apply special effects to these textures I recommend using the engineApplyShaderToWorldTexture function with textures named "p" and "l". With this function you can multiply the color of the indicator lights to make it brighter or darker depending on your style But you have to know how to code in HLSL to do this. Learning shader languages is really worth it! Edited March 29, 2020 by The_GTA 1 Link to comment
Rolplay Posted March 29, 2020 Author Share Posted March 29, 2020 I didn't heard about HLSL. Can you show me an example please? I want to make like this: Link to comment
The_GTA Posted March 29, 2020 Share Posted March 29, 2020 (edited) I have hacked together a little HLSL sample script for you. It is up to you to actually implement indicator light logic to this: indicatorshader.fx texture Tex0; float4x4 World; float4x4 View; float4x4 Projection; float4x4 WorldViewProjection; float Time; sampler Sampler0 = sampler_state { Texture = (Tex0); }; struct VSInput { float3 Position : POSITION; float4 Diffuse : COLOR0; float2 TexCoord : TEXCOORD0; }; struct PSInput { float4 Diffuse : COLOR0; float2 TexCoord : TEXCOORD0; }; struct VSOutput { PSInput psInput; float4 Position : POSITION; }; VSOutput PassthroughVS(VSInput input) { VSOutput output; output.psInput.Diffuse = input.Diffuse; output.psInput.TexCoord = input.TexCoord; //-- Transform vertex position (You nearly always have to do something like this) output.Position = mul(float4(input.Position, 1), WorldViewProjection); return output; } float4 IndicatorMultiply(PSInput input) : COLOR0 { return float4(1, 1, 0, 1); } technique indicators { pass P0 { VertexShader = compile vs_2_0 PassthroughVS(); PixelShader = compile ps_2_0 IndicatorMultiply(); } }; client.Lua local vehicleTXD = engineLoadTXD("car.txd"); engineImportTXD(vehicleTXD, 400); local vehicleDFF = engineLoadDFF("car.dff", 400); engineReplaceModel(vehicleDFF, 400); local shader = dxCreateShader("indicatorshader.fx"); outputChatBox("Loaded indicator lights shader and car model!"); for m,n in ipairs(getElementsByType("vehicle")) do if (getElementModel(n) == 400) then engineApplyShaderToWorldTexture(shader, "p", n); engineApplyShaderToWorldTexture(shader, "l", n); end end As you can see the script uses the Landstalker vehicle as an example. Just spawn a Landstalker and start the resource. You should see the indicator lights in yellow color. Take a look at the MTA wiki to find out more about shaders. You can find really cool effects over there! Edited March 29, 2020 by The_GTA 1 1 Link to comment
Rolplay Posted March 29, 2020 Author Share Posted March 29, 2020 Thanks, i try this currently. I need to export "p" and "l" from the police txd, or the script find it and use it on landstalker? Link to comment
The_GTA Posted March 29, 2020 Share Posted March 29, 2020 (edited) 6 minutes ago, Rolplay said: Thanks, i try this currently. I need to export "p" and "l" from the police txd, or the script find it and use it on landstalker? The script just works if you put the car.dff (copcarla.dff) and car.txd (copcarla.txd) into the resource because "p" and "l" are inside of the car.txd file, like shown in Magic.TXD above. meta.xml <meta> <file src="indicatorshader.fx" type="client" /> <file src="car.dff" type="client" /> <file src="car.txd" type="client" /> <script src="client.Lua" type="client" /> </meta> Edited March 29, 2020 by The_GTA 1 Link to comment
Rolplay Posted March 29, 2020 Author Share Posted March 29, 2020 That's didn't work for me: https://imgur.com/a/SH1BEWw I try that, with an another model, an it worked. Thanks for helping!! Can i bind that to right and left click? Link to comment
The_GTA Posted March 29, 2020 Share Posted March 29, 2020 34 minutes ago, Rolplay said: That's didn't work for me: https://imgur.com/a/SH1BEWw I try that, with an another model, an it worked. Thanks for helping!! Can i bind that to right and left click? Sure! You can use the dxSetShaderValue function to set a float value "intensity" and define it as global in the HLSL script. Then you can multiply the color with it inside of the "IndicatorMultiply" pixel shader function. In your client.Lua script you set intensity to 0 if the indicator lights are disabled and to 1 if they are enabled. Use the bindKey function with the "vehicle_left" and "vehicle_right" controls in combination with the intensity shader variable to achieve that. I have not investigated which of "p" or "l" is the left or right indicator texture. I would be very thankful if you could investigate and answer this question for us. 1 Link to comment
Rolplay Posted March 29, 2020 Author Share Posted March 29, 2020 I checked it with texture name shader. "p" is hte right , and "l" is the left indicator Link to comment
Rolplay Posted March 29, 2020 Author Share Posted March 29, 2020 local vehicleTXD = engineLoadTXD("skodafinal.txd"); engineImportTXD(vehicleTXD, 597); myShader = dxCreateShader( "indicatorshader.fx" ) local vehicleDFF = engineLoadDFF("skodafinal.dff", 597); engineReplaceModel(vehicleDFF, 597); local shader = dxCreateShader("indicatorshader.fx"); outputChatBox("Loaded indicator lights shader and car model!"); function bindTurnIndicators(player) bindKey(player, "mouse1", "down", "vehicle_left") bindKey(player, "mouse2", "down", "vehicle_right") end for m,n in ipairs(getElementsByType("vehicle")) do if (getElementModel(n) == 597) then engineApplyShaderToWorldTexture(shader, "p", n); engineApplyShaderToWorldTexture(shader, "l", n); end end function vehicle_left dxSetShaderValue(myShader, "intensity", 1); end function vehicle_left dxSetShaderValue(myShader, "intensity", 0); end This is my Lua now. But i have an error: https://imgur.com/MI7v97c texture Tex0; float4x4 World; float4x4 View; float4x4 Projection; float4x4 WorldViewProjection; float Time; float intensity; sampler Sampler0 = sampler_state { Texture = (Tex0); }; struct VSInput { float3 Position : POSITION; float4 Diffuse : COLOR0; float2 TexCoord : TEXCOORD0; }; struct PSInput { float4 Diffuse : COLOR0; float2 TexCoord : TEXCOORD0; }; struct VSOutput { PSInput psInput; float4 Position : POSITION; }; VSOutput PassthroughVS(VSInput input) { VSOutput output; output.psInput.Diffuse = input.Diffuse; output.psInput.TexCoord = input.TexCoord; //-- Transform vertex position (You nearly always have to do something like this) output.Position = mul(float4(input.Position, 1), WorldViewProjection); return output; } float4 IndicatorMultiply(PSInput input) : COLOR0 { return float4(1, 1, 0, 1); } technique indicators { pass P0 { VertexShader = compile vs_2_0 PassthroughVS(); PixelShader = compile ps_2_0 IndicatorMultiply(); } }; And this is my shader now, i only add "float Intensity" string. Link to comment
The_GTA Posted March 30, 2020 Share Posted March 30, 2020 I am back after sleeping (GMT+1). So let's hook up your functions to a key bind, shall we? Here is the improved sample code: improved shader code: texture Tex0 < string textureState="0,Texture"; >; float4x4 World; float4x4 View; float4x4 Projection; float4x4 WorldViewProjection; float Time; float intensity = 0; sampler Sampler0 = sampler_state { Texture = (Tex0); }; struct VSInput { float3 Position : POSITION; float4 Diffuse : COLOR0; float2 TexCoord : TEXCOORD0; }; struct PSInput { float4 Diffuse : COLOR0; float2 TexCoord : TEXCOORD0; }; struct VSOutput { PSInput psInput; float4 Position : POSITION; }; VSOutput PassthroughVS(VSInput input) { VSOutput output; output.psInput.Diffuse = input.Diffuse; output.psInput.TexCoord = input.TexCoord; //-- Transform vertex position (You nearly always have to do something like this) output.Position = mul(float4(input.Position, 1), WorldViewProjection); return output; } float4 IndicatorMultiply(PSInput input) : COLOR0 { float4 texColor = tex2D(Sampler0, input.TexCoord); return texColor * intensity; } technique indicators { pass P0 { VertexShader = compile vs_2_0 PassthroughVS(); PixelShader = compile ps_2_0 IndicatorMultiply(); } }; client-side Lua code: local vehicleTXD = engineLoadTXD("car.txd"); engineImportTXD(vehicleTXD, 400); local vehicleDFF = engineLoadDFF("car.dff", 400); engineReplaceModel(vehicleDFF, 400); local shader_left = dxCreateShader("indicatorshader.fx"); local shader_right = dxCreateShader("indicatorshader.fx"); outputChatBox("Loaded indicator lights shader and car model!"); for m,n in ipairs(getElementsByType("vehicle")) do if (getElementModel(n) == 400) then engineApplyShaderToWorldTexture(shader_right, "p", n); engineApplyShaderToWorldTexture(shader_left, "l", n); end end -- Starting time in milliseconds for the indicators. local indicator_blink_duration_ms = 500; -- time in milliseconds that the indicator should blink. local indicator_left_on = false; -- is the left indicator on? local indicator_left_start; local indicator_right_on = false; local indicator_right_start; local function vehicle_left_down() indicator_left_on = true; indicator_left_start = getTickCount(); end bindKey("vehicle_left", "down", vehicle_left_down) local function vehicle_left_up() dxSetShaderValue(shader_left, "intensity", 0); indicator_left_on = false; end bindKey("vehicle_left", "up", vehicle_left_up) -- TODO: add key binds for the right indicator. addEventHandler("onClientRender", root, function() local now = getTickCount(); if (indicator_left_on) then local passed_time_ms = now - indicator_left_start; local period = 1 - math.floor(( passed_time_ms / indicator_blink_duration_ms ) % 2); -- TODO: write 1 to intensity if the blinker is on, write 0 if the blinker if off. -- the blinker is off if the variable "period" is 0, the blinker is on if it is 1. dxSetShaderValue(shader_left, "intensity", 1); end -- TODO: add the same for the right indicator. end ); -- TODO: make sure the logic is synchronized across clients. -- TODO: make sure that each vehicle has its own indicator blinking start time, on/off switch, shader; right now each vehicle shares the same indicator logic. I did some non-trivial improvement on the shader code so that it reads from the GTA:SA texture instead of a fixed color. Seeing that you have some trouble coding in Lua I have helped you out again. The Lua code is not done yet. There are several exercises left for you: how do you implement blinking to the left indicator? (easy) how do you implement the indicator light for the right indicators? (easy) how to synchronize the indicator lights across multiple game clients? (medium) how to allow indicator lights for each vehicle separately? (hard) Try doing the above exercises to finish your indicator lights script. I think that you should be able to do the first two points. If you have any trouble further down the line then feel free to ask 1 Link to comment
Rolplay Posted March 30, 2020 Author Share Posted March 30, 2020 Thanks for helping me out! I try to make this exercieses, and if i finished,i put a video here of the final version. 1 Link to comment
Rolplay Posted March 30, 2020 Author Share Posted March 30, 2020 I should make the blinking with a timer? I mean like this: if (indicator_right_on) then local passed_time_ms = now - indicator_right_start; local period = 1 - math.floor(( passed_time_ms / indicator_blink_duration_ms ) % 2); dxSetShaderValue(shader_right, "intensity", 1); setTimer ( period, 500, 0,0) end Link to comment
The_GTA Posted March 30, 2020 Share Posted March 30, 2020 (edited) 28 minutes ago, Rolplay said: I should make the blinking with a timer? I mean like this: No, you just have to replace the 1 within the original script with something more fitting. I don't want to give it away, it is the point of the exercise, it is really easy, but you have to understand how Lua scripting works. Let's say that I did the groundwork already. Hint #1: the variable period is a number that switches between 1 and 0 in 500ms time distances. Edited March 30, 2020 by The_GTA 1 Link to comment
Rolplay Posted March 30, 2020 Author Share Posted March 30, 2020 I'm done with blinking, your hint was very helpful . I have a little problem with separated indicator light, but i try to make it Link to comment
Rolplay Posted March 30, 2020 Author Share Posted March 30, 2020 I didn't find any solving for this two: how to synchronize the indicator lights across multiple game clients? (medium) how to allow indicator lights for each vehicle separately? (hard) Can you give me a hint again please? Link to comment
#\_oskar_/# Posted March 30, 2020 Share Posted March 30, 2020 (edited) myShader = [[ float Time : TIME; float4 color = float4(1,1,1,1); float4 GetColor() {float4 tColor = float4(cos(Time*7),cos(Time*7),cos(Time*7),255); return tColor * color;} technique tec0 { pass P0 { MaterialEmissive = GetColor(); EmissiveMaterialSource = Material; ColorOp[0] = SELECTARG1; ColorArg1[0] = Diffuse; Lighting = true; }} ]] local ID = 597 engineImportTXD(engineLoadTXD("car.txd"),ID) engineReplaceModel(engineLoadDFF("car.dff",ID),ID) --- local shader = dxCreateShader(myShader) function SetShaderApply(Apply,Remove,r,g,b) local Vehicle = getPedOccupiedVehicle ( getLocalPlayer() ) if ( Vehicle ) then if getElementModel(Vehicle) == ID then dxSetShaderValue(shader, 'color',r,g,b) engineRemoveShaderFromWorldTexture(shader,Remove,Vehicle ) engineApplyShaderToWorldTexture(shader,Apply,Vehicle ) end end end function left() SetShaderApply('l','p',255,0,0) end bindKey ("vehicle_left","both",left) function right() SetShaderApply('p','l',255,0,0) end bindKey ("vehicle_right","both",right) try this Edited March 30, 2020 by #\_oskar_/# Link to comment
Rolplay Posted March 30, 2020 Author Share Posted March 30, 2020 3 hours ago, #\_oskar_/# said: myShader = [[ float Time : TIME; float4 color = float4(1,1,1,1); float4 GetColor() {float4 tColor = float4(cos(Time*7),cos(Time*7),cos(Time*7),255); return tColor * color;} technique tec0 { pass P0 { MaterialEmissive = GetColor(); EmissiveMaterialSource = Material; ColorOp[0] = SELECTARG1; ColorArg1[0] = Diffuse; Lighting = true; }} ]] local ID = 597 engineImportTXD(engineLoadTXD("car.txd"),ID) engineReplaceModel(engineLoadDFF("car.dff",ID),ID) --- local shader = dxCreateShader(myShader) function SetShaderApply(Apply,Remove,r,g,b) local Vehicle = getPedOccupiedVehicle ( getLocalPlayer() ) if ( Vehicle ) then if getElementModel(Vehicle) == ID then dxSetShaderValue(shader, 'color',r,g,b) engineRemoveShaderFromWorldTexture(shader,Remove,Vehicle ) engineApplyShaderToWorldTexture(shader,Apply,Vehicle ) end end end function left() SetShaderApply('l','p',255,0,0) end bindKey ("vehicle_left","both",left) function right() SetShaderApply('p','l',255,0,0) end bindKey ("vehicle_right","both",right) try this Don't work for me :=( i try to copy getPedOccupiedVehicle, but i can't. I think i need to use getPedOccupiedVehicle function, but now i dont know how to. Link to comment
koragg Posted March 31, 2020 Share Posted March 31, 2020 Won't it be better to use one of these mods instead of using shaders? https://community.multitheftauto.com/index.php?p=resources&s=list&name=signal&descr=&category= Link to comment
Rolplay Posted March 31, 2020 Author Share Posted March 31, 2020 I don't think so, thats the point of the script. Link to comment
Rolplay Posted March 31, 2020 Author Share Posted March 31, 2020 I have the same problems now, i try to copy functions of @#\_oskar_/# 's script but my script is very different from it. I have this problems now: All players in the car can use the indicator(i binded the function to mouse1 and mouse2) Only visible for the localPlayer. If i use indicator on a car, all spawned cars turn on indicators. Link to comment
The_GTA Posted March 31, 2020 Share Posted March 31, 2020 (edited) On 30/03/2020 at 17:28, Rolplay said: I didn't find any solving for this two: how to synchronize the indicator lights across multiple game clients? (medium) how to allow indicator lights for each vehicle separately? (hard) Can you give me a hint again please? Hello Rolplay, I see that other people attempted to help by posting their own solutions to light indicators. While it is quite interesting, let's continue with the mentioned points: for this point you have to create a server-side Lua script! open up that meta.xml file and add the following line inside the <meta> node: <script src="server.Lua" type="server" /> Then you have to create a server.Lua file in the resource. If you want to synchronize data between the server and game client you have to use MTA events. The necessary functions for that are addEvent, addEventHandler, triggerServerEvent and triggerClientEvent. In the game client we have four actions: turning on the left/right indicator, turning off the left/right indicator. Thus we want to create events that represent those actions: onVehicleTurnOnIndicator, onVehicleTurnOffIndicator, onClientVehicleTurnOnIndicator, onClientVehicleTurnOffIndicator. Then we have to use triggerServerEvent with the mentioned event names as first argument to tell the server that the vehicle indicator light should turn on. Then the server can tell all players about the event using the onClient eventname. here we require more book-keeping than previously: for every vehicle we should store the parameters left indicator on, right indicator on, left indicator start time, right indicator start time, left indicator shader, right indicator shader (shaders only on the clientside). Thus we need to create a table called "vehicle_indicator_lights" on both the server-side and the client-side. Using the events we created in point 1 we write data directly into the table instead of global variables. Hopefully you can follow my points. Feel free to ask questions. If you don't get them done by the weekend I will help you out with the synchronization bit I am not available all the time due to work and social life. But if I am away from the forums it means that I will return to your issue as soon as possible! So don't let yourself get confused. Edited March 31, 2020 by The_GTA 1 Link to comment
Rolplay Posted March 31, 2020 Author Share Posted March 31, 2020 A question about the first: Quote In the game client we have four actions: turning on the left/right indicator, turning off the left/right indicator. Thus we want to create events that represent those actions: onVehicleTurnOnIndicator, onVehicleTurnOffIndicator, onClientVehicleTurnOnIndicator, onClientVehicleTurnOffIndicator. i need to create this 4 event at client side, and if i created, then i need to call this events with triggerClientEvent on server side? Link to comment
The_GTA Posted March 31, 2020 Share Posted March 31, 2020 22 minutes ago, Rolplay said: A question about the first: i need to create this 4 event at client side, and if i created, ... You create the first two on the clientside, the second two on the server-side. For example like this: client-side: addEvent("onClientVehicleTurnOnIndicator", true); addEventHandler("onClientVehicleTurnOnIndicator", root, function(indicator_side) -- source is the vehicle for which we turn on the indicator lights end ); addEvent("onClientVehicleTurnOffIndicator", true); addEventHandler("onClientVehicleTurnOffIndicator", root, function(indicator_side) -- similar to above. end ); The serverside should be made similar, but for the onVehicle version of events. 27 minutes ago, Rolplay said: then i need to call this events with triggerClientEvent on server side? For the onClient ones, yes. Link to comment
Rolplay Posted March 31, 2020 Author Share Posted March 31, 2020 14 minutes ago, The_GTA said: You create the first two on the clientside, the second two on the server-side. For example like this: client-side: addEvent("onClientVehicleTurnOnIndicator", true); addEventHandler("onClientVehicleTurnOnIndicator", root, function(indicator_side) -- source is the vehicle for which we turn on the indicator lights end ); addEvent("onClientVehicleTurnOffIndicator", true); addEventHandler("onClientVehicleTurnOffIndicator", root, function(indicator_side) -- similar to above. end ); The serverside should be made similar, but for the onVehicle version of events. For the onClient ones, yes. My serverside look like this now: addEvent("onVehicleTurnOnIndicator", true); addEventHandler("onVehicleTurnOnIndicator", root, function(rightindicator) local vehicle = getPedOccupiedVehicle (localPlayer) if vehicle then triggerClientEvent ( playerSource, "onClientVehicleTurnOnIndicator", playerSource) end end ); addEvent("onVehicleTurnOffIndicator", true); addEventHandler("onVehicleTurnOffIndicator", root, function(right_indicator) local vehicle = getPedOccupiedVehicle (localPlayer) if vehicle then triggerClientEvent ( playerSource, "onClientVehicleTurnOnIndicator", playerSource) end end ); Any my client side is like this: function left_indicator() --right side turn on and turn off function end addEventHandler("onClientRender", root, left_indicator) addEvent("onClientVehicleTurnOnIndicator", true); addEventHandler("onClientVehicleTurnOnIndicator", root, function(left_indicator) end ); addEvent("onClientVehicleTurnOffIndicator", true); addEventHandler("onClientVehicleTurnOffIndicator", root, function(left_indicator) end ); function right_indicator() --right side turn on and turn off function end addEventHandler("onClientRender", root, right_indicator) addEvent("onClientVehicleTurnOnIndicator", true); addEventHandler("onClientVehicleTurnOnIndicator", root, function(right_indicator) end ); addEvent("onClientVehicleTurnOffIndicator", true); addEventHandler("onClientVehicleTurnOffIndicator", root, function(right_indicator) end ); It is good? Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now