add code source
47
Source/CMakeLists.txt
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
CMAKE_MINIMUM_REQUIRED(VERSION 3.21)
|
||||||
|
|
||||||
|
PROJECT(Dyt)
|
||||||
|
|
||||||
|
option(USE_HOST_EVENT_LOOP
|
||||||
|
"Enable the integration of CEF message loop thread into host event loop"
|
||||||
|
OFF
|
||||||
|
)
|
||||||
|
|
||||||
|
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
|
||||||
|
set(OS_MAC 1)
|
||||||
|
set(OS_MACOSX 1) # For backwards compatibility.
|
||||||
|
set(OS_POSIX 1)
|
||||||
|
add_definitions(-DOS_MACOS=1 -DOS_POSIX=1)
|
||||||
|
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
|
||||||
|
set(OS_LINUX 1)
|
||||||
|
set(OS_POSIX 1)
|
||||||
|
add_definitions(-DOS_LINUX=1 -DOS_POSIX=1)
|
||||||
|
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
|
||||||
|
set(OS_WINDOWS 1)
|
||||||
|
add_definitions(-DOS_WINDOWS=1 -DNOMINMAX)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
MACRO(SOURCE_GROUP_BY_DIR SOURCE_FILES)
|
||||||
|
IF(MSVC)
|
||||||
|
set(sgbd_cur_dir ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
foreach(sgbd_file ${${SOURCE_FILES}})
|
||||||
|
string(REGEX REPLACE ${sgbd_cur_dir}/\(.*\) \\1 sgbd_fpath ${sgbd_file})
|
||||||
|
string(REGEX REPLACE "\(.*\)/.*" \\1 sgbd_group_name ${sgbd_fpath})
|
||||||
|
string(COMPARE EQUAL ${sgbd_fpath} ${sgbd_group_name} sgbd_nogroup)
|
||||||
|
string(REPLACE "/" "\\" sgbd_group_name ${sgbd_group_name})
|
||||||
|
if(sgbd_nogroup)
|
||||||
|
set(sgbd_group_name "\\")
|
||||||
|
endif(sgbd_nogroup)
|
||||||
|
source_group(${sgbd_group_name} FILES ${sgbd_file})
|
||||||
|
endforeach(sgbd_file)
|
||||||
|
ENDIF(MSVC)
|
||||||
|
ENDMACRO(SOURCE_GROUP_BY_DIR)
|
||||||
|
|
||||||
|
SET(Thirdparty ${CMAKE_CURRENT_SOURCE_DIR}/../Tool)
|
||||||
|
SET(ProjectDIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
|
||||||
|
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO")
|
||||||
|
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SAFESEH:NO")
|
||||||
|
SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /SAFESEH:NO")
|
||||||
|
|
||||||
|
ADD_SUBDIRECTORY(src src)
|
BIN
Source/resources/island/detail.png
Normal file
After Width: | Height: | Size: 576 KiB |
BIN
Source/resources/island/islands.ive
Normal file
BIN
Source/resources/island/moss.png
Normal file
After Width: | Height: | Size: 515 KiB |
BIN
Source/resources/island/sand.png
Normal file
After Width: | Height: | Size: 2.3 MiB |
83
Source/resources/shaders/osgOcean_dof_combiner.frag
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
#extension GL_ARB_texture_rectangle : enable
|
||||||
|
|
||||||
|
uniform sampler2DRect osgOcean_FullColourMap; // full resolution image
|
||||||
|
uniform sampler2DRect osgOcean_FullDepthMap; // full resolution depth map
|
||||||
|
uniform sampler2DRect osgOcean_BlurMap; // downsampled and filtered image
|
||||||
|
|
||||||
|
uniform vec2 osgOcean_ScreenRes;
|
||||||
|
uniform vec2 osgOcean_ScreenResInv;
|
||||||
|
uniform vec2 osgOcean_LowRes;
|
||||||
|
|
||||||
|
#define NUM_TAPS 4
|
||||||
|
|
||||||
|
// maximum CoC radius and diameter in pixels
|
||||||
|
const vec2 vMaxCoC = vec2(5.0,10);
|
||||||
|
|
||||||
|
// scale factor for maximum CoC size on low res. image
|
||||||
|
const float radiusScale = 0.4;
|
||||||
|
|
||||||
|
// contains poisson-distributed positions on the unit circle
|
||||||
|
vec2 poisson[8];
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
poisson[0] = vec2( 0.0, 0.0);
|
||||||
|
poisson[1] = vec2( 0.527837, -0.085868);
|
||||||
|
poisson[2] = vec2(-0.040088, 0.536087);
|
||||||
|
poisson[3] = vec2(-0.670445, -0.179949);
|
||||||
|
poisson[4] = vec2(-0.419418, -0.616039);
|
||||||
|
poisson[5] = vec2( 0.440453, -0.639399);
|
||||||
|
poisson[6] = vec2(-0.757088, 0.349334);
|
||||||
|
poisson[7] = vec2( 0.574619, 0.685879);
|
||||||
|
|
||||||
|
// pixel size (1/image resolution) of full resolution image
|
||||||
|
vec2 pixelSizeHigh = osgOcean_ScreenResInv;
|
||||||
|
|
||||||
|
// pixel size of low resolution image
|
||||||
|
vec2 pixelSizeLow = 4.0 * pixelSizeHigh;
|
||||||
|
|
||||||
|
vec4 color = texture2DRect( osgOcean_FullColourMap, gl_TexCoord[0].st ); // fetch center tap
|
||||||
|
// float centerDepth = color.a; // save its depth
|
||||||
|
float centerDepth = texture2DRect( osgOcean_FullDepthMap, gl_TexCoord[0].st ).r; // save its depth
|
||||||
|
|
||||||
|
// convert depth into blur radius in pixels
|
||||||
|
float discRadius = abs(centerDepth * vMaxCoC.y - vMaxCoC.x);
|
||||||
|
|
||||||
|
// compute disc radius on low-res image
|
||||||
|
float discRadiusLow = discRadius * radiusScale;
|
||||||
|
|
||||||
|
vec4 colorAccum = vec4(0.0);
|
||||||
|
float depthAccum = 0.0;
|
||||||
|
|
||||||
|
for(int t = 0; t < NUM_TAPS; t++)
|
||||||
|
{
|
||||||
|
vec2 coordHigh = gl_TexCoord[0].st + ( osgOcean_ScreenRes * (pixelSizeHigh * poisson[t] * discRadius ));
|
||||||
|
vec2 coordLow = gl_TexCoord[1].st + ( osgOcean_LowRes * (pixelSizeLow * poisson[t] * discRadiusLow ));
|
||||||
|
|
||||||
|
// fetch low-res tap
|
||||||
|
vec4 tapLow = texture2DRect( osgOcean_BlurMap, coordLow );
|
||||||
|
|
||||||
|
// fetch high-res tap
|
||||||
|
vec4 tapHigh = texture2DRect( osgOcean_FullColourMap, coordHigh );
|
||||||
|
|
||||||
|
float tapHighDepth = texture2DRect( osgOcean_FullDepthMap, coordHigh ).r;
|
||||||
|
|
||||||
|
// put tap blurriness into [0, 1] range
|
||||||
|
float tapBlur = abs(tapHighDepth * 2.0 - 1.0);
|
||||||
|
|
||||||
|
// mix low- and hi-res taps based on tap blurriness
|
||||||
|
vec4 tapColor = mix(tapHigh, tapLow, tapBlur);
|
||||||
|
|
||||||
|
// apply leaking reduction: lower weight for taps that are
|
||||||
|
// closer than the center tap and in focus
|
||||||
|
float tapDepth = (tapHighDepth >= centerDepth) ? 1.0 : abs(tapHighDepth * 2.0 - 1.0);
|
||||||
|
|
||||||
|
// accumulate
|
||||||
|
colorAccum += tapColor * tapDepth;
|
||||||
|
depthAccum += tapDepth;
|
||||||
|
}
|
||||||
|
|
||||||
|
// normalize and return result
|
||||||
|
gl_FragColor = colorAccum / depthAccum;
|
||||||
|
}
|
||||||
|
|
11
Source/resources/shaders/osgOcean_dof_combiner.vert
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
uniform vec2 osgOcean_ScreenRes;
|
||||||
|
uniform vec2 osgOcean_LowRes;
|
||||||
|
|
||||||
|
void main( void )
|
||||||
|
{
|
||||||
|
gl_TexCoord[0] = gl_MultiTexCoord0 * vec4( osgOcean_ScreenRes, 1.0, 1.0 );
|
||||||
|
gl_TexCoord[1] = gl_MultiTexCoord0 * vec4( osgOcean_LowRes, 1.0, 1.0 );
|
||||||
|
|
||||||
|
gl_Position = ftransform();
|
||||||
|
}
|
||||||
|
|
27
Source/resources/shaders/osgOcean_downsample.frag
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#extension GL_ARB_texture_rectangle : enable
|
||||||
|
|
||||||
|
uniform sampler2DRect osgOcean_ColorTexture;
|
||||||
|
|
||||||
|
const vec2 s1 = vec2(-1, 1);
|
||||||
|
const vec2 s2 = vec2( 1, 1);
|
||||||
|
const vec2 s3 = vec2( 1,-1);
|
||||||
|
const vec2 s4 = vec2(-1,-1);
|
||||||
|
|
||||||
|
void main( void )
|
||||||
|
{
|
||||||
|
vec2 texCoordSample = vec2(0.0);
|
||||||
|
|
||||||
|
texCoordSample = gl_TexCoord[0].st + s1;
|
||||||
|
vec4 color = texture2DRect(osgOcean_ColorTexture, texCoordSample);
|
||||||
|
|
||||||
|
texCoordSample = gl_TexCoord[0].st + s2;
|
||||||
|
color += texture2DRect(osgOcean_ColorTexture, texCoordSample);
|
||||||
|
|
||||||
|
texCoordSample = gl_TexCoord[0].st + s3;
|
||||||
|
color += texture2DRect(osgOcean_ColorTexture, texCoordSample);
|
||||||
|
|
||||||
|
texCoordSample = gl_TexCoord[0].st + s4;
|
||||||
|
color += texture2DRect(osgOcean_ColorTexture, texCoordSample);
|
||||||
|
|
||||||
|
gl_FragColor = color * 0.25;
|
||||||
|
}
|
5
Source/resources/shaders/osgOcean_downsample.vert
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
void main( void )
|
||||||
|
{
|
||||||
|
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||||
|
gl_Position = ftransform();
|
||||||
|
}
|
41
Source/resources/shaders/osgOcean_downsample_glare.frag
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#extension GL_ARB_texture_rectangle : enable
|
||||||
|
|
||||||
|
uniform sampler2DRect osgOcean_ColorTexture;
|
||||||
|
uniform sampler2DRect osgOcean_LuminanceTexture;
|
||||||
|
uniform float osgOcean_GlareThreshold;
|
||||||
|
|
||||||
|
const vec2 s1 = vec2(-1, 1);
|
||||||
|
const vec2 s2 = vec2( 1, 1);
|
||||||
|
const vec2 s3 = vec2( 1,-1);
|
||||||
|
const vec2 s4 = vec2(-1,-1);
|
||||||
|
|
||||||
|
void main( void )
|
||||||
|
{
|
||||||
|
vec2 texCoordSample = vec2(0.0);
|
||||||
|
|
||||||
|
texCoordSample = gl_TexCoord[0].st + s1;
|
||||||
|
vec4 color = texture2DRect(osgOcean_ColorTexture, texCoordSample);
|
||||||
|
float lum = texture2DRect(osgOcean_LuminanceTexture, texCoordSample).r;
|
||||||
|
|
||||||
|
texCoordSample = gl_TexCoord[0].st + s2;
|
||||||
|
color += texture2DRect(osgOcean_ColorTexture, texCoordSample);
|
||||||
|
lum += texture2DRect(osgOcean_LuminanceTexture, texCoordSample).r;
|
||||||
|
|
||||||
|
texCoordSample = gl_TexCoord[0].st + s3;
|
||||||
|
color += texture2DRect(osgOcean_ColorTexture, texCoordSample);
|
||||||
|
lum += texture2DRect(osgOcean_LuminanceTexture, texCoordSample).r;
|
||||||
|
|
||||||
|
texCoordSample = gl_TexCoord[0].st +s4;
|
||||||
|
color += texture2DRect(osgOcean_ColorTexture, texCoordSample);
|
||||||
|
lum += texture2DRect(osgOcean_LuminanceTexture, texCoordSample).r;
|
||||||
|
|
||||||
|
color = color*0.25;
|
||||||
|
lum = lum*0.25;
|
||||||
|
|
||||||
|
// only want very high luminance values to pass otherwise
|
||||||
|
// we get streaks all over the scene
|
||||||
|
if(lum >= osgOcean_GlareThreshold)
|
||||||
|
gl_FragColor = color;
|
||||||
|
else
|
||||||
|
gl_FragColor = vec4(0.0);
|
||||||
|
}
|
5
Source/resources/shaders/osgOcean_gaussian.vert
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||||
|
gl_Position = ftransform();
|
||||||
|
}
|
19
Source/resources/shaders/osgOcean_gaussian1.frag
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#extension GL_ARB_texture_rectangle : enable
|
||||||
|
|
||||||
|
uniform sampler2DRect osgOcean_GaussianTexture;
|
||||||
|
|
||||||
|
void main( void )
|
||||||
|
{
|
||||||
|
vec2 texCoordSample = vec2( 0.0 );
|
||||||
|
|
||||||
|
vec4 color = 0.5 * texture2DRect( osgOcean_GaussianTexture, gl_TexCoord[0].st );
|
||||||
|
|
||||||
|
texCoordSample.x = gl_TexCoord[0].x;
|
||||||
|
texCoordSample.y = gl_TexCoord[0].y + 1.0;
|
||||||
|
color += 0.25 * texture2DRect( osgOcean_GaussianTexture, texCoordSample);
|
||||||
|
|
||||||
|
texCoordSample.y = gl_TexCoord[0].y - 1.0;
|
||||||
|
color += 0.25 * texture2DRect( osgOcean_GaussianTexture, texCoordSample);
|
||||||
|
|
||||||
|
gl_FragColor = color;
|
||||||
|
}
|
19
Source/resources/shaders/osgOcean_gaussian2.frag
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#extension GL_ARB_texture_rectangle : enable
|
||||||
|
|
||||||
|
uniform sampler2DRect osgOcean_GaussianTexture;
|
||||||
|
|
||||||
|
void main( void )
|
||||||
|
{
|
||||||
|
vec2 texCoordSample = vec2( 0.0 );
|
||||||
|
|
||||||
|
vec4 color = 0.5 * texture2DRect(osgOcean_GaussianTexture, gl_TexCoord[0].st );
|
||||||
|
|
||||||
|
texCoordSample.y = gl_TexCoord[0].y;
|
||||||
|
texCoordSample.x = gl_TexCoord[0].x + 1.0;
|
||||||
|
color += 0.25 * texture2DRect(osgOcean_GaussianTexture, texCoordSample);
|
||||||
|
|
||||||
|
texCoordSample.x = gl_TexCoord[0].x - 1.0;
|
||||||
|
color += 0.25 * texture2DRect(osgOcean_GaussianTexture, texCoordSample);
|
||||||
|
|
||||||
|
gl_FragColor = color;
|
||||||
|
}
|
20
Source/resources/shaders/osgOcean_glare_composite.frag
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#extension GL_ARB_texture_rectangle : enable
|
||||||
|
|
||||||
|
uniform sampler2DRect osgOcean_ColorBuffer;
|
||||||
|
uniform sampler2DRect osgOcean_StreakBuffer1;
|
||||||
|
uniform sampler2DRect osgOcean_StreakBuffer2;
|
||||||
|
uniform sampler2DRect osgOcean_StreakBuffer3;
|
||||||
|
uniform sampler2DRect osgOcean_StreakBuffer4;
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
vec4 fullColor = texture2DRect(osgOcean_ColorBuffer, gl_TexCoord[0].st );
|
||||||
|
vec4 streakColor1 = texture2DRect(osgOcean_StreakBuffer1, gl_TexCoord[1].st );
|
||||||
|
vec4 streakColor2 = texture2DRect(osgOcean_StreakBuffer2, gl_TexCoord[1].st );
|
||||||
|
vec4 streakColor3 = texture2DRect(osgOcean_StreakBuffer3, gl_TexCoord[1].st );
|
||||||
|
vec4 streakColor4 = texture2DRect(osgOcean_StreakBuffer4, gl_TexCoord[1].st );
|
||||||
|
|
||||||
|
vec4 streak = streakColor1+streakColor2+streakColor3+streakColor4;
|
||||||
|
|
||||||
|
gl_FragColor = streak+fullColor;
|
||||||
|
}
|
7
Source/resources/shaders/osgOcean_glare_composite.vert
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||||
|
gl_TexCoord[1] = gl_MultiTexCoord0 * vec4(0.25,0.25,1.0,1.0);
|
||||||
|
|
||||||
|
gl_Position = ftransform();
|
||||||
|
}
|
10
Source/resources/shaders/osgOcean_godray_glare.frag
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
uniform sampler2D osgOcean_GlareTexture;
|
||||||
|
|
||||||
|
varying vec3 vIntensity;
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
vec3 color = texture2D( osgOcean_GlareTexture, gl_TexCoord[0].st ).rgb;
|
||||||
|
|
||||||
|
gl_FragColor = vec4((vIntensity*color.r)*1.5, 1.0 );
|
||||||
|
}
|
22
Source/resources/shaders/osgOcean_godray_glare.vert
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
uniform vec3 osgOcean_Origin;
|
||||||
|
uniform vec3 osgOcean_Extinction_c;
|
||||||
|
uniform vec3 osgOcean_Eye;
|
||||||
|
uniform float osgOcean_Spacing;
|
||||||
|
|
||||||
|
varying vec3 vIntensity;
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||||
|
|
||||||
|
vec3 worldPos = gl_Vertex.xyz * vec3(osgOcean_Spacing,osgOcean_Spacing,1.0);
|
||||||
|
worldPos += osgOcean_Origin;
|
||||||
|
|
||||||
|
vec3 extinct = vec3(0.2,0.2,0.2);
|
||||||
|
|
||||||
|
float totalDist = length(worldPos-osgOcean_Eye)/3.0;
|
||||||
|
vIntensity = exp(-totalDist*osgOcean_Extinction_c);
|
||||||
|
vIntensity = clamp(vIntensity, 0.0, 1.0);
|
||||||
|
|
||||||
|
gl_Position = gl_ModelViewProjectionMatrix * vec4(worldPos,1.0);
|
||||||
|
}
|
55
Source/resources/shaders/osgOcean_godray_screen_blend.frag
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
uniform sampler2DRect osgOcean_GodRayTexture;
|
||||||
|
|
||||||
|
uniform vec3 osgOcean_SunDir;
|
||||||
|
uniform vec3 osgOcean_HGg; // Eccentricity constants controls power of forward scattering
|
||||||
|
uniform float osgOcean_Intensity; // Intensity tweak for god rays
|
||||||
|
uniform vec3 osgOcean_Eye;
|
||||||
|
|
||||||
|
varying vec3 vRay;
|
||||||
|
|
||||||
|
const float bias = 0.15; // used to hide aliasing
|
||||||
|
|
||||||
|
// Mie phase function
|
||||||
|
float computeMie(vec3 viewDir, vec3 sunDir)
|
||||||
|
{
|
||||||
|
float num = osgOcean_HGg.x;
|
||||||
|
float den = (osgOcean_HGg.y - osgOcean_HGg.z*dot(sunDir, viewDir));
|
||||||
|
den = inversesqrt(den);
|
||||||
|
|
||||||
|
float phase = num * (den*den*den);
|
||||||
|
|
||||||
|
return phase;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------
|
||||||
|
// Main Program
|
||||||
|
// ----------------------------------------------
|
||||||
|
|
||||||
|
void main( void )
|
||||||
|
{
|
||||||
|
vec4 shafts;
|
||||||
|
|
||||||
|
// average the pixels out a little to hide aliasing
|
||||||
|
// TODO: Maybe try a weak blur filter
|
||||||
|
shafts += texture2DRect(osgOcean_GodRayTexture, gl_TexCoord[1].xy);
|
||||||
|
shafts += texture2DRect(osgOcean_GodRayTexture, gl_TexCoord[1].zw);
|
||||||
|
shafts += texture2DRect(osgOcean_GodRayTexture, gl_TexCoord[2].xy);
|
||||||
|
shafts += texture2DRect(osgOcean_GodRayTexture, gl_TexCoord[2].zw);
|
||||||
|
|
||||||
|
shafts /= 4.0;
|
||||||
|
|
||||||
|
vec3 rayNormalised = normalize(vRay-osgOcean_Eye);
|
||||||
|
|
||||||
|
float phase = computeMie(rayNormalised, -osgOcean_SunDir);
|
||||||
|
|
||||||
|
// Calculate final color, adding a little bias (0.15 here)
|
||||||
|
// to hide aliasing
|
||||||
|
vec3 colour = (bias+osgOcean_Intensity*shafts.rgb)*phase;
|
||||||
|
|
||||||
|
vec3 ray = ( rayNormalised + vec3(1.0) ) / 2.0;
|
||||||
|
|
||||||
|
gl_FragColor = vec4(colour, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
15
Source/resources/shaders/osgOcean_godray_screen_blend.vert
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
varying vec3 vRay;
|
||||||
|
|
||||||
|
void main( void )
|
||||||
|
{
|
||||||
|
gl_Position = gl_Vertex;
|
||||||
|
|
||||||
|
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||||
|
|
||||||
|
gl_TexCoord[1].xy = gl_TexCoord[0].st;
|
||||||
|
gl_TexCoord[1].zw = gl_TexCoord[0].st + vec2(1.0, 0.0);
|
||||||
|
gl_TexCoord[2].xy = gl_TexCoord[0].st + vec2(1.0, 1.0);
|
||||||
|
gl_TexCoord[2].zw = gl_TexCoord[0].st + vec2(0.0, 1.0);
|
||||||
|
|
||||||
|
vRay = gl_Normal;
|
||||||
|
}
|
6
Source/resources/shaders/osgOcean_godrays.frag
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
varying vec3 vIntensity;
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
gl_FragColor = vec4(vIntensity,1.0);
|
||||||
|
}
|
88
Source/resources/shaders/osgOcean_godrays.vert
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
const int NUM_WAVES = 16;
|
||||||
|
|
||||||
|
uniform vec3 osgOcean_Origin; // central position of vertices - sun position on water surface
|
||||||
|
uniform vec3 osgOcean_Extinction_c; // extinction coefficient
|
||||||
|
uniform vec3 osgOcean_Eye; // Eye position in world space
|
||||||
|
uniform vec3 osgOcean_SunDir; // sunlight direction
|
||||||
|
uniform float osgOcean_Spacing; // spacing between vertices
|
||||||
|
uniform float osgOcean_Waves[NUM_WAVES * 5]; // wave constants
|
||||||
|
|
||||||
|
varying vec3 vIntensity;
|
||||||
|
|
||||||
|
float fastFresnel(vec3 I, vec3 N, float r0)
|
||||||
|
{
|
||||||
|
return r0 + (1.0-r0) * pow(1.0-dot(I, N), 5.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 calculateWaterNormal(float x0, float y0)
|
||||||
|
{
|
||||||
|
vec3 t1 = vec3(1.0,0.0,0.0);
|
||||||
|
vec3 t2 = vec3(0.0,1.0,0.0);
|
||||||
|
|
||||||
|
int itr = NUM_WAVES/4;
|
||||||
|
|
||||||
|
for (int i = 0, j = 0; i < itr; i++, j += 20)
|
||||||
|
{
|
||||||
|
vec4 kx = vec4( osgOcean_Waves[j+0], osgOcean_Waves[j+1], osgOcean_Waves[j+2], osgOcean_Waves[j+3] );
|
||||||
|
vec4 ky = vec4( osgOcean_Waves[j+4], osgOcean_Waves[j+5], osgOcean_Waves[j+6], osgOcean_Waves[j+7] );
|
||||||
|
vec4 Ainvk = vec4( osgOcean_Waves[j+8], osgOcean_Waves[j+9], osgOcean_Waves[j+10], osgOcean_Waves[j+11] );
|
||||||
|
vec4 A = vec4( osgOcean_Waves[j+12], osgOcean_Waves[j+13], osgOcean_Waves[j+14], osgOcean_Waves[j+15] );
|
||||||
|
vec4 wt = vec4( osgOcean_Waves[j+16], osgOcean_Waves[j+17], osgOcean_Waves[j+18], osgOcean_Waves[j+19] );
|
||||||
|
vec4 phase = (kx*x0 + ky*y0 - wt);
|
||||||
|
vec4 sinp, cosp;
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
sinp = sin(phase);
|
||||||
|
cosp = cos(phase);
|
||||||
|
#else
|
||||||
|
sincos(phase, sinp, cosp);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Update tangent vector along x0
|
||||||
|
t1.x -= dot(Ainvk, kx*cosp*kx);
|
||||||
|
t1.y -= dot(Ainvk, ky*cosp*kx);
|
||||||
|
t1.z += dot(A, (-sinp)*(kx));
|
||||||
|
|
||||||
|
// Update tangent vector along y0
|
||||||
|
t2.x -= dot(Ainvk, kx*cosp*ky);
|
||||||
|
t2.y -= dot(Ainvk, ky*cosp*ky);
|
||||||
|
t2.z += dot(A, (-sinp)*(ky));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate and return normal
|
||||||
|
return normalize( cross(t1, t2) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||||
|
|
||||||
|
// Scale and translate the vertex on the water surface
|
||||||
|
vec3 worldPos = gl_Vertex.xyz * vec3(osgOcean_Spacing,osgOcean_Spacing,1.0);
|
||||||
|
worldPos += osgOcean_Origin;
|
||||||
|
|
||||||
|
// Calculate the water normal at this point
|
||||||
|
vec3 normal = calculateWaterNormal(worldPos.x, worldPos.y);
|
||||||
|
|
||||||
|
// Calculate transmittance
|
||||||
|
// BUG: makes intensity too small not sure why.
|
||||||
|
float transmittance = 1.0-fastFresnel(-osgOcean_SunDir, normal, 0.0204);
|
||||||
|
|
||||||
|
// Extrude bottom vertices along the direction of the refracted
|
||||||
|
// sunlight
|
||||||
|
if (gl_TexCoord[0].s > 0.0)
|
||||||
|
{
|
||||||
|
// Calculate refraction vector and extrude polygon
|
||||||
|
vec3 refr = refract(osgOcean_SunDir, normal, 0.75);
|
||||||
|
worldPos += refr*gl_TexCoord[0].s;
|
||||||
|
}
|
||||||
|
// Set intensity so that the further away you go from the surface
|
||||||
|
float totalDist = gl_TexCoord[0].s + length(worldPos-osgOcean_Eye);
|
||||||
|
vIntensity = exp(-totalDist*osgOcean_Extinction_c)*transmittance;
|
||||||
|
vIntensity = clamp(vIntensity, 0.0, 0.06);
|
||||||
|
|
||||||
|
// Transform position from world to clip space
|
||||||
|
gl_Position = gl_ModelViewProjectionMatrix * vec4(worldPos, 1.0 );
|
||||||
|
// Tweak z position not to clip shafts very close to the viewer
|
||||||
|
gl_Position.z = 0.01;
|
||||||
|
}
|
16
Source/resources/shaders/osgOcean_heightmap.frag
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// osgOcean uniforms
|
||||||
|
// -------------------
|
||||||
|
uniform float osgOcean_WaterHeight;
|
||||||
|
// -------------------
|
||||||
|
|
||||||
|
varying vec4 vWorldVertex;
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
// Store the water depth
|
||||||
|
// maximum possible depth is 500,
|
||||||
|
// (a higher water depth value would not have a visible effect anyway)
|
||||||
|
gl_FragDepth = clamp((osgOcean_WaterHeight - vWorldVertex.z) / 500.0, 0.0, 1.0);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
24
Source/resources/shaders/osgOcean_heightmap.vert
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// osgOcean uniforms
|
||||||
|
// -------------------
|
||||||
|
uniform float osgOcean_WaterHeight;
|
||||||
|
// ------------------
|
||||||
|
|
||||||
|
uniform mat4 osg_ViewMatrixInverse;
|
||||||
|
uniform mat4 osg_ViewMatrix;
|
||||||
|
|
||||||
|
varying vec4 vWorldVertex;
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
// Transform the vertex into world space
|
||||||
|
vWorldVertex = (osg_ViewMatrixInverse * gl_ModelViewMatrix) * gl_Vertex;
|
||||||
|
vWorldVertex.xyzw /= vWorldVertex.w;
|
||||||
|
|
||||||
|
// Project the vertex onto the ocean plane
|
||||||
|
vec4 projectedVertex = vWorldVertex;
|
||||||
|
projectedVertex.z = osgOcean_WaterHeight;
|
||||||
|
|
||||||
|
gl_Position = (gl_ProjectionMatrix * osg_ViewMatrix) * projectedVertex;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
124
Source/resources/shaders/osgOcean_ocean_scene.frag
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
// osgOcean Uniforms
|
||||||
|
// -----------------
|
||||||
|
uniform float osgOcean_DOF_Near;
|
||||||
|
uniform float osgOcean_DOF_Focus;
|
||||||
|
uniform float osgOcean_DOF_Far;
|
||||||
|
uniform float osgOcean_DOF_Clamp;
|
||||||
|
|
||||||
|
uniform float osgOcean_UnderwaterFogDensity;
|
||||||
|
uniform float osgOcean_AboveWaterFogDensity;
|
||||||
|
uniform vec4 osgOcean_UnderwaterFogColor;
|
||||||
|
uniform vec4 osgOcean_AboveWaterFogColor;
|
||||||
|
|
||||||
|
uniform float osgOcean_WaterHeight;
|
||||||
|
|
||||||
|
uniform bool osgOcean_EnableGlare;
|
||||||
|
uniform bool osgOcean_EnableDOF;
|
||||||
|
uniform bool osgOcean_EyeUnderwater;
|
||||||
|
uniform bool osgOcean_EnableUnderwaterScattering;
|
||||||
|
// -------------------
|
||||||
|
|
||||||
|
uniform sampler2D uTextureMap;
|
||||||
|
|
||||||
|
varying vec3 vExtinction;
|
||||||
|
varying vec3 vInScattering;
|
||||||
|
varying vec3 vNormal;
|
||||||
|
varying vec3 vLightDir;
|
||||||
|
varying vec3 vEyeVec;
|
||||||
|
|
||||||
|
varying float vWorldHeight;
|
||||||
|
|
||||||
|
float computeDepthBlur(float depth, float focus, float near, float far, float clampval )
|
||||||
|
{
|
||||||
|
float f;
|
||||||
|
if (depth < focus){
|
||||||
|
f = (depth - focus)/(focus - near);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
f = (depth - focus)/(far - focus);
|
||||||
|
f = clamp(f, 0.0, clampval);
|
||||||
|
}
|
||||||
|
return f * 0.5 + 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 lighting( vec4 colormap )
|
||||||
|
{
|
||||||
|
vec4 final_color = gl_LightSource[osgOcean_LightID].ambient * colormap;
|
||||||
|
|
||||||
|
vec3 N = normalize(vNormal);
|
||||||
|
vec3 L = normalize(vLightDir);
|
||||||
|
|
||||||
|
float lambertTerm = dot(N,L);
|
||||||
|
|
||||||
|
if(lambertTerm > 0.0)
|
||||||
|
{
|
||||||
|
final_color += gl_LightSource[osgOcean_LightID].diffuse * lambertTerm * colormap;
|
||||||
|
|
||||||
|
vec3 E = normalize(vEyeVec);
|
||||||
|
vec3 R = reflect(-L, N);
|
||||||
|
|
||||||
|
float specular = pow( max(dot(R, E), 0.0), 2.0 );
|
||||||
|
|
||||||
|
final_color += gl_LightSource[osgOcean_LightID].specular * specular;
|
||||||
|
}
|
||||||
|
|
||||||
|
return final_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
float computeFogFactor( float density, float fogCoord )
|
||||||
|
{
|
||||||
|
return exp2(density * fogCoord * fogCoord );
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
vec4 final_color;
|
||||||
|
|
||||||
|
vec4 textureColor = texture2D( uTextureMap, gl_TexCoord[0].st );
|
||||||
|
|
||||||
|
// Underwater
|
||||||
|
// +2 tweak here as waves peak above average wave height,
|
||||||
|
// and surface fog becomes visible.
|
||||||
|
if(osgOcean_EyeUnderwater && vWorldHeight < osgOcean_WaterHeight+2.0 )
|
||||||
|
{
|
||||||
|
final_color = lighting( textureColor );
|
||||||
|
|
||||||
|
// mix in underwater light
|
||||||
|
if(osgOcean_EnableUnderwaterScattering)
|
||||||
|
{
|
||||||
|
final_color.rgb = final_color.rgb * vExtinction + vInScattering;
|
||||||
|
}
|
||||||
|
|
||||||
|
float fogFactor = computeFogFactor( osgOcean_UnderwaterFogDensity, gl_FogFragCoord );
|
||||||
|
|
||||||
|
// write to depth buffer (actually a GL_LUMINANCE)
|
||||||
|
if(osgOcean_EnableDOF)
|
||||||
|
{
|
||||||
|
float depth = computeDepthBlur(gl_FogFragCoord, osgOcean_DOF_Focus, osgOcean_DOF_Near, osgOcean_DOF_Far, osgOcean_DOF_Clamp);
|
||||||
|
gl_FragData[1] = vec4(depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
// color buffer
|
||||||
|
gl_FragData[0] = mix( osgOcean_UnderwaterFogColor, final_color, fogFactor );
|
||||||
|
}
|
||||||
|
// Above water
|
||||||
|
else
|
||||||
|
{
|
||||||
|
final_color = lighting( textureColor );
|
||||||
|
|
||||||
|
float fogFactor = computeFogFactor( osgOcean_AboveWaterFogDensity, gl_FogFragCoord );
|
||||||
|
final_color = mix( osgOcean_AboveWaterFogColor, final_color, fogFactor );
|
||||||
|
|
||||||
|
// write to luminance buffer
|
||||||
|
// might not need the IF here, glsl compiler doesn't complain if
|
||||||
|
// you try and write to a FragData index that doesn't exist. But since
|
||||||
|
// Mac GLSL support seems so fussy I'll leave it in.
|
||||||
|
if(osgOcean_EnableGlare)
|
||||||
|
{
|
||||||
|
gl_FragData[1] = vec4(0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// write to color buffer
|
||||||
|
gl_FragData[0] = final_color;
|
||||||
|
}
|
||||||
|
}
|
49
Source/resources/shaders/osgOcean_ocean_scene.vert
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// osgOcean Uniforms
|
||||||
|
// -----------------
|
||||||
|
uniform mat4 osg_ViewMatrixInverse;
|
||||||
|
uniform float osgOcean_WaterHeight;
|
||||||
|
uniform vec3 osgOcean_Eye;
|
||||||
|
uniform vec3 osgOcean_UnderwaterAttenuation;
|
||||||
|
uniform vec4 osgOcean_UnderwaterDiffuse;
|
||||||
|
uniform bool osgOcean_EnableUnderwaterScattering;
|
||||||
|
// -----------------
|
||||||
|
|
||||||
|
varying vec3 vExtinction;
|
||||||
|
varying vec3 vInScattering;
|
||||||
|
|
||||||
|
varying vec3 vNormal;
|
||||||
|
varying vec3 vLightDir;
|
||||||
|
varying vec3 vEyeVec;
|
||||||
|
varying float vWorldHeight;
|
||||||
|
|
||||||
|
void computeScattering( in vec3 eye, in vec3 worldVertex, out vec3 extinction, out vec3 inScattering )
|
||||||
|
{
|
||||||
|
float viewDist = length(eye-worldVertex);
|
||||||
|
|
||||||
|
float depth = max(osgOcean_WaterHeight-worldVertex.z, 0.0);
|
||||||
|
|
||||||
|
extinction = exp(-osgOcean_UnderwaterAttenuation*viewDist*2.0);
|
||||||
|
|
||||||
|
// Need to compute accurate kd constant.
|
||||||
|
// const vec3 kd = vec3(0.001, 0.001, 0.001);
|
||||||
|
inScattering = osgOcean_UnderwaterDiffuse.rgb * (1.0-extinction*exp(-depth*vec3(0.001)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||||
|
gl_Position = ftransform();
|
||||||
|
gl_FogFragCoord = gl_Position.z;
|
||||||
|
gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex; // for reflections
|
||||||
|
|
||||||
|
vNormal = gl_NormalMatrix * gl_Normal;
|
||||||
|
vLightDir = gl_LightSource[osgOcean_LightID].position.xyz;
|
||||||
|
vEyeVec = -vec3(gl_ModelViewMatrix*gl_Vertex);
|
||||||
|
|
||||||
|
vec4 worldVertex = (osg_ViewMatrixInverse*gl_ModelViewMatrix) * gl_Vertex;
|
||||||
|
|
||||||
|
if (osgOcean_EnableUnderwaterScattering)
|
||||||
|
computeScattering( osgOcean_Eye, worldVertex.xyz, vExtinction, vInScattering);
|
||||||
|
|
||||||
|
vWorldHeight = worldVertex.z;
|
||||||
|
}
|
128
Source/resources/shaders/osgOcean_ocean_scene_lispsm.frag
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
// osgOcean Uniforms
|
||||||
|
// -----------------
|
||||||
|
uniform float osgOcean_DOF_Near;
|
||||||
|
uniform float osgOcean_DOF_Focus;
|
||||||
|
uniform float osgOcean_DOF_Far;
|
||||||
|
uniform float osgOcean_DOF_Clamp;
|
||||||
|
|
||||||
|
uniform float osgOcean_UnderwaterFogDensity;
|
||||||
|
uniform float osgOcean_AboveWaterFogDensity;
|
||||||
|
uniform vec4 osgOcean_UnderwaterFogColor;
|
||||||
|
uniform vec4 osgOcean_AboveWaterFogColor;
|
||||||
|
|
||||||
|
uniform float osgOcean_WaterHeight;
|
||||||
|
|
||||||
|
uniform bool osgOcean_EnableGlare;
|
||||||
|
uniform bool osgOcean_EnableDOF;
|
||||||
|
uniform bool osgOcean_EyeUnderwater;
|
||||||
|
uniform bool osgOcean_EnableUnderwaterScattering;
|
||||||
|
// -------------------
|
||||||
|
|
||||||
|
uniform sampler2D uTextureMap;
|
||||||
|
|
||||||
|
varying vec3 vExtinction;
|
||||||
|
varying vec3 vInScattering;
|
||||||
|
varying vec3 vNormal;
|
||||||
|
varying vec3 vLightDir;
|
||||||
|
varying vec3 vEyeVec;
|
||||||
|
|
||||||
|
varying float vWorldHeight;
|
||||||
|
|
||||||
|
uniform sampler2DShadow shadowTexture;
|
||||||
|
|
||||||
|
float computeDepthBlur(float depth, float focus, float near, float far, float clampval )
|
||||||
|
{
|
||||||
|
float f;
|
||||||
|
if (depth < focus){
|
||||||
|
f = (depth - focus)/(focus - near);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
f = (depth - focus)/(far - focus);
|
||||||
|
f = clamp(f, 0.0, clampval);
|
||||||
|
}
|
||||||
|
return f * 0.5 + 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 lighting( vec4 colormap )
|
||||||
|
{
|
||||||
|
vec4 final_color = gl_LightSource[0].ambient * colormap;
|
||||||
|
|
||||||
|
float light = shadow2DProj( shadowTexture, gl_TexCoord[7] ).r;
|
||||||
|
|
||||||
|
vec3 N = normalize(vNormal);
|
||||||
|
vec3 L = normalize(vLightDir);
|
||||||
|
|
||||||
|
float lambertTerm = dot(N,L);
|
||||||
|
|
||||||
|
if(lambertTerm > 0.0)
|
||||||
|
{
|
||||||
|
final_color += gl_LightSource[0].diffuse * lambertTerm * colormap * light;
|
||||||
|
|
||||||
|
vec3 E = normalize(vEyeVec);
|
||||||
|
vec3 R = reflect(-L, N);
|
||||||
|
|
||||||
|
float specular = pow( max(dot(R, E), 0.0), 2.0 );
|
||||||
|
|
||||||
|
final_color += gl_LightSource[0].specular * specular * light;
|
||||||
|
}
|
||||||
|
|
||||||
|
return final_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
float computeFogFactor( float density, float fogCoord )
|
||||||
|
{
|
||||||
|
return exp2(density * fogCoord * fogCoord );
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
vec4 final_color;
|
||||||
|
|
||||||
|
vec4 textureColor = texture2D( uTextureMap, gl_TexCoord[0].st );
|
||||||
|
|
||||||
|
// Underwater
|
||||||
|
// +2 tweak here as waves peak above average wave height,
|
||||||
|
// and surface fog becomes visible.
|
||||||
|
if(osgOcean_EyeUnderwater && vWorldHeight < osgOcean_WaterHeight+2.0 )
|
||||||
|
{
|
||||||
|
final_color = lighting( textureColor );
|
||||||
|
|
||||||
|
// mix in underwater light
|
||||||
|
if(osgOcean_EnableUnderwaterScattering)
|
||||||
|
{
|
||||||
|
final_color.rgb = final_color.rgb * vExtinction + vInScattering;
|
||||||
|
}
|
||||||
|
|
||||||
|
float fogFactor = computeFogFactor( osgOcean_UnderwaterFogDensity, gl_FogFragCoord );
|
||||||
|
|
||||||
|
// write to depth buffer (actually a GL_LUMINANCE)
|
||||||
|
if(osgOcean_EnableDOF)
|
||||||
|
{
|
||||||
|
float depth = computeDepthBlur(gl_FogFragCoord, osgOcean_DOF_Focus, osgOcean_DOF_Near, osgOcean_DOF_Far, osgOcean_DOF_Clamp);
|
||||||
|
gl_FragData[1] = vec4(depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
// color buffer
|
||||||
|
gl_FragData[0] = mix( osgOcean_UnderwaterFogColor, final_color, fogFactor );
|
||||||
|
}
|
||||||
|
// Above water
|
||||||
|
else
|
||||||
|
{
|
||||||
|
final_color = lighting( textureColor );
|
||||||
|
|
||||||
|
float fogFactor = computeFogFactor( osgOcean_AboveWaterFogDensity, gl_FogFragCoord );
|
||||||
|
final_color = mix( osgOcean_AboveWaterFogColor, final_color, fogFactor );
|
||||||
|
|
||||||
|
// write to luminance buffer
|
||||||
|
// might not need the IF here, glsl compiler doesn't complain if
|
||||||
|
// you try and write to a FragData index that doesn't exist. But since
|
||||||
|
// Mac GLSL support seems so fussy I'll leave it in.
|
||||||
|
if(osgOcean_EnableGlare)
|
||||||
|
{
|
||||||
|
gl_FragData[1] = vec4(0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// write to color buffer
|
||||||
|
gl_FragData[0] = final_color;
|
||||||
|
}
|
||||||
|
}
|
57
Source/resources/shaders/osgOcean_ocean_scene_lispsm.vert
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
// osgOcean Uniforms
|
||||||
|
// -----------------
|
||||||
|
uniform mat4 osg_ViewMatrixInverse;
|
||||||
|
uniform float osgOcean_WaterHeight;
|
||||||
|
uniform vec3 osgOcean_Eye;
|
||||||
|
uniform vec3 osgOcean_UnderwaterAttenuation;
|
||||||
|
uniform vec4 osgOcean_UnderwaterDiffuse;
|
||||||
|
uniform bool osgOcean_EnableUnderwaterScattering;
|
||||||
|
// -----------------
|
||||||
|
|
||||||
|
varying vec3 vExtinction;
|
||||||
|
varying vec3 vInScattering;
|
||||||
|
|
||||||
|
varying vec3 vNormal;
|
||||||
|
varying vec3 vLightDir;
|
||||||
|
varying vec3 vEyeVec;
|
||||||
|
varying float vWorldHeight;
|
||||||
|
|
||||||
|
void computeScattering( in vec3 eye, in vec3 worldVertex, out vec3 extinction, out vec3 inScattering )
|
||||||
|
{
|
||||||
|
float viewDist = length(eye-worldVertex);
|
||||||
|
|
||||||
|
float depth = max(osgOcean_WaterHeight-worldVertex.z, 0.0);
|
||||||
|
|
||||||
|
extinction = exp(-osgOcean_UnderwaterAttenuation*viewDist*2.0);
|
||||||
|
|
||||||
|
// Need to compute accurate kd constant.
|
||||||
|
// const vec3 kd = vec3(0.001, 0.001, 0.001);
|
||||||
|
inScattering = osgOcean_UnderwaterDiffuse.rgb * (1.0-extinction*exp(-depth*vec3(0.001)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||||
|
gl_Position = ftransform();
|
||||||
|
gl_FogFragCoord = gl_Position.z;
|
||||||
|
vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex;
|
||||||
|
gl_ClipVertex = ecPosition; // for reflections
|
||||||
|
|
||||||
|
vNormal = gl_NormalMatrix * gl_Normal;
|
||||||
|
vLightDir = gl_LightSource[0].position.xyz;
|
||||||
|
vEyeVec = -vec3(gl_ModelViewMatrix*gl_Vertex);
|
||||||
|
|
||||||
|
vec4 worldVertex = (osg_ViewMatrixInverse*gl_ModelViewMatrix) * gl_Vertex;
|
||||||
|
|
||||||
|
if (osgOcean_EnableUnderwaterScattering)
|
||||||
|
computeScattering( osgOcean_Eye, worldVertex.xyz, vExtinction, vInScattering);
|
||||||
|
|
||||||
|
vWorldHeight = worldVertex.z;
|
||||||
|
|
||||||
|
// Generate shadow map coords
|
||||||
|
gl_TexCoord[7].s = dot( ecPosition, gl_EyePlaneS[7] );
|
||||||
|
gl_TexCoord[7].t = dot( ecPosition, gl_EyePlaneT[7] );
|
||||||
|
gl_TexCoord[7].p = dot( ecPosition, gl_EyePlaneR[7] );
|
||||||
|
gl_TexCoord[7].q = dot( ecPosition, gl_EyePlaneQ[7] );
|
||||||
|
|
||||||
|
}
|
350
Source/resources/shaders/osgOcean_ocean_surface.frag
Normal file
@ -0,0 +1,350 @@
|
|||||||
|
uniform bool osgOcean_EnableReflections;
|
||||||
|
uniform bool osgOcean_EnableRefractions;
|
||||||
|
uniform bool osgOcean_EnableHeightmap;
|
||||||
|
uniform bool osgOcean_EnableCrestFoam;
|
||||||
|
uniform bool osgOcean_EnableUnderwaterScattering;
|
||||||
|
|
||||||
|
uniform bool osgOcean_EnableDOF;
|
||||||
|
uniform bool osgOcean_EnableGlare;
|
||||||
|
|
||||||
|
uniform float osgOcean_DOF_Near;
|
||||||
|
uniform float osgOcean_DOF_Focus;
|
||||||
|
uniform float osgOcean_DOF_Far;
|
||||||
|
uniform float osgOcean_DOF_Clamp;
|
||||||
|
uniform float osgOcean_FresnelMul;
|
||||||
|
|
||||||
|
uniform samplerCube osgOcean_EnvironmentMap;
|
||||||
|
uniform sampler2D osgOcean_ReflectionMap;
|
||||||
|
uniform sampler2D osgOcean_RefractionMap;
|
||||||
|
uniform sampler2D osgOcean_RefractionDepthMap;
|
||||||
|
uniform sampler2D osgOcean_FoamMap;
|
||||||
|
uniform sampler2D osgOcean_NoiseMap;
|
||||||
|
uniform sampler2D osgOcean_Heightmap;
|
||||||
|
|
||||||
|
uniform float osgOcean_UnderwaterFogDensity;
|
||||||
|
uniform float osgOcean_AboveWaterFogDensity;
|
||||||
|
uniform vec4 osgOcean_UnderwaterFogColor;
|
||||||
|
uniform vec4 osgOcean_AboveWaterFogColor;
|
||||||
|
uniform vec3 osgOcean_UnderwaterAttenuation;
|
||||||
|
uniform vec4 osgOcean_UnderwaterDiffuse;
|
||||||
|
|
||||||
|
uniform mat4 osg_ViewMatrixInverse;
|
||||||
|
|
||||||
|
uniform mat4 osgOcean_RefractionInverseTransformation;
|
||||||
|
|
||||||
|
uniform vec2 osgOcean_ViewportDimensions;
|
||||||
|
|
||||||
|
uniform float osgOcean_WaterHeight;
|
||||||
|
uniform float osgOcean_FoamCapBottom;
|
||||||
|
uniform float osgOcean_FoamCapTop;
|
||||||
|
|
||||||
|
varying vec3 vNormal;
|
||||||
|
varying vec3 vViewerDir;
|
||||||
|
varying vec3 vLightDir;
|
||||||
|
varying vec4 vVertex;
|
||||||
|
varying vec4 vWorldVertex;
|
||||||
|
|
||||||
|
varying vec3 vExtinction;
|
||||||
|
varying vec3 vInScattering;
|
||||||
|
|
||||||
|
varying vec3 vWorldViewDir;
|
||||||
|
varying vec3 vWorldNormal;
|
||||||
|
|
||||||
|
varying float height;
|
||||||
|
|
||||||
|
mat4 worldObjectMatrix;
|
||||||
|
|
||||||
|
const float shininess = 2000.0;
|
||||||
|
|
||||||
|
const vec4 BlueEnvColor = vec4(0.75, 0.85, 1.0, 1.0);
|
||||||
|
|
||||||
|
vec4 distortGen( vec4 v, vec3 N )
|
||||||
|
{
|
||||||
|
// transposed
|
||||||
|
const mat4 mr =
|
||||||
|
mat4( 0.5, 0.0, 0.0, 0.0,
|
||||||
|
0.0, 0.5, 0.0, 0.0,
|
||||||
|
0.0, 0.0, 0.5, 0.0,
|
||||||
|
0.5, 0.5, 0.5, 1.0 );
|
||||||
|
|
||||||
|
mat4 texgen_matrix = mr * gl_ProjectionMatrix * gl_ModelViewMatrix;
|
||||||
|
|
||||||
|
//float disp = 8.0;
|
||||||
|
float disp = 4.0;
|
||||||
|
|
||||||
|
vec4 tempPos;
|
||||||
|
|
||||||
|
tempPos.xy = v.xy + disp * N.xy;
|
||||||
|
tempPos.z = v.z;
|
||||||
|
tempPos.w = 1.0;
|
||||||
|
|
||||||
|
return texgen_matrix * tempPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 reorientate( vec3 v )
|
||||||
|
{
|
||||||
|
float y = v.y;
|
||||||
|
|
||||||
|
v.y = -v.z;
|
||||||
|
v.z = y;
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat3 getLinearPart( mat4 m )
|
||||||
|
{
|
||||||
|
mat3 result;
|
||||||
|
|
||||||
|
result[0][0] = m[0][0];
|
||||||
|
result[0][1] = m[0][1];
|
||||||
|
result[0][2] = m[0][2];
|
||||||
|
|
||||||
|
result[1][0] = m[1][0];
|
||||||
|
result[1][1] = m[1][1];
|
||||||
|
result[1][2] = m[1][2];
|
||||||
|
|
||||||
|
result[2][0] = m[2][0];
|
||||||
|
result[2][1] = m[2][1];
|
||||||
|
result[2][2] = m[2][2];
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
float calcFresnel( float dotEN, float mul )
|
||||||
|
{
|
||||||
|
float fresnel = clamp( dotEN, 0.0, 1.0 ) + 1.0;
|
||||||
|
return pow(fresnel, -8.0) * mul;
|
||||||
|
}
|
||||||
|
|
||||||
|
float alphaHeight( float min, float max, float val)
|
||||||
|
{
|
||||||
|
if(max-min == 0.0)
|
||||||
|
return 1.0;
|
||||||
|
|
||||||
|
return (val - min) / (max - min);
|
||||||
|
}
|
||||||
|
|
||||||
|
float computeDepthBlur(float depth, float focus, float near, float far, float clampval )
|
||||||
|
{
|
||||||
|
float f;
|
||||||
|
|
||||||
|
if (depth < focus){
|
||||||
|
// scale depth value between near blur distance and focal distance to [-1, 0] range
|
||||||
|
f = (depth - focus)/(focus - near);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
// scale depth value between focal distance and far blur
|
||||||
|
// distance to [0, 1] range
|
||||||
|
f = (depth - focus)/(far - focus);
|
||||||
|
|
||||||
|
// clamp the far blur to a maximum blurriness
|
||||||
|
f = clamp(f, 0.0, clampval);
|
||||||
|
}
|
||||||
|
|
||||||
|
// scale and bias into [0, 1] range
|
||||||
|
return f * 0.5 + 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
float luminance( vec4 color )
|
||||||
|
{
|
||||||
|
return (0.3*color.r) + (0.59*color.g) + (0.11*color.b);
|
||||||
|
}
|
||||||
|
|
||||||
|
float computeFogFactor( float density, float fogCoord )
|
||||||
|
{
|
||||||
|
return exp2(density * fogCoord * fogCoord );
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------
|
||||||
|
// Main Program
|
||||||
|
// -------------------------------
|
||||||
|
|
||||||
|
void main( void )
|
||||||
|
{
|
||||||
|
vec4 final_color;
|
||||||
|
|
||||||
|
vec3 noiseNormal = vec3( texture2D( osgOcean_NoiseMap, gl_TexCoord[0].xy ) * 2.0 - 1.0 );
|
||||||
|
noiseNormal += vec3( texture2D( osgOcean_NoiseMap, gl_TexCoord[0].zw ) * 2.0 - 1.0 );
|
||||||
|
|
||||||
|
worldObjectMatrix = osg_ViewMatrixInverse * gl_ModelViewMatrix;
|
||||||
|
|
||||||
|
if(gl_FrontFacing)
|
||||||
|
{
|
||||||
|
vec3 N = normalize( vNormal + noiseNormal );
|
||||||
|
vec3 L = normalize( vLightDir );
|
||||||
|
vec3 E = normalize( vViewerDir );
|
||||||
|
vec3 R = reflect( -L, N );
|
||||||
|
|
||||||
|
vec4 specular_color = vec4(0.0);
|
||||||
|
|
||||||
|
float lambertTerm = dot(N,L);
|
||||||
|
|
||||||
|
if( lambertTerm > 0.0 )
|
||||||
|
{
|
||||||
|
float specCoeff = pow( max( dot(R, E), 0.0 ), shininess );
|
||||||
|
specular_color = gl_LightSource[osgOcean_LightID].diffuse * specCoeff * 6.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
float dotEN = dot(E, N);
|
||||||
|
float dotLN = dot(L, N);
|
||||||
|
|
||||||
|
vec4 distortedVertex = distortGen(vVertex, N);
|
||||||
|
|
||||||
|
// Calculate the position in world space of the pixel on the ocean floor
|
||||||
|
vec4 refraction_ndc = vec4(gl_FragCoord.xy / osgOcean_ViewportDimensions, texture2DProj(osgOcean_RefractionDepthMap, distortedVertex).x, 1.0);
|
||||||
|
vec4 refraction_screen = refraction_ndc * 2.0 - 1.0;
|
||||||
|
vec4 refraction_world = osgOcean_RefractionInverseTransformation * refraction_screen;
|
||||||
|
refraction_world = refraction_world / refraction_world.w;
|
||||||
|
|
||||||
|
// The amount of water behind the pixel
|
||||||
|
// (water depth as seen from the camera position)
|
||||||
|
float waterDepth = distance(vWorldVertex, refraction_world);
|
||||||
|
vec4 refraction_dir = refraction_world - vWorldVertex;
|
||||||
|
|
||||||
|
vec4 env_color;
|
||||||
|
|
||||||
|
if(osgOcean_EnableReflections)
|
||||||
|
{
|
||||||
|
env_color = texture2DProj( osgOcean_ReflectionMap, distortedVertex );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
env_color = BlueEnvColor * gl_LightSource[osgOcean_LightID].diffuse * vec4(vec3(1.25), 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine refraction color
|
||||||
|
vec4 refraction_color = vec4( gl_Color.rgb, 1.0 );
|
||||||
|
// Only use refraction for under the ocean surface.
|
||||||
|
if(osgOcean_EnableRefractions)
|
||||||
|
{
|
||||||
|
vec4 refractionmap_color = texture2DProj(osgOcean_RefractionMap, distortedVertex );
|
||||||
|
|
||||||
|
if(osgOcean_EnableUnderwaterScattering)
|
||||||
|
{
|
||||||
|
// Compute underwater scattering the same way as when underwater,
|
||||||
|
// see vertex shader computeScattering() function, but a higher
|
||||||
|
// underwater attenuation factor is required so it matches the
|
||||||
|
// underwater look.
|
||||||
|
float depth = max(osgOcean_WaterHeight-vWorldVertex.z, 0.0);
|
||||||
|
vec3 extinction = exp(-osgOcean_UnderwaterAttenuation*waterDepth*4.0);
|
||||||
|
vec3 inScattering = osgOcean_UnderwaterDiffuse.rgb * vec3(0.6, 0.6, 0.5) * (1.0-extinction*exp(-depth*vec3(0.001)));
|
||||||
|
|
||||||
|
refraction_color.rgb = refractionmap_color.rgb * extinction + inScattering;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
refraction_color.rgb *= refractionmap_color.rgb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float fresnel = calcFresnel(dotEN, osgOcean_FresnelMul );
|
||||||
|
|
||||||
|
final_color = mix(refraction_color, env_color, fresnel) + specular_color;
|
||||||
|
|
||||||
|
// Store the color here to compute luminance later, we don't want
|
||||||
|
// foam or fog to be taken into account for this calculation.
|
||||||
|
vec4 lumColor = final_color;
|
||||||
|
|
||||||
|
float waterHeight = 0.0;
|
||||||
|
if (osgOcean_EnableHeightmap)
|
||||||
|
{
|
||||||
|
// The vertical distance between the ocean surface and ocean floor, this uses the projected heightmap
|
||||||
|
waterHeight = (texture2DProj(osgOcean_Heightmap, distortedVertex).x) * 500.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(osgOcean_EnableCrestFoam)
|
||||||
|
{
|
||||||
|
if( vVertex.z > osgOcean_FoamCapBottom ||
|
||||||
|
(osgOcean_EnableHeightmap && waterHeight < 10.0))
|
||||||
|
{
|
||||||
|
vec4 foam_color = texture2D( osgOcean_FoamMap, gl_TexCoord[1].st / 10.0);
|
||||||
|
|
||||||
|
float alpha;
|
||||||
|
if (osgOcean_EnableHeightmap)
|
||||||
|
{
|
||||||
|
alpha = max(alphaHeight( osgOcean_FoamCapBottom, osgOcean_FoamCapTop, vVertex.z ) * (fresnel*2.0),
|
||||||
|
0.8 - clamp(waterHeight / 10.0, 0.0, 0.8));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
alpha = alphaHeight( osgOcean_FoamCapBottom, osgOcean_FoamCapTop, vVertex.z ) * (fresnel*2.0);
|
||||||
|
}
|
||||||
|
final_color = final_color + (foam_color * alpha);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// exp2 fog
|
||||||
|
float fogFactor = computeFogFactor( osgOcean_AboveWaterFogDensity, gl_FogFragCoord );
|
||||||
|
|
||||||
|
final_color = mix( osgOcean_AboveWaterFogColor, final_color, fogFactor );
|
||||||
|
|
||||||
|
if(osgOcean_EnableGlare)
|
||||||
|
{
|
||||||
|
float lum = luminance(lumColor);
|
||||||
|
gl_FragData[1] = vec4(lum);
|
||||||
|
}
|
||||||
|
|
||||||
|
gl_FragData[0] = final_color;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vec3 E = normalize( vViewerDir );
|
||||||
|
vec3 N = -normalize( (vWorldNormal + noiseNormal) );
|
||||||
|
|
||||||
|
vec3 incident = normalize( vWorldViewDir );
|
||||||
|
|
||||||
|
//------ Find the reflection
|
||||||
|
// not really usable as we would need to use cubemap again..
|
||||||
|
// the ocean is blue not much to reflect back
|
||||||
|
//vec3 reflected = reflect( incident, -N );
|
||||||
|
//reflected = reorientate( reflected );
|
||||||
|
//vec3 reflVec = normalize( reflected );
|
||||||
|
|
||||||
|
//------ Find the refraction from cubemap
|
||||||
|
vec3 refracted = refract( incident, N, 1.3333333333 ); // 1.1 looks better? - messes up position of godrays though
|
||||||
|
refracted.z = refracted.z - 0.015; // on the fringes push it down to show base texture color
|
||||||
|
refracted = reorientate( refracted );
|
||||||
|
|
||||||
|
vec4 refractColor = textureCube( osgOcean_EnvironmentMap, refracted );
|
||||||
|
|
||||||
|
//------ Project texture where the light isn't internally reflected
|
||||||
|
if(osgOcean_EnableRefractions)
|
||||||
|
{
|
||||||
|
// if alpha is 1.0 then it's a sky pixel
|
||||||
|
if(refractColor.a == 1.0 )
|
||||||
|
{
|
||||||
|
vec4 env_color = texture2DProj( osgOcean_RefractionMap, distortGen(vVertex, N) );
|
||||||
|
refractColor.rgb = mix( refractColor.rgb, env_color.rgb, env_color.a );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if it's not refracting in, add a bit of highlighting with fresnel
|
||||||
|
if( refractColor.a == 0.0 )
|
||||||
|
{
|
||||||
|
float fresnel = calcFresnel( dot(E, N), 0.7 );
|
||||||
|
refractColor.rgb = osgOcean_UnderwaterFogColor.rgb*fresnel + (1.0-fresnel)* refractColor.rgb;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mix in underwater light
|
||||||
|
if(osgOcean_EnableUnderwaterScattering)
|
||||||
|
{
|
||||||
|
refractColor.rgb = refractColor.rgb * vExtinction + vInScattering;
|
||||||
|
}
|
||||||
|
|
||||||
|
float fogFactor = computeFogFactor( osgOcean_UnderwaterFogDensity, gl_FogFragCoord );
|
||||||
|
final_color = mix( osgOcean_UnderwaterFogColor, refractColor, fogFactor );
|
||||||
|
|
||||||
|
if(osgOcean_EnableDOF)
|
||||||
|
{
|
||||||
|
float depthBlur = computeDepthBlur( gl_FogFragCoord, osgOcean_DOF_Focus, osgOcean_DOF_Near, osgOcean_DOF_Far, osgOcean_DOF_Clamp );
|
||||||
|
gl_FragData[1] = vec4(depthBlur);
|
||||||
|
}
|
||||||
|
|
||||||
|
gl_FragData[0] = final_color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
136
Source/resources/shaders/osgOcean_ocean_surface.vert
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
uniform mat4 osg_ViewMatrixInverse;
|
||||||
|
|
||||||
|
uniform vec3 osgOcean_Eye;
|
||||||
|
|
||||||
|
uniform vec3 osgOcean_NoiseCoords0;
|
||||||
|
uniform vec3 osgOcean_NoiseCoords1;
|
||||||
|
|
||||||
|
uniform vec4 osgOcean_WaveTop;
|
||||||
|
uniform vec4 osgOcean_WaveBot;
|
||||||
|
|
||||||
|
uniform float osgOcean_FoamScale;
|
||||||
|
|
||||||
|
uniform float osgOcean_FrameTime;
|
||||||
|
|
||||||
|
// Used to blend the waves into a sinus curve near the shore
|
||||||
|
uniform sampler2D osgOcean_Heightmap;
|
||||||
|
uniform bool osgOcean_EnableHeightmap;
|
||||||
|
|
||||||
|
uniform bool osgOcean_EnableUnderwaterScattering;
|
||||||
|
uniform float osgOcean_WaterHeight;
|
||||||
|
uniform vec3 osgOcean_UnderwaterAttenuation;
|
||||||
|
uniform vec4 osgOcean_UnderwaterDiffuse;
|
||||||
|
|
||||||
|
varying vec4 vVertex;
|
||||||
|
varying vec4 vWorldVertex;
|
||||||
|
varying vec3 vNormal;
|
||||||
|
varying vec3 vViewerDir;
|
||||||
|
varying vec3 vLightDir;
|
||||||
|
|
||||||
|
varying vec3 vExtinction;
|
||||||
|
varying vec3 vInScattering;
|
||||||
|
|
||||||
|
varying vec3 vWorldViewDir;
|
||||||
|
varying vec3 vWorldNormal;
|
||||||
|
|
||||||
|
varying float height;
|
||||||
|
|
||||||
|
mat3 get3x3Matrix( mat4 m )
|
||||||
|
{
|
||||||
|
mat3 result;
|
||||||
|
|
||||||
|
result[0][0] = m[0][0];
|
||||||
|
result[0][1] = m[0][1];
|
||||||
|
result[0][2] = m[0][2];
|
||||||
|
|
||||||
|
result[1][0] = m[1][0];
|
||||||
|
result[1][1] = m[1][1];
|
||||||
|
result[1][2] = m[1][2];
|
||||||
|
|
||||||
|
result[2][0] = m[2][0];
|
||||||
|
result[2][1] = m[2][1];
|
||||||
|
result[2][2] = m[2][2];
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void computeScattering( in vec3 eye, in vec3 worldVertex, out vec3 extinction, out vec3 inScattering )
|
||||||
|
{
|
||||||
|
float viewDist = length(eye-worldVertex);
|
||||||
|
|
||||||
|
float depth = max(osgOcean_WaterHeight-worldVertex.z, 0.0);
|
||||||
|
|
||||||
|
extinction = exp(-osgOcean_UnderwaterAttenuation*viewDist*2.0);
|
||||||
|
|
||||||
|
// Need to compute accurate kd constant.
|
||||||
|
// const vec3 kd = vec3(0.001, 0.001, 0.001);
|
||||||
|
inScattering = osgOcean_UnderwaterDiffuse.rgb * (1.0-extinction*exp(-depth*vec3(0.001)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------
|
||||||
|
// Main Program
|
||||||
|
// -------------------------------
|
||||||
|
|
||||||
|
void main( void )
|
||||||
|
{
|
||||||
|
// Transform the vertex
|
||||||
|
vec4 inputVertex = gl_Vertex;
|
||||||
|
gl_Position = gl_ModelViewProjectionMatrix * inputVertex;
|
||||||
|
|
||||||
|
// Blend the wave into a sinus curve near the shore
|
||||||
|
// note that this requires a vertex shader texture lookup
|
||||||
|
// vertex has to be transformed a second time with the new z-value
|
||||||
|
if (osgOcean_EnableHeightmap)
|
||||||
|
{
|
||||||
|
vec2 screenCoords = gl_Position.xy / gl_Position.w;
|
||||||
|
|
||||||
|
height = pow(clamp(1.0 - texture2D(osgOcean_Heightmap, clamp(screenCoords * 0.5 + 0.5, 0.0, 1.0)).x, 0.0, 1.0), 32.0);
|
||||||
|
|
||||||
|
inputVertex = vec4(gl_Vertex.x,
|
||||||
|
gl_Vertex.y,
|
||||||
|
mix(gl_Vertex.z, sin(osgOcean_FrameTime), height),
|
||||||
|
gl_Vertex.w);
|
||||||
|
|
||||||
|
gl_Position = gl_ModelViewProjectionMatrix * inputVertex;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------
|
||||||
|
|
||||||
|
// In object space
|
||||||
|
vVertex = inputVertex;
|
||||||
|
vLightDir = normalize( vec3( gl_ModelViewMatrixInverse * ( gl_LightSource[osgOcean_LightID].position ) ) );
|
||||||
|
vViewerDir = gl_ModelViewMatrixInverse[3].xyz - inputVertex.xyz;
|
||||||
|
vNormal = normalize(gl_Normal);
|
||||||
|
|
||||||
|
vec4 waveColorDiff = osgOcean_WaveTop - osgOcean_WaveBot;
|
||||||
|
|
||||||
|
gl_FrontColor = waveColorDiff *
|
||||||
|
clamp((gl_Vertex.z + osgOcean_Eye.z) * 0.1111111 + vNormal.z - 0.4666667, 0.0, 1.0) + osgOcean_WaveBot;
|
||||||
|
|
||||||
|
// -------------------------------------------------------------
|
||||||
|
|
||||||
|
mat4 modelMatrix = osg_ViewMatrixInverse * gl_ModelViewMatrix;
|
||||||
|
mat3 modelMatrix3x3 = get3x3Matrix( modelMatrix );
|
||||||
|
|
||||||
|
// world space
|
||||||
|
vWorldVertex = modelMatrix * gl_Vertex;
|
||||||
|
vWorldNormal = modelMatrix3x3 * gl_Normal;
|
||||||
|
vWorldViewDir = vWorldVertex.xyz - osgOcean_Eye.xyz;
|
||||||
|
|
||||||
|
// ------------- Texture Coords ---------------------------------
|
||||||
|
|
||||||
|
// Normal Map Coords
|
||||||
|
gl_TexCoord[0].xy = ( gl_Vertex.xy * osgOcean_NoiseCoords0.z + osgOcean_NoiseCoords0.xy );
|
||||||
|
gl_TexCoord[0].zw = ( gl_Vertex.xy * osgOcean_NoiseCoords1.z + osgOcean_NoiseCoords1.xy );
|
||||||
|
gl_TexCoord[0].y = -gl_TexCoord[0].y;
|
||||||
|
gl_TexCoord[0].w = -gl_TexCoord[0].w;
|
||||||
|
|
||||||
|
// Foam coords
|
||||||
|
gl_TexCoord[1].st = gl_Vertex.xy * osgOcean_FoamScale;
|
||||||
|
|
||||||
|
// Fog coords
|
||||||
|
gl_FogFragCoord = gl_Position.z;
|
||||||
|
|
||||||
|
if (osgOcean_EnableUnderwaterScattering)
|
||||||
|
computeScattering( osgOcean_Eye, vWorldVertex.xyz, vExtinction, vInScattering);
|
||||||
|
}
|
137
Source/resources/shaders/osgOcean_ocean_surface_vbo.vert
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
uniform mat4 osg_ViewMatrixInverse;
|
||||||
|
uniform float osg_FrameTime;
|
||||||
|
|
||||||
|
uniform vec3 osgOcean_Eye;
|
||||||
|
|
||||||
|
uniform vec3 osgOcean_NoiseCoords0;
|
||||||
|
uniform vec3 osgOcean_NoiseCoords1;
|
||||||
|
|
||||||
|
uniform vec4 osgOcean_WaveTop;
|
||||||
|
uniform vec4 osgOcean_WaveBot;
|
||||||
|
|
||||||
|
uniform float osgOcean_FoamScale;
|
||||||
|
|
||||||
|
// Used to blend the waves into a sinus curve near the shore
|
||||||
|
uniform sampler2D osgOcean_Heightmap;
|
||||||
|
uniform bool osgOcean_EnableHeightmap;
|
||||||
|
|
||||||
|
uniform bool osgOcean_EnableUnderwaterScattering;
|
||||||
|
uniform float osgOcean_WaterHeight;
|
||||||
|
uniform vec3 osgOcean_UnderwaterAttenuation;
|
||||||
|
uniform vec4 osgOcean_UnderwaterDiffuse;
|
||||||
|
|
||||||
|
varying vec4 vVertex;
|
||||||
|
varying vec4 vWorldVertex;
|
||||||
|
varying vec3 vNormal;
|
||||||
|
varying vec3 vViewerDir;
|
||||||
|
varying vec3 vLightDir;
|
||||||
|
|
||||||
|
varying vec3 vExtinction;
|
||||||
|
varying vec3 vInScattering;
|
||||||
|
|
||||||
|
varying vec3 vWorldViewDir;
|
||||||
|
varying vec3 vWorldNormal;
|
||||||
|
|
||||||
|
varying float height;
|
||||||
|
|
||||||
|
mat3 get3x3Matrix( mat4 m )
|
||||||
|
{
|
||||||
|
mat3 result;
|
||||||
|
|
||||||
|
result[0][0] = m[0][0];
|
||||||
|
result[0][1] = m[0][1];
|
||||||
|
result[0][2] = m[0][2];
|
||||||
|
|
||||||
|
result[1][0] = m[1][0];
|
||||||
|
result[1][1] = m[1][1];
|
||||||
|
result[1][2] = m[1][2];
|
||||||
|
|
||||||
|
result[2][0] = m[2][0];
|
||||||
|
result[2][1] = m[2][1];
|
||||||
|
result[2][2] = m[2][2];
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void computeScattering( in vec3 eye, in vec3 worldVertex, out vec3 extinction, out vec3 inScattering )
|
||||||
|
{
|
||||||
|
float viewDist = length(eye-worldVertex);
|
||||||
|
|
||||||
|
float depth = max(osgOcean_WaterHeight-worldVertex.z, 0.0);
|
||||||
|
|
||||||
|
extinction = exp(-osgOcean_UnderwaterAttenuation*viewDist*2.0);
|
||||||
|
|
||||||
|
// Need to compute accurate kd constant.
|
||||||
|
// const vec3 kd = vec3(0.001, 0.001, 0.001);
|
||||||
|
inScattering = osgOcean_UnderwaterDiffuse.rgb * (1.0-extinction*exp(-depth*vec3(0.001)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------
|
||||||
|
// Main Program
|
||||||
|
// -------------------------------
|
||||||
|
|
||||||
|
void main( void )
|
||||||
|
{
|
||||||
|
// Transform the vertex
|
||||||
|
vec4 inputVertex = gl_Vertex;
|
||||||
|
inputVertex.xyz += gl_Color.xyz;
|
||||||
|
|
||||||
|
gl_Position = gl_ModelViewProjectionMatrix * inputVertex;
|
||||||
|
|
||||||
|
// Blend the wave into a sinus curve near the shore
|
||||||
|
// note that this requires a vertex shader texture lookup
|
||||||
|
// vertex has to be transformed a second time with the new z-value
|
||||||
|
if (osgOcean_EnableHeightmap)
|
||||||
|
{
|
||||||
|
vec2 screenCoords = gl_Position.xy / gl_Position.w;
|
||||||
|
|
||||||
|
height = pow(clamp(1.0 - texture2D(osgOcean_Heightmap, clamp(screenCoords * 0.5 + 0.5, 0.0, 1.0)).x, 0.0, 1.0), 32.0);
|
||||||
|
|
||||||
|
inputVertex = vec4(inputVertex.x,
|
||||||
|
inputVertex.y,
|
||||||
|
mix(inputVertex.z, sin(osg_FrameTime), height),
|
||||||
|
inputVertex.w);
|
||||||
|
|
||||||
|
gl_Position = gl_ModelViewProjectionMatrix * inputVertex;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------
|
||||||
|
|
||||||
|
// In object space
|
||||||
|
vVertex = inputVertex;
|
||||||
|
vLightDir = normalize( vec3( gl_ModelViewMatrixInverse * ( gl_LightSource[osgOcean_LightID].position ) ) );
|
||||||
|
vViewerDir = gl_ModelViewMatrixInverse[3].xyz - inputVertex.xyz;
|
||||||
|
vNormal = normalize(gl_Normal);
|
||||||
|
|
||||||
|
vec4 waveColorDiff = osgOcean_WaveTop-osgOcean_WaveBot;
|
||||||
|
|
||||||
|
gl_FrontColor = waveColorDiff *
|
||||||
|
clamp((inputVertex.z + osgOcean_Eye.z) * 0.1111111 + vNormal.z - 0.4666667, 0.0, 1.0) + osgOcean_WaveBot;
|
||||||
|
|
||||||
|
// -------------------------------------------------------------
|
||||||
|
|
||||||
|
mat4 modelMatrix = osg_ViewMatrixInverse * gl_ModelViewMatrix;
|
||||||
|
mat3 modelMatrix3x3 = get3x3Matrix( modelMatrix );
|
||||||
|
|
||||||
|
// world space
|
||||||
|
vWorldVertex = modelMatrix * inputVertex;
|
||||||
|
vWorldNormal = modelMatrix3x3 * gl_Normal;
|
||||||
|
vWorldViewDir = vWorldVertex.xyz - osgOcean_Eye.xyz;
|
||||||
|
|
||||||
|
// ------------- Texture Coords ---------------------------------
|
||||||
|
|
||||||
|
// Normal Map Coords
|
||||||
|
gl_TexCoord[0].xy = ( inputVertex.xy * osgOcean_NoiseCoords0.z + osgOcean_NoiseCoords0.xy );
|
||||||
|
gl_TexCoord[0].zw = ( inputVertex.xy * osgOcean_NoiseCoords1.z + osgOcean_NoiseCoords1.xy );
|
||||||
|
gl_TexCoord[0].y = -gl_TexCoord[0].y;
|
||||||
|
gl_TexCoord[0].w = -gl_TexCoord[0].w;
|
||||||
|
|
||||||
|
// Foam coords
|
||||||
|
gl_TexCoord[1].st = inputVertex.xy * osgOcean_FoamScale;
|
||||||
|
|
||||||
|
// Fog coords
|
||||||
|
gl_FogFragCoord = gl_Position.z;
|
||||||
|
|
||||||
|
if (osgOcean_EnableUnderwaterScattering)
|
||||||
|
computeScattering( osgOcean_Eye, vWorldVertex.xyz, vExtinction, vInScattering);
|
||||||
|
}
|
7
Source/resources/shaders/osgOcean_silt_points.frag
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
uniform sampler2D osgOcean_BaseTexture;
|
||||||
|
varying vec4 colour;
|
||||||
|
|
||||||
|
void main (void)
|
||||||
|
{
|
||||||
|
gl_FragColor = colour * texture2D( osgOcean_BaseTexture, gl_TexCoord[0].xy);
|
||||||
|
}
|
34
Source/resources/shaders/osgOcean_silt_points.vert
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
uniform float osgOcean_InversePeriod;
|
||||||
|
uniform vec4 osgOcean_ParticleColour;
|
||||||
|
uniform float osgOcean_ParticleSize;
|
||||||
|
|
||||||
|
uniform float osg_SimulationTime;
|
||||||
|
|
||||||
|
varying vec4 colour;
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
float startTime = gl_MultiTexCoord1.x;
|
||||||
|
|
||||||
|
vec4 v_current = gl_Vertex;
|
||||||
|
|
||||||
|
float disp = (osg_SimulationTime - startTime)*osgOcean_InversePeriod;
|
||||||
|
|
||||||
|
vec3 direction = sign(gl_Normal);
|
||||||
|
|
||||||
|
v_current.x = direction.x * fract( disp + gl_Vertex.x );
|
||||||
|
v_current.y = direction.y * fract( disp + gl_Vertex.y );
|
||||||
|
v_current.z = direction.z * fract( disp + gl_Vertex.z );
|
||||||
|
|
||||||
|
colour = osgOcean_ParticleColour;
|
||||||
|
|
||||||
|
gl_Position = gl_ModelViewProjectionMatrix * v_current;
|
||||||
|
|
||||||
|
float pointSize = abs(1280.0*osgOcean_ParticleSize / gl_Position.w);
|
||||||
|
|
||||||
|
gl_PointSize = ceil(pointSize);
|
||||||
|
|
||||||
|
colour.a = 0.05+(pointSize*pointSize)/(gl_PointSize*gl_PointSize);
|
||||||
|
|
||||||
|
gl_ClipVertex = v_current;
|
||||||
|
}
|
8
Source/resources/shaders/osgOcean_silt_quads.frag
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
uniform sampler2D osgOcean_BaseTexture;
|
||||||
|
varying vec2 texCoord;
|
||||||
|
varying vec4 colour;
|
||||||
|
|
||||||
|
void main (void)
|
||||||
|
{
|
||||||
|
gl_FragColor = colour * texture2D( osgOcean_BaseTexture, texCoord);
|
||||||
|
}
|
52
Source/resources/shaders/osgOcean_silt_quads.vert
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
uniform vec4 osgOcean_ParticleColour;
|
||||||
|
|
||||||
|
uniform float osgOcean_InversePeriod;
|
||||||
|
uniform float osgOcean_ParticleSize;
|
||||||
|
uniform float osg_SimulationTime;
|
||||||
|
uniform float osg_DeltaSimulationTime;
|
||||||
|
|
||||||
|
varying vec4 colour;
|
||||||
|
varying vec2 texCoord;
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
float startTime = gl_MultiTexCoord1.x;
|
||||||
|
texCoord = gl_MultiTexCoord0.xy;
|
||||||
|
|
||||||
|
float disp = (osg_SimulationTime - startTime)*osgOcean_InversePeriod;
|
||||||
|
|
||||||
|
vec4 v_previous = gl_Vertex;
|
||||||
|
|
||||||
|
vec3 direction = sign(gl_Normal);
|
||||||
|
|
||||||
|
v_previous.x = direction.x * fract( disp + gl_Vertex.x );
|
||||||
|
v_previous.y = direction.y * fract( disp + gl_Vertex.y );
|
||||||
|
v_previous.z = direction.z * fract( disp + gl_Vertex.z );
|
||||||
|
|
||||||
|
vec4 v_current = v_previous;
|
||||||
|
|
||||||
|
v_current.x += ( osg_DeltaSimulationTime * osgOcean_InversePeriod );
|
||||||
|
v_current.y += ( osg_DeltaSimulationTime * osgOcean_InversePeriod );
|
||||||
|
v_current.z += ( osg_DeltaSimulationTime * osgOcean_InversePeriod );
|
||||||
|
|
||||||
|
colour = osgOcean_ParticleColour;
|
||||||
|
|
||||||
|
vec4 v1 = gl_ModelViewMatrix * v_current;
|
||||||
|
vec4 v2 = gl_ModelViewMatrix * v_previous;
|
||||||
|
|
||||||
|
vec3 dv = v2.xyz - v1.xyz;
|
||||||
|
|
||||||
|
vec2 dv_normalized = normalize(dv.xy);
|
||||||
|
dv.xy += dv_normalized * osgOcean_ParticleSize;
|
||||||
|
vec2 dp = vec2( -dv_normalized.y, dv_normalized.x ) * osgOcean_ParticleSize;
|
||||||
|
|
||||||
|
float area = length(dv.xy);
|
||||||
|
colour.a = 0.05+(osgOcean_ParticleSize)/area;
|
||||||
|
|
||||||
|
v1.xyz += dv*texCoord.y;
|
||||||
|
v1.xy += dp*texCoord.x;
|
||||||
|
|
||||||
|
gl_Position = gl_ProjectionMatrix * v1;
|
||||||
|
gl_Position.z = 0.01;
|
||||||
|
gl_ClipVertex = v1;
|
||||||
|
}
|
36
Source/resources/shaders/osgOcean_streak.frag
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#extension GL_ARB_texture_rectangle : enable
|
||||||
|
|
||||||
|
#define NUM_SAMPLES 4
|
||||||
|
|
||||||
|
uniform sampler2DRect osgOcean_Buffer;
|
||||||
|
uniform vec2 osgOcean_Direction;
|
||||||
|
uniform float osgOcean_Attenuation;
|
||||||
|
uniform float osgOcean_Pass;
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
vec2 sampleCoord = vec2(0.0);
|
||||||
|
vec3 cOut = vec3(0.0);
|
||||||
|
|
||||||
|
// sample weight = a^(b*s)
|
||||||
|
// a = attenuation
|
||||||
|
// b = 4^(pass-1)
|
||||||
|
// s = sample number
|
||||||
|
|
||||||
|
vec2 pxSize = vec2(0.5);
|
||||||
|
|
||||||
|
float b = pow( float(NUM_SAMPLES), float(osgOcean_Pass));
|
||||||
|
float sf = 0.0;
|
||||||
|
|
||||||
|
for (int s = 0; s < NUM_SAMPLES; s++)
|
||||||
|
{
|
||||||
|
sf = float(s);
|
||||||
|
float weight = pow(osgOcean_Attenuation, b * sf);
|
||||||
|
sampleCoord = gl_TexCoord[0].st + (osgOcean_Direction * b * vec2(sf) * pxSize);
|
||||||
|
cOut += clamp(weight,0.0,1.0) * texture2DRect(osgOcean_Buffer, sampleCoord).rgb;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 streak = clamp(cOut, 0.0, 1.0);
|
||||||
|
|
||||||
|
gl_FragColor = vec4(streak,1.0);
|
||||||
|
}
|
6
Source/resources/shaders/osgOcean_streak.vert
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||||
|
gl_Position = ftransform();
|
||||||
|
}
|
45
Source/resources/shaders/osgOcean_water_distortion.frag
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
// Based on Jon Kennedy's heat haze shader
|
||||||
|
// Copyright (c) 2002-2006 3Dlabs Inc. Ltd.
|
||||||
|
|
||||||
|
uniform float osgOcean_Frequency;
|
||||||
|
uniform float osgOcean_Offset;
|
||||||
|
uniform float osgOcean_Speed;
|
||||||
|
uniform vec2 osgOcean_ScreenRes;
|
||||||
|
|
||||||
|
uniform sampler2DRect osgOcean_FrameBuffer;
|
||||||
|
|
||||||
|
varying vec4 vEyePos;
|
||||||
|
|
||||||
|
void main (void)
|
||||||
|
{
|
||||||
|
vec2 index;
|
||||||
|
|
||||||
|
// perform the div by w to put the texture into screen space
|
||||||
|
float recipW = 1.0 / vEyePos.w;
|
||||||
|
vec2 eye = vEyePos.xy * vec2(recipW);
|
||||||
|
|
||||||
|
float blend = max(1.0 - eye.y, 0.0);
|
||||||
|
|
||||||
|
// calc the wobble
|
||||||
|
// index.s = eye.x ;
|
||||||
|
index.s = eye.x + blend * sin( osgOcean_Frequency * 5.0 * eye.x + osgOcean_Offset * osgOcean_Speed ) * 0.004;
|
||||||
|
index.t = eye.y + blend * sin( osgOcean_Frequency * 5.0 * eye.y + osgOcean_Offset * osgOcean_Speed ) * 0.004;
|
||||||
|
|
||||||
|
// scale and shift so we're in the range 0-1
|
||||||
|
index.s = index.s * 0.5 + 0.5;
|
||||||
|
index.t = index.t * 0.5 + 0.5;
|
||||||
|
|
||||||
|
vec2 recipRes = vec2(1.0/osgOcean_ScreenRes.x, 1.0/osgOcean_ScreenRes.y);
|
||||||
|
|
||||||
|
index.s = clamp(index.s, 0.0, 1.0 - recipRes.x);
|
||||||
|
index.t = clamp(index.t, 0.0, 1.0 - recipRes.y);
|
||||||
|
|
||||||
|
// scale the texture so we just see the rendered framebuffer
|
||||||
|
index.s = index.s * osgOcean_ScreenRes.x;
|
||||||
|
index.t = index.t * osgOcean_ScreenRes.y;
|
||||||
|
|
||||||
|
vec3 RefractionColor = vec3( texture2DRect( osgOcean_FrameBuffer, index ) );
|
||||||
|
|
||||||
|
gl_FragColor = vec4( RefractionColor, 1.0 );
|
||||||
|
//gl_FragColor = texture2DRect( osgOcean_FrameBuffer, gl_TexCoord[0].st );
|
||||||
|
}
|
8
Source/resources/shaders/osgOcean_water_distortion.vert
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
varying vec4 vEyePos;
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||||
|
vEyePos = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||||
|
gl_Position = ftransform();
|
||||||
|
}
|
11
Source/resources/shaders/skydome.frag
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
uniform samplerCube uEnvironmentMap;
|
||||||
|
|
||||||
|
varying vec3 vTexCoord;
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
vec3 texcoord = vec3(vTexCoord.x, vTexCoord.y, -vTexCoord.z);
|
||||||
|
gl_FragData[0] = textureCube( uEnvironmentMap, texcoord.xzy );
|
||||||
|
gl_FragData[0].a = 0.0;
|
||||||
|
gl_FragData[1] = vec4(0.0);
|
||||||
|
}
|
8
Source/resources/shaders/skydome.vert
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
varying vec3 vTexCoord;
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
gl_Position = gl_ModelViewProjectionMatrix * vec4(gl_Vertex.xyz, 1.0);
|
||||||
|
|
||||||
|
vTexCoord = gl_Vertex.xyz;
|
||||||
|
}
|
125
Source/resources/shaders/terrain.frag
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
// osgOcean uniforms
|
||||||
|
// -------------------
|
||||||
|
uniform float osgOcean_DOF_Near;
|
||||||
|
uniform float osgOcean_DOF_Focus;
|
||||||
|
uniform float osgOcean_DOF_Far;
|
||||||
|
uniform float osgOcean_DOF_Clamp;
|
||||||
|
|
||||||
|
uniform bool osgOcean_EnableGlare;
|
||||||
|
uniform bool osgOcean_EnableDOF;
|
||||||
|
uniform bool osgOcean_EyeUnderwater;
|
||||||
|
uniform bool osgOcean_EnableUnderwaterScattering;
|
||||||
|
|
||||||
|
uniform float osgOcean_UnderwaterFogDensity;
|
||||||
|
uniform float osgOcean_AboveWaterFogDensity;
|
||||||
|
uniform float osgOcean_WaterHeight;
|
||||||
|
|
||||||
|
uniform vec4 osgOcean_UnderwaterFogColor;
|
||||||
|
uniform vec4 osgOcean_AboveWaterFogColor;
|
||||||
|
// -------------------
|
||||||
|
|
||||||
|
uniform sampler2D uTextureMap;
|
||||||
|
uniform sampler2D uOverlayMap;
|
||||||
|
uniform sampler2D uNormalMap;
|
||||||
|
|
||||||
|
varying vec3 vLightDir;
|
||||||
|
varying vec3 vEyeVec;
|
||||||
|
varying vec3 vExtinction;
|
||||||
|
varying vec3 vInScattering;
|
||||||
|
|
||||||
|
varying vec4 vWorldVertex;
|
||||||
|
|
||||||
|
varying float vUnitHeight;
|
||||||
|
|
||||||
|
float computeDepthBlur(float depth, float focus, float near, float far, float clampval )
|
||||||
|
{
|
||||||
|
float f;
|
||||||
|
if (depth < focus){
|
||||||
|
f = (depth - focus)/(focus - near);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
f = (depth - focus)/(far - focus);
|
||||||
|
f = clamp(f, 0.0, clampval);
|
||||||
|
}
|
||||||
|
return f * 0.5 + 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 lighting( in vec4 colormap, in vec3 N )
|
||||||
|
{
|
||||||
|
vec4 final_color = gl_LightSource[osgOcean_LightID].ambient * colormap;
|
||||||
|
|
||||||
|
vec3 L = normalize(vLightDir);
|
||||||
|
|
||||||
|
float lambertTerm = dot(N,L);
|
||||||
|
|
||||||
|
if(lambertTerm > 0.0)
|
||||||
|
{
|
||||||
|
final_color += gl_LightSource[osgOcean_LightID].diffuse * lambertTerm * colormap;
|
||||||
|
|
||||||
|
vec3 E = normalize(vEyeVec);
|
||||||
|
vec3 R = reflect(-L, N);
|
||||||
|
|
||||||
|
float specular = pow( max(dot(R, E), 0.0), 2.0 );
|
||||||
|
|
||||||
|
final_color += gl_LightSource[osgOcean_LightID].specular * specular;
|
||||||
|
}
|
||||||
|
|
||||||
|
return final_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
float computeFogFactor( float density, float fogCoord )
|
||||||
|
{
|
||||||
|
return exp2(density * fogCoord * fogCoord );
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
vec4 baseColor = texture2D( uTextureMap, gl_TexCoord[0].st );
|
||||||
|
vec4 overlayColor = texture2D( uOverlayMap, gl_TexCoord[1].st );
|
||||||
|
vec4 bumpColor = texture2D( uNormalMap, gl_TexCoord[0].st );
|
||||||
|
|
||||||
|
float unitHeight = clamp( vUnitHeight, 0.0, 1.0);
|
||||||
|
vec4 textureColor = mix(overlayColor, baseColor, unitHeight);
|
||||||
|
|
||||||
|
vec3 bump = (bumpColor.xyz*2.0)-1.0;
|
||||||
|
|
||||||
|
float fogFactor = 0.0;
|
||||||
|
vec4 fogColor;
|
||||||
|
|
||||||
|
vec4 final_color = lighting( textureColor, bump );
|
||||||
|
|
||||||
|
// +2 tweak here as waves peak above average wave height,
|
||||||
|
// and surface fog becomes visible.
|
||||||
|
if(osgOcean_EyeUnderwater && vWorldVertex.z < osgOcean_WaterHeight+2.0)
|
||||||
|
{
|
||||||
|
// mix in underwater light
|
||||||
|
if( osgOcean_EnableUnderwaterScattering )
|
||||||
|
{
|
||||||
|
final_color.rgb = final_color.rgb * vExtinction + vInScattering;
|
||||||
|
}
|
||||||
|
|
||||||
|
fogFactor = computeFogFactor( osgOcean_UnderwaterFogDensity, gl_FogFragCoord );
|
||||||
|
fogColor = osgOcean_UnderwaterFogColor;
|
||||||
|
|
||||||
|
// depth buffer
|
||||||
|
if(osgOcean_EnableDOF)
|
||||||
|
{
|
||||||
|
float depthBlur = computeDepthBlur( gl_FogFragCoord, osgOcean_DOF_Focus, osgOcean_DOF_Near, osgOcean_DOF_Far, osgOcean_DOF_Clamp );
|
||||||
|
gl_FragData[1] = vec4(depthBlur);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fogFactor = computeFogFactor( osgOcean_AboveWaterFogDensity, gl_FogFragCoord );
|
||||||
|
fogColor = osgOcean_AboveWaterFogColor;
|
||||||
|
|
||||||
|
// luminance buffer
|
||||||
|
if(osgOcean_EnableGlare)
|
||||||
|
{
|
||||||
|
gl_FragData[1] = vec4(0.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// color buffer
|
||||||
|
gl_FragData[0] = mix( fogColor, final_color, fogFactor );
|
||||||
|
}
|
79
Source/resources/shaders/terrain.vert
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
// osgOcean uniforms
|
||||||
|
// -------------------
|
||||||
|
uniform float osgOcean_WaterHeight;
|
||||||
|
uniform vec3 osgOcean_Eye;
|
||||||
|
uniform vec3 osgOcean_UnderwaterAttenuation;
|
||||||
|
uniform vec4 osgOcean_UnderwaterDiffuse;
|
||||||
|
uniform bool osgOcean_EnableUnderwaterScattering;
|
||||||
|
// ------------------
|
||||||
|
|
||||||
|
uniform vec2 uHeightRange;
|
||||||
|
uniform float uOneOverHeight;
|
||||||
|
uniform mat4 osg_ViewMatrixInverse;
|
||||||
|
|
||||||
|
varying float vUnitHeight;
|
||||||
|
|
||||||
|
varying vec3 vLightDir;
|
||||||
|
varying vec3 vEyeVec;
|
||||||
|
varying vec3 vExtinction;
|
||||||
|
varying vec3 vInScattering;
|
||||||
|
varying vec4 vWorldVertex;
|
||||||
|
|
||||||
|
attribute vec3 aTangent;
|
||||||
|
|
||||||
|
void computeScattering( in vec3 eye, in vec3 worldVertex, out vec3 extinction, out vec3 inScattering )
|
||||||
|
{
|
||||||
|
float viewDist = length(eye-worldVertex);
|
||||||
|
|
||||||
|
float depth = max(osgOcean_WaterHeight-worldVertex.z, 0.0);
|
||||||
|
|
||||||
|
extinction = exp(-osgOcean_UnderwaterAttenuation*viewDist*2.0);
|
||||||
|
|
||||||
|
// Need to compute accurate kd constant.
|
||||||
|
// const vec3 kd = vec3(0.001, 0.001, 0.001);
|
||||||
|
inScattering = osgOcean_UnderwaterDiffuse.rgb * (1.0-extinction*exp(-depth*vec3(0.001)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
gl_TexCoord[0] = gl_MultiTexCoord0*vec4(16.0,16.0,1.0,1.0);
|
||||||
|
gl_TexCoord[1] = gl_MultiTexCoord0*vec4(20.0,20.0,1.0,1.0);
|
||||||
|
gl_TexCoord[2] = gl_MultiTexCoord0*vec4(25.0,25.0,1.0,1.0);
|
||||||
|
|
||||||
|
vec3 vertex = vec3(gl_ModelViewMatrix * gl_Vertex);
|
||||||
|
vEyeVec = -vertex;
|
||||||
|
|
||||||
|
vec3 n = normalize(gl_NormalMatrix * gl_Normal);
|
||||||
|
vec3 t = normalize(gl_NormalMatrix * aTangent);
|
||||||
|
vec3 b = cross(n, t);
|
||||||
|
|
||||||
|
vec3 tmpVec = vec3(gl_LightSource[0].position.xyz);
|
||||||
|
tmpVec = normalize(tmpVec);
|
||||||
|
|
||||||
|
vLightDir.x = dot(tmpVec, t);
|
||||||
|
vLightDir.y = dot(tmpVec, b);
|
||||||
|
vLightDir.z = dot(tmpVec, n);
|
||||||
|
|
||||||
|
tmpVec = -vertex;
|
||||||
|
vEyeVec.x = dot(tmpVec, t);
|
||||||
|
vEyeVec.y = dot(tmpVec, b);
|
||||||
|
vEyeVec.z = dot(tmpVec, n);
|
||||||
|
|
||||||
|
gl_Position = ftransform();
|
||||||
|
|
||||||
|
gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;
|
||||||
|
|
||||||
|
gl_FogFragCoord = gl_Position.z;
|
||||||
|
|
||||||
|
float inv = 1.0 / ( uHeightRange.y - (uHeightRange.x+65.0) );
|
||||||
|
vUnitHeight = inv * (gl_Vertex.z - (uHeightRange.x+65.0));
|
||||||
|
|
||||||
|
vWorldVertex = (osg_ViewMatrixInverse*gl_ModelViewMatrix) * gl_Vertex;
|
||||||
|
|
||||||
|
if( osgOcean_EnableUnderwaterScattering )
|
||||||
|
{
|
||||||
|
computeScattering( osgOcean_Eye, vWorldVertex.xyz, vExtinction, vInScattering );
|
||||||
|
}
|
||||||
|
|
||||||
|
gl_Position = ftransform();
|
||||||
|
}
|
129
Source/resources/shaders/terrain_lispsm.frag
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
// osgOcean uniforms
|
||||||
|
// -------------------
|
||||||
|
uniform float osgOcean_DOF_Near;
|
||||||
|
uniform float osgOcean_DOF_Focus;
|
||||||
|
uniform float osgOcean_DOF_Far;
|
||||||
|
uniform float osgOcean_DOF_Clamp;
|
||||||
|
|
||||||
|
uniform bool osgOcean_EnableGlare;
|
||||||
|
uniform bool osgOcean_EnableDOF;
|
||||||
|
uniform bool osgOcean_EyeUnderwater;
|
||||||
|
uniform bool osgOcean_EnableUnderwaterScattering;
|
||||||
|
|
||||||
|
uniform float osgOcean_UnderwaterFogDensity;
|
||||||
|
uniform float osgOcean_AboveWaterFogDensity;
|
||||||
|
uniform float osgOcean_WaterHeight;
|
||||||
|
|
||||||
|
uniform vec4 osgOcean_UnderwaterFogColor;
|
||||||
|
uniform vec4 osgOcean_AboveWaterFogColor;
|
||||||
|
// -------------------
|
||||||
|
|
||||||
|
uniform sampler2D uTextureMap;
|
||||||
|
uniform sampler2D uOverlayMap;
|
||||||
|
uniform sampler2D uNormalMap;
|
||||||
|
|
||||||
|
varying vec3 vLightDir;
|
||||||
|
varying vec3 vEyeVec;
|
||||||
|
varying vec3 vExtinction;
|
||||||
|
varying vec3 vInScattering;
|
||||||
|
|
||||||
|
varying vec4 vWorldVertex;
|
||||||
|
|
||||||
|
varying float vUnitHeight;
|
||||||
|
|
||||||
|
uniform sampler2DShadow shadowTexture;
|
||||||
|
|
||||||
|
float computeDepthBlur(float depth, float focus, float near, float far, float clampval )
|
||||||
|
{
|
||||||
|
float f;
|
||||||
|
if (depth < focus){
|
||||||
|
f = (depth - focus)/(focus - near);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
f = (depth - focus)/(far - focus);
|
||||||
|
f = clamp(f, 0.0, clampval);
|
||||||
|
}
|
||||||
|
return f * 0.5 + 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 lighting( in vec4 colormap, in vec3 N )
|
||||||
|
{
|
||||||
|
vec4 final_color = gl_LightSource[osgOcean_LightID].ambient * colormap;
|
||||||
|
|
||||||
|
float light = shadow2DProj( shadowTexture, gl_TexCoord[7] ).r;
|
||||||
|
|
||||||
|
vec3 L = normalize(vLightDir);
|
||||||
|
|
||||||
|
float lambertTerm = dot(N,L);
|
||||||
|
|
||||||
|
if(lambertTerm > 0.0)
|
||||||
|
{
|
||||||
|
final_color += gl_LightSource[osgOcean_LightID].diffuse * lambertTerm * colormap * light;
|
||||||
|
|
||||||
|
vec3 E = normalize(vEyeVec);
|
||||||
|
vec3 R = reflect(-L, N);
|
||||||
|
|
||||||
|
float specular = pow( max(dot(R, E), 0.0), 2.0 );
|
||||||
|
|
||||||
|
final_color += gl_LightSource[osgOcean_LightID].specular * specular * light;
|
||||||
|
}
|
||||||
|
|
||||||
|
return final_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
float computeFogFactor( float density, float fogCoord )
|
||||||
|
{
|
||||||
|
return exp2(density * fogCoord * fogCoord );
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
vec4 baseColor = texture2D( uTextureMap, gl_TexCoord[0].st );
|
||||||
|
vec4 overlayColor = texture2D( uOverlayMap, gl_TexCoord[1].st );
|
||||||
|
vec4 bumpColor = texture2D( uNormalMap, gl_TexCoord[0].st );
|
||||||
|
|
||||||
|
float unitHeight = clamp( vUnitHeight, 0.0, 1.0);
|
||||||
|
vec4 textureColor = mix(overlayColor, baseColor, unitHeight);
|
||||||
|
|
||||||
|
vec3 bump = (bumpColor.xyz*2.0)-1.0;
|
||||||
|
|
||||||
|
float fogFactor = 0.0;
|
||||||
|
vec4 fogColor;
|
||||||
|
|
||||||
|
vec4 final_color = lighting( textureColor, bump );
|
||||||
|
|
||||||
|
// +2 tweak here as waves peak above average wave height,
|
||||||
|
// and surface fog becomes visible.
|
||||||
|
if(osgOcean_EyeUnderwater && vWorldVertex.z < osgOcean_WaterHeight+2.0)
|
||||||
|
{
|
||||||
|
// mix in underwater light
|
||||||
|
if( osgOcean_EnableUnderwaterScattering )
|
||||||
|
{
|
||||||
|
final_color.rgb = final_color.rgb * vExtinction + vInScattering;
|
||||||
|
}
|
||||||
|
|
||||||
|
fogFactor = computeFogFactor( osgOcean_UnderwaterFogDensity, gl_FogFragCoord );
|
||||||
|
fogColor = osgOcean_UnderwaterFogColor;
|
||||||
|
|
||||||
|
// depth buffer
|
||||||
|
if(osgOcean_EnableDOF)
|
||||||
|
{
|
||||||
|
float depthBlur = computeDepthBlur( gl_FogFragCoord, osgOcean_DOF_Focus, osgOcean_DOF_Near, osgOcean_DOF_Far, osgOcean_DOF_Clamp );
|
||||||
|
gl_FragData[1] = vec4(depthBlur);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fogFactor = computeFogFactor( osgOcean_AboveWaterFogDensity, gl_FogFragCoord );
|
||||||
|
fogColor = osgOcean_AboveWaterFogColor;
|
||||||
|
|
||||||
|
// luminance buffer
|
||||||
|
if(osgOcean_EnableGlare)
|
||||||
|
{
|
||||||
|
gl_FragData[1] = vec4(0.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// color buffer
|
||||||
|
gl_FragData[0] = mix( fogColor, final_color, fogFactor );
|
||||||
|
}
|
86
Source/resources/shaders/terrain_lispsm.vert
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
// osgOcean uniforms
|
||||||
|
// -------------------
|
||||||
|
uniform float osgOcean_WaterHeight;
|
||||||
|
uniform vec3 osgOcean_Eye;
|
||||||
|
uniform vec3 osgOcean_UnderwaterAttenuation;
|
||||||
|
uniform vec4 osgOcean_UnderwaterDiffuse;
|
||||||
|
uniform bool osgOcean_EnableUnderwaterScattering;
|
||||||
|
// ------------------
|
||||||
|
|
||||||
|
uniform vec2 uHeightRange;
|
||||||
|
uniform float uOneOverHeight;
|
||||||
|
uniform mat4 osg_ViewMatrixInverse;
|
||||||
|
|
||||||
|
varying float vUnitHeight;
|
||||||
|
|
||||||
|
varying vec3 vLightDir;
|
||||||
|
varying vec3 vEyeVec;
|
||||||
|
varying vec3 vExtinction;
|
||||||
|
varying vec3 vInScattering;
|
||||||
|
varying vec4 vWorldVertex;
|
||||||
|
|
||||||
|
attribute vec3 aTangent;
|
||||||
|
|
||||||
|
void computeScattering( in vec3 eye, in vec3 worldVertex, out vec3 extinction, out vec3 inScattering )
|
||||||
|
{
|
||||||
|
float viewDist = length(eye-worldVertex);
|
||||||
|
|
||||||
|
float depth = max(osgOcean_WaterHeight-worldVertex.z, 0.0);
|
||||||
|
|
||||||
|
extinction = exp(-osgOcean_UnderwaterAttenuation*viewDist*2.0);
|
||||||
|
|
||||||
|
// Need to compute accurate kd constant.
|
||||||
|
// const vec3 kd = vec3(0.001, 0.001, 0.001);
|
||||||
|
inScattering = osgOcean_UnderwaterDiffuse.rgb * (1.0-extinction*exp(-depth*vec3(0.001)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
gl_TexCoord[0] = gl_MultiTexCoord0*vec4(16.0,16.0,1.0,1.0);
|
||||||
|
gl_TexCoord[1] = gl_MultiTexCoord0*vec4(20.0,20.0,1.0,1.0);
|
||||||
|
gl_TexCoord[2] = gl_MultiTexCoord0*vec4(25.0,25.0,1.0,1.0);
|
||||||
|
|
||||||
|
vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex;
|
||||||
|
vec3 vertex = vec3(ecPosition);
|
||||||
|
vEyeVec = -vertex;
|
||||||
|
|
||||||
|
vec3 n = normalize(gl_NormalMatrix * gl_Normal);
|
||||||
|
vec3 t = normalize(gl_NormalMatrix * aTangent);
|
||||||
|
vec3 b = cross(n, t);
|
||||||
|
|
||||||
|
vec3 tmpVec = vec3(gl_LightSource[0].position.xyz);
|
||||||
|
tmpVec = normalize(tmpVec);
|
||||||
|
|
||||||
|
vLightDir.x = dot(tmpVec, t);
|
||||||
|
vLightDir.y = dot(tmpVec, b);
|
||||||
|
vLightDir.z = dot(tmpVec, n);
|
||||||
|
|
||||||
|
tmpVec = -vertex;
|
||||||
|
vEyeVec.x = dot(tmpVec, t);
|
||||||
|
vEyeVec.y = dot(tmpVec, b);
|
||||||
|
vEyeVec.z = dot(tmpVec, n);
|
||||||
|
|
||||||
|
gl_Position = ftransform();
|
||||||
|
|
||||||
|
gl_ClipVertex = ecPosition;
|
||||||
|
|
||||||
|
gl_FogFragCoord = gl_Position.z;
|
||||||
|
|
||||||
|
float inv = 1.0 / ( uHeightRange.y - (uHeightRange.x+65.0) );
|
||||||
|
vUnitHeight = inv * (gl_Vertex.z - (uHeightRange.x+65.0));
|
||||||
|
|
||||||
|
vWorldVertex = (osg_ViewMatrixInverse*gl_ModelViewMatrix) * gl_Vertex;
|
||||||
|
|
||||||
|
if( osgOcean_EnableUnderwaterScattering )
|
||||||
|
{
|
||||||
|
computeScattering( osgOcean_Eye, vWorldVertex.xyz, vExtinction, vInScattering );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate shadow map coords
|
||||||
|
gl_TexCoord[7].s = dot( ecPosition, gl_EyePlaneS[7] );
|
||||||
|
gl_TexCoord[7].t = dot( ecPosition, gl_EyePlaneT[7] );
|
||||||
|
gl_TexCoord[7].p = dot( ecPosition, gl_EyePlaneR[7] );
|
||||||
|
gl_TexCoord[7].q = dot( ecPosition, gl_EyePlaneQ[7] );
|
||||||
|
|
||||||
|
gl_Position = ftransform();
|
||||||
|
}
|
BIN
Source/resources/textures/sea_foam.png
Normal file
After Width: | Height: | Size: 61 KiB |
BIN
Source/resources/textures/sky_clear/down.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
BIN
Source/resources/textures/sky_clear/east.png
Normal file
After Width: | Height: | Size: 173 KiB |
BIN
Source/resources/textures/sky_clear/north.png
Normal file
After Width: | Height: | Size: 180 KiB |
BIN
Source/resources/textures/sky_clear/south.png
Normal file
After Width: | Height: | Size: 166 KiB |
BIN
Source/resources/textures/sky_clear/up.png
Normal file
After Width: | Height: | Size: 237 KiB |
BIN
Source/resources/textures/sky_clear/west.png
Normal file
After Width: | Height: | Size: 170 KiB |
BIN
Source/resources/textures/sky_dusk/down.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
BIN
Source/resources/textures/sky_dusk/east.png
Normal file
After Width: | Height: | Size: 238 KiB |
BIN
Source/resources/textures/sky_dusk/north.png
Normal file
After Width: | Height: | Size: 295 KiB |
BIN
Source/resources/textures/sky_dusk/old/down.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
BIN
Source/resources/textures/sky_dusk/old/east.png
Normal file
After Width: | Height: | Size: 259 KiB |
BIN
Source/resources/textures/sky_dusk/old/north.png
Normal file
After Width: | Height: | Size: 319 KiB |
BIN
Source/resources/textures/sky_dusk/old/south.png
Normal file
After Width: | Height: | Size: 216 KiB |
BIN
Source/resources/textures/sky_dusk/old/up.png
Normal file
After Width: | Height: | Size: 363 KiB |
BIN
Source/resources/textures/sky_dusk/old/west.png
Normal file
After Width: | Height: | Size: 251 KiB |
BIN
Source/resources/textures/sky_dusk/south.png
Normal file
After Width: | Height: | Size: 197 KiB |
BIN
Source/resources/textures/sky_dusk/up.png
Normal file
After Width: | Height: | Size: 363 KiB |
BIN
Source/resources/textures/sky_dusk/west.png
Normal file
After Width: | Height: | Size: 228 KiB |
BIN
Source/resources/textures/sky_fair_cloudy/down.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
BIN
Source/resources/textures/sky_fair_cloudy/east.png
Normal file
After Width: | Height: | Size: 268 KiB |
BIN
Source/resources/textures/sky_fair_cloudy/north.png
Normal file
After Width: | Height: | Size: 528 KiB |
BIN
Source/resources/textures/sky_fair_cloudy/south.png
Normal file
After Width: | Height: | Size: 559 KiB |
BIN
Source/resources/textures/sky_fair_cloudy/up.png
Normal file
After Width: | Height: | Size: 568 KiB |
BIN
Source/resources/textures/sky_fair_cloudy/west.png
Normal file
After Width: | Height: | Size: 286 KiB |
BIN
Source/resources/textures/sun_glare.png
Normal file
After Width: | Height: | Size: 14 KiB |
205
Source/src/CMakeLists.txt
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
PROJECT(Dyt)
|
||||||
|
|
||||||
|
set(CMAKE_AUTOUIC ON)
|
||||||
|
set(CMAKE_AUTOMOC ON)
|
||||||
|
set(CMAKE_AUTORCC ON)
|
||||||
|
|
||||||
|
SET(CMAKE_CXX_STANDARD 17)
|
||||||
|
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
SET(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
|
|
||||||
|
find_package(QT NAMES Qt6 Qt5 COMPONENTS Widgets LinguistTools REQUIRED)
|
||||||
|
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets LinguistTools REQUIRED)
|
||||||
|
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Widgets LinguistTools DataVisualization Charts Network REQUIRED)
|
||||||
|
|
||||||
|
message("qt VERSION " ${QT_VERSION_MAJOR})
|
||||||
|
|
||||||
|
FILE(GLOB_RECURSE HEADER_FILES ./*.h common/*.h common/*.hpp model/*.h app/*.h)
|
||||||
|
FILE(GLOB_RECURSE CPP_FILES ./*.cpp common/*.cpp model/*.cpp app/*.cpp)
|
||||||
|
FILE(GLOB_RECURSE CC_FILES ./*.cc)
|
||||||
|
FILE(GLOB_RECURSE UI_FILES ./*.ui)
|
||||||
|
FILE(GLOB_RECURSE QRC_FILES ./*.qrc)
|
||||||
|
|
||||||
|
SET(
|
||||||
|
TS_FILES
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/translations/Dyt_zh_CN.ts
|
||||||
|
)
|
||||||
|
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
|
||||||
|
qt6_create_translation(QM_FILES ${CMAKE_CURRENT_SOURCE_DIR} ${TS_FILES})
|
||||||
|
add_custom_target(translations DEPENDS ${QM_FILES})
|
||||||
|
else()
|
||||||
|
qt5_create_translation(QM_FILES ${CMAKE_CURRENT_SOURCE_DIR} ${TS_FILES})
|
||||||
|
add_custom_target(translations DEPENDS ${QM_FILES})
|
||||||
|
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS WinExtras REQUIRED)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT QT_TRANSLATIONS_DIR)
|
||||||
|
get_target_property(QT${QT_VERSION_MAJOR}_QMAKE_EXECUTABLE Qt${QT_VERSION_MAJOR}::qmake IMPORTED_LOCATION)
|
||||||
|
execute_process( COMMAND ${QT6_QMAKE_EXECUTABLE} -query QT_INSTALL_TRANSLATIONS
|
||||||
|
OUTPUT_VARIABLE qt_translations_dir OUTPUT_STRIP_TRAILING_WHITESPACE )
|
||||||
|
file( TO_CMAKE_PATH "${qt_translations_dir}" qt_translations_dir)
|
||||||
|
set( QT_TRANSLATIONS_DIR ${qt_translations_dir} CACHE PATH
|
||||||
|
"The location of the Qt translations" FORCE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(USE_HOST_EVENT_LOOP)
|
||||||
|
add_definitions(-DCEF_USE_HOST_EVENT_LOOP)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_definitions(-D_SILENCE_ALL_MS_EXT_DEPRECATION_WARNINGS)
|
||||||
|
|
||||||
|
install(
|
||||||
|
FILES
|
||||||
|
${QM_FILES}
|
||||||
|
DESTINATION
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/translations
|
||||||
|
)
|
||||||
|
|
||||||
|
SET(
|
||||||
|
CONFIG_PATH
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/config/
|
||||||
|
)
|
||||||
|
|
||||||
|
SET(
|
||||||
|
THIRTY_PATH
|
||||||
|
${Thirdparty}/
|
||||||
|
)
|
||||||
|
|
||||||
|
configure_file(
|
||||||
|
${PROJECT_SOURCE_DIR}/config.cpp.in
|
||||||
|
${PROJECT_BINARY_DIR}/config.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
SET(
|
||||||
|
ALL_FILES
|
||||||
|
${HEADER_FILES}
|
||||||
|
${CPP_FILES}
|
||||||
|
${CC_FILES}
|
||||||
|
${UI_FILES}
|
||||||
|
${QRC_FILES}
|
||||||
|
${QM_FILES}
|
||||||
|
${PROJECT_BINARY_DIR}/config.cpp
|
||||||
|
${PROJECT_SOURCE_DIR}/${PROJECT_NAME}.manifest
|
||||||
|
)
|
||||||
|
|
||||||
|
INCLUDE_DIRECTORIES(
|
||||||
|
${PROJECT_BINARY_DIR}
|
||||||
|
${Thirdparty}/spdlog/include
|
||||||
|
${Thirdparty}/breakpad/include
|
||||||
|
${Thirdparty}/3rdParty_x64/include
|
||||||
|
${Thirdparty}/OpenSceneGraph-3.6.5/include
|
||||||
|
${Thirdparty}/osgOcean/include
|
||||||
|
${Thirdparty}/matlab/include
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
LINK_DIRECTORIES(
|
||||||
|
${Thirdparty}/spdlog/lib
|
||||||
|
${Thirdparty}/3rdParty_x64/lib
|
||||||
|
${Thirdparty}/OpenSceneGraph-3.6.5/lib
|
||||||
|
${Thirdparty}/osgOcean/lib
|
||||||
|
${Thirdparty}/matlab/lib/win64/microsoft
|
||||||
|
)
|
||||||
|
|
||||||
|
if(MSVC)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi")
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF")
|
||||||
|
|
||||||
|
foreach(var
|
||||||
|
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
|
||||||
|
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
|
||||||
|
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
|
||||||
|
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO
|
||||||
|
)
|
||||||
|
if(${var} MATCHES "/MD")
|
||||||
|
string(REGEX REPLACE "/MD" "/MT" ${var} "${${var}}")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
endif(MSVC)
|
||||||
|
if(NOT MSVC)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||||
|
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||||
|
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
|
||||||
|
endif()
|
||||||
|
endif(NOT MSVC)
|
||||||
|
|
||||||
|
SOURCE_GROUP_BY_DIR(ALL_FILES)
|
||||||
|
|
||||||
|
if(${QT_VERSION_MAJOR} GREATER_EQUAL 5)
|
||||||
|
add_executable(${PROJECT_NAME}
|
||||||
|
WIN32
|
||||||
|
${ALL_FILES}
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
if(MINGW OR MSVC)
|
||||||
|
target_compile_definitions(${PROJECT_NAME} PRIVATE
|
||||||
|
UNICODE _UNICODE
|
||||||
|
)
|
||||||
|
|
||||||
|
SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "/MP")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
target_link_libraries(
|
||||||
|
${PROJECT_NAME}
|
||||||
|
PRIVATE
|
||||||
|
Qt${QT_VERSION_MAJOR}::Core
|
||||||
|
Qt${QT_VERSION_MAJOR}::Widgets
|
||||||
|
Qt${QT_VERSION_MAJOR}::Charts
|
||||||
|
Qt${QT_VERSION_MAJOR}::DataVisualization
|
||||||
|
Qt${QT_VERSION_MAJOR}::Network
|
||||||
|
spdlog
|
||||||
|
OpenThreads
|
||||||
|
osg
|
||||||
|
osgAnimation
|
||||||
|
osgDB
|
||||||
|
osgFX
|
||||||
|
osgGA
|
||||||
|
osgManipulator
|
||||||
|
osgUtil
|
||||||
|
osgViewer
|
||||||
|
osgShadow
|
||||||
|
osgOcean
|
||||||
|
osgParticle
|
||||||
|
osgSim
|
||||||
|
libMatlabDataArray
|
||||||
|
libMatlabEngine
|
||||||
|
)
|
||||||
|
|
||||||
|
if(${QT_VERSION_MAJOR} LESS 6)
|
||||||
|
target_link_libraries(
|
||||||
|
${PROJECT_NAME}
|
||||||
|
PRIVATE
|
||||||
|
Qt${QT_VERSION_MAJOR}::WinExtras
|
||||||
|
)
|
||||||
|
|
||||||
|
endif()
|
||||||
|
|
||||||
|
SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${ProjectDIR}/bin)
|
||||||
|
|
||||||
|
TARGET_LINK_LIBRARIES(${PROJECT_NAME})
|
||||||
|
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:CONSOLE")
|
||||||
|
|
||||||
|
add_custom_command(TARGET ${PROJECT_NAME}
|
||||||
|
POST_BUILD
|
||||||
|
|
||||||
|
COMMAND mt.exe
|
||||||
|
-manifest \"${CMAKE_CURRENT_SOURCE_DIR}\\${PROJECT_NAME}.manifest\"
|
||||||
|
-inputresource:\"$<TARGET_FILE:${PROJECT_NAME}>\"
|
||||||
|
-outputresource:\"$<TARGET_FILE:${PROJECT_NAME}>\"
|
||||||
|
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||||
|
${ProjectDIR}/resources
|
||||||
|
${ProjectDIR}/bin/Release/resources
|
||||||
|
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||||
|
${ProjectDIR}/workspace
|
||||||
|
${ProjectDIR}/bin/Release/workspace
|
||||||
|
#
|
||||||
|
# COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||||
|
# ${Thirdparty}/libcef/resources
|
||||||
|
# ${ProjectDIR}/bin/Debug
|
||||||
|
)
|
11
Source/src/Dyt.manifest
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||||
|
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||||
|
<application>
|
||||||
|
<!--The ID below indicates application support for Windows 8.1 -->
|
||||||
|
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
|
||||||
|
<!-- 10.0 -->
|
||||||
|
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
|
||||||
|
</application>
|
||||||
|
</compatibility>
|
||||||
|
</assembly>
|
31
Source/src/Dyt.qrc
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<RCC>
|
||||||
|
<qresource prefix="/">
|
||||||
|
<file>res/sys_close.png</file>
|
||||||
|
<file>res/sys_max.png</file>
|
||||||
|
<file>res/sys_min.png</file>
|
||||||
|
<file>res/sys_restore.png</file>
|
||||||
|
<file>res/sys_icon.png</file>
|
||||||
|
<file>res/sys_down.png</file>
|
||||||
|
<file>res/sys_up.png</file>
|
||||||
|
<file>res/default/menu_new_file.png</file>
|
||||||
|
<file>res/default/menu_open_file.png</file>
|
||||||
|
<file>res/default/menu_save_file.png</file>
|
||||||
|
<file>res/default/menu_save_as_file.png</file>
|
||||||
|
<file>res/default/menu_save_shape_file.png</file>
|
||||||
|
<file>res/default/menu_save_store_file.png</file>
|
||||||
|
<file>res/default/menu_report_mesh.png</file>
|
||||||
|
<file>res/default/menu_exit.png</file>
|
||||||
|
<file>res/default/menu_helper.png</file>
|
||||||
|
<file>res/default/menu_license.png</file>
|
||||||
|
<file>res/default/menu_logs.png</file>
|
||||||
|
<file>res/default/menu_logs_clean.png</file>
|
||||||
|
<file>res/default/menu_restart.png</file>
|
||||||
|
<file>res/default/menu_setting_restore.png</file>
|
||||||
|
<file>res/default/menu_setting.png</file>
|
||||||
|
</qresource>
|
||||||
|
<qresource prefix="/qss">
|
||||||
|
</qresource>
|
||||||
|
<qresource prefix="/fonts">
|
||||||
|
<file>res/fonts/fontawesome-webfont.ttf</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
42
Source/src/app/Application.cpp
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#include "app/Application.h"
|
||||||
|
|
||||||
|
#include "common/RecourceHelper.h"
|
||||||
|
#include "workspace/WorkSpaceManager.h"
|
||||||
|
#include "entities/EntitiesManager.h"
|
||||||
|
#include "viewer/OsgViewer.h"
|
||||||
|
#include "scene/MeshManager.h"
|
||||||
|
#include "network/NetDriver.h"
|
||||||
|
|
||||||
|
|
||||||
|
Application::Application(int& argc, char** argv, int /*= ApplicationFlags*/)
|
||||||
|
: QApplication(argc, argv) {
|
||||||
|
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
Application::~Application() {
|
||||||
|
Uninit();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Application::GetWorkSpacePath() {
|
||||||
|
const QString path = QString("%1/workspace").arg(applicationDirPath());
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::Init() {
|
||||||
|
Singleton<MeshManager>::Create(this);
|
||||||
|
Singleton<OsgViewer>::Create(this);
|
||||||
|
Singleton<RecourceHelper>::Create(this);
|
||||||
|
Singleton<EntitiesManager>::Create(this);
|
||||||
|
Singleton<WorkSpaceManager>::Create(this);
|
||||||
|
Singleton<NetDriver>::Create(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::Uninit() {
|
||||||
|
Singleton<NetDriver>::Destory();
|
||||||
|
Singleton<WorkSpaceManager>::Destory();
|
||||||
|
Singleton<EntitiesManager>::Destory();
|
||||||
|
Singleton<RecourceHelper>::Destory();
|
||||||
|
Singleton<OsgViewer>::Destory();
|
||||||
|
Singleton<MeshManager>::Destory();
|
||||||
|
}
|
17
Source/src/app/Application.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
class Application : public QApplication {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
Application(int& argc, char** argv, int = ApplicationFlags);
|
||||||
|
~Application() override;
|
||||||
|
|
||||||
|
static QString GetWorkSpacePath();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void Init();
|
||||||
|
void Uninit();
|
||||||
|
};
|
39
Source/src/app/Singleton.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class Singleton {
|
||||||
|
|
||||||
|
public:
|
||||||
|
Singleton() {
|
||||||
|
assert(nullptr == instance_);
|
||||||
|
instance_ = static_cast<T*>(this);
|
||||||
|
}
|
||||||
|
~Singleton() {
|
||||||
|
assert(nullptr != instance_);
|
||||||
|
instance_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static T& Get() {
|
||||||
|
assert(nullptr != instance_);
|
||||||
|
return *instance_;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class O>
|
||||||
|
static T* Create(O* obj) {
|
||||||
|
T* t = new T(obj);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Destory() {
|
||||||
|
T* t = &T::Get();
|
||||||
|
t->OnDestory();
|
||||||
|
delete t;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static T* instance_;
|
||||||
|
};
|
112
Source/src/common/CrashHandler.cpp
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
#include "CrashHandler.h"
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QDateTime>
|
||||||
|
#if NDEBUG
|
||||||
|
|
||||||
|
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
|
||||||
|
#include "client/windows/handler/exception_handler.h"
|
||||||
|
|
||||||
|
#elif defined(__APPLE__) && (defined(__GNUC__) || defined(__xlC__) || defined(__xlc__))
|
||||||
|
#include "client/mac/handler/exception_handler.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
bool FindFileForDelete(const QString& path) {
|
||||||
|
QDir dir(path);
|
||||||
|
if (!dir.exists())
|
||||||
|
return false;
|
||||||
|
dir.setFilter(QDir::Dirs | QDir::Files);
|
||||||
|
dir.setSorting(QDir::DirsFirst);
|
||||||
|
QFileInfoList list = dir.entryInfoList();
|
||||||
|
int i = 0;
|
||||||
|
do {
|
||||||
|
QFileInfo fileInfo = list.at(i);
|
||||||
|
if (fileInfo.fileName() == "." || fileInfo.fileName() == "..") {
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
bool bisDir = fileInfo.isDir();
|
||||||
|
if (bisDir) {
|
||||||
|
|
||||||
|
qDebug() << qPrintable(QString("%1 %2 %3").arg(fileInfo.size(), 10)
|
||||||
|
.arg(fileInfo.fileName(), 10).arg(fileInfo.path())) ;
|
||||||
|
|
||||||
|
FindFileForDelete(fileInfo.filePath());
|
||||||
|
} else {
|
||||||
|
QDateTime delDateTime = QDateTime::currentDateTime().addDays(-5);
|
||||||
|
qint64 nSecs = delDateTime.secsTo(fileInfo.birthTime());
|
||||||
|
if (nSecs < 0) {
|
||||||
|
|
||||||
|
qDebug() << qPrintable(QString("%1 %2 %3").arg(fileInfo.size(), 10)
|
||||||
|
.arg(fileInfo.fileName(), 10).arg(fileInfo.path())) ;
|
||||||
|
fileInfo.dir().remove(fileInfo.fileName());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
} while (i < list.size());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
|
||||||
|
static bool OnMinidumpCallback(const wchar_t* dump_path,
|
||||||
|
const wchar_t* minidump_id,
|
||||||
|
void* context,
|
||||||
|
EXCEPTION_POINTERS* exinfo,
|
||||||
|
MDRawAssertionInfo* assertion,
|
||||||
|
bool succeeded) {
|
||||||
|
#else
|
||||||
|
static bool OnMinidumpCallback(const char* dump_path,
|
||||||
|
const char* id,
|
||||||
|
void* context,
|
||||||
|
bool succeeded) {
|
||||||
|
#endif
|
||||||
|
qCritical() << __FUNCTION__ << minidump_id;
|
||||||
|
const QString title = QObject::tr("error");
|
||||||
|
const QString content = QObject::tr("the appliaction is crash");
|
||||||
|
|
||||||
|
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
|
||||||
|
MessageBox(nullptr, content.toStdWString().c_str(), title.toStdWString().c_str(), MB_OK);
|
||||||
|
#endif
|
||||||
|
return succeeded;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<google_breakpad::ExceptionHandler> exceptionHandler;
|
||||||
|
#endif
|
||||||
|
bool InstallCrashHandler() {
|
||||||
|
#if NDEBUG
|
||||||
|
FindFileForDelete("D:/pcm");
|
||||||
|
QString appDirPath = QCoreApplication::applicationDirPath() + "/crash";
|
||||||
|
QDir dir;
|
||||||
|
if (!dir.exists(appDirPath)) {
|
||||||
|
bool res = dir.mkpath(appDirPath);
|
||||||
|
qDebug() << "New mkdir " << appDirPath << " " << res;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exceptionHandler) {
|
||||||
|
qWarning() << __FUNCTION__ << "exceptionHandler exits";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
|
||||||
|
exceptionHandler.reset(new google_breakpad::ExceptionHandler(
|
||||||
|
appDirPath.toStdWString(), NULL, OnMinidumpCallback, NULL,
|
||||||
|
google_breakpad::ExceptionHandler::HANDLER_ALL));
|
||||||
|
#else
|
||||||
|
exceptionHandler.reset(new google_breakpad::ExceptionHandler(
|
||||||
|
appDirPath.toStdString(), NULL, OnMinidumpCallback, NULL,
|
||||||
|
google_breakpad::ExceptionHandler::HANDLER_ALL));
|
||||||
|
#endif
|
||||||
|
return !!exceptionHandler;
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestCrash() {
|
||||||
|
volatile int* a = (int*)(nullptr);
|
||||||
|
*a = 1;
|
||||||
|
}
|
5
Source/src/common/CrashHandler.h
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
bool InstallCrashHandler();
|
||||||
|
void TestCrash();
|
77
Source/src/common/PugiXML/pugiconfig.hpp
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
/**
|
||||||
|
* pugixml parser - version 1.14
|
||||||
|
* --------------------------------------------------------
|
||||||
|
* Copyright (C) 2006-2024, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
|
||||||
|
* Report bugs and download new versions at https://pugixml.org/
|
||||||
|
*
|
||||||
|
* This library is distributed under the MIT License. See notice at the end
|
||||||
|
* of this file.
|
||||||
|
*
|
||||||
|
* This work is based on the pugxml parser, which is:
|
||||||
|
* Copyright (C) 2003, by Kristen Wegner (kristen@tima.net)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HEADER_PUGICONFIG_HPP
|
||||||
|
#define HEADER_PUGICONFIG_HPP
|
||||||
|
|
||||||
|
// Uncomment this to enable wchar_t mode
|
||||||
|
// #define PUGIXML_WCHAR_MODE
|
||||||
|
|
||||||
|
// Uncomment this to enable compact mode
|
||||||
|
// #define PUGIXML_COMPACT
|
||||||
|
|
||||||
|
// Uncomment this to disable XPath
|
||||||
|
// #define PUGIXML_NO_XPATH
|
||||||
|
|
||||||
|
// Uncomment this to disable STL
|
||||||
|
// #define PUGIXML_NO_STL
|
||||||
|
|
||||||
|
// Uncomment this to disable exceptions
|
||||||
|
// #define PUGIXML_NO_EXCEPTIONS
|
||||||
|
|
||||||
|
// Set this to control attributes for public classes/functions, i.e.:
|
||||||
|
// #define PUGIXML_API __declspec(dllexport) // to export all public symbols from DLL
|
||||||
|
// #define PUGIXML_CLASS __declspec(dllimport) // to import all classes from DLL
|
||||||
|
// #define PUGIXML_FUNCTION __fastcall // to set calling conventions to all public functions to fastcall
|
||||||
|
// In absence of PUGIXML_CLASS/PUGIXML_FUNCTION definitions PUGIXML_API is used instead
|
||||||
|
|
||||||
|
// Tune these constants to adjust memory-related behavior
|
||||||
|
// #define PUGIXML_MEMORY_PAGE_SIZE 32768
|
||||||
|
// #define PUGIXML_MEMORY_OUTPUT_STACK 10240
|
||||||
|
// #define PUGIXML_MEMORY_XPATH_PAGE_SIZE 4096
|
||||||
|
|
||||||
|
// Tune this constant to adjust max nesting for XPath queries
|
||||||
|
// #define PUGIXML_XPATH_DEPTH_LIMIT 1024
|
||||||
|
|
||||||
|
// Uncomment this to switch to header-only version
|
||||||
|
// #define PUGIXML_HEADER_ONLY
|
||||||
|
|
||||||
|
// Uncomment this to enable long long support
|
||||||
|
// #define PUGIXML_HAS_LONG_LONG
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2006-2024 Arseny Kapoulkine
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use,
|
||||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following
|
||||||
|
* conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
|
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
13245
Source/src/common/PugiXML/pugixml.cpp
Normal file
1516
Source/src/common/PugiXML/pugixml.hpp
Normal file
89
Source/src/common/RecourceHelper.cpp
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
#include "RecourceHelper.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QLocale>
|
||||||
|
|
||||||
|
#include <QFontDatabase>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QAbstractButton>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QAction>
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
template<> RecourceHelper* Singleton<RecourceHelper>::instance_ = nullptr;
|
||||||
|
RecourceHelper::RecourceHelper(QObject* parent)
|
||||||
|
: QObject(parent) {
|
||||||
|
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
RecourceHelper::~RecourceHelper() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void RecourceHelper::OnDestory() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void RecourceHelper::SetIcon(QLabel* lab, QChar c, quint32 size) {
|
||||||
|
iconFont_.setPointSize(size);
|
||||||
|
lab->setFont(iconFont_);
|
||||||
|
lab->setText(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RecourceHelper::SetIcon(QAbstractButton* btn, QChar c, quint32 size) {
|
||||||
|
iconFont_.setPointSize(size);
|
||||||
|
btn->setFont(iconFont_);
|
||||||
|
btn->setText(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RecourceHelper::OnChangeStyle() {
|
||||||
|
QAction* act = reinterpret_cast<QAction*>(sender());
|
||||||
|
QString skin = act->data().toString();
|
||||||
|
|
||||||
|
ChangeSkin(skin);
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString RecourceHelper::GetBasePath() const {
|
||||||
|
return QApplication::applicationDirPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RecourceHelper::ChangeSkin(const QString& skin) {
|
||||||
|
#if _DEBUG
|
||||||
|
const QString qssFile = QString("%1skin/%2.qss").arg(QString(CONFIG_PATH)).arg(skin);
|
||||||
|
#else
|
||||||
|
const QString appDirPath = QApplication::applicationDirPath();
|
||||||
|
const QString qssFile = QString("%1/config/skin/%2.qss").arg(appDirPath).arg(skin);
|
||||||
|
#endif
|
||||||
|
QFile file(qssFile);
|
||||||
|
if (file.open(QFile::ReadOnly | QFile::Text)) {
|
||||||
|
QTextStream stream(&file);
|
||||||
|
QString qss = stream.readAll();
|
||||||
|
qApp->setStyleSheet(qss);
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RecourceHelper::Init() {
|
||||||
|
int fontId = QFontDatabase::addApplicationFont(":/fonts/res/fonts/fontawesome-webfont.ttf");
|
||||||
|
QStringList fontName = QFontDatabase::applicationFontFamilies(fontId);
|
||||||
|
|
||||||
|
if (fontName.count() > 0) {
|
||||||
|
iconFont_ = QFont(fontName.at(0));
|
||||||
|
} else {
|
||||||
|
qDebug() << "fontName count <= 0 error";
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString appName = QApplication::applicationDisplayName();
|
||||||
|
#ifndef NDEBUG
|
||||||
|
const QString transName = QString("./%1_%2.qm").arg(appName, QLocale().name());
|
||||||
|
#else
|
||||||
|
const QString transName = QString("./translations/%1_%2.qm").arg(appName, QLocale().name());
|
||||||
|
#endif
|
||||||
|
bool success = trans_.load(transName);
|
||||||
|
if (!success) {
|
||||||
|
qDebug() << "load translations error";
|
||||||
|
}
|
||||||
|
QApplication::installTranslator(&trans_);
|
||||||
|
}
|
36
Source/src/common/RecourceHelper.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QFont>
|
||||||
|
#include <QTranslator>
|
||||||
|
|
||||||
|
#include "app/Singleton.h"
|
||||||
|
|
||||||
|
|
||||||
|
class QLabel;
|
||||||
|
class QAbstractButton;
|
||||||
|
|
||||||
|
class RecourceHelper : public QObject, public Singleton<RecourceHelper> {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit RecourceHelper(QObject* parent = 0);
|
||||||
|
~RecourceHelper() override;
|
||||||
|
void OnDestory();
|
||||||
|
|
||||||
|
static void ChangeSkin(const QString& skin);
|
||||||
|
|
||||||
|
void SetIcon(QLabel* lab, QChar c, quint32 size = 9);
|
||||||
|
void SetIcon(QAbstractButton* btn, QChar c, quint32 size = 9);
|
||||||
|
|
||||||
|
void OnChangeStyle();
|
||||||
|
|
||||||
|
const QString GetBasePath() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Init();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QFont iconFont_;
|
||||||
|
QTranslator trans_;
|
||||||
|
};
|
81
Source/src/common/SpdLogger.cpp
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
#include "SpdLogger.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
|
||||||
|
#include "spdlog/async.h"
|
||||||
|
#include "spdlog/sinks/rotating_file_sink.h"
|
||||||
|
#include "spdlog/sinks/stdout_sinks.h"
|
||||||
|
#include "spdlog/sinks/stdout_color_sinks.h"
|
||||||
|
|
||||||
|
const char* LoggerName = "spd_logger";
|
||||||
|
|
||||||
|
static SpdLogger* SpdLoggerIns_{ nullptr };
|
||||||
|
static void LogMessageOutput(QtMsgType type, const QMessageLogContext& context, const QString& msg) {
|
||||||
|
if (nullptr == SpdLoggerIns_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case QtDebugMsg:
|
||||||
|
LOG_DEBUG(msg.toStdString());
|
||||||
|
break;
|
||||||
|
case QtInfoMsg:
|
||||||
|
LOG_INFO(msg.toStdString());
|
||||||
|
break;
|
||||||
|
case QtWarningMsg:
|
||||||
|
LOG_WARN(msg.toStdString());
|
||||||
|
break;
|
||||||
|
case QtCriticalMsg:
|
||||||
|
LOG_CRITI(msg.toStdString());
|
||||||
|
break;
|
||||||
|
case QtFatalMsg:
|
||||||
|
LOG_ERROR(msg.toStdString());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SpdLogger::SpdLogger(const std::string& filename, int flush) {
|
||||||
|
constexpr std::size_t max_size = 1024 * 1024 * 10;
|
||||||
|
constexpr std::size_t max_files = 5;
|
||||||
|
//std::shared_ptr<spdlog::logger> logHander = spdlog::rotating_logger_mt<spdlog::async_factory>(LoggerName, filename, max_size, max_files);
|
||||||
|
auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(filename, max_size, max_files);
|
||||||
|
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
|
||||||
|
|
||||||
|
const char* pFormat = "[%Y-%m-%d %H:%M:%S.%e][%t][%^%l%$][%@]%v";
|
||||||
|
file_sink->set_pattern(pFormat);
|
||||||
|
console_sink->set_pattern(pFormat);
|
||||||
|
std::vector<spdlog::sink_ptr> sinks;
|
||||||
|
sinks.push_back(console_sink);
|
||||||
|
sinks.push_back(file_sink);
|
||||||
|
std::shared_ptr<spdlog::logger> logHander = std::make_shared<spdlog::logger>(LoggerName, begin(sinks), end(sinks));
|
||||||
|
|
||||||
|
#if NDEBUG
|
||||||
|
logHander->set_level(spdlog::level::debug);
|
||||||
|
|
||||||
|
#else
|
||||||
|
logHander->set_level(spdlog::level::debug);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (flush > 0) {
|
||||||
|
spdlog::flush_every(std::chrono::seconds(flush));
|
||||||
|
}
|
||||||
|
|
||||||
|
logHander->flush_on(spdlog::level::warn);
|
||||||
|
spdlog::initialize_logger(std::move(logHander));
|
||||||
|
std::shared_ptr< spdlog::logger>ll = spdlog::get(LoggerName);
|
||||||
|
|
||||||
|
assert(nullptr == SpdLoggerIns_);
|
||||||
|
SpdLoggerIns_ = this;
|
||||||
|
LOG_INFO("----------------------MAIN----------------------------------------");
|
||||||
|
qInstallMessageHandler(LogMessageOutput);
|
||||||
|
}
|
||||||
|
|
||||||
|
SpdLogger::~SpdLogger() {
|
||||||
|
assert(nullptr != SpdLoggerIns_);
|
||||||
|
SpdLoggerIns_ = nullptr;
|
||||||
|
|
||||||
|
LOG_INFO("----------------------FINISH----------------------------------------");
|
||||||
|
|
||||||
|
spdlog::drop_all();
|
||||||
|
spdlog::shutdown();
|
||||||
|
}
|
28
Source/src/common/SpdLogger.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "spdlog/spdlog.h"
|
||||||
|
|
||||||
|
#ifndef SPDLOG_NO_SOURCE_LOC
|
||||||
|
#undef SPDLOG_LOGGER_CALL
|
||||||
|
#define SPDLOG_LOGGER_CALL(logger, level, ...) \
|
||||||
|
(logger)->log(spdlog::source_loc{__FUNCTION__, __LINE__, SPDLOG_FUNCTION}, level, __VA_ARGS__)
|
||||||
|
#else
|
||||||
|
# define SPDLOG_LOGGER_CALL(logger, level, ...) (logger)->log(spdlog::source_loc{}, level, __VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class SpdLogger final {
|
||||||
|
public:
|
||||||
|
SpdLogger(const std::string& filename, int flush);
|
||||||
|
~SpdLogger();
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const char* LoggerName;
|
||||||
|
|
||||||
|
#define LOG_TRACE(...) SPDLOG_LOGGER_CALL(spdlog::get(LoggerName), spdlog::level::trace, __VA_ARGS__)
|
||||||
|
#define LOG_DEBUG(...) SPDLOG_LOGGER_CALL(spdlog::get(LoggerName), spdlog::level::debug, __VA_ARGS__)
|
||||||
|
#define LOG_INFO(...) SPDLOG_LOGGER_CALL(spdlog::get(LoggerName), spdlog::level::info, __VA_ARGS__)
|
||||||
|
#define LOG_WARN(...) SPDLOG_LOGGER_CALL(spdlog::get(LoggerName), spdlog::level::warn, __VA_ARGS__)
|
||||||
|
#define LOG_ERROR(...) SPDLOG_LOGGER_CALL(spdlog::get(LoggerName), spdlog::level::err, __VA_ARGS__)
|
||||||
|
#define LOG_CRITI(...) SPDLOG_LOGGER_CALL(spdlog::get(LoggerName), spdlog::level::critical, __VA_ARGS__)
|
||||||
|
|
17
Source/src/config.cpp.in
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#if WIN32
|
||||||
|
|
||||||
|
#if _DEBUG
|
||||||
|
#pragma comment(lib, "@THIRTY_PATH@breakpad/debug/lib/libbreakpad_clientd.lib")
|
||||||
|
#pragma comment(lib, "@THIRTY_PATH@breakpad/debug/lib/libbreakpadd.lib")
|
||||||
|
#pragma comment(lib, "@THIRTY_PATH@breakpad/debug/lib/libdisasmd.lib")
|
||||||
|
|
||||||
|
#else
|
||||||
|
#pragma comment(lib, "@THIRTY_PATH@breakpad/lib/libbreakpad_client.lib")
|
||||||
|
#pragma comment(lib, "@THIRTY_PATH@breakpad/lib/libbreakpad.lib")
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const char* CONFIG_PATH = "@CONFIG_PATH@";
|
18
Source/src/config.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
extern const char* CONFIG_PATH;
|
||||||
|
|
||||||
|
#define Q_REGISTER_METATYPE(T) \
|
||||||
|
static struct T##MetaTypeRegister { \
|
||||||
|
T##MetaTypeRegister() { \
|
||||||
|
qRegisterMetaType<T>(); \
|
||||||
|
} \
|
||||||
|
} g_##T##MetaTypeRegister; \
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#define FORCE_INLINE __forceinline
|
||||||
|
#elif defined(__GNUC__) || defined(__clang__)
|
||||||
|
#define FORCE_INLINE inline __attribute__((always_inline))
|
||||||
|
#else
|
||||||
|
#define FORCE_INLINE inline
|
||||||
|
#endif
|
144
Source/src/config/skin/blue.qss
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
QPalette{background:#F5F5F5;}*{outline:0px;color:#000000;}
|
||||||
|
|
||||||
|
QFrame {
|
||||||
|
background: #2E86C1;
|
||||||
|
border-top-left-radius:10px;
|
||||||
|
border-top-right-radius:10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QFrame#titleFrame{
|
||||||
|
border-bottom: 1 solid #76448A;
|
||||||
|
}
|
||||||
|
|
||||||
|
QLabel#sys_title {
|
||||||
|
color: #F4F6F6;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#sys_close {
|
||||||
|
max-width:48px;
|
||||||
|
min-width:48px;
|
||||||
|
max-height:28px;
|
||||||
|
min-height:28px;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
image: url(:/res/sys_close.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#sys_min {
|
||||||
|
max-width:48px;
|
||||||
|
min-width:48px;
|
||||||
|
max-height:28px;
|
||||||
|
min-height:28px;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
image: url(:/res/sys_min.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#sys_max {
|
||||||
|
max-width:48px;
|
||||||
|
min-width:48px;
|
||||||
|
max-height:28px;
|
||||||
|
min-height:28px;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
image: url(:/res/sys_max.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#sys_restore {
|
||||||
|
max-width:48px;
|
||||||
|
min-width:48px;
|
||||||
|
max-height:28px;
|
||||||
|
min-height:28px;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
image: url(:/res/sys_restore.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton#sys_skin {
|
||||||
|
max-width:48px;
|
||||||
|
min-width:48px;
|
||||||
|
max-height:28px;
|
||||||
|
min-height:28px;
|
||||||
|
border: none;
|
||||||
|
image: url(:/res/sys_down.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton#sys_skin::menu-indicator {
|
||||||
|
image: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#sys_close::hover, QPushButton#sys_close::pressed,
|
||||||
|
QPushButton#sys_min::hover, QPushButton#sys_min::pressed,
|
||||||
|
QPushButton#sys_max::hover, QPushButton#sys_max::pressed,
|
||||||
|
QPushButton#sys_restore::hover, QPushButton#sys_restore::pressed,
|
||||||
|
QToolButton#sys_skin::hover, QToolButton#sys_skin::pressed {
|
||||||
|
background: #38C0C0C0;
|
||||||
|
border: 1 solid #C0C0C0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton#sys_skin::checked {
|
||||||
|
image: url(:/res/sys_up.png);
|
||||||
|
background: #38C0C0C0;
|
||||||
|
border: 1 solid #C0C0C0;
|
||||||
|
}
|
||||||
|
QToolButton#sys_skin::unchecked {
|
||||||
|
image: url(:/res/sys_dwon.png);
|
||||||
|
background: #38C0C0C0;
|
||||||
|
border: 1 solid #C0C0C0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QTabWidget::pane{
|
||||||
|
border:1 solid #5D6D7E;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTabWidget::tab-bar {
|
||||||
|
left: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTabBar::tab {
|
||||||
|
background: #212F3C;
|
||||||
|
color:#7F8997;
|
||||||
|
min-width: 60px;
|
||||||
|
min-height: 25px;
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTabBar::tab:selected{
|
||||||
|
border: 2 solid #5D6D7E;
|
||||||
|
border-bottom: none;
|
||||||
|
border-top-left-radius: 5px;
|
||||||
|
border-top-right-radius: 5px;
|
||||||
|
color:#D6DBDF;
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton:hover {
|
||||||
|
background: #85929E ;
|
||||||
|
border: 1 solid #D6DBDF;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#FileManagerMenu > QToolButton {
|
||||||
|
qproperty-toolButtonStyle:ToolButtonTextUnderIcon;
|
||||||
|
qproperty-iconSize: 32px 32px;
|
||||||
|
font-size: 12px;
|
||||||
|
border-style:inset;
|
||||||
|
border:0px solid #E5E5E5;
|
||||||
|
min-height: 60px;
|
||||||
|
min-width: 60px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#FileManagerMenu > QToolButton#menu_new_file {
|
||||||
|
qproperty-icon: url(:/res/default/menu_new_file.png);
|
||||||
|
}
|
||||||
|
QWidget#FileManagerMenu > QToolButton#menu_open_file {
|
||||||
|
qproperty-icon: url(:/res/default/menu_open_file.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#view_display {
|
||||||
|
background:white;
|
||||||
|
}
|
295
Source/src/config/skin/default.css
Normal file
@ -0,0 +1,295 @@
|
|||||||
|
QPalette{background:#F5F5F5;}*{outline:0px;color:#000000;}
|
||||||
|
|
||||||
|
QWidget {
|
||||||
|
background: #1b2c3bcb;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
FrameTitleBar{
|
||||||
|
border-bottom: 1 solid #7FB3D5 ;
|
||||||
|
border-top-left-radius:10px;
|
||||||
|
border-top-right-radius:10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QFrame>QLabel#sys_icon {
|
||||||
|
max-width:24px;
|
||||||
|
min-width:24px;
|
||||||
|
max-height:24px;
|
||||||
|
min-height:24px;
|
||||||
|
image: url(:/res/sys_icon.png)
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#menu_Widget > QPushButton {
|
||||||
|
color: #FFFFFF;
|
||||||
|
min-height:28px;
|
||||||
|
min-width:78px;
|
||||||
|
font-size: 16px;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#menu_Widget > QPushButton:hover {
|
||||||
|
background: #2999CBF3;
|
||||||
|
border: 1px solid #A2C2DB;
|
||||||
|
border-top-left-radius:6px;
|
||||||
|
border-top-right-radius:6px;
|
||||||
|
}
|
||||||
|
QWidget#menu_Widget > QPushButton:checked {
|
||||||
|
background: #6F99CBF3;
|
||||||
|
border-bottom:1px solid #A2C2DB;
|
||||||
|
border-top-left-radius:6px;
|
||||||
|
border-top-right-radius:6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton {
|
||||||
|
font-family:Microsoft Yahei;
|
||||||
|
font-size:20px;
|
||||||
|
color:white;
|
||||||
|
background-color:#e91e1e;
|
||||||
|
border-radius:8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton:hover {
|
||||||
|
background-color:#59656e;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton:pressed {
|
||||||
|
background-color:#3c4349;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#sys_close {
|
||||||
|
max-width:48px;
|
||||||
|
min-width:48px;
|
||||||
|
max-height:28px;
|
||||||
|
min-height:28px;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
image: url(:/res/sys_close.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#sys_min {
|
||||||
|
max-width:48px;
|
||||||
|
min-width:48px;
|
||||||
|
max-height:28px;
|
||||||
|
min-height:28px;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
image: url(:/res/sys_min.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#sys_max {
|
||||||
|
max-width:48px;
|
||||||
|
min-width:48px;
|
||||||
|
max-height:28px;
|
||||||
|
min-height:28px;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
image: url(:/res/sys_max.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#sys_restore {
|
||||||
|
max-width:48px;
|
||||||
|
min-width:48px;
|
||||||
|
max-height:28px;
|
||||||
|
min-height:28px;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
image: url(:/res/sys_restore.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton#sys_skin {
|
||||||
|
max-width:48px;
|
||||||
|
min-width:48px;
|
||||||
|
max-height:28px;
|
||||||
|
min-height:28px;
|
||||||
|
border: none;
|
||||||
|
image: url(:/res/sys_down.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton#sys_skin::menu-indicator {
|
||||||
|
image: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#sys_close::hover, QPushButton#sys_close::pressed,
|
||||||
|
QPushButton#sys_min::hover, QPushButton#sys_min::pressed,
|
||||||
|
QPushButton#sys_max::hover, QPushButton#sys_max::pressed,
|
||||||
|
QPushButton#sys_restore::hover, QPushButton#sys_restore::pressed,
|
||||||
|
QToolButton#sys_skin::hover, QToolButton#sys_skin::pressed {
|
||||||
|
background: #38C0C0C0;
|
||||||
|
border: 1 solid #C0C0C0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton#sys_skin::checked {
|
||||||
|
image: url(:/res/sys_up.png);
|
||||||
|
background: #38C0C0C0;
|
||||||
|
border: 1 solid #C0C0C0;
|
||||||
|
}
|
||||||
|
QToolButton#sys_skin::unchecked {
|
||||||
|
image: url(:/res/sys_dwon.png);
|
||||||
|
background: #38C0C0C0;
|
||||||
|
border: 1 solid #C0C0C0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTabWidget::pane{
|
||||||
|
background: #636364;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTabWidget::tab-bar {
|
||||||
|
left: 1px;
|
||||||
|
}
|
||||||
|
QTabBar::scroller {
|
||||||
|
width:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTabBar::tab {
|
||||||
|
background: #0B0B0B;
|
||||||
|
color:#7F8997;
|
||||||
|
padding: 2px;
|
||||||
|
min-width: 20px;
|
||||||
|
min-height: 30px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTabBar::tab:selected{
|
||||||
|
border-top: 2 solid #246CD5;
|
||||||
|
color: #246CD5;
|
||||||
|
background: #212F3C;
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton:hover {
|
||||||
|
background: #85929E ;
|
||||||
|
border: 1 solid #D6DBDF;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#FileManagerMenu > QFrame, QWidget#SystemManagerMenu > QFrame {
|
||||||
|
border:none;
|
||||||
|
background-color:#3AEEF1F7;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#FileManagerMenu > QToolButton, QWidget#SystemManagerMenu > QToolButton {
|
||||||
|
qproperty-toolButtonStyle:ToolButtonIconOnly;
|
||||||
|
qproperty-iconSize: 24px 24px;
|
||||||
|
font-size: 12px;
|
||||||
|
border-style:inset;
|
||||||
|
border:0px solid #E5E5E5;
|
||||||
|
min-height: 32px;
|
||||||
|
min-width: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#FileManagerMenu > QToolButton#menu_new_file {
|
||||||
|
qproperty-icon: url(:/res/default/menu_new_file.png);
|
||||||
|
}
|
||||||
|
QWidget#FileManagerMenu > QToolButton#menu_open_file {
|
||||||
|
qproperty-icon: url(:/res/default/menu_open_file.png);
|
||||||
|
}
|
||||||
|
QWidget#FileManagerMenu > QToolButton#menu_save_file {
|
||||||
|
qproperty-icon: url(:/res/default/menu_save_file.png);
|
||||||
|
}
|
||||||
|
QWidget#FileManagerMenu > QToolButton#menu_save_as_file {
|
||||||
|
qproperty-icon: url(:/res/default/menu_save_as_file.png);
|
||||||
|
}
|
||||||
|
QWidget#FileManagerMenu > QToolButton#menu_save_shape_file {
|
||||||
|
qproperty-icon: url(:/res/default/menu_save_shape_file.png);
|
||||||
|
}
|
||||||
|
QWidget#FileManagerMenu > QToolButton#menu_save_shape_file {
|
||||||
|
qproperty-icon: url(:/res/default/menu_save_store_file.png);
|
||||||
|
}
|
||||||
|
QWidget#FileManagerMenu > QToolButton#menu_save_shape_file {
|
||||||
|
qproperty-icon: url(:/res/default/menu_report_mesh.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#SystemManagerMenu > QToolButton#menu_exit {
|
||||||
|
qproperty-icon: url(:/res/default/menu_exit.png);
|
||||||
|
}
|
||||||
|
QWidget#SystemManagerMenu > QToolButton#menu_restart {
|
||||||
|
qproperty-icon: url(:/res/default/menu_restart.png);
|
||||||
|
}
|
||||||
|
QWidget#SystemManagerMenu > QToolButton#menu_setting {
|
||||||
|
qproperty-icon: url(:/res/default/menu_setting.png);
|
||||||
|
}
|
||||||
|
QWidget#SystemManagerMenu > QToolButton#menu_setting_restore {
|
||||||
|
qproperty-icon: url(:/res/default/menu_setting_restore.png);
|
||||||
|
}
|
||||||
|
QWidget#SystemManagerMenu > QToolButton#menu_helper {
|
||||||
|
qproperty-icon: url(:/res/default/menu_helper.png);
|
||||||
|
}
|
||||||
|
QWidget#SystemManagerMenu > QToolButton#menu_license {
|
||||||
|
qproperty-icon: url(:/res/default/menu_license.png);
|
||||||
|
}
|
||||||
|
QWidget#SystemManagerMenu > QToolButton#menu_logs {
|
||||||
|
qproperty-icon: url(:/res/default/menu_logs.png);
|
||||||
|
}
|
||||||
|
QWidget#SystemManagerMenu > QToolButton#menu_logs_clean {
|
||||||
|
qproperty-icon: url(:/res/default/menu_logs_clean.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#viewDisplay {
|
||||||
|
border: 5 solid #1C1D1F;
|
||||||
|
background: qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:0 #34495E, stop:1 #0B0B0B);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#statusWidget {
|
||||||
|
max-height: 30px;
|
||||||
|
background: #2D3944;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#viewWidget {
|
||||||
|
border: 1 solid #676767;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#calcPlaneWidget, QWidget#deveToolsWidget, QWidget#modelEleWidget {
|
||||||
|
background: #212F3C;
|
||||||
|
}
|
||||||
|
|
||||||
|
QLabel#discript {
|
||||||
|
background: transparent;
|
||||||
|
color: #FFFFFF;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QLabel#status {
|
||||||
|
background: transparent;
|
||||||
|
color: #42B9F4;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDockWidget {
|
||||||
|
titlebar-close-icon: url(:/res/sys_close.png);
|
||||||
|
}
|
||||||
|
QDockWidget::title {
|
||||||
|
border: 0;
|
||||||
|
background: #212F3C;
|
||||||
|
}
|
||||||
|
QDockWidget::title QLabel {
|
||||||
|
color: #FF0000;
|
||||||
|
}
|
||||||
|
QDockWidget QWidget {
|
||||||
|
border: 0;
|
||||||
|
background: #212F3C;
|
||||||
|
}
|
||||||
|
QDockWidget DockTitleWidget {
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
color: #FF0000;
|
||||||
|
}
|
||||||
|
QDockWidget DockTitleWidget QPushButton,
|
||||||
|
QDockWidget DockTitleWidget QToolButton {
|
||||||
|
background: transparent;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
right: 6px;
|
||||||
|
top: 3px;
|
||||||
|
}
|
||||||
|
QDockWidget DockTitleWidget QPushButton:hover,
|
||||||
|
QDockWidget DockTitleWidget QToolButton:hover {
|
||||||
|
border-color: #8A8A8A;
|
||||||
|
border-radius: 2px;
|
||||||
|
background: #212F3C;
|
||||||
|
}
|
||||||
|
QDockWidget DockTitleWidget QPushButton::menu-indicator,
|
||||||
|
QDockWidget DockTitleWidget QToolButton::menu-indicator {
|
||||||
|
image: none;
|
||||||
|
}
|
324
Source/src/config/skin/default.qss
Normal file
@ -0,0 +1,324 @@
|
|||||||
|
QPalette{background:#F5F5F5;}*{outline:0px;color:#000000;}
|
||||||
|
|
||||||
|
QWidget {
|
||||||
|
background: #212F3C;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
FrameTitleBar{
|
||||||
|
border-bottom: 1 solid #7FB3D5 ;
|
||||||
|
border-top-left-radius:10px;
|
||||||
|
border-top-right-radius:10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QFrame>QLabel#sys_icon {
|
||||||
|
max-width:24px;
|
||||||
|
min-width:24px;
|
||||||
|
max-height:24px;
|
||||||
|
min-height:24px;
|
||||||
|
image: url(:/res/sys_icon.png)
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#menu_Widget > QPushButton {
|
||||||
|
color: #FFFFFF;
|
||||||
|
min-height:16px;
|
||||||
|
min-width:68px;
|
||||||
|
font-size: 16px;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#menu_Widget > QPushButton:hover {
|
||||||
|
background: #2999CBF3;
|
||||||
|
border: 1px solid #A2C2DB;
|
||||||
|
border-top-left-radius:6px;
|
||||||
|
border-top-right-radius:6px;
|
||||||
|
}
|
||||||
|
QWidget#menu_Widget > QPushButton:checked {
|
||||||
|
background: #6F99CBF3;
|
||||||
|
border-bottom:1px solid #A2C2DB;
|
||||||
|
border-top-left-radius:6px;
|
||||||
|
border-top-right-radius:6px;
|
||||||
|
}
|
||||||
|
QWidget#menu_Widget > QPushButton:pressed {
|
||||||
|
padding-left:10px;
|
||||||
|
padding-top:10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton {
|
||||||
|
background: #384c5e;
|
||||||
|
color:white;
|
||||||
|
border-radius:8px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton:hover {
|
||||||
|
background-color:#59656e;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton:pressed {
|
||||||
|
background-color: #3c4349;
|
||||||
|
padding-left:13px;
|
||||||
|
padding-top:13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#sys_close {
|
||||||
|
max-width:48px;
|
||||||
|
min-width:48px;
|
||||||
|
max-height:28px;
|
||||||
|
min-height:28px;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
image: url(:/res/sys_close.png);
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#sys_min {
|
||||||
|
max-width:48px;
|
||||||
|
min-width:48px;
|
||||||
|
max-height:28px;
|
||||||
|
min-height:28px;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
image: url(:/res/sys_min.png);
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#sys_max {
|
||||||
|
max-width:48px;
|
||||||
|
min-width:48px;
|
||||||
|
max-height:28px;
|
||||||
|
min-height:28px;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
image: url(:/res/sys_max.png);
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#sys_restore {
|
||||||
|
max-width:48px;
|
||||||
|
min-width:48px;
|
||||||
|
max-height:28px;
|
||||||
|
min-height:28px;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
image: url(:/res/sys_restore.png);
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton#sys_skin {
|
||||||
|
max-width:48px;
|
||||||
|
min-width:48px;
|
||||||
|
max-height:28px;
|
||||||
|
min-height:28px;
|
||||||
|
border: none;
|
||||||
|
image: url(:/res/sys_down.png);
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton#sys_skin::menu-indicator {
|
||||||
|
image: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#sys_close::hover, QPushButton#sys_close::pressed {
|
||||||
|
background:#e91e1e;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#sys_min::hover, QPushButton#sys_min::pressed,
|
||||||
|
QPushButton#sys_max::hover, QPushButton#sys_max::pressed,
|
||||||
|
QPushButton#sys_restore::hover, QPushButton#sys_restore::pressed,
|
||||||
|
QToolButton#sys_skin::hover, QToolButton#sys_skin::pressed {
|
||||||
|
background: #38C0C0C0;
|
||||||
|
border: 1 solid #C0C0C0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton#sys_skin::checked {
|
||||||
|
image: url(:/res/sys_up.png);
|
||||||
|
background: #38C0C0C0;
|
||||||
|
border: 1 solid #C0C0C0;
|
||||||
|
}
|
||||||
|
QToolButton#sys_skin::unchecked {
|
||||||
|
image: url(:/res/sys_dwon.png);
|
||||||
|
background: #38C0C0C0;
|
||||||
|
border: 1 solid #C0C0C0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTabWidget::pane{
|
||||||
|
background: #636364;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTabWidget::tab-bar {
|
||||||
|
left: 1px;
|
||||||
|
}
|
||||||
|
QTabBar::scroller {
|
||||||
|
width:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTabBar::tab {
|
||||||
|
background: #0B0B0B;
|
||||||
|
color:#7F8997;
|
||||||
|
padding: 2px;
|
||||||
|
min-width: 20px;
|
||||||
|
min-height: 30px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTabBar::tab:selected{
|
||||||
|
border-top: 2 solid #246CD5;
|
||||||
|
color: #246CD5;
|
||||||
|
background: #212F3C;
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton:hover {
|
||||||
|
background: #85929E ;
|
||||||
|
border: 1 solid #D6DBDF;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QLineEdit, QTextEdit {
|
||||||
|
border: 1px solid #384c5e;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 0 8px;
|
||||||
|
selection-background-color: darkgray;
|
||||||
|
}
|
||||||
|
|
||||||
|
QLineEdit:read-only,
|
||||||
|
QTextEdit:read-only {
|
||||||
|
color: #b4b7bb;
|
||||||
|
}
|
||||||
|
|
||||||
|
QLineEdit[echoMode="2"] {
|
||||||
|
lineedit-password-character: 42;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#FileManagerMenu > QFrame, QWidget#SystemManagerMenu > QFrame {
|
||||||
|
border:none;
|
||||||
|
background-color:#3AEEF1F7;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#FileManagerMenu > QToolButton, QWidget#SystemManagerMenu > QToolButton {
|
||||||
|
qproperty-toolButtonStyle:ToolButtonIconOnly;
|
||||||
|
qproperty-iconSize: 24px 24px;
|
||||||
|
font-size: 12px;
|
||||||
|
border-style:inset;
|
||||||
|
border:0px solid #E5E5E5;
|
||||||
|
min-height: 32px;
|
||||||
|
min-width: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#FileManagerMenu > QToolButton#menu_new_file {
|
||||||
|
qproperty-icon: url(:/res/default/menu_new_file.png);
|
||||||
|
}
|
||||||
|
QWidget#FileManagerMenu > QToolButton#menu_open_file {
|
||||||
|
qproperty-icon: url(:/res/default/menu_open_file.png);
|
||||||
|
}
|
||||||
|
QWidget#FileManagerMenu > QToolButton#menu_save_file {
|
||||||
|
qproperty-icon: url(:/res/default/menu_save_file.png);
|
||||||
|
}
|
||||||
|
QWidget#FileManagerMenu > QToolButton#menu_save_as_file {
|
||||||
|
qproperty-icon: url(:/res/default/menu_save_as_file.png);
|
||||||
|
}
|
||||||
|
QWidget#FileManagerMenu > QToolButton#menu_save_shape_file {
|
||||||
|
qproperty-icon: url(:/res/default/menu_save_shape_file.png);
|
||||||
|
}
|
||||||
|
QWidget#FileManagerMenu > QToolButton#menu_save_shape_file {
|
||||||
|
qproperty-icon: url(:/res/default/menu_save_store_file.png);
|
||||||
|
}
|
||||||
|
QWidget#FileManagerMenu > QToolButton#menu_save_shape_file {
|
||||||
|
qproperty-icon: url(:/res/default/menu_report_mesh.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#SystemManagerMenu > QToolButton#menu_exit {
|
||||||
|
qproperty-icon: url(:/res/default/menu_exit.png);
|
||||||
|
}
|
||||||
|
QWidget#SystemManagerMenu > QToolButton#menu_restart {
|
||||||
|
qproperty-icon: url(:/res/default/menu_restart.png);
|
||||||
|
}
|
||||||
|
QWidget#SystemManagerMenu > QToolButton#menu_setting {
|
||||||
|
qproperty-icon: url(:/res/default/menu_setting.png);
|
||||||
|
}
|
||||||
|
QWidget#SystemManagerMenu > QToolButton#menu_setting_restore {
|
||||||
|
qproperty-icon: url(:/res/default/menu_setting_restore.png);
|
||||||
|
}
|
||||||
|
QWidget#SystemManagerMenu > QToolButton#menu_helper {
|
||||||
|
qproperty-icon: url(:/res/default/menu_helper.png);
|
||||||
|
}
|
||||||
|
QWidget#SystemManagerMenu > QToolButton#menu_license {
|
||||||
|
qproperty-icon: url(:/res/default/menu_license.png);
|
||||||
|
}
|
||||||
|
QWidget#SystemManagerMenu > QToolButton#menu_logs {
|
||||||
|
qproperty-icon: url(:/res/default/menu_logs.png);
|
||||||
|
}
|
||||||
|
QWidget#SystemManagerMenu > QToolButton#menu_logs_clean {
|
||||||
|
qproperty-icon: url(:/res/default/menu_logs_clean.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#viewDisplay {
|
||||||
|
border: 5 solid #1C1D1F;
|
||||||
|
background: qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:0 #34495E, stop:1 #0B0B0B);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#statusWidget {
|
||||||
|
max-height: 30px;
|
||||||
|
background: #2D3944;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#viewWidget {
|
||||||
|
border: 1 solid #676767;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#calcPlaneWidget, QWidget#deveToolsWidget, QWidget#modelEleWidget {
|
||||||
|
background: #212F3C;
|
||||||
|
}
|
||||||
|
|
||||||
|
QLabel#discript {
|
||||||
|
background: transparent;
|
||||||
|
color: #FFFFFF;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QLabel#status {
|
||||||
|
background: transparent;
|
||||||
|
color: #42B9F4;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDockWidget {
|
||||||
|
titlebar-close-icon: url(:/res/sys_close.png);
|
||||||
|
}
|
||||||
|
QDockWidget::title {
|
||||||
|
border: 0;
|
||||||
|
background: #212F3C;
|
||||||
|
}
|
||||||
|
QDockWidget::title QLabel {
|
||||||
|
color: #FF0000;
|
||||||
|
}
|
||||||
|
QDockWidget QWidget {
|
||||||
|
border: 0;
|
||||||
|
background: #212F3C;
|
||||||
|
}
|
||||||
|
QDockWidget DockTitleWidget {
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
color: #FF0000;
|
||||||
|
}
|
||||||
|
QDockWidget DockTitleWidget QPushButton,
|
||||||
|
QDockWidget DockTitleWidget QToolButton {
|
||||||
|
background: transparent;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
right: 6px;
|
||||||
|
top: 3px;
|
||||||
|
}
|
||||||
|
QDockWidget DockTitleWidget QPushButton:hover,
|
||||||
|
QDockWidget DockTitleWidget QToolButton:hover {
|
||||||
|
border-color: #8A8A8A;
|
||||||
|
border-radius: 2px;
|
||||||
|
background: #212F3C;
|
||||||
|
}
|
||||||
|
QDockWidget DockTitleWidget QPushButton::menu-indicator,
|
||||||
|
QDockWidget DockTitleWidget QToolButton::menu-indicator {
|
||||||
|
image: none;
|
||||||
|
}
|
145
Source/src/config/skin/silver.qss
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
QPalette{background:#F5F5F5;}*{outline:0px;color:#000000;}
|
||||||
|
|
||||||
|
QFrame {
|
||||||
|
background: #E1E4E6;
|
||||||
|
border-top-left-radius:10px;
|
||||||
|
border-top-right-radius:10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QFrame#titleFrame{
|
||||||
|
border-bottom: 1 solid #34495E;
|
||||||
|
}
|
||||||
|
|
||||||
|
QLabel#sys_title {
|
||||||
|
color: #F4F6F6;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#sys_close {
|
||||||
|
max-width:48px;
|
||||||
|
min-width:48px;
|
||||||
|
max-height:28px;
|
||||||
|
min-height:28px;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
image: url(:/res/sys_close.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#sys_min {
|
||||||
|
max-width:48px;
|
||||||
|
min-width:48px;
|
||||||
|
max-height:28px;
|
||||||
|
min-height:28px;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
image: url(:/res/sys_min.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#sys_max {
|
||||||
|
max-width:48px;
|
||||||
|
min-width:48px;
|
||||||
|
max-height:28px;
|
||||||
|
min-height:28px;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
image: url(:/res/sys_max.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#sys_restore {
|
||||||
|
max-width:48px;
|
||||||
|
min-width:48px;
|
||||||
|
max-height:28px;
|
||||||
|
min-height:28px;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
image: url(:/res/sys_restore.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton#sys_skin {
|
||||||
|
max-width:48px;
|
||||||
|
min-width:48px;
|
||||||
|
max-height:28px;
|
||||||
|
min-height:28px;
|
||||||
|
border: none;
|
||||||
|
image: url(:/res/sys_down.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton#sys_skin::menu-indicator {
|
||||||
|
image: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#sys_close::hover, QPushButton#sys_close::pressed,
|
||||||
|
QPushButton#sys_min::hover, QPushButton#sys_min::pressed,
|
||||||
|
QPushButton#sys_max::hover, QPushButton#sys_max::pressed,
|
||||||
|
QPushButton#sys_restore::hover, QPushButton#sys_restore::pressed,
|
||||||
|
QToolButton#sys_skin::hover, QToolButton#sys_skin::pressed {
|
||||||
|
background: #38C0C0C0;
|
||||||
|
border: 1 solid #C0C0C0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton#sys_skin::checked {
|
||||||
|
image: url(:/res/sys_up.png);
|
||||||
|
background: #38C0C0C0;
|
||||||
|
border: 1 solid #C0C0C0;
|
||||||
|
}
|
||||||
|
QToolButton#sys_skin::unchecked {
|
||||||
|
image: url(:/res/sys_dwon.png);
|
||||||
|
background: #38C0C0C0;
|
||||||
|
border: 1 solid #C0C0C0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QTabWidget::pane{
|
||||||
|
border:1 solid #5D6D7E;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTabWidget::tab-bar {
|
||||||
|
left: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTabBar::tab {
|
||||||
|
background: #212F3C;
|
||||||
|
color:#7F8997;
|
||||||
|
min-width: 60px;
|
||||||
|
min-height: 25px;
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTabBar::tab:selected{
|
||||||
|
border: 2 solid #5D6D7E;
|
||||||
|
border-bottom: none;
|
||||||
|
border-top-left-radius: 5px;
|
||||||
|
border-top-right-radius: 5px;
|
||||||
|
color:#D6DBDF;
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
QToolButton:hover {
|
||||||
|
background: #85929E ;
|
||||||
|
border: 1 solid #D6DBDF;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#FileManagerMenu > QToolButton {
|
||||||
|
qproperty-toolButtonStyle:ToolButtonTextUnderIcon;
|
||||||
|
qproperty-iconSize: 32px 32px;
|
||||||
|
font-size: 12px;
|
||||||
|
border-style:inset;
|
||||||
|
border:0px solid #E5E5E5;
|
||||||
|
min-height: 60px;
|
||||||
|
min-width: 60px;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#FileManagerMenu > QToolButton#menu_new_file {
|
||||||
|
qproperty-icon: url(:/res/default/menu_new_file.png);
|
||||||
|
}
|
||||||
|
QWidget#FileManagerMenu > QToolButton#menu_open_file {
|
||||||
|
qproperty-icon: url(:/res/default/menu_open_file.png);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget#view_display {
|
||||||
|
background:white;
|
||||||
|
}
|
||||||
|
|
23
Source/src/effects/ChaffBombs.cpp
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#include "effects/ChaffBombs.h"
|
||||||
|
|
||||||
|
#include <osgDB/ReadFile>
|
||||||
|
|
||||||
|
#include "common/SpdLogger.h"
|
||||||
|
|
||||||
|
ChaffBombs::ChaffBombs() {
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
ChaffBombs::~ChaffBombs() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChaffBombs::Init() {
|
||||||
|
osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("chaff_bombs.osg");
|
||||||
|
if (nullptr == node) {
|
||||||
|
LOG_WARN("node is read failed, name: chaff_bombs.osg");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//node->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||||
|
addChild(node);
|
||||||
|
}
|
26
Source/src/effects/ChaffBombs.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <osg/Group>
|
||||||
|
|
||||||
|
|
||||||
|
class ChaffBombs : public osg::Group {
|
||||||
|
public:
|
||||||
|
ChaffBombs();
|
||||||
|
|
||||||
|
META_Node(osg, Group);
|
||||||
|
|
||||||
|
Group* asGroup() override {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
const Group* asGroup() const override {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
~ChaffBombs() override;
|
||||||
|
|
||||||
|
void Init();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
};
|
126
Source/src/effects/ConeWave.cpp
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
#include "effects/ConeWave.h"
|
||||||
|
|
||||||
|
#include <osg/BlendFunc>
|
||||||
|
#include <osg/Material>
|
||||||
|
#include <osg/Texture2D>
|
||||||
|
#include <osg/ShapeDrawable>
|
||||||
|
#include <osg/Group>
|
||||||
|
#include <osgViewer/Viewer>
|
||||||
|
#include <osgDB/ReadFile>
|
||||||
|
#include <osg/Shader>
|
||||||
|
#include <osg/Program>
|
||||||
|
#include <osg/Uniform>
|
||||||
|
|
||||||
|
|
||||||
|
ConeWave::ConeWave(const std::string& path)
|
||||||
|
: txturePath_(path) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ConeWave::~ConeWave(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConeWave::Render(double dt) {
|
||||||
|
if (timeUniform_) {
|
||||||
|
//float timeValue;
|
||||||
|
//timeUniform_->get(timeValue);
|
||||||
|
//timeValue += dt * 0.1; // ¿ØÖƹö¶¯ËÙ¶È
|
||||||
|
timeUniform_->set(static_cast<float>(dt * 0.1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConeWave::InitGeode() {
|
||||||
|
CreateTexturedCone(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConeWave::Destory() {
|
||||||
|
OnDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConeWave::SetHeight(float height) {
|
||||||
|
height_ = height;
|
||||||
|
if (cone_) {
|
||||||
|
cone_->setHeight(height_);
|
||||||
|
}
|
||||||
|
coneDrawable_->build();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConeWave::SetRadius(float radius) {
|
||||||
|
radius_ = radius;
|
||||||
|
if (cone_) {
|
||||||
|
cone_->setRadius(radius);
|
||||||
|
}
|
||||||
|
coneDrawable_->build();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConeWave::SetBaseColor(const osg::Vec4& color) {
|
||||||
|
baseColor_ = color;
|
||||||
|
if (baseColorUniform_) {
|
||||||
|
baseColorUniform_->set(color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConeWave::CreateTexturedCone(osg::Geode* geode) {
|
||||||
|
cone_ = new osg::Cone(osg::Vec3(0, 0, 0.), radius_, height_);
|
||||||
|
osg::TessellationHints* tesselate = new osg::TessellationHints;
|
||||||
|
tesselate->setCreateBottom(false);
|
||||||
|
tesselate->setCreateBackFace(false);
|
||||||
|
coneDrawable_ = new osg::ShapeDrawable(cone_, tesselate);
|
||||||
|
addDrawable(coneDrawable_);
|
||||||
|
|
||||||
|
osg::Texture2D* texture = new osg::Texture2D;
|
||||||
|
texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR);
|
||||||
|
texture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR);
|
||||||
|
texture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::REPEAT);
|
||||||
|
texture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::REPEAT);
|
||||||
|
osg::Image* image = osgDB::readImageFile(txturePath_);
|
||||||
|
texture->setImage(image);
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Shader> vertexShader = new osg::Shader(osg::Shader::VERTEX);
|
||||||
|
vertexShader->setShaderSource(
|
||||||
|
"#version 330\n"
|
||||||
|
"in vec4 osg_Vertex;\n"
|
||||||
|
"in vec2 osg_MultiTexCoord0;\n"
|
||||||
|
"uniform mat4 osg_ModelViewProjectionMatrix;\n"
|
||||||
|
"uniform float time;\n"
|
||||||
|
"out vec2 texCoord;\n"
|
||||||
|
"void main()\n"
|
||||||
|
"{\n"
|
||||||
|
" gl_Position = osg_ModelViewProjectionMatrix * osg_Vertex;\n"
|
||||||
|
" texCoord = osg_MultiTexCoord0 + vec2(0.0, time);\n"
|
||||||
|
"}\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Shader> fragmentShader = new osg::Shader(osg::Shader::FRAGMENT);
|
||||||
|
fragmentShader->setShaderSource(
|
||||||
|
"#version 330\n"
|
||||||
|
"in vec2 texCoord;\n"
|
||||||
|
"uniform sampler2D texture;\n"
|
||||||
|
"uniform vec4 baseColor;\n"
|
||||||
|
"out vec4 fragColor;\n"
|
||||||
|
"void main()\n"
|
||||||
|
"{\n"
|
||||||
|
" vec4 color = texture2D(texture, texCoord);\n"
|
||||||
|
" fragColor = clamp(texture2D(texture, texCoord) * baseColor + vec4(0,0,0, 0.2), 0.0, 1.0);\n"
|
||||||
|
"}\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
osg::StateSet* stateset = coneDrawable_->getOrCreateStateSet();
|
||||||
|
|
||||||
|
stateset->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
|
||||||
|
stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
|
||||||
|
osg::ref_ptr<osg::BlendFunc> blendFunc = new osg::BlendFunc();
|
||||||
|
stateset->setAttributeAndModes(blendFunc, osg::StateAttribute::ON);
|
||||||
|
osg::ref_ptr<osg::Program> program = new osg::Program();
|
||||||
|
program->addShader(vertexShader);
|
||||||
|
program->addShader(fragmentShader);
|
||||||
|
stateset->addUniform(new osg::Uniform("texture", 0));
|
||||||
|
baseColorUniform_ = new osg::Uniform("baseColor", baseColor_);
|
||||||
|
stateset->addUniform(baseColorUniform_);
|
||||||
|
stateset->setAttributeAndModes(program, osg::StateAttribute::ON);
|
||||||
|
|
||||||
|
timeUniform_ = new osg::Uniform("time", 0.0f);
|
||||||
|
stateset->addUniform(timeUniform_);
|
||||||
|
}
|
51
Source/src/effects/ConeWave.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <osg/Matrix>
|
||||||
|
#include <osg/Array>
|
||||||
|
#include <osg/Geometry>
|
||||||
|
#include <osg/Geode>
|
||||||
|
#include <osg/ShapeDrawable>
|
||||||
|
|
||||||
|
#include "effects/DrawDecorate.h"
|
||||||
|
#include "viewer/UpdateRenderStd.h"
|
||||||
|
|
||||||
|
class ConeWave : public osg::Geode
|
||||||
|
, public UpdateRenderStd {
|
||||||
|
public:
|
||||||
|
explicit ConeWave(const std::string& path);
|
||||||
|
~ConeWave(void) override;
|
||||||
|
|
||||||
|
void Render(double dt) override;
|
||||||
|
|
||||||
|
void InitGeode();
|
||||||
|
void Destory();
|
||||||
|
|
||||||
|
void SetHeight(float height);
|
||||||
|
float GetHeght() const {
|
||||||
|
return height_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetRadius(float radius);
|
||||||
|
float GetRadius() const {
|
||||||
|
return radius_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetBaseColor(const osg::Vec4& color);
|
||||||
|
const osg::Vec4 GetBaseColor() const {
|
||||||
|
return baseColor_;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void CreateTexturedCone(osg::Geode* geode);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string txturePath_;
|
||||||
|
osg::ref_ptr<osg::Cone> cone_;
|
||||||
|
osg::ref_ptr<osg::ShapeDrawable> coneDrawable_;
|
||||||
|
osg::ref_ptr<osg::Uniform> timeUniform_;
|
||||||
|
osg::ref_ptr<osg::Uniform> baseColorUniform_;
|
||||||
|
osg::Vec4 baseColor_{ 0.0f, 0.2f, 0.5f, 0.2f };
|
||||||
|
float height_{ 60.0f };
|
||||||
|
float radius_{ 10.0f };
|
||||||
|
};
|
||||||
|
|
165
Source/src/effects/DashedLine.cpp
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
#include "effects/DashedLine.h"
|
||||||
|
|
||||||
|
#include <osg/BlendFunc>
|
||||||
|
#include <osg/Material>
|
||||||
|
#include <osg/Texture2D>
|
||||||
|
#include <osg/ShapeDrawable>
|
||||||
|
#include <osg/Group>
|
||||||
|
#include <osgViewer/Viewer>
|
||||||
|
#include <osgDB/ReadFile>
|
||||||
|
#include <osg/Shader>
|
||||||
|
#include <osg/Program>
|
||||||
|
#include <osg/Uniform>
|
||||||
|
|
||||||
|
#include "viewer/OsgViewer.h"
|
||||||
|
|
||||||
|
|
||||||
|
DashedLine::DashedLine(const std::string& path)
|
||||||
|
: txturePath_(path) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DashedLine::~DashedLine(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void DashedLine::Render(double dt) {
|
||||||
|
if (timeUniform_) {
|
||||||
|
timeUniform_->set(static_cast<float>(dt * 0.1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DashedLine::InitGeode() {
|
||||||
|
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
|
||||||
|
addChild(geode);
|
||||||
|
CreateTexturedCone(geode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DashedLine::Destory() {
|
||||||
|
OnDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DashedLine::SetStart(const osg::Vec3& start) {
|
||||||
|
if (start == start_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
start_ = start;
|
||||||
|
UpdateRotaion();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DashedLine::SetEnd(const osg::Vec3& end) {
|
||||||
|
if (end == end_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
end_ = end;
|
||||||
|
UpdateRotaion();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DashedLine::SetForward(const osg::Vec3& start, const osg::Vec3& end) {
|
||||||
|
if (start == start_ && end == end_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
start_ = start;
|
||||||
|
end_ = end;
|
||||||
|
UpdateRotaion();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DashedLine::SetRadius(float radius) {
|
||||||
|
if (radius == radius_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
radius_ = radius;
|
||||||
|
if (cylinder_) {
|
||||||
|
cylinder_->setRadius(radius);
|
||||||
|
}
|
||||||
|
UpdateRotaion();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DashedLine::SetBaseColor(const osg::Vec4& color) {
|
||||||
|
baseColor_ = color;
|
||||||
|
if (baseColorUniform_) {
|
||||||
|
baseColorUniform_->set(color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DashedLine::CreateTexturedCone(osg::Geode* geode) {
|
||||||
|
cylinder_ = new osg::Cylinder(osg::Vec3(0.0f, 0.0f, 0.0f), radius_, 1.0f);
|
||||||
|
cylinderDrawable_ = new osg::ShapeDrawable(cylinder_);
|
||||||
|
geode->addDrawable(cylinderDrawable_);
|
||||||
|
|
||||||
|
osg::Texture2D* texture = new osg::Texture2D;
|
||||||
|
texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR);
|
||||||
|
texture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR);
|
||||||
|
texture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::REPEAT);
|
||||||
|
texture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::REPEAT);
|
||||||
|
osg::Image* image = osgDB::readImageFile(txturePath_);
|
||||||
|
texture->setImage(image);
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Shader> vertexShader = new osg::Shader(osg::Shader::VERTEX);
|
||||||
|
vertexShader->setShaderSource(
|
||||||
|
"#version 330\n"
|
||||||
|
"in vec4 osg_Vertex;\n"
|
||||||
|
"in vec2 osg_MultiTexCoord0;\n"
|
||||||
|
"uniform mat4 osg_ModelViewProjectionMatrix;\n"//当前OSG摄像机的观察矩阵;
|
||||||
|
"uniform float time;\n"
|
||||||
|
"out vec2 texCoord;\n"
|
||||||
|
"void main()\n"
|
||||||
|
"{\n"
|
||||||
|
" gl_Position = osg_ModelViewProjectionMatrix * osg_Vertex;\n"
|
||||||
|
" texCoord = osg_MultiTexCoord0 + vec2(0.0, time);\n"
|
||||||
|
"}\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Shader> fragmentShader = new osg::Shader(osg::Shader::FRAGMENT);
|
||||||
|
fragmentShader->setShaderSource(
|
||||||
|
"#version 330\n"
|
||||||
|
"in vec2 texCoord;\n"
|
||||||
|
"uniform sampler2D texture;\n"
|
||||||
|
"uniform vec4 baseColor;\n"
|
||||||
|
"out vec4 fragColor;\n"
|
||||||
|
"void main()\n"
|
||||||
|
"{\n"
|
||||||
|
" vec4 color = texture2D(texture, texCoord);\n"
|
||||||
|
" fragColor = clamp(texture2D(texture, texCoord) * baseColor + vec4(0,0,0, 0.2), 0.0, 1.0);\n"
|
||||||
|
"}\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
osg::StateSet* stateset = cylinderDrawable_->getOrCreateStateSet();
|
||||||
|
|
||||||
|
stateset->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
|
||||||
|
stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
|
||||||
|
osg::ref_ptr<osg::BlendFunc> blendFunc = new osg::BlendFunc();
|
||||||
|
stateset->setAttributeAndModes(blendFunc, osg::StateAttribute::ON);
|
||||||
|
osg::ref_ptr<osg::Program> program = new osg::Program();
|
||||||
|
program->addShader(vertexShader);
|
||||||
|
program->addShader(fragmentShader);
|
||||||
|
stateset->addUniform(new osg::Uniform("texture", 0));
|
||||||
|
baseColorUniform_ = new osg::Uniform("baseColor", baseColor_);
|
||||||
|
stateset->addUniform(baseColorUniform_);
|
||||||
|
stateset->setAttributeAndModes(program, osg::StateAttribute::ON);
|
||||||
|
|
||||||
|
timeUniform_ = new osg::Uniform("time", 0.0f);
|
||||||
|
stateset->addUniform(timeUniform_);
|
||||||
|
|
||||||
|
UpdateRotaion();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DashedLine::UpdateRotaion() {
|
||||||
|
osg::Vec3 direction = end_ - start_;
|
||||||
|
float height = direction.length();
|
||||||
|
|
||||||
|
cylinder_->setHeight(height);
|
||||||
|
cylinderDrawable_->build();
|
||||||
|
|
||||||
|
osg::Vec3 center = (start_ + end_) * 0.5f;
|
||||||
|
direction.normalize();
|
||||||
|
|
||||||
|
setPosition(center);
|
||||||
|
osg::Vec3 up(0.0f, 0.0f, 1.0f);
|
||||||
|
osg::Quat rotation;
|
||||||
|
rotation.makeRotate(up, direction);
|
||||||
|
|
||||||
|
setAttitude(rotation);
|
||||||
|
}
|
55
Source/src/effects/DashedLine.h
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <osg/Matrix>
|
||||||
|
#include <osg/Array>
|
||||||
|
#include <osg/ShapeDrawable>
|
||||||
|
#include <osg/PositionAttitudeTransform>
|
||||||
|
|
||||||
|
#include "effects/DrawDecorate.h"
|
||||||
|
|
||||||
|
#include "viewer/UpdateRenderStd.h"
|
||||||
|
|
||||||
|
class DashedLine : public osg::PositionAttitudeTransform
|
||||||
|
, public UpdateRenderStd {
|
||||||
|
public:
|
||||||
|
explicit DashedLine(const std::string& path);
|
||||||
|
~DashedLine(void) override;
|
||||||
|
|
||||||
|
void Render(double dt) override;
|
||||||
|
|
||||||
|
void InitGeode();
|
||||||
|
void Destory();
|
||||||
|
|
||||||
|
void SetStart(const osg::Vec3& start);
|
||||||
|
void SetEnd(const osg::Vec3& end);
|
||||||
|
void SetForward(const osg::Vec3& start, const osg::Vec3& end);
|
||||||
|
|
||||||
|
void SetRadius(float radius);
|
||||||
|
float GetRadius() const {
|
||||||
|
return radius_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetBaseColor(const osg::Vec4& color);
|
||||||
|
const osg::Vec4 GetBaseColor() const {
|
||||||
|
return baseColor_;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void CreateTexturedCone(osg::Geode* geode);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void UpdateRotaion();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string txturePath_;
|
||||||
|
osg::ref_ptr<osg::Uniform> timeUniform_;
|
||||||
|
osg::ref_ptr<osg::Uniform> baseColorUniform_;
|
||||||
|
osg::Vec3 start_{ 20.f, 30.0, 0.0f };
|
||||||
|
osg::Vec3 end_{ 10.f, 0.0, 0.0f };
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Cylinder> cylinder_;
|
||||||
|
osg::ref_ptr<osg::ShapeDrawable> cylinderDrawable_;
|
||||||
|
osg::Vec4 baseColor_{ 0.0, 0.2, 0.5, 0.2 };
|
||||||
|
float radius_{ 0.20f };
|
||||||
|
};
|
||||||
|
|
83
Source/src/effects/DottedLine.cpp
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
#include "effects/DottedLine.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <math.h>
|
||||||
|
#include <osg/Drawable>
|
||||||
|
#include <osg/Geometry>
|
||||||
|
#include <osg/CullFace>
|
||||||
|
#include <osg/Depth>
|
||||||
|
#include <osg/LineWidth>
|
||||||
|
|
||||||
|
DottedLine::DottedLine(ElectricWave* pElectricWave)
|
||||||
|
: TrackWave(pElectricWave),width_(10),m_i(1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DottedLine::~DottedLine(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置宽度
|
||||||
|
void DottedLine::SetWidth(int nWidth)
|
||||||
|
{
|
||||||
|
width_ = nWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获得宽度
|
||||||
|
int DottedLine::GetWidth(void)
|
||||||
|
{
|
||||||
|
return (width_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置起始和终点
|
||||||
|
void DottedLine::SetStartAndEnd(const osg::Vec3d& vStart, const osg::Vec3d& vEnd)
|
||||||
|
{
|
||||||
|
TrackWave::SetStartAndEnd(vStart, vEnd);
|
||||||
|
|
||||||
|
// 设置向量节点
|
||||||
|
temp_ = vEnd - vStart;
|
||||||
|
temp_.normalize();;
|
||||||
|
height_ = temp_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获得数据
|
||||||
|
void DottedLine::CreateSingleVertex(double index, osg::Vec3dArray* pVertexArray)
|
||||||
|
{
|
||||||
|
double fHeight = index * (m_fLoopHeight + m_fSpaceHeight) + m_fLoopHeight + m_fdHeight;
|
||||||
|
|
||||||
|
if (((fHeight - m_fLoopHeight) >= m_fHeight) || ((fHeight - m_fLoopHeight) <= -m_fHeight))
|
||||||
|
{
|
||||||
|
fHeight -= m_fHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
double ftemp = fHeight;
|
||||||
|
//判断值有效
|
||||||
|
if (ftemp >= m_fHeight )
|
||||||
|
{
|
||||||
|
ftemp = m_fHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::Vec3d vTop = height_ * ftemp;
|
||||||
|
ftemp = fHeight - m_fLoopHeight;
|
||||||
|
|
||||||
|
osg::Vec3d vBotton = height_ * ftemp;
|
||||||
|
pVertexArray->push_back(vTop + m_vStart);
|
||||||
|
pVertexArray->push_back(vBotton + m_vStart );
|
||||||
|
}
|
||||||
|
|
||||||
|
void DottedLine::CreatePrimitiveSet(osg::Geometry* pGeometry, int nStart, int nCount)
|
||||||
|
{
|
||||||
|
pGeometry->removePrimitiveSet(0, pGeometry->getNumPrimitiveSets());
|
||||||
|
pGeometry->addPrimitiveSet(new osg::DrawArrays(GL_LINES, 0, nCount));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获得属性
|
||||||
|
void DottedLine::SetStateSet(osg::StateSet* pStateSet)
|
||||||
|
{
|
||||||
|
TrackWave::SetStateSet(pStateSet);
|
||||||
|
|
||||||
|
osg::LineWidth* pLineWidth = new osg::LineWidth(width_);
|
||||||
|
pStateSet->setAttributeAndModes(pLineWidth);
|
||||||
|
|
||||||
|
}
|
32
Source/src/effects/DottedLine.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "effects/TrackWave.h"
|
||||||
|
|
||||||
|
class DottedLine : public TrackWave {
|
||||||
|
public:
|
||||||
|
explicit DottedLine(ElectricWave* pElectricWave);
|
||||||
|
virtual ~DottedLine(void);
|
||||||
|
int m_i;
|
||||||
|
|
||||||
|
// 设置宽度
|
||||||
|
void SetWidth(int nWidth);
|
||||||
|
// 获得宽度
|
||||||
|
int GetWidth(void);
|
||||||
|
// 设置起始和终点
|
||||||
|
void SetStartAndEnd(const osg::Vec3d& vStart, const osg::Vec3d& vEnd);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// 创建圆环
|
||||||
|
virtual void CreateSingleVertex(double index, osg::Vec3dArray* pVertexArray);
|
||||||
|
// 获得渲染体
|
||||||
|
// virtual osg::PrimitiveSet* GetPrimitiveSet(int nStart, int nCount);
|
||||||
|
virtual void CreatePrimitiveSet(osg::Geometry* pGeometry, int nStart, int nCount);
|
||||||
|
// 获得属性
|
||||||
|
virtual void SetStateSet(osg::StateSet* pStateSet);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int width_;
|
||||||
|
osg::Vec3d temp_;
|
||||||
|
osg::Vec3d height_;
|
||||||
|
};
|
||||||
|
|
229
Source/src/effects/DrawDecorate.cpp
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
#include "effects/DrawDecorate.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <osg/Drawable>
|
||||||
|
#include <osg/Geode>
|
||||||
|
#include <osg/Geometry>
|
||||||
|
#include <osgUtil/SmoothingVisitor>
|
||||||
|
#include <osg/Depth>
|
||||||
|
#include <osg/PolygonMode>
|
||||||
|
#include <osg/BlendFunc>
|
||||||
|
|
||||||
|
#include "effects/ElectricWave.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//class CUpdateDecorate : public osg::Drawable::UpdateCallback
|
||||||
|
//{
|
||||||
|
//public:
|
||||||
|
// explicit CUpdateDecorate(CDrawDecorate* pScansion):m_pScansion(pScansion)
|
||||||
|
// {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// virtual void update(osg::NodeVisitor*, osg::Drawable* pDrawalbe)
|
||||||
|
// {
|
||||||
|
// osg::Geometry* pGeomtry = pDrawalbe->asGeometry();
|
||||||
|
// if ((NULL == pGeomtry) || (NULL == m_pScansion))
|
||||||
|
// {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// m_pScansion->UpdataDrawable( pGeomtry);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//private:
|
||||||
|
// CDrawDecorate* m_pScansion;
|
||||||
|
//};
|
||||||
|
|
||||||
|
DrawDecorate::DrawDecorate(ElectricWave* pElectricWave)
|
||||||
|
: electricWave_(pElectricWave),
|
||||||
|
drawable_(NULL),create_(false),wireframe_(false),colorArray_(NULL),forceDraw_(false),
|
||||||
|
forceColors_(false),forceDrawStyle_(false),state_(true),in_(false)
|
||||||
|
{
|
||||||
|
colorArray_ = new osg::Vec4Array;
|
||||||
|
colorArray_->push_back(osg::Vec4(1.0, 0.0, 0.2, 0.3));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DrawDecorate::~DrawDecorate(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawDecorate::InitDrawable(void)
|
||||||
|
{
|
||||||
|
// 创建顶点
|
||||||
|
drawable_ = CreateDrawable();
|
||||||
|
drawable_->setUseDisplayList(false);
|
||||||
|
|
||||||
|
// 设置颜色
|
||||||
|
osg::Geometry* pGeometry = drawable_->asGeometry();
|
||||||
|
if (NULL == pGeometry)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::Vec3dArray* pVertex = GetVertexArrays();
|
||||||
|
// 设置顶点
|
||||||
|
pGeometry->setVertexArray(pVertex);
|
||||||
|
// 设置颜色
|
||||||
|
pGeometry->setColorArray(GetColorArrays());
|
||||||
|
pGeometry->setColorBinding(GetColorBinding());
|
||||||
|
|
||||||
|
SetNormal(drawable_->asGeometry());
|
||||||
|
|
||||||
|
// 设置渲染体
|
||||||
|
//pGeometry->addPrimitiveSet(GetPrimitiveSet(0, pVertex->size()));
|
||||||
|
CreatePrimitiveSet(pGeometry, 0, pVertex->size());
|
||||||
|
// 设置属性
|
||||||
|
SetStateSet(pGeometry->getOrCreateStateSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置渲染体
|
||||||
|
void DrawDecorate::AddDrawable(osg::Drawable* pDrawable)
|
||||||
|
{
|
||||||
|
drawable_ = pDrawable;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置顶点法线
|
||||||
|
void DrawDecorate::SetNormal(osg::Geometry* pDrawable)
|
||||||
|
{
|
||||||
|
//osgUtil::SmoothingVisitor::smooth(*pDrawable);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获得渲染体
|
||||||
|
void DrawDecorate::GetDrawable(osg::Geode* pGeode)
|
||||||
|
{
|
||||||
|
if (!create_)
|
||||||
|
{
|
||||||
|
InitDrawable();
|
||||||
|
create_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
pGeode->addDrawable(drawable_);
|
||||||
|
// 判断装饰目标是否为空
|
||||||
|
if (NULL == electricWave_)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
electricWave_->GetDrawable(pGeode);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置颜色数组
|
||||||
|
void DrawDecorate::SetColorArray(const osg::Vec4Array* pColorArray)
|
||||||
|
{
|
||||||
|
colorArray_ = (osg::Vec4Array*)pColorArray->clone(osg::CopyOp::DEEP_COPY_ALL);
|
||||||
|
|
||||||
|
ForceColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建渲染体
|
||||||
|
osg::Drawable* DrawDecorate::CreateDrawable(void)
|
||||||
|
{
|
||||||
|
osg::Drawable* pDrawable = new osg::Geometry;
|
||||||
|
return (pDrawable);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获得渲染体
|
||||||
|
osg::Drawable* DrawDecorate::GetDrawable(void)
|
||||||
|
{
|
||||||
|
return (drawable_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 颜色绑定形式
|
||||||
|
osg::Geometry::AttributeBinding DrawDecorate::GetColorBinding(void)
|
||||||
|
{
|
||||||
|
return osg::Geometry::BIND_OVERALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获得颜色
|
||||||
|
osg::Vec4Array* DrawDecorate::GetColorArrays(void)
|
||||||
|
{
|
||||||
|
osg::Vec4Array* pColorArray = (osg::Vec4Array*)colorArray_->clone(osg::CopyOp::DEEP_COPY_ARRAYS);
|
||||||
|
return (pColorArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置属性
|
||||||
|
void DrawDecorate::SetStateSet(osg::StateSet* pStateSet)
|
||||||
|
{
|
||||||
|
pStateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||||
|
pStateSet->setRenderBinDetails(in_ ? REANDER_IN : REANDER_OUT, "DepthSortedBin");
|
||||||
|
pStateSet->setMode(GL_BLEND, osg::StateAttribute::ON);
|
||||||
|
osg::Depth* pDepth = new osg::Depth;
|
||||||
|
pDepth->setWriteMask(false);
|
||||||
|
pStateSet->setAttributeAndModes(pDepth);
|
||||||
|
|
||||||
|
osg::BlendFunc* pBlendFunc = new osg::BlendFunc;
|
||||||
|
pBlendFunc->setSource(osg::BlendFunc::SRC_ALPHA);
|
||||||
|
pBlendFunc->setDestination(osg::BlendFunc::SRC_ALPHA_SATURATE);
|
||||||
|
pStateSet->setAttributeAndModes(pBlendFunc);
|
||||||
|
//pStateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新
|
||||||
|
void DrawDecorate::UpdataDrawable(void)
|
||||||
|
{
|
||||||
|
osg::Geometry* pGeometry = drawable_->asGeometry();
|
||||||
|
if (NULL == pGeometry)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!state_)
|
||||||
|
{
|
||||||
|
pGeometry->removePrimitiveSet(0, pGeometry->getNumPrimitiveSets());
|
||||||
|
ForceColor();
|
||||||
|
ForceDraw();
|
||||||
|
ForceDrawStyle();
|
||||||
|
|
||||||
|
pGeometry->dirtyBound();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (forceDraw_)
|
||||||
|
{
|
||||||
|
osg::Vec3dArray* pVertexs = GetVertexArrays();
|
||||||
|
pGeometry->setVertexArray(pVertexs);
|
||||||
|
SetNormal(pGeometry);
|
||||||
|
|
||||||
|
// 重新绘制
|
||||||
|
if (forceDrawStyle_)
|
||||||
|
{
|
||||||
|
pGeometry->removePrimitiveSet(0, pGeometry->getNumPrimitiveSets());
|
||||||
|
CreatePrimitiveSet(pGeometry, 0, pVertexs->size());
|
||||||
|
forceDrawStyle_ = false;
|
||||||
|
// 更新属性
|
||||||
|
SetStateSet(pGeometry->getOrCreateStateSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
pGeometry->dirtyBound();
|
||||||
|
forceDraw_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (forceColors_)
|
||||||
|
{
|
||||||
|
// 设置颜色
|
||||||
|
pGeometry->setColorArray(GetColorArrays());
|
||||||
|
pGeometry->setColorBinding(GetColorBinding());
|
||||||
|
forceColors_ = false;
|
||||||
|
|
||||||
|
// 更新属性
|
||||||
|
SetStateSet(pGeometry->getOrCreateStateSet());
|
||||||
|
pGeometry->dirtyBound();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断装饰的对象是否为空
|
||||||
|
DrawDecorate* pDrawDecorate = dynamic_cast<DrawDecorate*>(electricWave_);
|
||||||
|
if (NULL == pDrawDecorate)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pDrawDecorate->UpdataDrawable();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示开关
|
||||||
|
void DrawDecorate::SetState(bool bOpened)
|
||||||
|
{
|
||||||
|
state_ = bOpened;
|
||||||
|
}
|