Fade dust motes to clear instead of black when shady.

git-svn-id: http://svn.berlios.de/svnroot/repos/oolite-linux/trunk@3298 127b21dd-08f5-0310-b4b7-95ae10353056
This commit is contained in:
Jens Ayton 2010-05-06 18:22:53 +00:00
parent aa05c0eb93
commit 8392bee4a5
5 changed files with 174 additions and 26 deletions

View File

@ -61,6 +61,8 @@
1A0BF3DE10DAE3490099984D /* python_redux2.dat in Copy Models */ = {isa = PBXBuildFile; fileRef = 1A0BF3DC10DAE3490099984D /* python_redux2.dat */; };
1A0BF3E010DAE3610099984D /* transporter_redux1.dat in Copy Models */ = {isa = PBXBuildFile; fileRef = 1A0BF3DF10DAE3610099984D /* transporter_redux1.dat */; };
1A0BF3E210DAE3760099984D /* worm_redux1.dat in Copy Models */ = {isa = PBXBuildFile; fileRef = 1A0BF3E110DAE3760099984D /* worm_redux1.dat */; };
1A0C3EDE11933076007935E5 /* oolite-dust.vertex in Copy Shaders */ = {isa = PBXBuildFile; fileRef = 1A0C3EDD1193306B007935E5 /* oolite-dust.vertex */; };
1A0C3EEB11933274007935E5 /* oolite-dust.fragment in Copy Shaders */ = {isa = PBXBuildFile; fileRef = 1A0C3EEA11933272007935E5 /* oolite-dust.fragment */; };
1A0DA2EE0D71D280009B0970 /* OOJSSpecialFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A0DA2EC0D71D280009B0970 /* OOJSSpecialFunctions.h */; };
1A0DA2EF0D71D280009B0970 /* OOJSSpecialFunctions.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A0DA2ED0D71D280009B0970 /* OOJSSpecialFunctions.m */; };
1A11273B105994D000DF9D12 /* OOExhaustPlumeEntity.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A112739105994D000DF9D12 /* OOExhaustPlumeEntity.h */; };
@ -1106,6 +1108,8 @@
dstPath = Shaders;
dstSubfolderSpec = 7;
files = (
1A0C3EEB11933274007935E5 /* oolite-dust.fragment in Copy Shaders */,
1A0C3EDE11933076007935E5 /* oolite-dust.vertex in Copy Shaders */,
1A6515100CCC9E2E0054D01B /* oolite-standard-vertex.vertex in Copy Shaders */,
1A02FD460EE0490B008F9B09 /* oolite-tangent-space-vertex.vertex in Copy Shaders */,
1A6515110CCC9E2E0054D01B /* oolite-default-shader.fragment in Copy Shaders */,
@ -1168,6 +1172,8 @@
1A0BF3DC10DAE3490099984D /* python_redux2.dat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = python_redux2.dat; sourceTree = "<group>"; };
1A0BF3DF10DAE3610099984D /* transporter_redux1.dat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = transporter_redux1.dat; sourceTree = "<group>"; };
1A0BF3E110DAE3760099984D /* worm_redux1.dat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = worm_redux1.dat; sourceTree = "<group>"; };
1A0C3EDD1193306B007935E5 /* oolite-dust.vertex */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.frag; path = "oolite-dust.vertex"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.glsl; };
1A0C3EEA11933272007935E5 /* oolite-dust.fragment */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.vert; path = "oolite-dust.fragment"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.glsl; };
1A0DA2EC0D71D280009B0970 /* OOJSSpecialFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOJSSpecialFunctions.h; sourceTree = "<group>"; };
1A0DA2ED0D71D280009B0970 /* OOJSSpecialFunctions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOJSSpecialFunctions.m; sourceTree = "<group>"; };
1A112739105994D000DF9D12 /* OOExhaustPlumeEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOExhaustPlumeEntity.h; sourceTree = "<group>"; };
@ -2479,6 +2485,8 @@
1A65150E0CCC9E220054D01B /* oolite-default-shader.fragment */,
1ADA576710CDB1C300E891B8 /* oolite-default-planet.vertex */,
1ADA576910CDB1C600E891B8 /* oolite-default-planet.fragment */,
1A0C3EDD1193306B007935E5 /* oolite-dust.vertex */,
1A0C3EEA11933272007935E5 /* oolite-dust.fragment */,
);
path = Shaders;
sourceTree = "<group>";

View File

@ -0,0 +1,32 @@
/*
oolite-dust.fragment
Fragment shader for interplanetary dust.
© 2010 Jens Ayton
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
*/
varying vec4 vColor;
void main(void)
{
gl_FragColor = vColor;
}

View File

@ -0,0 +1,52 @@
/*
oolite-dust.vertex
Vertex shader for interplanetary dust.
© 2010 Jens Ayton
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
*/
varying vec4 vColor;
/* The following macros are provided by Oolite, to ensure that they stay in
sync with the values used in non-shader mode.
#define OODUST_SCALE_MAX (float(2))
#define OODUST_SCALE_FACTOR (float(0.002))
*/
void main(void)
{
float distance = length(gl_ModelViewMatrix * gl_Vertex);
/* The original non-shader code fades to black using linear fog, with a
near plane of 500 and a far plane of 1000.
OODUST_SCALE_MAX is far plane/near plane, and OODUST_SCALE_FACTOR
is 1.0/(far plane - near plane).
This gives us a function such that f(x) ≥ 1 when x ≤ near plane,
f(x) ≤ 0 when x ≥ far plane, and a linear ramp in between, which we
then clamp to [0..1].
*/
float alpha = clamp(OODUST_SCALE_MAX - distance * OODUST_SCALE_FACTOR, 0.0, 1.0);
vColor = vec4(gl_Color.rgb, alpha);
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

View File

@ -25,6 +25,7 @@ MA 02110-1301, USA.
*/
#import "Entity.h"
#import "OOShaderProgram.h"
#define DUST_SCALE 2000
#define DUST_N_PARTICLES 600
@ -33,13 +34,17 @@ MA 02110-1301, USA.
@interface DustEntity: Entity
{
OOColor *dust_color;
Vector vertices[DUST_N_PARTICLES];
GLfloat color_fv[4];
GLuint displayListName;
OOColor *dust_color;
Vector vertices[DUST_N_PARTICLES];
GLfloat color_fv[4];
GLuint displayListName;
#if OO_SHADERS
OOShaderProgram *shader;
#endif
}
- (void) setDustColor:(OOColor *) color;
- (OOColor *) dust_color;
- (OOColor *) dustColor;
@end

View File

@ -33,6 +33,10 @@ MA 02110-1301, USA.
#import "PlayerEntity.h"
#define FAR_PLANE (DUST_SCALE * 0.50f)
#define NEAR_PLANE (DUST_SCALE * 0.25f)
// Declare protocol conformance
@interface DustEntity (OOGraphicsResetClient) <OOGraphicsResetClient>
@end
@ -67,10 +71,14 @@ MA 02110-1301, USA.
- (void) dealloc
{
[dust_color release];
DESTROY(dust_color);
[[OOGraphicsResetManager sharedManager] unregisterClient:self];
OOGL(glDeleteLists(displayListName, 1));
#if OO_SHADERS
DESTROY(shader);
#endif
[super dealloc];
}
@ -83,7 +91,7 @@ MA 02110-1301, USA.
}
- (OOColor *) dust_color
- (OOColor *) dustColor
{
return dust_color;
}
@ -102,7 +110,7 @@ MA 02110-1301, USA.
zero_distance = 0.0;
Vector offset = player->position;
Vector offset = [player position];
GLfloat half_scale = DUST_SCALE * 0.50;
int vi;
for (vi = 0; vi < DUST_N_PARTICLES; vi++)
@ -122,10 +130,31 @@ MA 02110-1301, USA.
while (vertices[vi].z - offset.z > half_scale)
vertices[vi].z -= DUST_SCALE;
}
}
#if OO_SHADERS
- (OOShaderProgram *) shader
{
if (shader == nil)
{
NSString *prefix = [NSString stringWithFormat:
@"#define OODUST_SCALE_MAX (float(%g))\n"
"#define OODUST_SCALE_FACTOR (float(%g))\n",
FAR_PLANE / NEAR_PLANE,
1.0f / (FAR_PLANE - NEAR_PLANE)];
shader = [[OOShaderProgram shaderProgramWithVertexShaderName:@"oolite-dust.vertex"
fragmentShaderName:@"oolite-dust.fragment"
prefix:prefix
attributeBindings:nil] retain];
}
return shader;
}
#endif
- (void) drawEntity:(BOOL) immediate :(BOOL) translucent
{
PlayerEntity* player = [PlayerEntity sharedPlayer];
@ -138,28 +167,37 @@ MA 02110-1301, USA.
int vi;
GLfloat *fogcolor = [UNIVERSE skyClearColor];
int dust_size = floor([[UNIVERSE gameView] viewSize].width / 480.0);
if (dust_size < 1.0)
dust_size = 1.0;
int dust_size = [[UNIVERSE gameView] viewSize].width / 480.0;
if (dust_size < 1) dust_size = 1;
int line_size = dust_size / 2;
if (line_size < 1.0)
line_size = 1.0;
GLfloat half_scale = DUST_SCALE * 0.50;
GLfloat quarter_scale = DUST_SCALE * 0.25;
if (line_size < 1) line_size = 1;
if ([UNIVERSE breakPatternHide]) return; // DON'T DRAW
if ([UNIVERSE breakPatternHide]) return; // DON'T DRAW
BOOL warp_stars = [player atHyperspeed];
Vector warp_vector = vector_multiply_scalar([player velocity], 1.0f / HYPERSPEED_FACTOR);
#if OO_SHADERS
BOOL useShader = [UNIVERSE shaderEffectsLevel] > SHADERS_OFF;
#endif
if (translucent)
{
OOGL(glEnable(GL_FOG));
OOGL(glFogi(GL_FOG_MODE, GL_LINEAR));
OOGL(glFogfv(GL_FOG_COLOR, fogcolor));
OOGL(glHint(GL_FOG_HINT, GL_NICEST));
OOGL(glFogf(GL_FOG_START, quarter_scale));
OOGL(glFogf(GL_FOG_END, half_scale));
#if OO_SHADERS
if (useShader)
{
[[self shader] apply];
OOGL(glEnable(GL_BLEND));
}
else
#endif
{
OOGL(glEnable(GL_FOG));
OOGL(glFogi(GL_FOG_MODE, GL_LINEAR));
OOGL(glFogfv(GL_FOG_COLOR, fogcolor));
OOGL(glHint(GL_FOG_HINT, GL_NICEST));
OOGL(glFogf(GL_FOG_START, NEAR_PLANE));
OOGL(glFogf(GL_FOG_END, FAR_PLANE));
}
// disapply lighting and texture
OOGL(glDisable(GL_TEXTURE_2D));
@ -192,7 +230,16 @@ MA 02110-1301, USA.
OOGLEND();
// reapply normal conditions
OOGL(glDisable(GL_FOG));
#if OO_SHADERS
if (useShader)
{
[OOShaderProgram applyNone];
}
else
#endif
{
OOGL(glDisable(GL_FOG));
}
}
CheckOpenGLErrors(@"DustEntity after drawing %@", self);
@ -206,6 +253,10 @@ MA 02110-1301, USA.
OOGL(glDeleteLists(displayListName, 1));
displayListName = 0;
}
#if OO_SHADERS
DESTROY(shader);
#endif
}