From: John Tsiombikas Date: Sat, 30 Mar 2024 07:39:00 +0000 (+0200) Subject: starting a new 3d engine X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=commitdiff_plain;h=dc5d3ad8a536d96254447efbe8cd0b1edc9944e6;p=nexus3d starting a new 3d engine --- dc5d3ad8a536d96254447efbe8cd0b1edc9944e6 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0497878 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +*.o +*.d +*.swp +*.a +test +compile_commands.json +.cache/ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..27ec497 --- /dev/null +++ b/Makefile @@ -0,0 +1,31 @@ +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) diff --git a/src/cgmath2/cgmath2.h b/src/cgmath2/cgmath2.h new file mode 100644 index 0000000..0e34f38 --- /dev/null +++ b/src/cgmath2/cgmath2.h @@ -0,0 +1,196 @@ +#ifndef NEXUS3D_CGMATH2_H_ +#define NEXUS3D_CGMATH2_H_ + +#include +#include + +#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_ */ diff --git a/src/cgmath2/cgmvec3.inl b/src/cgmath2/cgmvec3.inl new file mode 100644 index 0000000..d6a50f2 --- /dev/null +++ b/src/cgmath2/cgmvec3.inl @@ -0,0 +1,197 @@ +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; +} diff --git a/src/gfx.h b/src/gfx.h new file mode 100644 index 0000000..beac8c1 --- /dev/null +++ b/src/gfx.h @@ -0,0 +1,7 @@ +#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_ */ diff --git a/src/gl/gfx_gl.c b/src/gl/gfx_gl.c new file mode 100644 index 0000000..4156368 --- /dev/null +++ b/src/gl/gfx_gl.c @@ -0,0 +1,12 @@ +#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); +} diff --git a/src/gl/opengl.c b/src/gl/opengl.c new file mode 100644 index 0000000..ca7fb6b --- /dev/null +++ b/src/gl/opengl.c @@ -0,0 +1,6 @@ +#include "opengl.h" + +int init_gl(void) +{ + return 0; +} diff --git a/src/gl/opengl.h b/src/gl/opengl.h new file mode 100644 index 0000000..4723efc --- /dev/null +++ b/src/gl/opengl.h @@ -0,0 +1,8 @@ +#ifndef NEXUS3D_OPENGL_H_ +#define NEXUS3D_OPENGL_H_ + +#include + +int init_gl(void); + +#endif /* NEXUS3D_OPENGL_H_ */ diff --git a/src/nexus3d.c b/src/nexus3d.c new file mode 100644 index 0000000..a4e8f1e --- /dev/null +++ b/src/nexus3d.c @@ -0,0 +1,13 @@ +#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; +} diff --git a/src/nexus3d.h b/src/nexus3d.h new file mode 100644 index 0000000..1de3560 --- /dev/null +++ b/src/nexus3d.h @@ -0,0 +1,15 @@ +#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_ */ diff --git a/src/nexus3d_impl.h b/src/nexus3d_impl.h new file mode 100644 index 0000000..288badc --- /dev/null +++ b/src/nexus3d_impl.h @@ -0,0 +1,33 @@ +#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_ */ diff --git a/src/wsys/wsys.c b/src/wsys/wsys.c new file mode 100644 index 0000000..f5c1f77 --- /dev/null +++ b/src/wsys/wsys.c @@ -0,0 +1,34 @@ +#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; +} + diff --git a/src/wsys/wsys.h b/src/wsys/wsys.h new file mode 100644 index 0000000..6a5fa05 --- /dev/null +++ b/src/wsys/wsys.h @@ -0,0 +1,60 @@ +#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_ */ diff --git a/src/wsys/wsys_fglut.c b/src/wsys/wsys_fglut.c new file mode 100644 index 0000000..8194813 --- /dev/null +++ b/src/wsys/wsys_fglut.c @@ -0,0 +1,209 @@ +#include +#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); + } +} diff --git a/test.c b/test.c new file mode 100644 index 0000000..e38d66f --- /dev/null +++ b/test.c @@ -0,0 +1,63 @@ +#include +#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) +{ +}