#ifndef UTIL_H #define UTIL_H #include #include #include #include #include #include "opengl.h" #include using namespace std; extern CGcontext cgc; extern CGprogram vsh; extern CGprogram fsh; extern CGparameter mv, mvp, lightpos; extern CGprofile vsh_profile, fsh_profile; typedef long long soffs; // 32 bit typedef unsigned long long uoffs; #define OFFS_BITS 63 #define SOFFS_MIN (soffs)-(1LL << (OFFS_BITS - 2)) #define SOFFS_MAX (soffs)+(1LL << (OFFS_BITS - 2)) #define MAXEXTENT (1ULL << (OFFS_BITS - 1)) #define ABS(n) ((n) < 0 ? -(n) : (n)) struct sector { soffs x, y, z; sector (soffs x, soffs y, soffs z) : x(x), y(y), z(z) { }; sector (soffs xyz = 0) : x(xyz), y(xyz), z(xyz) { }; void offset (int subindex, uoffs extent) { if (subindex & 1) x += extent; if (subindex & 2) y += extent; if (subindex & 4) z += extent; } }; inline sector operator +(const sector &a, const sector &b) { return sector (a.x + b.x, a.y + b.y, a.z + b.z); } inline sector operator -(const sector &a, const sector &b) { return sector (a.x - b.x, a.y - b.y, a.z - b.z); } inline sector operator /(const sector &a, soffs b) { return sector (a.x / b, a.y / b, a.z / b); } inline sector operator >>(const sector &a, unsigned int b) { return sector (a.x >> b, a.y >> b, a.z >> b); } inline bool operator <=(const sector &a, const sector &b) { return a.x <= b.x && a.y <= b.y && a.z <= b.z; } inline soffs max (const sector &a) { return max (a.x, max (a.y, a.z)); } inline sector translate (const sector &p, const sector &src, const sector &dst) { return p + (dst - src); } inline sector abs (const sector &s) { return sector (ABS (s.x), ABS (s.y), ABS (s.z)); } struct vec3 { GLfloat x, y, z; vec3 () { }; vec3 (GLfloat s) : x(s), y(s), z(s) { }; vec3 (GLfloat x, GLfloat y, GLfloat z) : x(x), y(y), z(z) { }; vec3 (const sector &s) : x(s.x), y(s.y), z(s.z) { }; const vec3 operator -() const { return vec3 (-x, -y, -z); } }; const vec3 normalize (const vec3 &v); const vec3 cross (const vec3 &a, const vec3 &b); inline const vec3 operator *(const vec3 &a, GLfloat s) { return vec3 (a.x * s, a.y * s, a.z * s); } inline const vec3 operator +(const vec3 &a, const vec3 &b) { return vec3 (a.x + b.x, a.y + b.y, a.z + b.z); } inline const vec3 operator -(const vec3 &a, const vec3 &b) { return vec3 (a.x - b.x, a.y - b.y, a.z - b.z); } inline GLfloat dot (const vec3 &a, const vec3 &b) { return a.x * b.x + a.y * b.y + a.z * b.z; } // squared length inline const GLfloat length2 (const vec3 &v) { return dot (v, v); } inline const GLfloat length (const vec3 &v) { return sqrtf (length2 (v)); } typedef vec3 point; // a generic plane struct plane { vec3 n; GLfloat d; plane () { }; plane (GLfloat a, GLfloat b, GLfloat c, GLfloat d); }; inline GLfloat distance (const plane &a, const point &p) { return dot (a.n, p) + a.d; } struct sphere { point p; GLfloat r; sphere () { }; sphere (const point &p, GLfloat r) : p(p), r(r) { }; }; inline bool overlap (const sphere &a, const sphere &b) { GLfloat d = a.r + b.r; return length2 (a.p - b.p) <= d * d; } struct cone { point p; vec3 a; // axis GLfloat f, fs, fc; // angle cone () { }; cone (const point &p, const vec3 &a, GLfloat f) : p(p), a(a), f(f) { fs = sinf (f); fc = cosf (f); }; }; inline bool overlap (const cone &c, const sphere &s) { vec3 u = c.p - c.a * (s.r / c.fs); vec3 d = s.p - u; return dot (c.a, d) >= length (d) * c.fc; } void renormalize (sector &s, point &p); struct colour { GLubyte r, g, b, a; colour (GLfloat r = 1., GLfloat g = 1., GLfloat b = 1., GLfloat a = 1.) : r(GLubyte (r * 255.F + .5F)) , g(GLubyte (g * 255.F + .5F)) , b(GLubyte (b * 255.F + .5F)) , a(GLubyte (a * 255.F + .5F)) { } }; struct tex2 { GLfloat s, t; tex2 () { }; tex2 (GLfloat s, GLfloat t) : s(s), t(t) { }; }; struct box { point a, b; box() { }; void reset () { a = point ( FLT_MAX, FLT_MAX, FLT_MAX); b = point (-FLT_MAX, -FLT_MAX, -FLT_MAX); } void add (const box &o); void add (const point &p); }; struct entity; struct geometry; struct view; struct octant; extern struct timer { static double now; static double diff; static double fps; static void frame (); timer (); } timer; /* #define MAX_EVENT_TYPES 10 enum event_type { TIMER_EV }; struct event { event_type type; }; typedef callback1 event_cb; class skedjuhlar { public: // only 10 types for now private: vector > event_lists; public: skedjuhlar () { event_lists.resize (MAX_EVENT_TYPES, list()); } void register_event_cb (const event_type &t, const event_cb &e) { event_lists[t].push_back (e); }; void send_event (event &e) { list &l = event_lists[e.type]; for (list::iterator it = l.begin (); it != l.end (); it++) { (*it)(e); } }; void check_events () { while (!events.empty ()) { event &e = events.pop_front (); list &l = event_lists[e->name]; for (list::iterator it = l.begin (); it !+ l.end (); it++) { (*it)(e); } delete e; // ugly slow? hai hai..... 183G } } }; extern skedjuhlar main_scheduler; */ namespace gl { #ifdef DEBUG extern int nesting; void errchk (const char *name, const char *args, const char *file, int line); #endif struct vertex_v3f { point p; // vertex vertex_v3f () { }; vertex_v3f (point p) : p(p) { }; GLenum gl_format () const { return GL_V3F; } }; struct vertex_t2f_n3f_v3f { tex2 t; // texture vec3 n; // normal point p; // vertex vertex_t2f_n3f_v3f () { }; vertex_t2f_n3f_v3f (point p, vec3 n, tex2 t = tex2()) : p(p), n(n), t(t) { }; GLenum gl_format () const { return GL_T2F_N3F_V3F; } }; struct matrix { GLfloat data[4][4]; const GLfloat operator ()(int i, int j) const { return data[j][i]; }; GLfloat &operator ()(int i, int j) { return data[j][i]; }; operator GLfloat *() { return &data[0][0]; } void diagonal (GLfloat v); void clear () { diagonal (0.F); }; void identity () { diagonal (1.F); }; void print (); // ugly static const matrix translation (const vec3 &v); static const matrix rotation (GLfloat degrees, const vec3 &axis); matrix () { }; matrix (GLfloat diag) { diagonal (diag); }; }; const matrix operator *(const matrix &a, const matrix &b); const vec3 operator *(const matrix &a, const vec3 &v); struct vertex_buffer_object { GLuint buffer; GLenum format; void alloc () { if (!buffer) glGenBuffersARB (1, &buffer); } void bind (GLenum target = GL_ARRAY_BUFFER_ARB) { glBindBufferARB (target, buffer); glInterleavedArrays (format, 0, 0); } void draw (GLenum mode, GLint first, GLsizei count) { bind (); glDrawArrays (mode, first, count); } template void set (const vertex *v, GLsizei count, GLenum usage = GL_STATIC_DRAW_ARB, GLenum target = GL_ARRAY_BUFFER_ARB) { alloc (); format = v->gl_format (); glBindBufferARB (target, buffer); glBufferDataARB (target, count * sizeof (vertex), v, usage); } template void set (const vector &v, GLenum usage = GL_STATIC_DRAW_ARB, GLenum target = GL_ARRAY_BUFFER_ARB) { set (&v[0], v.size (), usage, target); } vertex_buffer_object () : buffer(0) { } ~vertex_buffer_object () { glDeleteBuffersARB (1, &buffer); } operator GLint () { return buffer; } }; void draw_bbox (vertex_buffer_object &vb, const sector &a, const sector &b); } GLuint SDL_GL_LoadTexture (SDL_Surface *surface, GLfloat *texcoord); #endif