From 3b21507274aa4f98644382903ae529c1fc2c7bd4 Mon Sep 17 00:00:00 2001 From: inmarket Date: Wed, 20 Aug 2014 01:36:33 +1000 Subject: GL3D GWIN window + demo --- 3rdparty/tinygl-0.4-ugfx/src/vertex.c | 365 ++++++++++++++++++++++++++++++++++ 1 file changed, 365 insertions(+) create mode 100644 3rdparty/tinygl-0.4-ugfx/src/vertex.c (limited to '3rdparty/tinygl-0.4-ugfx/src/vertex.c') diff --git a/3rdparty/tinygl-0.4-ugfx/src/vertex.c b/3rdparty/tinygl-0.4-ugfx/src/vertex.c new file mode 100644 index 00000000..6532c433 --- /dev/null +++ b/3rdparty/tinygl-0.4-ugfx/src/vertex.c @@ -0,0 +1,365 @@ +#include "zgl.h" + +void glopNormal(GLContext * c, GLParam * p) +{ + V3 v; + + v.X = p[1].f; + v.Y = p[2].f; + v.Z = p[3].f; + + c->current_normal.X = v.X; + c->current_normal.Y = v.Y; + c->current_normal.Z = v.Z; + c->current_normal.W = 0; +} + +void glopTexCoord(GLContext * c, GLParam * p) +{ + c->current_tex_coord.X = p[1].f; + c->current_tex_coord.Y = p[2].f; + c->current_tex_coord.Z = p[3].f; + c->current_tex_coord.W = p[4].f; +} + +void glopEdgeFlag(GLContext * c, GLParam * p) +{ + c->current_edge_flag = p[1].i; +} + +void glopColor(GLContext * c, GLParam * p) +{ + + c->current_color.X = p[1].f; + c->current_color.Y = p[2].f; + c->current_color.Z = p[3].f; + c->current_color.W = p[4].f; + c->longcurrent_color[0] = p[5].ui; + c->longcurrent_color[1] = p[6].ui; + c->longcurrent_color[2] = p[7].ui; + + if (c->color_material_enabled) { + GLParam q[7]; + q[0].op = OP_Material; + q[1].i = c->current_color_material_mode; + q[2].i = c->current_color_material_type; + q[3].f = p[1].f; + q[4].f = p[2].f; + q[5].f = p[3].f; + q[6].f = p[4].f; + glopMaterial(c, q); + } +} + + +void gl_eval_viewport(GLContext * c) +{ + GLViewport *v; + float zsize = (1 << (ZB_Z_BITS + ZB_POINT_Z_FRAC_BITS)); + + v = &c->viewport; + + v->trans.X = ((v->xsize - 0.5) / 2.0) + v->xmin; + v->trans.Y = ((v->ysize - 0.5) / 2.0) + v->ymin; + v->trans.Z = ((zsize - 0.5) / 2.0) + ((1 << ZB_POINT_Z_FRAC_BITS)) / 2; + + v->scale.X = (v->xsize - 0.5) / 2.0; + v->scale.Y = -(v->ysize - 0.5) / 2.0; + v->scale.Z = -((zsize - 0.5) / 2.0); +} + +void glopBegin(GLContext * c, GLParam * p) +{ + int type; + M4 tmp; + + gl_assert(c->in_begin == 0); + + type = p[1].i; + c->begin_type = type; + c->in_begin = 1; + c->vertex_n = 0; + c->vertex_cnt = 0; + + if (c->matrix_model_projection_updated) { + + if (c->lighting_enabled) { + /* precompute inverse modelview */ + gl_M4_Inv(&tmp, c->matrix_stack_ptr[0]); + gl_M4_Transpose(&c->matrix_model_view_inv, &tmp); + } else { + float *m = &c->matrix_model_projection.m[0][0]; + /* precompute projection matrix */ + gl_M4_Mul(&c->matrix_model_projection, + c->matrix_stack_ptr[1], + c->matrix_stack_ptr[0]); + /* test to accelerate computation */ + c->matrix_model_projection_no_w_transform = 0; + if (m[12] == 0.0 && m[13] == 0.0 && m[14] == 0.0) + c->matrix_model_projection_no_w_transform = 1; + } + + /* test if the texture matrix is not Identity */ + c->apply_texture_matrix = !gl_M4_IsId(c->matrix_stack_ptr[2]); + + c->matrix_model_projection_updated = 0; + } + /* viewport */ + if (c->viewport.updated) { + gl_eval_viewport(c); + c->viewport.updated = 0; + } + /* triangle drawing functions */ + if (c->render_mode == GL_SELECT) { + c->draw_triangle_front = gl_draw_triangle_select; + c->draw_triangle_back = gl_draw_triangle_select; + } else { + switch (c->polygon_mode_front) { + case GL_POINT: + c->draw_triangle_front = gl_draw_triangle_point; + break; + case GL_LINE: + c->draw_triangle_front = gl_draw_triangle_line; + break; + default: + c->draw_triangle_front = gl_draw_triangle_fill; + break; + } + + switch (c->polygon_mode_back) { + case GL_POINT: + c->draw_triangle_back = gl_draw_triangle_point; + break; + case GL_LINE: + c->draw_triangle_back = gl_draw_triangle_line; + break; + default: + c->draw_triangle_back = gl_draw_triangle_fill; + break; + } + } +} + +/* coords, tranformation , clip code and projection */ +/* TODO : handle all cases */ +static inline void gl_vertex_transform(GLContext * c, GLVertex * v) +{ + float *m; + V4 *n; + + if (c->lighting_enabled) { + /* eye coordinates needed for lighting */ + + m = &c->matrix_stack_ptr[0]->m[0][0]; + v->ec.X = (v->coord.X * m[0] + v->coord.Y * m[1] + + v->coord.Z * m[2] + m[3]); + v->ec.Y = (v->coord.X * m[4] + v->coord.Y * m[5] + + v->coord.Z * m[6] + m[7]); + v->ec.Z = (v->coord.X * m[8] + v->coord.Y * m[9] + + v->coord.Z * m[10] + m[11]); + v->ec.W = (v->coord.X * m[12] + v->coord.Y * m[13] + + v->coord.Z * m[14] + m[15]); + + /* projection coordinates */ + m = &c->matrix_stack_ptr[1]->m[0][0]; + v->pc.X = (v->ec.X * m[0] + v->ec.Y * m[1] + + v->ec.Z * m[2] + v->ec.W * m[3]); + v->pc.Y = (v->ec.X * m[4] + v->ec.Y * m[5] + + v->ec.Z * m[6] + v->ec.W * m[7]); + v->pc.Z = (v->ec.X * m[8] + v->ec.Y * m[9] + + v->ec.Z * m[10] + v->ec.W * m[11]); + v->pc.W = (v->ec.X * m[12] + v->ec.Y * m[13] + + v->ec.Z * m[14] + v->ec.W * m[15]); + + m = &c->matrix_model_view_inv.m[0][0]; + n = &c->current_normal; + + v->normal.X = (n->X * m[0] + n->Y * m[1] + n->Z * m[2]); + v->normal.Y = (n->X * m[4] + n->Y * m[5] + n->Z * m[6]); + v->normal.Z = (n->X * m[8] + n->Y * m[9] + n->Z * m[10]); + + if (c->normalize_enabled) { + gl_V3_Norm(&v->normal); + } + } else { + /* no eye coordinates needed, no normal */ + /* NOTE: W = 1 is assumed */ + m = &c->matrix_model_projection.m[0][0]; + + v->pc.X = (v->coord.X * m[0] + v->coord.Y * m[1] + + v->coord.Z * m[2] + m[3]); + v->pc.Y = (v->coord.X * m[4] + v->coord.Y * m[5] + + v->coord.Z * m[6] + m[7]); + v->pc.Z = (v->coord.X * m[8] + v->coord.Y * m[9] + + v->coord.Z * m[10] + m[11]); + if (c->matrix_model_projection_no_w_transform) { + v->pc.W = m[15]; + } else { + v->pc.W = (v->coord.X * m[12] + v->coord.Y * m[13] + + v->coord.Z * m[14] + m[15]); + } + } + + v->clip_code = gl_clipcode(v->pc.X, v->pc.Y, v->pc.Z, v->pc.W); +} + +void glopVertex(GLContext * c, GLParam * p) +{ + GLVertex *v; + int n, i, cnt; + + gl_assert(c->in_begin != 0); + + n = c->vertex_n; + cnt = c->vertex_cnt; + cnt++; + c->vertex_cnt = cnt; + + /* quick fix to avoid crashes on large polygons */ + if (n >= c->vertex_max) { + GLVertex *newarray; + c->vertex_max <<= 1; /* just double size */ + newarray = gl_malloc(sizeof(GLVertex) * c->vertex_max); + if (!newarray) { + gl_fatal_error("unable to allocate GLVertex array.\n"); + } + memcpy(newarray, c->vertex, n * sizeof(GLVertex)); + gl_free(c->vertex); + c->vertex = newarray; + } + /* new vertex entry */ + v = &c->vertex[n]; + n++; + + v->coord.X = p[1].f; + v->coord.Y = p[2].f; + v->coord.Z = p[3].f; + v->coord.W = p[4].f; + + gl_vertex_transform(c, v); + + /* color */ + + if (c->lighting_enabled) { + gl_shade_vertex(c, v); + } else { + v->color = c->current_color; + } + + /* tex coords */ + + if (c->texture_2d_enabled) { + if (c->apply_texture_matrix) { + gl_M4_MulV4(&v->tex_coord, c->matrix_stack_ptr[2], &c->current_tex_coord); + } else { + v->tex_coord = c->current_tex_coord; + } + } + /* precompute the mapping to the viewport */ + if (v->clip_code == 0) + gl_transform_to_viewport(c, v); + + /* edge flag */ + + v->edge_flag = c->current_edge_flag; + + switch (c->begin_type) { + case GL_POINTS: + gl_draw_point(c, &c->vertex[0]); + n = 0; + break; + + case GL_LINES: + if (n == 2) { + gl_draw_line(c, &c->vertex[0], &c->vertex[1]); + n = 0; + } + break; + case GL_LINE_STRIP: + case GL_LINE_LOOP: + if (n == 1) { + c->vertex[2] = c->vertex[0]; + } else if (n == 2) { + gl_draw_line(c, &c->vertex[0], &c->vertex[1]); + c->vertex[0] = c->vertex[1]; + n = 1; + } + break; + + case GL_TRIANGLES: + if (n == 3) { + gl_draw_triangle(c, &c->vertex[0], &c->vertex[1], &c->vertex[2]); + n = 0; + } + break; + case GL_TRIANGLE_STRIP: + if (cnt >= 3) { + if (n == 3) + n = 0; + /* needed to respect triangle orientation */ + switch(cnt & 1) { + case 0: + gl_draw_triangle(c,&c->vertex[2],&c->vertex[1],&c->vertex[0]); + break; + default: + case 1: + gl_draw_triangle(c,&c->vertex[0],&c->vertex[1],&c->vertex[2]); + break; + } + } + break; + case GL_TRIANGLE_FAN: + if (n == 3) { + gl_draw_triangle(c, &c->vertex[0], &c->vertex[1], &c->vertex[2]); + c->vertex[1] = c->vertex[2]; + n = 2; + } + break; + + case GL_QUADS: + if (n == 4) { + c->vertex[2].edge_flag = 0; + gl_draw_triangle(c, &c->vertex[0], &c->vertex[1], &c->vertex[2]); + c->vertex[2].edge_flag = 1; + c->vertex[0].edge_flag = 0; + gl_draw_triangle(c, &c->vertex[0], &c->vertex[2], &c->vertex[3]); + n = 0; + } + break; + + case GL_QUAD_STRIP: + if (n == 4) { + gl_draw_triangle(c, &c->vertex[0], &c->vertex[1], &c->vertex[2]); + gl_draw_triangle(c, &c->vertex[1], &c->vertex[3], &c->vertex[2]); + for (i = 0; i < 2; i++) + c->vertex[i] = c->vertex[i + 2]; + n = 2; + } + break; + case GL_POLYGON: + break; + default: + gl_fatal_error("glBegin: type %x not handled\n", c->begin_type); + } + + c->vertex_n = n; +} + +void glopEnd(GLContext * c, GLParam * param) +{ + (void) param; + gl_assert(c->in_begin == 1); + + if (c->begin_type == GL_LINE_LOOP) { + if (c->vertex_cnt >= 3) { + gl_draw_line(c, &c->vertex[0], &c->vertex[2]); + } + } else if (c->begin_type == GL_POLYGON) { + int i = c->vertex_cnt; + while (i >= 3) { + i--; + gl_draw_triangle(c, &c->vertex[i], &c->vertex[0], &c->vertex[i - 1]); + } + } + c->in_begin = 0; +} -- cgit v1.2.3