ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

zgl.h

Go to the documentation of this file.
00001 /* ResidualVM - A 3D game interpreter
00002  *
00003  * ResidualVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the AUTHORS
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 /*
00024  * This file is based on, or a modified version of code from TinyGL (C) 1997-1998 Fabrice Bellard,
00025  * which is licensed under the zlib-license (see LICENSE).
00026  * It also has modifications by the ResidualVM-team, which are covered under the GPLv2 (or later).
00027  */
00028 
00029 #ifndef _tgl_zgl_h_
00030 #define _tgl_zgl_h_
00031 
00032 #include "common/util.h"
00033 #include "common/textconsole.h"
00034 #include "common/array.h"
00035 #include "common/list.h"
00036 
00037 #include "graphics/tinygl/gl.h"
00038 #include "graphics/tinygl/zbuffer.h"
00039 #include "graphics/tinygl/zmath.h"
00040 #include "graphics/tinygl/zblit.h"
00041 #include "graphics/tinygl/zdirtyrect.h"
00042 
00043 namespace TinyGL {
00044 
00045 enum {
00046 
00047 #define ADD_OP(a,b,c) OP_ ## a ,
00048 
00049 #include "graphics/tinygl/opinfo.h"
00050 
00051     DUMMY
00052 };
00053 
00054 // initially # of allocated GLVertexes (will grow when necessary)
00055 #define POLYGON_MAX_VERTEX 16
00056 
00057 // Max # of specular light pow buffers
00058 #define MAX_SPECULAR_BUFFERS 8
00059 // # of entries in specular buffer
00060 #define SPECULAR_BUFFER_SIZE 1024
00061 // specular buffer granularity
00062 #define SPECULAR_BUFFER_RESOLUTION 1024
00063 
00064 #define MAX_MODELVIEW_STACK_DEPTH   35
00065 #define MAX_PROJECTION_STACK_DEPTH  8
00066 #define MAX_TEXTURE_STACK_DEPTH     8
00067 #define MAX_NAME_STACK_DEPTH        64
00068 #define MAX_TEXTURE_LEVELS          11
00069 #define T_MAX_LIGHTS                32
00070 
00071 #define VERTEX_HASH_SIZE 1031
00072 
00073 #define MAX_DISPLAY_LISTS 1024
00074 #define OP_BUFFER_MAX_SIZE 512
00075 
00076 #define TGL_OFFSET_FILL    0x1
00077 #define TGL_OFFSET_LINE    0x2
00078 #define TGL_OFFSET_POINT   0x4
00079 
00080 struct GLSpecBuf {
00081     int shininess_i;
00082     int last_used;
00083     float buf[SPECULAR_BUFFER_SIZE + 1];
00084     struct GLSpecBuf *next;
00085 };
00086 
00087 struct GLLight {
00088     Vector4 ambient;
00089     Vector4 diffuse;
00090     Vector4 specular;
00091     bool has_specular;
00092     Vector4 position;
00093     Vector3 spot_direction;
00094     float spot_exponent;
00095     float spot_cutoff;
00096     float attenuation[3];
00097     // precomputed values
00098     float cos_spot_cutoff;
00099     Vector3 norm_spot_direction;
00100     Vector3 norm_position;
00101     // we use a linked list to know which are the enabled lights
00102     int enabled;
00103     struct GLLight *next, *prev;
00104 };
00105 
00106 struct GLMaterial {
00107     Vector4 emission;
00108     Vector4 ambient;
00109     Vector4 diffuse;
00110     Vector4 specular;
00111     bool has_specular;
00112     float shininess;
00113 
00114     // computed values
00115     int shininess_i;
00116     int do_specular;
00117 };
00118 
00119 
00120 struct GLViewport {
00121     int xmin, ymin, xsize, ysize;
00122     Vector3 scale;
00123     Vector3 trans;
00124     int updated;
00125 };
00126 
00127 union GLParam {
00128     int op;
00129     float f;
00130     int i;
00131     unsigned int ui;
00132     void *p;
00133 };
00134 
00135 struct GLParamBuffer {
00136     GLParam ops[OP_BUFFER_MAX_SIZE];
00137     struct GLParamBuffer *next;
00138 };
00139 
00140 struct GLList {
00141     GLParamBuffer *first_op_buffer;
00142     // TODO: extensions for an hash table or a better allocating scheme
00143 };
00144 
00145 struct GLVertex {
00146     int edge_flag;
00147     Vector3 normal;
00148     Vector4 coord;
00149     Vector4 tex_coord;
00150     Vector4 color;
00151 
00152     // computed values
00153     Vector4 ec;                // eye coordinates
00154     Vector4 pc;                // coordinates in the normalized volume
00155     int clip_code;        // clip code
00156     ZBufferPoint zp;      // integer coordinates for the rasterization
00157 
00158     bool operator==(const GLVertex &other) const {
00159         return  edge_flag == other.edge_flag &&
00160                 normal == other.normal &&
00161                 coord == other.coord && 
00162                 tex_coord == other.tex_coord && 
00163                 color == other.color &&
00164                 ec == other.ec &&
00165                 pc == other.pc && 
00166                 clip_code == other.clip_code &&
00167                 zp == other.zp;
00168     }
00169 
00170     bool operator!=(const GLVertex &other) const {
00171         return !(*this == other);
00172     }
00173 };
00174 
00175 struct GLImage {
00176     Graphics::PixelBuffer pixmap;
00177     int xsize, ysize;
00178 };
00179 
00180 // textures
00181 
00182 #define TEXTURE_HASH_TABLE_SIZE 256
00183 
00184 struct GLTexture {
00185     GLImage images[MAX_TEXTURE_LEVELS];
00186     unsigned int handle;
00187     int versionNumber;
00188     struct GLTexture *next, *prev;
00189     bool disposed;
00190 };
00191 
00192 
00193 // shared state
00194 
00195 struct GLSharedState {
00196     GLList **lists;
00197     GLTexture **texture_hash_table;
00198 };
00199 
00208 class LinearAllocator {
00209 public:
00210     LinearAllocator() {
00211         _memoryBuffer = nullptr;
00212         _memorySize = 0;
00213         _memoryPosition = 0;
00214     }
00215 
00216     void initialize(size_t newSize) {
00217         assert(_memoryBuffer == nullptr);
00218         void *newBuffer = gl_malloc(newSize);
00219         if (newBuffer == nullptr) {
00220             error("Couldn't allocate memory for linear allocator.");
00221         }
00222         _memoryBuffer = newBuffer;
00223         _memorySize = newSize;
00224     }
00225 
00226     ~LinearAllocator() {
00227         if (_memoryBuffer != nullptr) {
00228             gl_free(_memoryBuffer);
00229         }
00230     }
00231 
00232     void *allocate(size_t size) {
00233         if (_memoryPosition + size >= _memorySize) {
00234             error("Allocator out of memory: couldn't allocate more memory from linear allocator.");
00235         }
00236         size_t returnPos = _memoryPosition;
00237         _memoryPosition += size;
00238         return ((char *)_memoryBuffer) + returnPos;
00239     }
00240 
00241     void reset() {
00242         _memoryPosition = 0;
00243     }
00244 private:
00245     void *_memoryBuffer;
00246     size_t _memorySize;
00247     size_t _memoryPosition;
00248 };
00249 
00250 struct GLContext;
00251 
00252 typedef void (*gl_draw_triangle_func)(GLContext *c, GLVertex *p0, GLVertex *p1, GLVertex *p2);
00253 
00254 // display context
00255 
00256 struct GLContext {
00257     // Z buffer
00258     FrameBuffer *fb;
00259     Common::Rect renderRect;
00260 
00261     // Internal texture size
00262     int _textureSize;
00263 
00264     // lights
00265     GLLight lights[T_MAX_LIGHTS];
00266     GLLight *first_light;
00267     Vector4 ambient_light_model;
00268     int local_light_model;
00269     int lighting_enabled;
00270     int light_model_two_side;
00271 
00272     // materials
00273     GLMaterial materials[2];
00274     int color_material_enabled;
00275     int current_color_material_mode;
00276     int current_color_material_type;
00277 
00278     // textures
00279     GLTexture *current_texture;
00280     int texture_2d_enabled;
00281 
00282     // shared state
00283     GLSharedState shared_state;
00284 
00285     // current list
00286     GLParamBuffer *current_op_buffer;
00287     int current_op_buffer_index;
00288     int exec_flag, compile_flag, print_flag;
00289 
00290     // matrix
00291     int matrix_mode;
00292     Matrix4 *matrix_stack[3];
00293     Matrix4 *matrix_stack_ptr[3];
00294     int matrix_stack_depth_max[3];
00295 
00296     Matrix4 matrix_model_view_inv;
00297     Matrix4 matrix_model_projection;
00298     int matrix_model_projection_updated;
00299     int matrix_model_projection_no_w_transform;
00300     int apply_texture_matrix;
00301 
00302     // viewport
00303     GLViewport viewport;
00304 
00305     // current state
00306     int polygon_mode_back;
00307     int polygon_mode_front;
00308 
00309     int current_front_face;
00310     int current_shade_model;
00311     int current_cull_face;
00312     int cull_face_enabled;
00313     int normalize_enabled;
00314     gl_draw_triangle_func draw_triangle_front, draw_triangle_back;
00315 
00316     // selection
00317     int render_mode;
00318     unsigned int *select_buffer;
00319     int select_size;
00320     unsigned int *select_ptr, *select_hit;
00321     int select_overflow;
00322     int select_hits;
00323 
00324     // names
00325     unsigned int name_stack[MAX_NAME_STACK_DEPTH];
00326     int name_stack_size;
00327 
00328     // clear
00329     float clear_depth;
00330     Vector4 clear_color;
00331 
00332     // current vertex state
00333     Vector4 current_color;
00334     Vector4 current_normal;
00335     Vector4 current_tex_coord;
00336     int current_edge_flag;
00337 
00338     // glBegin / glEnd
00339     int in_begin;
00340     int begin_type;
00341     int vertex_n, vertex_cnt;
00342     int vertex_max;
00343     GLVertex *vertex;
00344 
00345     // opengl 1.1 arrays
00346     float *vertex_array;
00347     int vertex_array_size;
00348     int vertex_array_stride;
00349     float *normal_array;
00350     int normal_array_stride;
00351     float *color_array;
00352     int color_array_size;
00353     int color_array_stride;
00354     float *texcoord_array;
00355     int texcoord_array_size;
00356     int texcoord_array_stride;
00357     int client_states;
00358 
00359     // opengl 1.1 polygon offset
00360     float offset_factor;
00361     float offset_units;
00362     int offset_states;
00363 
00364     int shadow_mode;
00365 
00366     // specular buffer. could probably be shared between contexts,
00367     // but that wouldn't be 100% thread safe
00368     GLSpecBuf *specbuf_first;
00369     int specbuf_used_counter;
00370     int specbuf_num_buffers;
00371 
00372     // opaque structure for user's use
00373     void *opaque;
00374     // resize viewport function
00375     int (*gl_resize_viewport)(GLContext *c, int *xsize, int *ysize);
00376 
00377     // depth test
00378     int depth_test;
00379     int color_mask;
00380 
00381     Common::Rect _scissorRect;
00382 
00383     bool _enableDirtyRectangles;
00384 
00385     // blit test
00386     Common::List<Graphics::BlitImage *> _blitImages;
00387 
00388     // Draw call queue
00389     Common::List<Graphics::DrawCall *> _drawCallsQueue;
00390     Common::List<Graphics::DrawCall *> _previousFrameDrawCallsQueue;
00391     int _currentAllocatorIndex;
00392     LinearAllocator _drawCallAllocator[2];
00393 };
00394 
00395 extern GLContext *gl_ctx;
00396 
00397 void gl_add_op(GLParam *p);
00398 
00399 // clip.c
00400 void gl_transform_to_viewport(GLContext *c, GLVertex *v);
00401 void gl_draw_triangle(GLContext *c, GLVertex *p0, GLVertex *p1, GLVertex *p2);
00402 void gl_draw_line(GLContext *c, GLVertex *p0, GLVertex *p1);
00403 void gl_draw_point(GLContext *c, GLVertex *p0);
00404 
00405 void gl_draw_triangle_point(GLContext *c, GLVertex *p0, GLVertex *p1, GLVertex *p2);
00406 void gl_draw_triangle_line(GLContext *c, GLVertex *p0, GLVertex *p1, GLVertex *p2);
00407 void gl_draw_triangle_fill(GLContext *c, GLVertex *p0, GLVertex *p1, GLVertex *p2);
00408 void gl_draw_triangle_select(GLContext *c, GLVertex *p0, GLVertex *p1, GLVertex *p2);
00409 
00410 // matrix.c
00411 void gl_print_matrix(const float *m);
00412 
00413 // light.c
00414 void gl_add_select(GLContext *c, unsigned int zmin, unsigned int zmax);
00415 void gl_enable_disable_light(GLContext *c, int light, int v);
00416 void gl_shade_vertex(GLContext *c, GLVertex *v);
00417 
00418 void glInitTextures(GLContext *c);
00419 void glEndTextures(GLContext *c);
00420 GLTexture *alloc_texture(GLContext *c, int h);
00421 void free_texture(GLContext *c, int h);
00422 void free_texture(GLContext *c, GLTexture *t);
00423 
00424 // image_util.c
00425 void gl_resizeImage(unsigned char *dest, int xsize_dest, int ysize_dest,
00426                     unsigned char *src, int xsize_src, int ysize_src);
00427 void gl_resizeImageNoInterpolate(unsigned char *dest, int xsize_dest, int ysize_dest,
00428                                  unsigned char *src, int xsize_src, int ysize_src);
00429 
00430 void tglIssueDrawCall(Graphics::DrawCall *drawCall);
00431 
00432 // zdirtyrect.cpp
00433 void tglDisposeResources(GLContext *c);
00434 void tglDisposeDrawCallLists(TinyGL::GLContext *c);
00435 
00436 GLContext *gl_get_context();
00437 
00438 // specular buffer "api"
00439 GLSpecBuf *specbuf_get_buffer(GLContext *c, const int shininess_i, const float shininess);
00440 void specbuf_cleanup(GLContext *c); // free all memory used
00441 
00442 void glInit(void *zbuffer, int textureSize);
00443 void glClose();
00444 
00445 #ifdef DEBUG
00446 #define dprintf fprintf
00447 #else
00448 #define dprintf
00449 #endif
00450 
00451 #ifndef LOCAL_PI
00452 #define LOCAL_PI    (3.14159265358979323846)
00453 #endif
00454 
00455 // glopXXX functions
00456 
00457 #define ADD_OP(a,b,c) void glop ## a (GLContext *, GLParam *);
00458 #include "opinfo.h"
00459 
00460 // this clip epsilon is needed to avoid some rounding errors after
00461 // several clipping stages
00462 
00463 #define CLIP_EPSILON (1E-5)
00464 
00465 static inline int gl_clipcode(float x, float y, float z, float w1) {
00466     float w;
00467 
00468     w = (float)(w1 * (1.0 + CLIP_EPSILON));
00469     return (x < -w) | ((x > w) << 1) | ((y < -w) << 2) | ((y > w) << 3) | ((z < -w) << 4) | ((z > w) << 5);
00470 }
00471 
00472 } // end of namespace TinyGL
00473 
00474 #endif


Generated on Sat Dec 7 2019 05:00:41 for ResidualVM by doxygen 1.7.1
curved edge   curved edge