--- /dev/null
+*.o
+*.d
+*.swp
+*.a
+test
+compile_commands.json
+.cache/
--- /dev/null
+src = $(wildcard src/*.c) $(wildcard src/gl/*.c) $(wildcard src/wsys/*.c) \
+ $(wildcard src/unix/*.c)
+obj = $(src:.c=.o)
+dep = $(src:.c=.d)
+
+name = nexus3d
+liba = lib$(name).a
+
+warn = -pedantic -Wall
+dbg = -g
+#opt = -O3 -ffast-math
+inc = -Isrc
+
+CFLAGS = $(warn) $(dbg) $(opt) $(inc) $(def) -MMD
+LDFLAGS = -lGL -lglut -lm
+
+test: test.o $(liba)
+ $(CC) -o $@ test.o $(obj) $(liba) $(LDFLAGS)
+
+$(liba): $(obj)
+ $(AR) rcs $@ $(obj)
+
+-include $(dep)
+
+.PHONY: clean
+clean:
+ rm -f $(obj) $(liba) test test.o
+
+.PHONY: cleandep
+cleandep:
+ rm -f $(dep)
--- /dev/null
+#ifndef NEXUS3D_CGMATH2_H_
+#define NEXUS3D_CGMATH2_H_
+
+#include <math.h>
+#include <string.h>
+
+#define CGM_PI 3.141592653589793
+
+typedef struct {
+ float x, y;
+} cgm_vec2;
+
+typedef struct {
+ float x, y, z;
+} cgm_vec3;
+
+typedef struct {
+ float x, y, z, w;
+} cgm_vec4, cgm_quat;
+
+typedef struct {
+ cgm_vec3 origin, dir;
+} cgm_ray;
+
+typedef enum cgm_euler_mode {
+ CGM_EULER_XYZ,
+ CGM_EULER_XZY,
+ CGM_EULER_YXZ,
+ CGM_EULER_YZX,
+ CGM_EULER_ZXY,
+ CGM_EULER_ZYX,
+ CGM_EULER_ZXZ,
+ CGM_EULER_ZYZ,
+ CGM_EULER_YXY,
+ CGM_EULER_YZY,
+ CGM_EULER_XYX,
+ CGM_EULER_XZX
+} cgm_euler_mode;
+
+#ifdef __cplusplus
+#define CGM_INLINE inline
+
+extern "C" {
+#else
+
+#if (__STDC_VERSION__ >= 199901) || defined(__GNUC__)
+#define CGM_INLINE inline
+#else
+#define CGM_INLINE __inline
+#endif
+
+#endif
+
+/* --- operations on cgm_vec3 --- */
+static CGM_INLINE cgm_vec3 cgm_vcons(float x, float y, float z);
+
+static CGM_INLINE cgm_vec3 cgm_vadd(cgm_vec3 a, cgm_vec3 b);
+static CGM_INLINE cgm_vec3 cgm_vsub(cgm_vec3 a, cgm_vec3 b);
+static CGM_INLINE cgm_vec3 cgm_vmul(cgm_vec3 a, cgm_vec3 b);
+static CGM_INLINE cgm_vec3 cgm_vscale(cgm_vec3 v, float s);
+
+static CGM_INLINE cgm_vec3 cgm_vmul_m4v3(const float *m, cgm_vec3 v); /* m4x4 * v */
+static CGM_INLINE cgm_vec3 cgm_vmul_v3m4(cgm_vec3 v, const float *m); /* v * m4x4 */
+static CGM_INLINE cgm_vec3 cgm_vmul_m3v3(const float *m, cgm_vec3 v); /* m3x3 * v (m still 16 floats) */
+static CGM_INLINE cgm_vec3 cgm_vmul_v3m3(cgm_vec3 v, const float *m); /* v * m3x3 (m still 16 floats) */
+
+static CGM_INLINE float cgm_vdot(cgm_vec3 a, cgm_vec3 b);
+static CGM_INLINE cgm_vec3 cgm_vcross(cgm_vec3 a, cgm_vec3 b);
+static CGM_INLINE float cgm_vlength(cgm_vec3 v);
+static CGM_INLINE float cgm_vlength_sq(cgm_vec3 v);
+static CGM_INLINE float cgm_vdist(cgm_vec3 a, cgm_vec3 b);
+static CGM_INLINE float cgm_vdist_sq(cgm_vec3 a, cgm_vec3 b);
+
+static CGM_INLINE cgm_vec3 cgm_normalize(cgm_vec3 v);
+
+static CGM_INLINE cgm_vec3 cgm_vreflect(cgm_vec3 v, cgm_vec3 n);
+static CGM_INLINE cgm_vec3 cgm_vrefract(cgm_vec3 v, cgm_vec3 n, float ior);
+
+static CGM_INLINE cgm_vec3 cgm_vrotate_quat(cgm_vec3 v, cgm_quat q);
+static CGM_INLINE cgm_vec3 cgm_vrotate_axis(cgm_vec3 v, int axis, float angle);
+static CGM_INLINE cgm_vec3 cgm_vrotate(cgm_vec3 v, float angle, float x, float y, float z);
+static CGM_INLINE cgm_vec3 cgm_vrotate_euler(cgm_vec3 v, float a, float b, float c, enum cgm_euler_mode mode);
+
+static CGM_INLINE cgm_vec3 cgm_vlerp(cgm_vec3 a, cgm_vec3 b, float t);
+static CGM_INLINE cgm_vec3 cgm_vblend(cgm_vec3 a, float fa, cgm_vec3 b, float fb);
+
+#define cgm_velem(v, idx) ((&(v).x)[idx])
+
+/* --- operations on matrices --- */
+static CGM_INLINE void cgm_mcopy(float *dest, const float *src);
+static CGM_INLINE void cgm_mzero(float *m);
+static CGM_INLINE void cgm_midentity(float *m);
+
+static CGM_INLINE void cgm_mmul(float *a, const float *b);
+static CGM_INLINE void cgm_mpremul(float *a, const float *b);
+
+static CGM_INLINE void cgm_msubmatrix(float *m, int row, int col);
+static CGM_INLINE void cgm_mupper3(float *m);
+static CGM_INLINE float cgm_msubdet(const float *m, int row, int col);
+static CGM_INLINE float cgm_mcofactor(const float *m, int row, int col);
+static CGM_INLINE float cgm_mdet(const float *m);
+static CGM_INLINE void cgm_mtranspose(float *m);
+static CGM_INLINE void cgm_mcofmatrix(float *m);
+static CGM_INLINE int cgm_minverse(float *m); /* returns 0 on success, -1 for singular */
+
+static CGM_INLINE void cgm_mtranslation(float *m, float x, float y, float z);
+static CGM_INLINE void cgm_mscaling(float *m, float sx, float sy, float sz);
+static CGM_INLINE void cgm_mrotation_x(float *m, float angle);
+static CGM_INLINE void cgm_mrotation_y(float *m, float angle);
+static CGM_INLINE void cgm_mrotation_z(float *m, float angle);
+static CGM_INLINE void cgm_mrotation_axis(float *m, int idx, float angle);
+static CGM_INLINE void cgm_mrotation(float *m, float angle, float x, float y, float z);
+static CGM_INLINE void cgm_mrotation_euler(float *m, float a, float b, float c, int mode);
+static CGM_INLINE void cgm_mrotation_quat(float *m, cgm_quat q);
+
+static CGM_INLINE void cgm_mtranslate(float *m, float x, float y, float z);
+static CGM_INLINE void cgm_mscale(float *m, float sx, float sy, float sz);
+static CGM_INLINE void cgm_mrotate_x(float *m, float angle);
+static CGM_INLINE void cgm_mrotate_y(float *m, float angle);
+static CGM_INLINE void cgm_mrotate_z(float *m, float angle);
+static CGM_INLINE void cgm_mrotate_axis(float *m, int idx, float angle);
+static CGM_INLINE void cgm_mrotate(float *m, float angle, float x, float y, float z);
+static CGM_INLINE void cgm_mrotate_euler(float *m, float a, float b, float c, int mode);
+static CGM_INLINE void cgm_mrotate_quat(float *m, cgm_quat q);
+
+static CGM_INLINE void cgm_mpretranslate(float *m, float x, float y, float z);
+static CGM_INLINE void cgm_mprescale(float *m, float sx, float sy, float sz);
+static CGM_INLINE void cgm_mprerotate_x(float *m, float angle);
+static CGM_INLINE void cgm_mprerotate_y(float *m, float angle);
+static CGM_INLINE void cgm_mprerotate_z(float *m, float angle);
+static CGM_INLINE void cgm_mprerotate_axis(float *m, int idx, float angle);
+static CGM_INLINE void cgm_mprerotate(float *m, float angle, float x, float y, float z);
+static CGM_INLINE void cgm_mprerotate_euler(float *m, float a, float b, float c, int mode);
+static CGM_INLINE void cgm_mprerotate_quat(float *m, cgm_quat q);
+
+static CGM_INLINE cgm_vec3 cgm_mget_translation(const float *m);
+static CGM_INLINE cgm_quat cgm_mget_rotation(const float *m);
+static CGM_INLINE cgm_vec3 cgm_mget_scaling(const float *m);
+static CGM_INLINE cgm_vec4 cgm_mget_frustum_plane(const float *m, int p);
+
+static CGM_INLINE cgm_vec4 cgm_normalize_plane(cgm_vec4 p);
+
+static CGM_INLINE void cgm_mlookat(float *m, cgm_vec3 pos, cgm_vec3 targ, cgm_vec3 up);
+static CGM_INLINE void cgm_minv_lookat(float *m, cgm_vec3 pos, cgm_vec3 targ, cgm_vec3 up);
+static CGM_INLINE void cgm_mortho(float *m, float left, float right, float bot, float top,
+ float znear, float zfar);
+static CGM_INLINE void cgm_mfrustum(float *m, float left, float right, float bot, float top,
+ float znear, float zfar);
+static CGM_INLINE void cgm_mperspective(float *m, float vfov, float aspect, float znear, float zfar);
+
+static CGM_INLINE void cgm_mmirror(float *m, float a, float b, float c, float d);
+
+/* --- miscellaneous utility functions --- */
+static CGM_INLINE float cgm_deg_to_rad(float deg);
+static CGM_INLINE float cgm_rad_to_deg(float rad);
+
+static CGM_INLINE float cgm_smoothstep(float a, float b, float x);
+static CGM_INLINE float cgm_lerp(float a, float b, float t);
+static CGM_INLINE float cgm_logerp(float a, float b, float t);
+static CGM_INLINE float cgm_bezier(float a, float b, float c, float d, float t);
+static CGM_INLINE float cgm_bspline(float a, float b, float c, float d, float t);
+static CGM_INLINE float cgm_spline(float a, float b, float c, float d, float t);
+
+static CGM_INLINE cgm_vec3 cgm_discrand(float rad);
+static CGM_INLINE cgm_vec3 cgm_sphrand(float rad);
+
+static CGM_INLINE cgm_vec3 cgm_unproject(cgm_vec3 norm_scrpos, const float *inv_viewproj);
+static CGM_INLINE void cgm_glu_unproject(float winx, float winy, float winz,
+ const float *view, const float *proj, const int *vp,
+ float *objx, float *objy, float *objz);
+
+static CGM_INLINE cgm_ray cgm_pick_ray(float nx, float ny, const float *viewmat,
+ const float *projmat);
+
+static CGM_INLINE cgm_vec3 cgm_raypos(cgm_ray ray, float t);
+
+/* calculate barycentric coordinates of point pt in triangle (a, b, c) */
+static CGM_INLINE cgm_vec3 cgm_bary(cgm_vec3 a, cgm_vec3 b, cgm_vec3 c, cgm_vec3 pt);
+
+/* convert between unit vectors and spherical coordinates */
+static CGM_INLINE cgm_vec3 cgm_uvec_to_sph(cgm_vec3 v);
+static CGM_INLINE cgm_vec3 cgm_sph_to_uvec(float theta, float phi);
+
+#include "cgmvec3.inl"
+/*#include "cgmvec4.inl"
+#include "cgmquat.inl"*/
+#include "cgmmat.inl"
+/*#include "cgmray.inl"*/
+#include "cgmmisc.inl"
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NEXUS3D_CGMATH2_H_ */
--- /dev/null
+static CGM_INLINE cgm_vec3 cgm_vcons(float x, float y, float z)
+{
+ cgm_vec3 v;
+ v.x = x;
+ v.y = y;
+ v.z = z;
+ return v;
+}
+
+static CGM_INLINE cgm_vec3 cgm_vadd(cgm_vec3 a, cgm_vec3 b)
+{
+ return cgm_vcons(a.x + b.x, a.y + b.y, a.z + b.z);
+}
+
+static CGM_INLINE cgm_vec3 cgm_vsub(cgm_vec3 a, cgm_vec3 b)
+{
+ return cgm_vcons(a.x - b.x, a.y - b.y, a.z - b.z);
+}
+
+static CGM_INLINE cgm_vec3 cgm_vmul(cgm_vec3 a, cgm_vec3 b)
+{
+ return cgm_vcons(a.x * b.x, a.y * b.y, a.z * b.z);
+}
+
+static CGM_INLINE cgm_vec3 cgm_vscale(cgm_vec3 v, float s)
+{
+ return cgm_vcons(a.x * s, a.y * s, a.z * s);
+}
+
+
+static CGM_INLINE cgm_vec3 cgm_vmul_m4v3(const float *m, cgm_vec3 v)
+{
+ cgm_vec3 res;
+ res.x = v.x * m[0] + v.y * m[4] + v.z * m[8] + m[12];
+ res.y = v.x * m[1] + v.y * m[5] + v.z * m[9] + m[13];
+ res.z = v.x * m[2] + v.y * m[6] + v.z * m[10] + m[14];
+ return res;
+}
+
+static CGM_INLINE cgm_vec3 cgm_vmul_v3m4(cgm_vec3 v, const float *m)
+{
+ cgm_vec3 res;
+ res.x = v.x * m[0] + v.y * m[1] + v.z * m[2] + m[3];
+ res.y = v.x * m[4] + v.y * m[5] + v.z * m[6] + m[7];
+ res.z = v.x * m[8] + v.y * m[9] + v.z * m[10] + m[11];
+ return res;
+}
+
+static CGM_INLINE cgm_vec3 cgm_vmul_m3v3(const float *m, cgm_vec3 v)
+{
+ cgm_vec3 res;
+ res.x = v.x * m[0] + v.y * m[4] + v.z * m[8];
+ res.y = v.x * m[1] + v.y * m[5] + v.z * m[9];
+ res.z = v.x * m[2] + v.y * m[6] + v.z * m[10];
+ return res;
+}
+
+static CGM_INLINE cgm_vec3 cgm_vmul_v3m3(cgm_vec3 v, const float *m)
+{
+ cgm_vec3 res;
+ res.x = v.x * m[0] + v.y * m[1] + v.z * m[2];
+ res.y = v.x * m[4] + v.y * m[5] + v.z * m[6];
+ res.z = v.x * m[8] + v.y * m[9] + v.z * m[10];
+ return res;
+}
+
+
+static CGM_INLINE float cgm_vdot(cgm_vec3 a, cgm_vec3 b)
+{
+ return a.x * b.x + a.y * b.y + a.z * b.z;
+}
+
+static CGM_INLINE cgm_vec3 cgm_vcross(cgm_vec3 a, cgm_vec3 b)
+{
+ cgm_vec3 res;
+ res.x = a.y * b.z - a.z * b.y;
+ res.y = a.z * b.x - a.x * b.z;
+ res.z = a.x * b.y - a.y * b.x;
+ return res;
+}
+
+static CGM_INLINE float cgm_vlength(cgm_vec3 v)
+{
+ return sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
+}
+
+static CGM_INLINE float cgm_vlength_sq(cgm_vec3 v)
+{
+ return v.x * v.x + v.y * v.y + v.z * v.z;
+}
+
+static CGM_INLINE float cgm_vdist(cgm_vec3 a, cgm_vec3 b)
+{
+ float dx = a.x - b.x;
+ float dy = a.y - b.y;
+ float dz = a.z - b.z;
+ return sqrt(dx * dx + dy * dy + dz * dz);
+}
+
+static CGM_INLINE float cgm_vdist_sq(cgm_vec3 a, cgm_vec3 b)
+{
+ float dx = a.x - b.x;
+ float dy = a.y - b.y;
+ float dz = a.z - b.z;
+ return dx * dx + dy * dy + dz * dz;
+}
+
+
+static CGM_INLINE cgm_vec3 cgm_normalize(cgm_vec3 v)
+{
+ cgm_vec3 res;
+ float len = cgm_vlength(v);
+ if(len != 0.0f) {
+ float s = 1.0f / len;
+ res.x = v.x * s;
+ res.y = v.y * s;
+ res.z = v.z * s;
+ } else {
+ res = v;
+ }
+ return res;
+}
+
+
+static CGM_INLINE cgm_vec3 cgm_vreflect(cgm_vec3 v, cgm_vec3 n)
+{
+ float ndotv2 = cgm_vdot(v, n) * 2.0f;
+ return cgm_vcons(v.x - n.x * ndotv2, v.y - n.y * ndotv2, v.z - n.z * ndotv2);
+}
+
+static CGM_INLINE cgm_vec3 cgm_vrefract(cgm_vec3 v, cgm_vec3 n, float ior)
+{
+ float ndotv = cgm_vdot(v, n);
+ float k = 1.0f - ior * ior * (1.0f - ndotv * ndotv);
+ if(k < 0.0f) {
+ return cgm_vreflect(v, n); /* TIR */
+ } else {
+ cgm_vec3 res;
+ float sqrt_k = sqrt(k);
+ res.x = ior * v.x - (ior * ndotv + sqrt_k) * n.x;
+ res.y = ior * v.y - (ior * ndotv + sqrt_k) * n.y;
+ res.z = ior * v.z - (ior * ndotv + sqrt_k) * n.z;
+ return res;
+ }
+}
+
+
+static CGM_INLINE cgm_vec3 cgm_vrotate_quat(cgm_vec3 v, cgm_quat q)
+{
+ cgm_quat vq, inv_q, tmp_q;
+
+ vq = cgm_qcons(v->x, v->y, v->z, 0.0f);
+ inv_q = cgm_qinvert(q);
+ tmp_q = cgm_qmul(q, vq);
+ tmp_q = cgm_qmul(tmp_q, inv_q);
+ return cgm_vcons(tmp_q.x, tmp_q.y, tmp_q.z);
+}
+
+static CGM_INLINE cgm_vec3 cgm_vrotate_axis(cgm_vec3 v, int axis, float angle)
+{
+ float m[16];
+ cgm_mrotation_axis(m, axis, angle);
+ cgm_vmul_m3v3(v, m);
+}
+
+static CGM_INLINE cgm_vec3 cgm_vrotate(cgm_vec3 v, float angle, float x, float y, float z)
+{
+ float m[16];
+ cgm_mrotation(m, angle, x, y, z);
+ cgm_vmul_m3v3(v, m);
+}
+
+static CGM_INLINE cgm_vec3 cgm_vrotate_euler(cgm_vec3 v, float a, float b, float c, enum cgm_euler_mode mode)
+{
+ float m[16];
+ cgm_mrotation_euler(m, a, b, c, mode);
+ cgm_vmul_m3v3(v, m);
+}
+
+
+static CGM_INLINE cgm_vec3 cgm_vlerp(cgm_vec3 a, cgm_vec3 b, float t)
+{
+ cgm_vec3 res;
+ res.x = a.x + (b.x - a.x) * t;
+ res.y = a.y + (b.y - a.y) * t;
+ res.z = a.z + (b.z - a.z) * t;
+ return res;
+}
+
+static CGM_INLINE cgm_vec3 cgm_vblend(cgm_vec3 a, float fa, cgm_vec3 b, float fb)
+{
+ cgm_vec3 res;
+ res.x = a.x * fa + b.x * fb;
+ res.y = a.y * fa + b.y * fb;
+ res.z = a.z * fa + b.z * fb;
+ return res;
+}
--- /dev/null
+#ifndef NEXUS3D_GFX_H_
+#define NEXUS3D_GFX_H_
+
+void nex_clear(void);
+void nex_viewport(int x, int y, int w, int h);
+
+#endif /* NEXUS3D_GFX_H_ */
--- /dev/null
+#include "opengl.h"
+#include "nexus3d_impl.h"
+
+void nex_clear(void)
+{
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+}
+
+void nex_viewport(int x, int y, int w, int h)
+{
+ glViewport(x, y, w, h);
+}
--- /dev/null
+#include "opengl.h"
+
+int init_gl(void)
+{
+ return 0;
+}
--- /dev/null
+#ifndef NEXUS3D_OPENGL_H_
+#define NEXUS3D_OPENGL_H_
+
+#include <GL/gl.h>
+
+int init_gl(void);
+
+#endif /* NEXUS3D_OPENGL_H_ */
--- /dev/null
+#include "nexus3d_impl.h"
+
+union nex_gfxapi nex_apicfg = {{NEX_OPENGL, 3, 3, 0}};
+enum nex_gfxflags nex_gfxflags;
+
+
+void nex_gfxapi_opengl(int vmaj, int vmin, enum nex_apiflags_gl flags)
+{
+ nex_apicfg.api = NEX_OPENGL;
+ nex_apicfg.gl.ver_major = vmaj;
+ nex_apicfg.gl.ver_minor = vmin;
+ nex_apicfg.gl.flags = flags;
+}
--- /dev/null
+#ifndef NEXUS3D_H_
+#define NEXUS3D_H_
+
+#include "gfx.h"
+#include "wsys/wsys.h"
+/*#include "cgmath2/cgmath2.h"*/
+
+enum nex_apiflags_gl {
+ NEX_OPENGL_COMPAT = 1,
+ NEX_OPENGL_DEBUG = 2
+};
+
+void nex_gfxapi_opengl(int vmaj, int vmin, enum nex_apiflags_gl flags);
+
+#endif /* NEXUS3D_H_ */
--- /dev/null
+#ifndef NEXUS3D_IMPL_H_
+#define NEXUS3D_IMPL_H_
+
+#include "nexus3d.h"
+
+struct nex_callbacks {
+ nex_cbdisplay_type display;
+ nex_cbreshape_type reshape;
+ nex_cbkey_type key;
+ nex_cbmousebn_type mousebn;
+ nex_cbmousemove_type mousemove;
+
+ void *display_cls, *reshape_cls, *key_cls, *mousebn_cls, *mousemove_cls;
+};
+
+enum nex_gfxapi_type { NEX_OPENGL };
+
+struct nex_gfxapi_opengl {
+ enum nex_gfxapi_type api;
+ int ver_major, ver_minor;
+ enum nex_apiflags_gl flags;
+};
+
+union nex_gfxapi {
+ struct nex_gfxapi_opengl gl;
+ enum nex_gfxapi_type api;
+};
+
+extern struct nex_callbacks nex_cb; /* defined in wsys/wsys.c */
+extern union nex_gfxapi nex_apicfg; /* defined in nexus3d.c */
+extern enum nex_gfxflags nex_gfxflags; /* defined in nexus3d.c */
+
+#endif /* NEXUS3D_IMPL_H_ */
--- /dev/null
+#include "nexus3d_impl.h"
+
+struct nex_callbacks nex_cb;
+
+void nex_cbdisplay(nex_cbdisplay_type func, void *cls)
+{
+ nex_cb.display = func;
+ nex_cb.display_cls = cls;
+}
+
+void nex_cbreshape(nex_cbreshape_type func, void *cls)
+{
+ nex_cb.reshape = func;
+ nex_cb.reshape_cls = cls;
+}
+
+void nex_cbkey(nex_cbkey_type func, void *cls)
+{
+ nex_cb.key = func;
+ nex_cb.key_cls = cls;
+}
+
+void nex_cbmousebn(nex_cbmousebn_type func, void *cls)
+{
+ nex_cb.mousebn = func;
+ nex_cb.mousebn_cls = cls;
+}
+
+void nex_cbmousemove(nex_cbmousemove_type func, void *cls)
+{
+ nex_cb.mousemove = func;
+ nex_cb.mousemove_cls = cls;
+}
+
--- /dev/null
+#ifndef NEXUS3D_WSYS_H_
+#define NEXUS3D_WSYS_H_
+
+enum nex_key {
+ NEX_KEY_ESC = 27,
+ NEX_KEY_DEL = 127,
+ NEX_KEY_HOME = 0xff50,
+ NEX_KEY_LEFT = 0xff51,
+ NEX_KEY_UP = 0xff52,
+ NEX_KEY_RIGHT = 0xff53,
+ NEX_KEY_DOWN = 0xff54,
+ NEX_KEY_PGUP = 0xff55,
+ NEX_KEY_PGDOWN = 0xff56,
+ NEX_KEY_END = 0xff57,
+ NEX_KEY_INS = 0xff63,
+ NEX_KEY_F1 = 0xffbe,
+ NEX_KEY_F2 = 0xffbf,
+ NEX_KEY_F3 = 0xffc0,
+ NEX_KEY_F4 = 0xffc1,
+ NEX_KEY_F5 = 0xffc2,
+ NEX_KEY_F6 = 0xffc3,
+ NEX_KEY_F7 = 0xffc4,
+ NEX_KEY_F8 = 0xffc5,
+ NEX_KEY_F9 = 0xffc6,
+ NEX_KEY_F10 = 0xffc7,
+ NEX_KEY_F11 = 0xffc8,
+ NEX_KEY_F12 = 0xffc9
+};
+
+enum nex_gfxflags {
+ NEX_GFX_STENCIL = 1,
+ NEX_GFX_FSAA = 2,
+ NEX_GFX_STEREO = 4,
+ NEX_GFX_DEBUG = 0x100
+};
+
+/* callback function types */
+typedef void (*nex_cbdisplay_type)(void *cls);
+typedef void (*nex_cbreshape_type)(int x, int y, void *cls);
+typedef void (*nex_cbkey_type)(int key, int pressed, void *cls);
+typedef void (*nex_cbmousebn_type)(int bn, int pressed, int x, int y, void *cls);
+typedef void (*nex_cbmousemove_type)(int x, int y, void *cls);
+
+int nex_initgfx(int xsz, int ysz, enum nex_gfxflags flags);
+void nex_closegfx(void);
+
+int nex_evloop_wait(void);
+int nex_evloop_poll(void);
+
+void nex_swap_buffers(void);
+void nex_redisplay(void);
+
+/* callback registration */
+void nex_cbdisplay(nex_cbdisplay_type func, void *cls);
+void nex_cbreshape(nex_cbreshape_type func, void *cls);
+void nex_cbkey(nex_cbkey_type func, void *cls);
+void nex_cbmousebn(nex_cbmousebn_type func, void *cls);
+void nex_cbmousemove(nex_cbmousemove_type func, void *cls);
+
+#endif /* NEXUS3D_WSYS_H_ */
--- /dev/null
+#include <GL/freeglut.h>
+#include "nexus3d_impl.h"
+#include "gl/opengl.h"
+
+static void winclose(void);
+static void display(void);
+static void idle(void);
+static void reshape(int x, int y);
+static void keydown(unsigned char key, int x, int y);
+static void keyup(unsigned char key, int x, int y);
+static void skeydown(int key, int x, int y);
+static void skeyup(int key, int x, int y);
+static void mouse(int bn, int st, int x, int y);
+static void motion(int x, int y);
+
+static int quit, have_idle;
+
+
+int nex_initgfx(int xsz, int ysz, enum nex_gfxflags flags)
+{
+ static char *fake_argv[] = {"nexus3d", 0};
+ static int fake_argc = 1;
+ unsigned int glut_flags;
+
+ if(flags & NEX_GFX_DEBUG) {
+ nex_apicfg.gl.flags |= NEX_OPENGL_DEBUG;
+ }
+
+ glut_flags = GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_SRGB;
+ if(flags & NEX_GFX_STENCIL) {
+ glut_flags |= GLUT_STENCIL;
+ }
+ if(flags & NEX_GFX_FSAA) {
+ glut_flags |= GLUT_MULTISAMPLE;
+ }
+ if(flags & NEX_GFX_STEREO) {
+ glut_flags |= GLUT_STEREO;
+ }
+
+ glutInit(&fake_argc, fake_argv);
+ glutInitWindowSize(xsz, ysz);
+ glutInitDisplayMode(glut_flags);
+
+ if(nex_apicfg.gl.flags & NEX_OPENGL_DEBUG) {
+ glutInitContextFlags(GLUT_DEBUG);
+ }
+ if(nex_apicfg.gl.ver_major > 1) {
+ glutInitContextVersion(3, 3);
+ if(nex_apicfg.gl.flags & NEX_OPENGL_COMPAT) {
+ glutInitContextProfile(GLUT_COMPATIBILITY_PROFILE);
+ } else {
+ glutInitContextProfile(GLUT_CORE_PROFILE);
+ }
+ }
+
+ glutCreateWindow("nexus3d engine");
+
+ glutCloseFunc(winclose);
+ glutDisplayFunc(display);
+ glutReshapeFunc(reshape);
+ glutKeyboardFunc(keydown);
+ glutKeyboardUpFunc(keyup);
+ glutSpecialFunc(skeydown);
+ glutSpecialUpFunc(skeyup);
+ glutMouseFunc(mouse);
+ glutMotionFunc(motion);
+
+ nex_gfxflags = flags;
+ quit = 0;
+ have_idle = 0;
+
+ if(init_gl() == -1) {
+ return -1;
+ }
+ return 0;
+}
+
+void nex_closegfx(void)
+{
+}
+
+int nex_evloop_wait(void)
+{
+ if(have_idle) {
+ glutIdleFunc(0);
+ have_idle = 0;
+ }
+
+ glutMainLoopEvent();
+ return quit ? 0 : 1;
+}
+
+int nex_evloop_poll(void)
+{
+ if(!have_idle) {
+ glutIdleFunc(idle);
+ have_idle = 1;
+ }
+
+ glutMainLoopEvent();
+ return quit ? 0 : 1;
+}
+
+void nex_swap_buffers(void)
+{
+ glutSwapBuffers();
+}
+
+void nex_redisplay(void)
+{
+ glutPostRedisplay();
+}
+
+static void winclose(void)
+{
+ quit = 1;
+}
+
+static void display(void)
+{
+ if(nex_cb.display) {
+ nex_cb.display(nex_cb.display_cls);
+ }
+}
+
+static void idle(void)
+{
+ glutPostRedisplay();
+}
+
+static void reshape(int x, int y)
+{
+ if(nex_cb.reshape) {
+ nex_cb.reshape(x, y, nex_cb.reshape_cls);
+ }
+}
+
+static void keydown(unsigned char key, int x, int y)
+{
+ if(nex_cb.key) {
+ nex_cb.key(key, 1, nex_cb.key_cls);
+ }
+}
+
+static void keyup(unsigned char key, int x, int y)
+{
+ if(nex_cb.key) {
+ nex_cb.key(key, 0, nex_cb.key_cls);
+ }
+}
+
+static int translate_skey(int key)
+{
+ switch(key) {
+ case GLUT_KEY_LEFT:
+ return NEX_KEY_LEFT;
+ case GLUT_KEY_UP:
+ return NEX_KEY_UP;
+ case GLUT_KEY_RIGHT:
+ return NEX_KEY_RIGHT;
+ case GLUT_KEY_DOWN:
+ return NEX_KEY_DOWN;
+ case GLUT_KEY_PAGE_UP:
+ return NEX_KEY_PGUP;
+ case GLUT_KEY_PAGE_DOWN:
+ return NEX_KEY_PGDOWN;
+ case GLUT_KEY_HOME:
+ return NEX_KEY_HOME;
+ case GLUT_KEY_END:
+ return NEX_KEY_END;
+ case GLUT_KEY_INSERT:
+ return NEX_KEY_INS;
+ default:
+ if(key >= GLUT_KEY_F1 && key <= GLUT_KEY_F12) {
+ return NEX_KEY_F1 + (key - GLUT_KEY_F1);
+ }
+ }
+ return -1;
+}
+
+static void skeydown(int key, int x, int y)
+{
+ if(nex_cb.key && (key = translate_skey(key)) > 0) {
+ nex_cb.key(key, 1, nex_cb.key_cls);
+ }
+}
+
+static void skeyup(int key, int x, int y)
+{
+ if(nex_cb.key && (key = translate_skey(key)) > 0) {
+ nex_cb.key(key, 0, nex_cb.key_cls);
+ }
+}
+
+static void mouse(int bn, int st, int x, int y)
+{
+ if(nex_cb.mousebn) {
+ int idx = bn - GLUT_LEFT_BUTTON;
+ int press = bn == GLUT_DOWN;
+ nex_cb.mousebn(idx, press, x, y, nex_cb.mousebn_cls);
+ }
+}
+
+static void motion(int x, int y)
+{
+ if(nex_cb.mousemove) {
+ nex_cb.mousemove(x, y, nex_cb.mousemove_cls);
+ }
+}
--- /dev/null
+#include <stdio.h>
+#include "nexus3d.h"
+
+
+static void display(void *cls);
+static void reshape(int x, int y, void *cls);
+static void keyb(int key, int pressed, void *cls);
+static void mbutton(int bn, int pressed, int x, int y, void *cls);
+static void mmove(int x, int y, void *cls);
+
+
+static int quit;
+
+int main(void)
+{
+ nex_gfxapi_opengl(3, 3, NEX_OPENGL_DEBUG);
+ if(nex_initgfx(1280, 800, 0) == -1) {
+ return 1;
+ }
+
+ nex_cbdisplay(display, 0);
+ nex_cbreshape(reshape, 0);
+ nex_cbkey(keyb, 0);
+ nex_cbmousebn(mbutton, 0);
+ nex_cbmousemove(mmove, 0);
+
+ while(nex_evloop_wait() && !quit);
+
+ nex_closegfx();
+ return 0;
+}
+
+
+static void display(void *cls)
+{
+ nex_clear();
+
+ nex_swap_buffers();
+}
+
+static void reshape(int x, int y, void *cls)
+{
+ nex_viewport(0, 0, x, y);
+}
+
+static void keyb(int key, int pressed, void *cls)
+{
+ if(!pressed) return;
+
+ switch(key) {
+ case 27:
+ quit = 1;
+ break;
+ }
+}
+
+static void mbutton(int bn, int pressed, int x, int y, void *cls)
+{
+}
+
+static void mmove(int x, int y, void *cls)
+{
+}