cassius Posted October 16, 2011 Share Posted October 16, 2011 I have small objects in my game,some of which can be picked up by the player with a keypress. Whats the best way to highlight them to indicate which ones are pickupable? Quote amd quad core 4 ghz / geforce 660 ti 2gb / win 10 Blender,gimp,silo2,ac3d,,audacity,Hexagon / using c++ Link to comment Share on other sites More sharing options...
Canardia Posted October 16, 2011 Share Posted October 16, 2011 Coincidentally I'm looking for this too right now, because I need to highlight hovered function blocks in SuperFlow. I tried first EntityColor, but it doesn't seem to work with meshes which have a texture which is lacking the highlighted color component: for example a blue texture will be black when I try to color it red. Then I tried a load the mesh_diffuse_vertexgi.frag shader and put it on the model's material, and it kinda worked: the model was much brighter. I think next I will copy the vertexgi.frag shader and make it so that it can also highlight with a specific color, for example red. For this it seems I need to set the shader variable fragcolor to vec4(1,0,0,1) from code. Quote ■ Ryzen 9 ■ RX 6800M ■ 16GB ■ XF8 ■ Windows 11 ■ ■ Ultra ■ LE 2.5 ■ 3DWS 5.6 ■ Reaper ■ C/C++ ■ C# ■ Fortran 2008 ■ Story ■ ■ Homepage: https://canardia.com ■ Link to comment Share on other sites More sharing options...
cassius Posted October 16, 2011 Author Share Posted October 16, 2011 Interesting. I played morrowind recently and they highlight objects when you hold the mouse pointer over them. In my case I suppose I could ise speech like"Is that a key I see lying around here?" I have a microphone and am good at mimicking, but I would prefer highlighting. Quote amd quad core 4 ghz / geforce 660 ti 2gb / win 10 Blender,gimp,silo2,ac3d,,audacity,Hexagon / using c++ Link to comment Share on other sites More sharing options...
Canardia Posted October 16, 2011 Share Posted October 16, 2011 It seems the mesh_diffuse_bloom.frag shader can be used for highlighting. I made a mat file like: texture0="mat/blue.dds" texture2="mat/red.dds" So the highlighting will be done using the red.dds texture. Then I loaded the shader with: shader=LoadShader("abstract::mesh_diffuse.vert","abstract::mesh_diffuse_bloom.frag"); And then I can apply the shader to any model with: SetMaterialShader(mat,shader); And it looks like this: EDIT: Ah damn, of course then all models with that mat will be hightlighted I guess I will have to use EntityColor then, but make sure no textures are completely black on one color component. Interestestingly, if I make the texture with color 63,127,255, then a highlight with EntityColor(0.5,1,0.5,1) will be too dark green, but I can do EntityColor(0.5,2,0.5,1) and the green is bright enough. Quote ■ Ryzen 9 ■ RX 6800M ■ 16GB ■ XF8 ■ Windows 11 ■ ■ Ultra ■ LE 2.5 ■ 3DWS 5.6 ■ Reaper ■ C/C++ ■ C# ■ Fortran 2008 ■ Story ■ ■ Homepage: https://canardia.com ■ Link to comment Share on other sites More sharing options...
Wchris Posted October 16, 2011 Share Posted October 16, 2011 I have small objects in my game,some of which can be picked up by the player with a keypress. Whats the best way to highlight them to indicate which ones are pickupable? Hi cassius, For me the best way is to outiline the objects like in starcraft interface. i did something like this in the past but it's not trivial and took me way too much time to find out how to alone ... this should be 1 command in the engine that sets an entity as selected and accepts a parameter to define selection kind. program cubeoutline; {$ifdef FPC} {$mode delphi} {$endif} {$H+} uses Classes, SysUtils, LeadWerks; const FullScreenDefaultWidth = 800; FullScreenDefaultHeight = 600; OutLineDefaultLineWidth = 6.0; var Framework: TFramework = 0; Lua: Pointer; World: Tworld; Camera: TCamera; Light: TLight; Material: TMaterial; Mesh, Mesh2: TMesh; MeshVector: Tvec3; Ground: Tmesh; Outline_World_Buffer: TBuffer = 0; Mem_buffer: TBuffer = 0; Post_shader: TShader = 0; Outline_world: Tworld = 0; Outline_camera: Tcamera = 0; OutLineWidth: Single = OutLineDefaultLineWidth; key: integer; begin RegisterAbstractPath('D:\Program Files\Leadwerks Engine SDK 231'); SetAppTitle('Exemple1'); try // Set graphics mode if Graphics(FullScreenDefaultWidth, FullScreenDefaultHeight)=0 then Exception.Create('ERROR: Failed to create set graphics mode.'); // Create framewerk object and set it to a global object so other scripts can access it Framework := CreateFramework; if Framework=0 then Exception.Create('ERROR: Failed to create Framework'); if Framework<>0 then begin // Set Lua variable Lua := GetLuaState; lua_pushobject(Lua, pointer(Framework)); lua_setglobal(Lua, 'fw'); lua_pop(Lua, 1); end; World := GetLayerWorld(GetFrameworkLayer(0)); Camera := GetLayerCamera(GetFrameworkLayer(0)); PositionEntity(Camera, Vec3(0, 0, -2)); Light := CreateSpotLight(10); RotateEntity(Light, Vec3(45, 55, 0), 0); PositionEntity(Light, Vec3(5, 5, -5), 0); Light := CreateDirectionalLight(0); RotateEntity(Light, Vec3(45, 45, 45), 0); Material := LoadMaterial('abstract::cobblestones.mat'); Mesh := CreateCube; PaintEntity(Mesh, Material, 0); Ground := CreateCube; ScaleEntity(Ground, Vec3(10, 1, 10)); PositionEntity(Ground, Vec3(0, -2, 0), 0); PaintEntity(Ground, Material, 0); // Activate Framework Postfilter Effects if needed //SetAntialias(2); //SetDistanceFog(1); SetStats(2); //SetHDR(1); SetGodRays(1); SetBloom(1); //SetSSAO(1); //SetShadowQuality(3); Outline_world := CreateWorld; SetWorld(Outline_world); Outline_camera := CreateCamera; PositionEntity(Outline_camera, Vec3(0, 0, -2)); Mesh2 := CreateCube; Outline_World_Buffer := createbuffer(GraphicsWidth, GraphicsHeight, BUFFER_COLOR or BUFFER_DEPTH); if Outline_world=0 then Exception.Create('ERROR: Failed to create Outline_World_Buffer'); Post_shader := loadshader('', 'outline.frag'); if Post_shader=0 then Exception.Create('ERROR: Failed to create Post_shader'); SetWorld(World); Mem_buffer := currentBuffer; while (KeyHit(KEY_ESCAPE)=0) and (AppTerminate=0) do begin if AppSuspended=1 then UpdateApptime else begin TurnEntity(Mesh, Vec3(AppSpeed*0.5, AppSpeed*0.5, AppSpeed*0.5), 0); UpdateFramework; RenderFramework; MeshVector := EntityRotation(Mesh); SetWorld(Outline_world); SetBuffer(Outline_World_Buffer); RotateEntity(Mesh2, MeshVector); UpdateWorld; RenderWorld(ENTITY_MESH); SetWorld(World); key := GetChar; if keyhit(KEY_UP)=1 then begin freeBuffer(Outline_World_Buffer); if Graphics(round(GraphicsWidth * 1.1), round(GraphicsHeight * 1.1))=0 then Exception.Create('ERROR: Failed to create set graphics mode.'); Outline_World_Buffer := createbuffer(GraphicsWidth, GraphicsHeight, BUFFER_COLOR or BUFFER_DEPTH); if Outline_world=0 then Exception.Create('ERROR: Failed to create Outline_World_Buffer'); OutLineWidth := round(OutLineDefaultLineWidth * (GraphicsWidth/FullScreenDefaultWidth)); end else if keyhit(KEY_DOWN)=1 then begin freeBuffer(Outline_World_Buffer); if Graphics(round(GraphicsWidth / 1.1), round(GraphicsHeight / 1.1))=0 then Exception.Create('ERROR: Failed to create set graphics mode.'); Outline_World_Buffer := createbuffer(GraphicsWidth, GraphicsHeight, BUFFER_COLOR or BUFFER_DEPTH); if Outline_world=0 then Exception.Create('ERROR: Failed to create Outline_World_Buffer'); OutLineWidth := round(OutLineDefaultLineWidth * (GraphicsWidth/FullScreenDefaultWidth)); end else Leadwerks.DrawText(100, 100, chr(lo(key))); SetBuffer(backbuffer); SetShader(Post_shader); BindTexture(GetDepthBuffer(Outline_World_Buffer), 1); SetShaderVec4(Post_shader, 'color', Vec4(1,0,0,1)); SetShaderVec4(Post_shader, 'alphacolor', Vec4(1,0,1,0)); SetShaderFloat(Post_shader, 'linewidth', OutLineWidth); SetBlend(BLEND_ALPHA); DrawImage(GetColorBuffer(Outline_World_Buffer), 0, GraphicsHeight, GraphicsWidth, -GraphicsHeight); SetBlend(0); SetShader(0); SetBuffer(Mem_buffer); Flip(1); end; end; except on E: exception do begin Applog(PAnsiChar(' Exception occured ! '+E.message)); end; end; end. and the shader code uniform vec2 buffersize; void main( void ) { vec2 _texcoord = gl_FragCoord.xy/buffersize; vec2 _pixelsize = linewidth/buffersize; float _depth = texture2D( texture0, _texcoord ).x/2; if (_depth != 0) { gl_FragColor = alphacolor; } else { float tl = texture2D(texture0, _texcoord + vec2(-_pixelsize.x, -_pixelsize.y)).x; float tm = texture2D(texture0, _texcoord + vec2(0.0, -_pixelsize.y)).x; float tr = texture2D(texture0, _texcoord + vec2(+_pixelsize.x, -_pixelsize.y)).x; float ml = texture2D(texture0, _texcoord + vec2(-_pixelsize.x, 0.0)).x; float mm = 0; //texture2D(texture0, _texcoord).x; float mr = texture2D(texture0, _texcoord + vec2(+_pixelsize.x, 0.0)).x; float bl = texture2D(texture0, _texcoord + vec2(-_pixelsize.x, +_pixelsize.y)).x; float bm = texture2D(texture0, _texcoord + vec2(0.0, +_pixelsize.y)).x; float br = texture2D(texture0, _texcoord + vec2(+_pixelsize.x, +_pixelsize.y)).x; float dpt = tl+tm+tr+ml+mm+mr+bl+bm+br; if (dpt != 0) { gl_FragColor = color; } else { gl_FragColor = alphacolor; } } } Notice you'll have to resize the outline buffer manually if you change screen resolution. also with this method, if you want to select an animated entity, you'll have to animate it twice. But i'm pretty sure there's a way to do this without worlds, only with a shader. and even with a glow efect. but my shader knowledge is not good enought. Cheers Chris Quote Windows 7 home - 32 bits Intel Quad Q6600 - nVidia GTX 460 1GB - 2 GB RAM Link to comment Share on other sites More sharing options...
Pixel Perfect Posted October 16, 2011 Share Posted October 16, 2011 Chris's method above is certainly widely used in games these days although walking into a room where objects are highlighted or glow at you I've personally found annoying as it takes any skill out of the game (a bit like playing a game with a walk through guide in your hand). An alternative is to either highlight the object only when your cursor is over it, as you suggested, or in my pick/inventory interface I simply enable inspect and pick icons when the cursor (a hand in my case) is over a pickable/inspectable item as show below: Quote Intel Core i5 2.66 GHz, Asus P7P55D, 8Gb DDR3 RAM, GTX460 1Gb DDR5, Windows 7 (x64), LE Editor, GMax, 3DWS, UU3D Pro, Texture Maker Pro, Shader Map Pro. Development language: C/C++ Link to comment Share on other sites More sharing options...
cassius Posted October 16, 2011 Author Share Posted October 16, 2011 Thanks for the interesting answers.I don't want to make puzzles too easy as pixel said and I don't want to make this a big deal so I may just use a spotlight that comes on when player gets near an object.But only for the first object. the player comes across. Quote amd quad core 4 ghz / geforce 660 ti 2gb / win 10 Blender,gimp,silo2,ac3d,,audacity,Hexagon / using c++ Link to comment Share on other sites More sharing options...
cassius Posted October 16, 2011 Author Share Posted October 16, 2011 Yeah, a simple spotlight with an intesity of 3 works fine. Only 2 lines of simple code required. Quote amd quad core 4 ghz / geforce 660 ti 2gb / win 10 Blender,gimp,silo2,ac3d,,audacity,Hexagon / using c++ Link to comment Share on other sites More sharing options...
Rick Posted October 16, 2011 Share Posted October 16, 2011 Another play with the hightlighting using lighting could be to have the object in another world. When you mouse over it you hide the one in the base world and show the one in the highlighted world. You can then have a high ambient light in that world and it would stand out then. If you went this route creating a system to automatically do all of that on special objects would be ideal. This is sort of a world of warcraft deal as when you highlight things the lighting changes on the object to show it's highlighted. Quote Link to comment Share on other sites More sharing options...
macklebee Posted October 17, 2011 Share Posted October 17, 2011 using the fullbright shader would probably give the same results as that and wouldnt require an additional world and doubling of the objects. and nice one wchris... nice idea with alpha in the shader... works nice. Quote Win7 64bit / Intel i7-2600 CPU @ 3.9 GHz / 16 GB DDR3 / NVIDIA GeForce GTX 590 LE / 3DWS / BMX / Hexagon macklebee's channel Link to comment Share on other sites More sharing options...
Rick Posted October 17, 2011 Share Posted October 17, 2011 using the fullbright shader would probably give the same results as that and wouldnt require an additional world and doubling of the objects. Good call. If you had multiple instances of the model you wanted highlighted and applied the shader at run-time to one instance would they all get that shader applied? If so a possible side effect to the shader based methods. Quote Link to comment Share on other sites More sharing options...
macklebee Posted October 17, 2011 Share Posted October 17, 2011 true but as always it depends on what it is required in the game and the circumstances... personally i like the postprocess effect that wchris is showing as its been something i have tried in the past but could never figure out how to merge the post process toon shader of one world with another world together without issues... another thing that is done alot is to put particles or a corona flash on the object to bring attention to it... but it depends on the game and the intentions... for pixel's game it would make sense to not make it too easy for them to find the items they need to inspect, but for a game where you just want to highlight money dropped or weapons, a common effect across all instances would work fine. Quote Win7 64bit / Intel i7-2600 CPU @ 3.9 GHz / 16 GB DDR3 / NVIDIA GeForce GTX 590 LE / 3DWS / BMX / Hexagon macklebee's channel Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.