add source first

This commit is contained in:
jiegeaiai 2025-01-04 12:12:51 +08:00
commit f4b93f7278
422 changed files with 99777 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
build/
bin/
thirdparty/

47
CMakeLists.txt Normal file
View 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}/thirdparty)
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
resources/island/detail.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 KiB

Binary file not shown.

BIN
resources/island/moss.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 515 KiB

BIN
resources/island/sand.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

View 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;
}

View 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();
}

View 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;
}

View File

@ -0,0 +1,5 @@
void main( void )
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}

View 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);
}

View File

@ -0,0 +1,5 @@
void main(void)
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}

View 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;
}

View 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;
}

View 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;
}

View 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();
}

View 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 );
}

View 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);
}

View 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);
}

View 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;
}

View File

@ -0,0 +1,6 @@
varying vec3 vIntensity;
void main(void)
{
gl_FragColor = vec4(vIntensity,1.0);
}

View 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;
}

View 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;
}

View 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;
}

View 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;
}
}

View 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;
}

View 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;
}
}

View 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] );
}

View 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;
}
}

View 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);
}

View 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);
}

View 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);
}

View 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;
}

View 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);
}

View 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;
}

View 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);
}

View File

@ -0,0 +1,6 @@
void main(void)
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}

View 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 );
}

View File

@ -0,0 +1,8 @@
varying vec4 vEyePos;
void main(void)
{
gl_TexCoord[0] = gl_MultiTexCoord0;
vEyePos = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_Position = ftransform();
}

View 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);
}

View 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;
}

View 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 );
}

View 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();
}

View 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 );
}

View 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();
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 295 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 363 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 363 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 559 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 568 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

207
src/CMakeLists.txt Normal file
View File

@ -0,0 +1,207 @@
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)
FILE(GLOB_RECURSE RC_FILES res/*.rc)
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()
add_definitions(-DFMT_UNICODE=0)
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}
${RC_FILES}
${QM_FILES}
${PROJECT_BINARY_DIR}/config.cpp
${PROJECT_SOURCE_DIR}/${PROJECT_NAME}.manifest
)
INCLUDE_DIRECTORIES(
${PROJECT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
${Thirdparty}/spdlog/include
${Thirdparty}/breakpad/include
${Thirdparty}/3rdParty_x64/include
${Thirdparty}/OpenSceneGraph-3.6.5/include
${Thirdparty}/TritonSDK/PublicHeaders
${Thirdparty}/matlab/include
# ${Thirdparty}/Python39/include
)
LINK_DIRECTORIES(
${Thirdparty}/spdlog/lib
${Thirdparty}/3rdParty_x64/lib
${Thirdparty}/OpenSceneGraph-3.6.5/lib
${Thirdparty}/matlab/lib/win64/microsoft
${Thirdparty}/TritonSDK/lib/vc143/x64
# ${Thirdparty}/Python39/libs
)
if(MSVC)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi /Od")
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++14")
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
osgParticle
osgSim
osgEarth
Triton-MT-DLL
libeng
libmx
libmat
# python39
)
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
src/Dyt.manifest Normal file
View 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
src/Dyt.qrc Normal file
View 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>

45
src/app/Application.cpp Normal file
View File

@ -0,0 +1,45 @@
#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"
#include "python/PythonModule.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);
//Singleton<PythonModule>::Create(this);
}
void Application::Uninit() {
//Singleton<PythonModule>::Destory();
Singleton<NetDriver>::Destory();
Singleton<WorkSpaceManager>::Destory();
Singleton<EntitiesManager>::Destory();
Singleton<RecourceHelper>::Destory();
Singleton<OsgViewer>::Destory();
Singleton<MeshManager>::Destory();
}

17
src/app/Application.h Normal file
View 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
src/app/Singleton.h Normal file
View 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
src/common/CrashHandler.cpp Normal file
View 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;
}

View File

@ -0,0 +1,5 @@
#pragma once
bool InstallCrashHandler();
void TestCrash();

View 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
src/common/PugiXML/pugixml.cpp Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,90 @@
#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
qDebug() << transName;
bool success = trans_.load(transName);
if (!success) {
qDebug() << "load translations error";
}
QApplication::installTranslator(&trans_);
}

View 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_;
};

82
src/common/SpdLogger.cpp Normal file
View File

@ -0,0 +1,82 @@
#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;
//auto tp = std::make_shared<spdlog::details::thread_pool>(1, 1);
//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>();
std::string 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
src/common/SpdLogger.h Normal file
View 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
src/config.cpp.in Normal file
View 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@";

43
src/config.h Normal file
View File

@ -0,0 +1,43 @@
#pragma once
#include <cmath>
#include <limits>
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
#define dyt_check(condition) \
do { \
if (!(condition)) { \
LOG_ERROR("Check failed: {}", #condition); \
abort(); \
} \
} while (0)
FORCE_INLINE bool IsValid(double value) {
constexpr double epsilon = std::numeric_limits<double>::epsilon();
return std::abs(value) > epsilon;
}
FORCE_INLINE bool IsDecimalValid(double value) {
double intPart;
double fractionalPart = std::modf(value, &intPart);
return IsValid(fractionalPart);
}

144
src/config/skin/blue.qss Normal file
View 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
src/config/skin/default.css Normal file
View 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
src/config/skin/default.qss Normal file
View 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
src/config/skin/silver.qss Normal file
View 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;
}

View 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
src/effects/ChaffBombs.h Normal file
View 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:
};

136
src/effects/ConeWave.cpp Normal file
View File

@ -0,0 +1,136 @@
#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() {
}
ConeWave::~ConeWave(void)
{
}
void ConeWave::Render(double dt) {
}
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::SetLevelCount(int count) {
levelCount_ = count;
if (levelCountUniform_) {
levelCountUniform_->set(float(levelCount_));
}
}
void ConeWave::SetLevelHeight(float height) {
levelHeight_ = height;
if (levelHeightUniform_) {
levelHeightUniform_->set(levelHeight_);
}
}
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_);
static const char* vertSource = {
"varying vec3 pos;\n"
"void main()\n"
"{\n"
"pos.x=gl_Vertex.x;\n"
"pos.y=gl_Vertex.y;\n"
"pos.z=gl_Vertex.z;\n"
"gl_Position = gl_ModelViewProjectionMatrix*gl_Vertex;\n"
"}\n"
};
static const char* fragSource = {
"uniform float num; \n"
"uniform float height; \n"
"uniform vec4 baseColor;\n"
"varying vec3 pos;\n"
"float Alpha = 1.0; \n"
"float f = pos.z;\n"
"uniform float osg_FrameTime;\n"
"void main()\n"
"{\n"
"if (sin(f/height*3.14*2*num+ osg_FrameTime*10) > 0)\n"
"{\n"
" Alpha = 0.8;\n"
"}\n"
"else\n"
"{\n"
" Alpha = 0.3;\n"
"}\n"
" gl_FragColor = vec4(baseColor.rgb, Alpha);\n"
"}\n "
};
osg::ref_ptr<osg::Shader> vertexShader = new osg::Shader(osg::Shader::VERTEX);
vertexShader->setShaderSource(vertSource);
osg::ref_ptr<osg::Shader> fragmentShader = new osg::Shader(osg::Shader::FRAGMENT);
fragmentShader->setShaderSource(fragSource);
osg::StateSet* stateset = coneDrawable_->getOrCreateStateSet();
stateset->setRenderBinDetails(10000, "RenderBin");
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);
baseColorUniform_ = new osg::Uniform("baseColor", baseColor_);
stateset->setMode(GL_CULL_FACE, osg::StateAttribute::ON);
stateset->addUniform(baseColorUniform_);
stateset->setAttributeAndModes(program, osg::StateAttribute::ON);
levelCountUniform_ = new osg::Uniform("num", float(levelCount_));
levelHeightUniform_ = new osg::Uniform("height", levelHeight_);
stateset->addUniform(levelCountUniform_);
stateset->addUniform(levelHeightUniform_.get());
}

64
src/effects/ConeWave.h Normal file
View File

@ -0,0 +1,64 @@
#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();
~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_;
}
void SetLevelCount(int count);
int GetLevelCount() const {
return levelCount_;
}
void SetLevelHeight(float height);
float GetLevelHeihgt() const {
return levelHeight_;
}
protected:
virtual void CreateTexturedCone(osg::Geode* geode);
private:
osg::ref_ptr<osg::Cone> cone_;
osg::ref_ptr<osg::ShapeDrawable> coneDrawable_;
osg::ref_ptr<osg::Uniform> baseColorUniform_;
osg::Vec4 baseColor_{ 0.0f, 0.2f, 0.5f, 0.2f };
osg::ref_ptr<osg::Uniform> levelCountUniform_;
int levelCount_{ 4 };
osg::ref_ptr<osg::Uniform> levelHeightUniform_;
float levelHeight_{ 500.0f };
float height_{ 60.0f };
float radius_{ 10.0f };
};

165
src/effects/DashedLine.cpp Normal file
View 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
src/effects/DashedLine.h Normal file
View 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 };
};

View 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
src/effects/DottedLine.h Normal file
View 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_;
};

Some files were not shown because too many files have changed in this diff Show More