Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

125 lines (113 sloc) 4.443 kb
%%
%% wings_shaders.erl --
%%
%% Support for vertex & fragment shaders (for cards with OpenGL 2.0).
%%
%% Copyright (c) 2001-2008 Bjorn Gustavsson
%%
%% See the file "license.terms" for information on usage and redistribution
%% of this file, and for a DISCLAIMER OF ALL WARRANTIES.
%%
%% $Id$
%%
-module(wings_shaders).
-export([init/0, read_texture/1]).
-define(NEED_OPENGL, 1).
-include("wings.hrl").
-include("e3d_image.hrl").
init() ->
Programs = {{make_hemi(), "Hemispherical Lighting"},
{make_prog("gooch"), "Gooch Tone"},
{make_prog("toon"), "Toon"},
{make_prog("brick"), "Brick"},
{make_prog("envmap"), "Environment Mapping"},
{make_prog("vertex_color", "Flag", 0), "Vertex Normals Color"},
{make_prog("vertex_color", "Flag", 1), "Face Normals Color"},
{make_prog("spherical_ao"), "Spherical Ambient Occlusion"},
{make_prog("depth"), "Depth"},
{make_prog("harmonics", "Type", 5), "Spherical Harmonics 5"},
{make_prog("harmonics", "Type", 8), "Spherical Harmonics 8"},
{make_prog("harmonics", "Type", 9), "Spherical Harmonics 9"}},
?CHECK_ERROR(),
gl:useProgram(0),
put(light_shaders, Programs),
case wings_pref:get_value(number_of_shaders) > tuple_size(Programs) of
true -> wings_pref:set_value(number_of_shaders, 1);
false -> ok
end,
io:format("Using GPU shaders.\n").
read_texture(FileName) ->
Path = filename:join(wings_util:lib_dir(wings), "textures"),
NewFileName = filename:join(Path, FileName),
ImgRec = e3d_image:load(NewFileName, [{order,lower_left}]),
ImgRec.
read_shader(FileName) ->
Path = filename:join(wings_util:lib_dir(wings), "shaders"),
NewFileName = filename:join(Path, FileName),
{ok,Bin} = file:read_file(NewFileName),
Bin.
make_prog(Name) ->
Shv = wings_gl:compile(vertex, read_shader(Name ++ ".vs")),
Shf = wings_gl:compile(fragment, read_shader(Name ++ ".fs")),
Prog = wings_gl:link_prog([Shv,Shf]),
gl:useProgram(Prog),
case Name == "envmap" of
true ->
FileName = "grandcanyon.png",
EnvImgRec = read_texture(FileName),
#e3d_image{width=ImgW,height=ImgH,image=ImgData} = EnvImgRec,
[TxId] = gl:genTextures(1),
gl:activeTexture(?GL_TEXTURE0 + TxId),
gl:bindTexture(?GL_TEXTURE_2D, TxId),
gl:texParameteri(?GL_TEXTURE_2D, ?GL_TEXTURE_WRAP_S, ?GL_REPEAT),
gl:texParameteri(?GL_TEXTURE_2D, ?GL_TEXTURE_WRAP_T, ?GL_REPEAT),
gl:texParameteri(?GL_TEXTURE_2D, ?GL_TEXTURE_MAG_FILTER, ?GL_LINEAR),
gl:texParameteri(?GL_TEXTURE_2D, ?GL_TEXTURE_MIN_FILTER, ?GL_LINEAR),
gl:texImage2D(?GL_TEXTURE_2D, 0, ?GL_RGB, ImgW, ImgH, 0, ?GL_RGB,
?GL_UNSIGNED_BYTE, ImgData),
wings_gl:set_uloc(Prog, "EnvMap", TxId),
gl:activeTexture(?GL_TEXTURE0);
false ->
ok
end,
Prog.
make_prog(Name, Var, Val) ->
Shv = wings_gl:compile(vertex, read_shader(Name ++ ".vs")),
Shf = wings_gl:compile(fragment, read_shader(Name ++ ".fs")),
Prog = wings_gl:link_prog([Shv,Shf]),
gl:useProgram(Prog),
wings_gl:set_uloc(Prog, Var, Val),
Prog.
make_hemi() ->
Sh = wings_gl:compile(vertex, light_shader_src()),
Prog = wings_gl:link_prog([Sh]),
gl:useProgram(Prog),
wings_pref:set_default(hl_lightpos, {3.0,10.0,1.0}),
wings_pref:set_default(hl_skycol, {0.95,0.95,0.90}),
wings_pref:set_default(hl_groundcol, {0.026,0.024,0.021}),
wings_gl:set_uloc(Prog, "LightPosition", wings_pref:get_value(hl_lightpos)),
wings_gl:set_uloc(Prog, "SkyColor", wings_pref:get_value(hl_skycol)),
wings_gl:set_uloc(Prog, "GroundColor", wings_pref:get_value(hl_groundcol)),
Prog.
light_shader_src() ->
<<"
uniform vec3 LightPosition;
uniform vec3 SkyColor;
uniform vec3 GroundColor;
void main()
{
vec3 ecPosition = vec3(gl_ModelViewMatrix * gl_Vertex);
vec3 tnorm = normalize(gl_NormalMatrix * gl_Normal);
vec3 lightVec = normalize(LightPosition - ecPosition);
float costheta = dot(tnorm, lightVec);
float a = 0.5 + 0.5 * costheta;
// ATI needs this for vcolors to work
vec4 color = gl_FrontMaterial.diffuse * gl_Color;
gl_FrontColor = color * vec4(mix(GroundColor, SkyColor, a), 1.0);
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
#ifdef __GLSL_CG_DATA_TYPES // Fix clipping for Nvidia and ATI
gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;
#endif
}
">>.
Jump to Line
Something went wrong with that request. Please try again.