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

vertex.cpp

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 #include "graphics/tinygl/zgl.h"
00030 #include "graphics/tinygl/zdirtyrect.h"
00031 
00032 namespace TinyGL {
00033 
00034 void glopNormal(GLContext *c, GLParam *p) {
00035     c->current_normal.X = p[1].f;
00036     c->current_normal.Y = p[2].f;
00037     c->current_normal.Z = p[3].f;
00038     c->current_normal.W = 0.0f;
00039 }
00040 
00041 void glopTexCoord(GLContext *c, GLParam *p) {
00042     c->current_tex_coord.X = p[1].f;
00043     c->current_tex_coord.Y = p[2].f;
00044     c->current_tex_coord.Z = p[3].f;
00045     c->current_tex_coord.W = p[4].f;
00046 }
00047 
00048 void glopEdgeFlag(GLContext *c, GLParam *p) {
00049     c->current_edge_flag = p[1].i;
00050 }
00051 
00052 void glopColor(GLContext *c, GLParam *p) {
00053     c->current_color.X = p[1].f;
00054     c->current_color.Y = p[2].f;
00055     c->current_color.Z = p[3].f;
00056     c->current_color.W = p[4].f;
00057 
00058     if (c->color_material_enabled) {
00059         GLParam q[7];
00060         q[0].op = OP_Material;
00061         q[1].i = c->current_color_material_mode;
00062         q[2].i = c->current_color_material_type;
00063         q[3].f = p[1].f;
00064         q[4].f = p[2].f;
00065         q[5].f = p[3].f;
00066         q[6].f = p[4].f;
00067         glopMaterial(c, q);
00068     }
00069 }
00070 
00071 void gl_eval_viewport(GLContext *c) {
00072     GLViewport *v;
00073     float zsize = (1 << (ZB_Z_BITS + ZB_POINT_Z_FRAC_BITS));
00074 
00075     v = &c->viewport;
00076 
00077     v->trans.X = (float)(((v->xsize - 0.5) / 2.0) + v->xmin);
00078     v->trans.Y = (float)(((v->ysize - 0.5) / 2.0) + v->ymin);
00079     v->trans.Z = (float)(((zsize - 0.5) / 2.0) + ((1 << ZB_POINT_Z_FRAC_BITS)) / 2);
00080 
00081     v->scale.X = (float)((v->xsize - 0.5) / 2.0);
00082     v->scale.Y = (float)(-(v->ysize - 0.5) / 2.0);
00083     v->scale.Z = (float)(-((zsize - 0.5) / 2.0));
00084 }
00085 
00086 void glopBegin(GLContext *c, GLParam *p) {
00087     int type;
00088 
00089     assert(c->in_begin == 0);
00090 
00091     type = p[1].i;
00092     c->begin_type = type;
00093     c->in_begin = 1;
00094     c->vertex_n = 0;
00095     c->vertex_cnt = 0;
00096 
00097     if (c->matrix_model_projection_updated) {
00098         if (c->lighting_enabled) {
00099             // precompute inverse modelview
00100             c->matrix_model_view_inv = *c->matrix_stack_ptr[0];
00101             c->matrix_model_view_inv.invert();
00102             c->matrix_model_view_inv.transpose();
00103         } else {
00104             // precompute projection matrix
00105             c->matrix_model_projection = (*c->matrix_stack_ptr[1]) * (*c->matrix_stack_ptr[0]);
00106             // test to accelerate computation
00107             c->matrix_model_projection_no_w_transform = 0;
00108             if (c->matrix_model_projection._m[3][0] == 0.0 && c->matrix_model_projection._m[3][1] == 0.0 && c->matrix_model_projection._m[3][2] == 0.0)
00109                 c->matrix_model_projection_no_w_transform = 1;
00110         }
00111 
00112         c->matrix_model_projection_updated = 0;
00113     }
00114     // test if the texture matrix is not Identity
00115     c->apply_texture_matrix = !c->matrix_stack_ptr[2]->isIdentity();
00116 
00117     // viewport
00118     if (c->viewport.updated) {
00119         gl_eval_viewport(c);
00120         c->viewport.updated = 0;
00121     }
00122     // triangle drawing functions
00123     if (c->render_mode == TGL_SELECT) {
00124         c->draw_triangle_front = gl_draw_triangle_select;
00125         c->draw_triangle_back = gl_draw_triangle_select;
00126     } else {
00127         switch (c->polygon_mode_front) {
00128         case TGL_POINT:
00129             c->draw_triangle_front = gl_draw_triangle_point;
00130             break;
00131         case TGL_LINE:
00132             c->draw_triangle_front = gl_draw_triangle_line;
00133             break;
00134         default:
00135             c->draw_triangle_front = gl_draw_triangle_fill;
00136             break;
00137         }
00138 
00139         switch (c->polygon_mode_back) {
00140         case TGL_POINT:
00141             c->draw_triangle_back = gl_draw_triangle_point;
00142             break;
00143         case TGL_LINE:
00144             c->draw_triangle_back = gl_draw_triangle_line;
00145             break;
00146         default:
00147             c->draw_triangle_back = gl_draw_triangle_fill;
00148             break;
00149         }
00150     }
00151 }
00152 
00153 // coords, tranformation, clip code and projection
00154 // TODO : handle all cases
00155 static inline void gl_vertex_transform(GLContext *c, GLVertex *v) {
00156     Matrix4 *m;
00157 
00158     if (c->lighting_enabled) {
00159         // eye coordinates needed for lighting
00160 
00161         m = c->matrix_stack_ptr[0];
00162         m->transform3x4(v->coord,v->ec);
00163 
00164         // projection coordinates
00165         m = c->matrix_stack_ptr[1];
00166         m->transform(v->ec, v->pc);
00167 
00168         m = &c->matrix_model_view_inv;
00169 
00170         m->transform3x3(c->current_normal, v->normal);
00171 
00172         if (c->normalize_enabled) {
00173             v->normal.normalize();
00174         }
00175     } else {
00176         // no eye coordinates needed, no normal
00177         // NOTE: W = 1 is assumed
00178         m = &c->matrix_model_projection;
00179 
00180         m->transform3x4(v->coord, v->pc);
00181         if (c->matrix_model_projection_no_w_transform) {
00182             v->pc.W = (m->_m[3][3]);
00183         }
00184         v->normal.X = v->normal.Y = v->normal.Z = 0;
00185         v->ec.X = v->ec.Y = v->ec.Z = v->ec.W = 0;
00186     }
00187 
00188     v->clip_code = gl_clipcode(v->pc.X, v->pc.Y, v->pc.Z, v->pc.W);
00189 }
00190 
00191 void glopVertex(GLContext *c, GLParam *p) {
00192     GLVertex *v;
00193     int n, cnt;
00194 
00195     assert(c->in_begin != 0);
00196 
00197     n = c->vertex_n;
00198     cnt = c->vertex_cnt;
00199     cnt++;
00200     c->vertex_cnt = cnt;
00201 
00202     // quick fix to avoid crashes on large polygons
00203     if (n >= c->vertex_max) {
00204         GLVertex *newarray;
00205         c->vertex_max <<= 1;    // just double size
00206         newarray = (GLVertex *)gl_malloc(sizeof(GLVertex) * c->vertex_max);
00207         if (!newarray) {
00208             error("unable to allocate GLVertex array.");
00209         }
00210         memcpy(newarray, c->vertex, n * sizeof(GLVertex));
00211         gl_free(c->vertex);
00212         c->vertex = newarray;
00213     }
00214     // new vertex entry
00215     v = &c->vertex[n];
00216     n++;
00217 
00218     v->coord.X = p[1].f;
00219     v->coord.Y = p[2].f;
00220     v->coord.Z = p[3].f;
00221     v->coord.W = p[4].f;
00222 
00223     gl_vertex_transform(c, v);
00224 
00225     // color
00226 
00227     if (c->lighting_enabled) {
00228         gl_shade_vertex(c, v);
00229     } else {
00230         v->color = c->current_color;
00231     }
00232 
00233     // tex coords
00234 
00235     if (c->texture_2d_enabled) {
00236         if (c->apply_texture_matrix) {
00237             c->matrix_stack_ptr[2]->transform(c->current_tex_coord, v->tex_coord);
00238         } else {
00239             v->tex_coord = c->current_tex_coord;
00240         }
00241     }
00242     // precompute the mapping to the viewport
00243     if (v->clip_code == 0)
00244         gl_transform_to_viewport(c, v);
00245 
00246     // edge flag
00247 
00248     v->edge_flag = c->current_edge_flag;
00249 
00250     c->vertex_n = n;
00251 }
00252 
00253 void glopEnd(GLContext *c, GLParam *) {
00254     assert(c->in_begin == 1);
00255     
00256     if (c->vertex_cnt > 0) {
00257         tglIssueDrawCall(new Graphics::RasterizationDrawCall());
00258     }
00259 
00260     c->in_begin = 0;
00261 }
00262 
00263 } // end of namespace TinyGL


Generated on Sat Feb 16 2019 05:01:10 for ResidualVM by doxygen 1.7.1
curved edge   curved edge