add assets/fs directory with initial OpenGL shaders and CCFS generation script

This commit is contained in:
Josh Holtrop 2012-08-28 20:57:03 -04:00
parent 38dbf27c82
commit 9c90adbc75
7 changed files with 248 additions and 1 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
bin bin
src/client/ccfs.*

View File

@ -1,10 +1,14 @@
# vim:filetype=python # vim:filetype=python
import os import os
import re
from subprocess import Popen, PIPE
client_name = 'treacherous-terrain' client_name = 'treacherous-terrain'
server_name = client_name + '-server' server_name = client_name + '-server'
CCFS_ROOT = 'assets/fs'
# determine our build platform # determine our build platform
platform = 'windows' if os.path.exists('/bin/cygwin1.dll') else 'unix' platform = 'windows' if os.path.exists('/bin/cygwin1.dll') else 'unix'
@ -44,7 +48,7 @@ else:
# our sources # our sources
sources_client = [Glob('src/common/*.cc'), Glob('src/client/*.cc')] sources_client = [Glob('src/common/*.cc'), Glob('src/client/*.cc')]
sources_server = [Glob('src/common/*.cc'), Glob('src/server/*.cc')] sources_server = [Glob('src/common/*.cc'), Glob('src/server/*.cc'), 'src/client/ccfs.cc']
# create the scons environments # create the scons environments
env_client = Environment( env_client = Environment(
@ -63,6 +67,38 @@ env_server = Environment(
LIBPATH = LIBPATH, LIBPATH = LIBPATH,
LIBS = LIBS_server) LIBS = LIBS_server)
# CCFS builder
def get_all_files(prefix):
files = []
for ent in os.listdir(prefix):
if ent.startswith('.'):
next
full_path = '%s/%s' % (prefix, ent)
if os.path.isdir(full_path):
files += get_all_files(full_path)
else:
files.append(full_path)
return files
def CCFS(target, source, env):
source_list = []
for s in source:
source_fname = str(s)
source_fname = source_fname.replace(CCFS_ROOT + '/', '')
source_list.append(source_fname)
Popen(['./ccfs_gen.py', '--root', 'assets/fs', str(target[0])] + source_list).wait()
return None
def CCFS_emitter(target, source, env):
target.append(re.sub(r'\..*$', '.h', str(target[0])))
return target, source
env_client.Append(BUILDERS = {'CCFS' : Builder(action = CCFS, emitter = CCFS_emitter)})
env_client.CCFS('src/client/ccfs.cc', get_all_files(CCFS_ROOT))
env_client.Depends('src/client/ccfs.cc', 'ccfs_gen.py')
for lib_path in libs_to_copy: for lib_path in libs_to_copy:
installed_libs = env_client.Install(BIN_DIR, lib_path) installed_libs = env_client.Install(BIN_DIR, lib_path)
env_client.Depends('%s/%s' % (BIN_DIR, client_name), installed_libs) env_client.Depends('%s/%s' % (BIN_DIR, client_name), installed_libs)

View File

@ -0,0 +1,33 @@
uniform vec4 ambient, diffuse, specular;
uniform float shininess;
varying vec3 pos_i;
varying vec3 normal_i;
void main(void)
{
vec3 n, lightDir;
vec4 color;
float NdotL, RdotEye;
lightDir = normalize(vec3(-0.1, 0, -0.9));
color = vec4(0.2, 0.2, 0.2, 1.0) * ambient; /* ambient light */
n = normalize(normal_i);
NdotL = max(dot(n, -lightDir), 0.0);
if (NdotL > 0.0)
{
/* diffuse component */
color += diffuse * NdotL;
/* specular component */
RdotEye = dot(normalize(-pos_i), normalize(reflect(-lightDir, n)));
if (RdotEye > 0.0)
{
color += clamp(specular * pow(RdotEye, shininess), 0.0, 1.0);
}
}
gl_FragColor = color;
}

View File

@ -0,0 +1,35 @@
uniform vec4 ambient, specular;
uniform float shininess;
uniform sampler2D tex;
varying vec3 pos_i;
varying vec3 normal_i;
varying vec2 tex_coord_i;
void main(void)
{
vec3 n, lightDir;
vec4 color;
float NdotL, RdotEye;
lightDir = normalize(vec3(-0.1, 0, -0.9));
color = vec4(0.2, 0.2, 0.2, 1.0) * ambient; /* ambient light */
n = normalize(normal_i);
NdotL = max(dot(n, -lightDir), 0.0);
if (NdotL > 0.0)
{
/* diffuse component */
color += texture2D(tex, tex_coord_i) * NdotL;
/* specular component */
RdotEye = dot(normalize(-pos_i), normalize(reflect(-lightDir, n)));
if (RdotEye > 0.0)
{
color += clamp(specular * pow(RdotEye, shininess), 0.0, 1.0);
}
}
gl_FragColor = color;
}

View File

@ -0,0 +1,16 @@
attribute vec3 pos;
attribute vec3 normal;
attribute vec2 tex_coord;
varying vec3 pos_i;
varying vec3 normal_i;
varying vec2 tex_coord_i;
void main(void)
{
gl_Position = gl_ModelViewProjectionMatrix * vec4(pos, 1);
pos_i = gl_Position.xyz;
tex_coord_i = tex_coord;
normal_i = gl_NormalMatrix * normal;
}

View File

@ -0,0 +1,13 @@
attribute vec3 pos;
attribute vec3 normal;
varying vec3 pos_i;
varying vec3 normal_i;
void main(void)
{
gl_Position = gl_ModelViewProjectionMatrix * vec4(pos, 1);
pos_i = gl_Position.xyz;
normal_i = gl_NormalMatrix * normal;
}

113
ccfs_gen.py Executable file
View File

@ -0,0 +1,113 @@
#!/usr/bin/env python
import sys
import re
import os
import getopt
def cname(s):
c = re.sub(r'\W', '_', s)
if re.search(r'^\d', c):
c = '_' + c
return c
def usage(prog_name, err=False):
out = sys.stderr if err else sys.stdout
out.write('Usage: %s [options] out_file.cc paths...\n' % prog_name)
out.write(' Options:\n')
out.write(' --root dir base directory in which to look up paths\n')
out.write(' --name name name of the instance object to generate (default CFS)\n')
return 2 if err else 0
def main(argv):
instance_name = 'CFS'
root_dir = '.'
opts, args = getopt.getopt(argv[1:], '', ['root=', 'name='])
for opt, val in opts:
if opt == '--root':
root_dir = val
elif opt == '--name':
instance_name = val
else:
sys.stderr.write('Unrecognized command-line option: "%s"\n' % opt)
return 2
if len(args) < 2:
return usage(argv[0], True)
out_fname = args[0]
paths = args[1:]
store = {}
header_fname = re.sub(r'\..*$', '.h', out_fname)
if header_fname == out_fname:
sys.stderr.write('Output file requires file extension\n')
return 2
c_file = open(out_fname, 'w')
h_file = open(header_fname, 'w')
c_file.write('#include <string.h>\n')
c_file.write('#include "%s"\n' % os.path.basename(header_fname))
for p in paths:
c_name = cname(p)
c_file.write('static const unsigned char %s[] = {' % c_name)
src = open('%s/%s' % (root_dir, p), 'r')
s_len = 0
while 1:
if s_len % 12 == 0:
c_file.write('\n ')
ch = src.read(1)
if len(ch) < 1:
break
s_len += 1
c_file.write('0x%02x, ' % ord(ch))
c_file.write('0x00\n')
src.close()
c_file.write('};\n')
store[p] = (c_name, s_len)
c_file.write('''static const struct {
const char *fname;
const unsigned char *data;
const unsigned int len;
} store[] = {\n''')
for ent in store:
c_file.write(' {"%s", %s, %d},\n' % \
(ent, store[ent][0], store[ent][1]))
c_file.write(' {NULL, NULL, 0}\n')
c_file.write('};\n')
c_file.write('''
const unsigned char *CCFSClass::get_file(const char *fname, unsigned int *length)
{
int i;
for (i = 0; store[i].fname != NULL; i++)
{
if (strcmp(fname, store[i].fname) == 0)
{
if (length != NULL)
*length = store[i].len;
return store[i].data;
}
}
return NULL;
}
''')
h_file.write('''#ifndef CCFS_GEN_%s
#define CCFS_GEN_%s
class CCFSClass
{
public:
const unsigned char *get_file(const char *fname, unsigned int *length);
};
CCFSClass %s;
#endif
''' % (cname(header_fname), cname(header_fname), instance_name))
h_file.close()
c_file.close()
return 0
if __name__ == "__main__":
sys.exit(main(sys.argv))