--- /dev/null
+#!/bin/sh
+
+DISPLAY=:0.1 ./demo -vr $*
--- /dev/null
+/* vi: set ft=glsl */
+uniform sampler2D lightmap;
+
+void main()
+{
+ vec3 lumel = texture2D(lightmap, gl_TexCoord[1].st).rgb;
+
+ vec3 diffuse = gl_FrontMaterial.diffuse.rgb * lumel * 1.8;
+
+ vec3 ambient = gl_LightModel.ambient.rgb * gl_FrontMaterial.diffuse.rgb;
+ gl_FragColor.rgb = ambient + diffuse;
+ gl_FragColor.a = gl_FrontMaterial.diffuse.a;
+}
--- /dev/null
+/* vi: set ft=glsl */
+uniform sampler2D texmap;
+uniform sampler2D lightmap;
+
+void main()
+{
+ vec3 texel = texture2D(texmap, gl_TexCoord[0].st).rgb;
+ vec3 lumel = texture2D(lightmap, gl_TexCoord[1].st).rgb;
+
+ vec3 diffuse = lumel * texel * 1.8;
+
+ vec3 ambient = gl_LightModel.ambient.rgb * texel;
+ gl_FragColor.rgb = ambient + diffuse;
+ gl_FragColor.a = gl_FrontMaterial.diffuse.a;
+}
--- /dev/null
+void main()
+{
+ gl_Position = ftransform();
+
+ gl_TexCoord[0] = gl_MultiTexCoord0;
+ gl_TexCoord[1] = gl_MultiTexCoord1;
+}
+++ /dev/null
-/* vi: set ft=glsl */
-uniform sampler2D texmap;
-uniform sampler2D lightmap;
-
-varying vec3 vdir, ldir[3], normal;
-
-//#define KD gl_FrontMaterial.diffuse.rgb
-#define KD vec3(1.0, 1.0, 1.0)
-
-#define KS gl_FrontMaterial.specular.rgb
-#define SPOW gl_FrontMaterial.shininess
-
-#define LD(i) gl_LightSource[i].diffuse.rgb
-#define LS(i) gl_LightSource[i].specular.rgb
-
-vec3 calc_diffuse(in vec3 n, in vec3 l, in vec3 lcol)
-{
- float ndotl = max(dot(n, l), 0.0);
- return KD * lcol * ndotl;
-}
-
-vec3 calc_specular(in vec3 n, in vec3 l, in vec3 v, in vec3 lcol)
-{
- vec3 h = normalize(l + v);
- float ndoth = max(dot(n, h), 0.0);
- return KS * lcol * pow(ndoth, SPOW);
-}
-
-void main()
-{
- vec3 texel = texture2D(texmap, gl_TexCoord[0].st).rgb;
- vec3 lumel = texture2D(lightmap, gl_TexCoord[1].st).rgb;
-
- vec3 n = normalize(normal);
- vec3 v = normalize(vdir);
-
- vec3 diffuse = lumel * texel * 1.8;
- vec3 specular = vec3(0.0, 0.0, 0.0);
-
- /*
- for(int i=0; i<3; i++) {
- vec3 l = normalize(ldir[i]);
- diffuse += calc_diffuse(n, l, LD(i)) * texel;
- specular += calc_specular(n, l, v, LS(i));
- }
- */
-
- vec3 ambient = gl_LightModel.ambient.rgb * KD * texel;
- gl_FragColor.rgb = ambient + diffuse;// + specular;
- gl_FragColor.a = gl_FrontMaterial.diffuse.a;
-}
+++ /dev/null
-varying vec3 vdir, ldir[3], normal;
-
-void main()
-{
- gl_Position = ftransform();
- vec3 vpos = (gl_ModelViewMatrix * gl_Vertex).xyz;
- normal = gl_NormalMatrix * gl_Normal;
- vdir = -vpos;
- ldir[0] = gl_LightSource[0].position.xyz - vpos;
- ldir[1] = gl_LightSource[1].position.xyz - vpos;
- ldir[2] = gl_LightSource[2].position.xyz - vpos;
-
- gl_TexCoord[0] = gl_MultiTexCoord0;
- gl_TexCoord[1] = gl_MultiTexCoord1;
-}
bool fb_srgb;
bool opt_gear_wireframe;
+unsigned int sdr_ltmap, sdr_ltmap_notex;
+
static float cam_dist = 0.0;
static float cam_theta, cam_phi = 20;
static Vec3 cam_pos;
static Mat4 view_matrix, mouse_view_matrix, proj_matrix;
static TextureSet texman;
static Scene *scn;
-static unsigned int sdr, sdr_post_gamma;
+static unsigned int sdr_post_gamma;
static long prev_msec;
cam_pos = bcent + Vec3(0, user_eye_height, 0);
}
- if(!(sdr = create_program_load("sdr/test.v.glsl", "sdr/test.p.glsl"))) {
- fprintf(stderr, "failed to load test shaders\n");
+ if(!(sdr_ltmap_notex = create_program_load("sdr/lightmap.v.glsl", "sdr/lightmap-notex.p.glsl"))) {
+ return false;
+ }
+
+ if(!(sdr_ltmap = create_program_load("sdr/lightmap.v.glsl", "sdr/lightmap-tex.p.glsl"))) {
return false;
}
- set_uniform_int(sdr, "texmap", 0);
- set_uniform_int(sdr, "lightmap", 1);
+ set_uniform_int(sdr_ltmap, "texmap", 0);
+ set_uniform_int(sdr_ltmap, "lightmap", 1);
if(!fb_srgb) {
sdr_post_gamma = create_program_load("sdr/post_gamma.v.glsl", "sdr/post_gamma.p.glsl");
set_light(1, lpos[1], Vec3(0.6, 0.7, 1.0) * 0.6);
set_light(2, lpos[2], Vec3(0.8, 1.0, 0.8) * 0.3);
- glUseProgram(sdr);
scn->draw();
- glUseProgram(0);
if(show_walk_mesh && scn->walk_mesh) {
glPushAttrib(GL_ENABLE_BIT);
app_quit();
break;
- case 'f':
- app_toggle_fullscreen();
+ case '\n':
+ case '\r':
+ if(mod & MOD_ALT) {
+ app_toggle_fullscreen();
+ }
break;
case '`':
}
break;
+ case 'f':
+ {
+ static float prev_walk_speed = -1.0;
+ if(prev_walk_speed < 0.0) {
+ noclip = true;
+ prev_walk_speed = walk_speed;
+ walk_speed = 1000.0;
+ show_message("fly mode\n");
+ } else {
+ noclip = false;
+ walk_speed = prev_walk_speed;
+ prev_walk_speed = -1.0;
+ show_message("walk mode\n");
+ }
+ }
+ break;
+
case 'p':
if(mod & MOD_CTRL) {
fb_srgb = !fb_srgb;
extern bool opt_gear_wireframe;
extern bool fb_srgb;
+extern unsigned int sdr_ltmap, sdr_ltmap_notex;
+
enum {
MOD_SHIFT = 1,
MOD_ALT = 2,
#include <stdio.h>
#include <string.h>
+#include "logger.h"
template <typename T>
DataSet<T>::DataSet(T (*create_func)(), bool (*load_func)(T, const char*), bool (*done_func)(T), void (*destr_func)(T))
int load_res = resman_get_res_result(dset->rman, id);
if(load_res != 0) {
- fprintf(stderr, "failed to load resource %d (%s)\n", id, resman_get_res_name(dset->rman, id));
+ error_log("failed to load resource %d (%s)\n", id, resman_get_res_name(dset->rman, id));
} else {
- printf("done loading resource %d (%s)\n", id, resman_get_res_name(dset->rman, id));
+ info_log("done loading resource %d (%s)\n", id, resman_get_res_name(dset->rman, id));
}
if(dset->done) {
--- /dev/null
+#include <stdio.h>
+#include <stdarg.h>
+#include "logger.h"
+#include "ui.h"
+
+#if defined(unix) || defined(__unix__) || defined(__APPLE__)
+#include <unistd.h>
+#elif defined(WIN32)
+#include <windows.h>
+#endif
+
+#define UI_MSG_TIMEOUT 4000
+
+enum { LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_FATAL, LOG_DEBUG };
+
+static int typecolor(int type);
+
+static FILE *fp = stdout;
+
+static void logmsg(int type, const char *fmt, va_list ap)
+{
+#if defined(unix) || defined(__unix__) || (defined(__APPLE__) && !defined(TARGET_IPHONE))
+ if(isatty(fileno(fp)) && type != LOG_INFO) {
+ int c = typecolor(type);
+ fprintf(fp, "\033[%dm", c);
+ vfprintf(fp, fmt, ap);
+ fprintf(fp, "\033[0m");
+ } else
+#endif
+ {
+ vfprintf(fp, fmt, ap);
+ }
+ if(type == LOG_ERROR || type == LOG_FATAL || type == LOG_DEBUG) {
+ fflush(fp);
+ }
+
+#ifdef WIN32
+ if(type == LOG_FATAL) {
+ static char msgbuf[1024];
+ vsnprintf(msgbuf, sizeof msgbuf - 1, fmt, ap);
+ msgbuf[sizeof msgbuf - 1] = 0;
+ MessageBox(0, msgbuf, "Fatal error", MB_OK | MB_ICONSTOP);
+ }
+#endif
+}
+
+extern "C" void info_log(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ logmsg(LOG_INFO, fmt, ap);
+ va_end(ap);
+}
+
+extern "C" void warning_log(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ logmsg(LOG_WARNING, fmt, ap);
+ va_end(ap);
+
+ va_start(ap, fmt);
+ show_messagev(UI_MSG_TIMEOUT, Vec3(1.0, 0.8, 0.1), fmt, ap);
+ va_end(ap);
+}
+
+extern "C" void error_log(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ logmsg(LOG_ERROR, fmt, ap);
+ va_end(ap);
+
+ va_start(ap, fmt);
+ show_messagev(UI_MSG_TIMEOUT, Vec3(1.0, 0.1, 0.1), fmt, ap);
+ va_end(ap);
+}
+
+extern "C" void fatal_log(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ logmsg(LOG_FATAL, fmt, ap);
+ va_end(ap);
+}
+
+extern "C" void debug_log(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ logmsg(LOG_DEBUG, fmt, ap);
+ va_end(ap);
+}
+
+enum {
+ BLACK = 0,
+ RED,
+ GREEN,
+ YELLOW,
+ BLUE,
+ MAGENTA,
+ CYAN,
+ WHITE
+};
+
+#define ANSI_FGCOLOR(x) (30 + (x))
+#define ANSI_BGCOLOR(x) (40 + (x))
+
+static int typecolor(int type)
+{
+ switch(type) {
+ case LOG_ERROR:
+ return ANSI_FGCOLOR(RED);
+ case LOG_FATAL:
+ return ANSI_FGCOLOR(RED); // TODO differentiate from LOG_ERROR
+ case LOG_WARNING:
+ return ANSI_FGCOLOR(YELLOW);
+ case LOG_DEBUG:
+ return ANSI_FGCOLOR(MAGENTA);
+ default:
+ break;
+ }
+ return 37;
+}
--- /dev/null
+#ifndef LOGGER_H_
+#define LOGGER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void info_log(const char *fmt, ...);
+void warning_log(const char *fmt, ...);
+void error_log(const char *fmt, ...);
+void fatal_log(const char *fmt, ...);
+void debug_log(const char *fmt, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LOGGER_H_
#include <string.h>
#include "opengl.h"
#include "material.h"
+#include "sdr.h"
+#include "app.h"
Material::Material()
: diffuse(1.0f, 1.0f, 1.0f)
for(int i=0; i<ntex; i++) {
bind_texture(textures[i], i);
}
+
+ if(stdtex[MTL_TEX_LIGHTMAP]) {
+ bind_program(stdtex[MTL_TEX_DIFFUSE] ? sdr_ltmap : sdr_ltmap_notex);
+ }
}
void Material::add_texture(Texture *tex, int type)
#include <assert.h>
#include "opengl.h"
#include "mesh.h"
+#include "logger.h"
//#include "xform_node.h"
#define USE_OLDGL
float *Mesh::set_attrib_data(int attrib, int nelem, unsigned int num, const float *data)
{
if(attrib < 0 || attrib >= NUM_MESH_ATTR) {
- fprintf(stderr, "%s: invalid attrib: %d\n", __FUNCTION__, attrib);
+ error_log("%s: invalid attrib: %d\n", __FUNCTION__, attrib);
return 0;
}
if(nverts && num != nverts) {
- fprintf(stderr, "%s: attribute count missmatch (%d instead of %d)\n", __FUNCTION__, num, nverts);
+ error_log("%s: attribute count missmatch (%d instead of %d)\n", __FUNCTION__, num, nverts);
return 0;
}
nverts = num;
float *Mesh::get_attrib_data(int attrib)
{
if(attrib < 0 || attrib >= NUM_MESH_ATTR) {
- fprintf(stderr, "%s: invalid attrib: %d\n", __FUNCTION__, attrib);
+ error_log("%s: invalid attrib: %d\n", __FUNCTION__, attrib);
return 0;
}
const float *Mesh::get_attrib_data(int attrib) const
{
if(attrib < 0 || attrib >= NUM_MESH_ATTR) {
- fprintf(stderr, "%s: invalid attrib: %d\n", __FUNCTION__, attrib);
+ error_log("%s: invalid attrib: %d\n", __FUNCTION__, attrib);
return 0;
}
if(!vattr[attrib].data_valid) {
#if GL_ES_VERSION_2_0
- fprintf(stderr, "%s: can't read back attrib data on CrippledGL ES\n", __FUNCTION__);
+ error_log("%s: can't read back attrib data on CrippledGL ES\n", __FUNCTION__);
return 0;
#else
if(!vattr[attrib].vbo_valid) {
- fprintf(stderr, "%s: unavailable attrib: %d\n", __FUNCTION__, attrib);
+ error_log("%s: unavailable attrib: %d\n", __FUNCTION__, attrib);
return 0;
}
{
int nidx = nfaces * 3;
if(nidx && num != nidx) {
- fprintf(stderr, "%s: index count mismatch (%d instead of %d)\n", __FUNCTION__, num, nidx);
+ error_log("%s: index count mismatch (%d instead of %d)\n", __FUNCTION__, num, nidx);
return 0;
}
nfaces = num / 3;
{
if(!idata_valid) {
#if GL_ES_VERSION_2_0
- fprintf(stderr, "%s: can't read back index data in CrippledGL ES\n", __FUNCTION__);
+ error_log("%s: can't read back index data in CrippledGL ES\n", __FUNCTION__);
return 0;
#else
if(!ibo_valid) {
- fprintf(stderr, "%s: indices unavailable\n", __FUNCTION__);
+ error_log("%s: indices unavailable\n", __FUNCTION__);
return 0;
}
((Mesh*)this)->update_buffers();
if(!vattr[MESH_ATTR_VERTEX].vbo_valid) {
- fprintf(stderr, "%s: invalid vertex buffer\n", __FUNCTION__);
+ error_log("%s: invalid vertex buffer\n", __FUNCTION__);
return false;
}
if(cur_sdr && use_custom_sdr_attr) {
// rendering with shaders
if(global_sdr_loc[MESH_ATTR_VERTEX] == -1) {
- fprintf(stderr, "%s: shader attribute location for vertices unset\n", __FUNCTION__);
+ error_log("%s: shader attribute location for vertices unset\n", __FUNCTION__);
return false;
}
#include "scene.h"
#include "datamap.h"
#include "treestore.h"
+#include "logger.h"
#ifdef WIN32
#include <malloc.h>
struct ts_node *root = ts_load(fname);
if(!root || strcmp(root->name, "scene") != 0) {
ts_free_tree(root);
- fprintf(stderr, "failed to load scene metadata: %s\n", fname);
+ error_log("failed to load scene metadata: %s\n", fname);
return false;
}
bool res = proc_node(scn, root);
ts_free_tree(root);
- printf("loaded scene: %s\n", fname);
- printf("scene graph:\n");
+ info_log("loaded scene: %s\n", fname);
+ info_log("scene graph:\n");
print_scene_graph(scn->nodes, 0);
return res;
}
// datapath
struct ts_attr *adpath = attr_inscope(node, "datapath");
if(adpath && adpath->val.type == TS_STRING) {
- printf("adding data path: %s\n", adpath->val.str);
+ info_log("adding data path: %s\n", adpath->val.str);
datamap_set_path(adpath->val.str);
}
if(!n) return;
for(int i=0; i<level; i++) {
- fputs(" ", stdout);
+ info_log(" ");
}
int nobj = n->get_num_objects();
if(nobj) {
- printf("%s - %d obj\n", n->get_name(), n->get_num_objects());
+ info_log("%s - %d obj\n", n->get_name(), n->get_num_objects());
} else {
- printf("%s\n", n->get_name());
+ info_log("%s\n", n->get_name());
}
for(int i=0; i<n->get_num_children(); i++) {
#include "scene.h"
#include "objmesh.h"
#include "datamap.h"
+#include "logger.h"
static bool load_material(Scene *scn, Material *mat, const aiMaterial *aimat);
static SceneNode *load_node(Scene *scn, const aiScene *aiscn, unsigned int flags, const aiNode *ainode);
ppflags |= aiProcess_FlipUVs;
}
- printf("Loading scene file: %s\n", fname);
+ info_log("Loading scene file: %s\n", fname);
const aiScene *aiscn = aiImportFile(fname, ppflags);
if(!aiscn) {
- fprintf(stderr, "failed to load scene file: %s\n", fname);
+ error_log("failed to load scene file: %s\n", fname);
return false;
}
break;
default:
- fprintf(stderr, "unsupported primitive type: %u\n", aimesh->mPrimitiveTypes);
+ error_log("unsupported primitive type: %u\n", aimesh->mPrimitiveTypes);
break;
}
}
mesh_by_aimesh.clear();
aiReleaseImport(aiscn);
- printf("loaded scene file: %s, %d meshes\n", fname, (int)meshes.size());
+ info_log("loaded scene file: %s, %d meshes\n", fname, (int)meshes.size());
nodes->update(0);
return true;
}
} else {
mat->name = "unknown";
}
- //printf("load_material: %s\n", mat->name.c_str());
+ //info_log("load_material: %s\n", mat->name.c_str());
if(aiGetMaterialColor(aimat, AI_MATKEY_COLOR_DIFFUSE, &aicol) == 0) {
mat->diffuse = Vec3(aicol[0], aicol[1], aicol[2]);
}
int textype = assimp_textype(aitype);
- printf("loading %s texture: %s\n", assimp_textypestr(aitype), fname);
+ info_log("loading %s texture: %s\n", assimp_textypestr(aitype), fname);
Texture *tex = scn->texset->get_texture(fname, TEX_2D);
assert(tex);
#include <stdarg.h>
#include <assert.h>
#include "opengl.h"
+#include "logger.h"
#if defined(unix) || defined(__unix__)
#include <unistd.h>
}
if(success) {
- fprintf(stderr, info_str ? "done: %s\n" : "done\n", info_str);
+ info_log(info_str ? "done: %s\n" : "done\n", info_str);
} else {
- fprintf(stderr, info_str ? "failed: %s\n" : "failed\n", info_str);
+ error_log(info_str ? "failed: %s\n" : "failed\n", info_str);
glDeleteShader(sdr);
sdr = 0;
}
char *src;
if(!(fp = fopen(fname, "rb"))) {
- fprintf(stderr, "failed to open shader %s: %s\n", fname, strerror(errno));
+ error_log("failed to open shader %s: %s\n", fname, strerror(errno));
return 0;
}
src[filesize] = 0;
fclose(fp);
- fprintf(stderr, "compiling %s shader: %s... ", sdrtypestr(sdr_type), fname);
+ info_log("compiling %s shader: %s... ", sdrtypestr(sdr_type), fname);
sdr = create_shader(src, sdr_type);
free(src);
assert(glGetError() == GL_NO_ERROR);
glAttachShader(prog, sdr);
if((err = glGetError()) != GL_NO_ERROR) {
- fprintf(stderr, "failed to attach shader %u to program %u (err: 0x%x)\n", sdr, prog, err);
+ error_log("failed to attach shader %u to program %u (err: 0x%x)\n", sdr, prog, err);
abort();
}
}
}
if(linked) {
- fprintf(stderr, info_str ? "linking done: %s\n" : "linking done\n", info_str);
+ info_log(info_str ? "linking done: %s\n" : "linking done\n", info_str);
} else {
- fprintf(stderr, info_str ? "linking failed: %s\n" : "linking failed\n", info_str);
+ error_log(info_str ? "linking failed: %s\n" : "linking failed\n", info_str);
retval = -1;
}
len = strlen(s);
newlen = str->len + len;
if(!(newstr = malloc(newlen + 2))) { /* leave space for a possible newline */
- fprintf(stderr, "shader composition: failed to append string of size %d\n", len);
+ error_log("shader composition: failed to append string of size %d\n", len);
abort();
}
#include "image.h"
#include "opengl.h"
#include "imago2.h"
+#include "logger.h"
static int glifmt_from_ifmt(unsigned int ifmt);
static int glfmt_from_ifmt(unsigned int ifmt);
void Texture::create(int xsz, int ysz, TextureType textype, unsigned int ifmt)
{
if(textype == TEX_CUBE && xsz != ysz) {
- fprintf(stderr, "trying to create cubemap with different width and height (%dx%d)\n", xsz, ysz);
+ error_log("trying to create cubemap with different width and height (%dx%d)\n", xsz, ysz);
return;
}
{
Image img;
if(!img.load(fname)) {
- fprintf(stderr, "failed to load 2D texture: %s\n", fname);
+ error_log("failed to load 2D texture: %s\n", fname);
return false;
}
set_image(img);
- printf("loaded 2D texture: %s\n", fname);
+ info_log("loaded 2D texture: %s\n", fname);
return true;
}
struct Message {
long start_time, show_until;
char *str;
+ Vec3 color;
Message *next;
};
static Message *msglist;
void show_message(const char *fmt, ...)
{
va_list ap;
+ va_start(ap, fmt);
+ show_messagev(timeout, Vec3(1, 1, 1), fmt, ap);
+ va_end(ap);
+}
+
+void show_message(long timeout, const Vec3 &color, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ show_messagev(timeout, color, fmt, ap);
+ va_end(ap);
+}
+
+void show_messagev(long timeout, const Vec3 &color, const char *fmt, va_list ap)
+{
char buf[512];
init();
- va_start(ap, fmt);
vsnprintf(buf, sizeof buf, fmt, ap);
- va_end(ap);
Message *msg = new Message;
int len = strlen(buf);
memcpy(msg->str, buf, len + 1);
msg->start_time = time_msec;
msg->show_until = time_msec + timeout;
+ msg->color = color;
Message dummy;
dummy.next = msglist;
long dur = msg->show_until - msg->start_time;
float alpha = smoothstep(0, trans_time, t) *
(1.0 - smoothstep(dur - trans_time, dur, t));
- glColor4f(1.0, 0.5, 0.1, alpha);
+ glColor4f(msg->color.x, msg->color.y, msg->color.z, alpha);
glTranslatef(0, -dtx_line_height(), 0);
dtx_string(msg->str);
msg = msg->next;
#ifndef UI_H_
#define UI_H_
+#include <stdarg.h>
+#include <gmath/gmath.h>
+
void set_message_timeout(long timeout);
void show_message(const char *fmt, ...);
+void show_message(long timeout, const Vec3 &color, const char *fmt, ...);
+void show_messagev(long timeout, const Vec3 &color, const char *fmt, va_list ap);
void draw_ui();