From ebee79a58e9e5358bb6883bdc945a8ffe2dd7aa4 Mon Sep 17 00:00:00 2001 From: David Rose Date: Fri, 2 May 2008 18:12:23 +0000 Subject: [PATCH] remove some API --- panda/src/tinydisplay/clip.c | 24 +- panda/src/tinydisplay/image_util.c | 22 +- panda/src/tinydisplay/texture.c | 42 +- .../tinydisplay/tinyGraphicsStateGuardian.cxx | 476 ++++++++++++++---- .../tinydisplay/tinyGraphicsStateGuardian.h | 18 +- panda/src/tinydisplay/zbuffer.h | 17 + panda/src/tinydisplay/zfeatures.h | 16 +- panda/src/tinydisplay/zgl.h | 3 + panda/src/tinydisplay/ztriangle.c | 272 ++++------ 9 files changed, 567 insertions(+), 323 deletions(-) diff --git a/panda/src/tinydisplay/clip.c b/panda/src/tinydisplay/clip.c index 85a16026cc..3e702a5bfd 100644 --- a/panda/src/tinydisplay/clip.c +++ b/panda/src/tinydisplay/clip.c @@ -23,19 +23,12 @@ void gl_transform_to_viewport(GLContext *c,GLVertex *v) v->zp.z= (int) ( v->pc.Z * winv * c->viewport.scale.Z + c->viewport.trans.Z ); /* color */ - if (c->lighting_enabled) { - v->zp.r=(int)(v->color.v[0] * (ZB_POINT_RED_MAX - ZB_POINT_RED_MIN) - + ZB_POINT_RED_MIN); - v->zp.g=(int)(v->color.v[1] * (ZB_POINT_GREEN_MAX - ZB_POINT_GREEN_MIN) - + ZB_POINT_GREEN_MIN); - v->zp.b=(int)(v->color.v[2] * (ZB_POINT_BLUE_MAX - ZB_POINT_BLUE_MIN) - + ZB_POINT_BLUE_MIN); - } else { - /* no need to convert to integer if no lighting : take current color */ - v->zp.r = c->longcurrent_color[0]; - v->zp.g = c->longcurrent_color[1]; - v->zp.b = c->longcurrent_color[2]; - } + v->zp.r=(int)(v->color.v[0] * (ZB_POINT_RED_MAX - ZB_POINT_RED_MIN) + + ZB_POINT_RED_MIN); + v->zp.g=(int)(v->color.v[1] * (ZB_POINT_GREEN_MAX - ZB_POINT_GREEN_MIN) + + ZB_POINT_GREEN_MIN); + v->zp.b=(int)(v->color.v[2] * (ZB_POINT_BLUE_MAX - ZB_POINT_BLUE_MIN) + + ZB_POINT_BLUE_MIN); /* texture */ @@ -295,7 +288,7 @@ static void gl_draw_triangle_clip(GLContext *c, int co,c_and,co1,cc[3],edge_flag_tmp,clip_mask; GLVertex tmp1,tmp2,*q[3]; float tt; - + cc[0]=p0->clip_code; cc[1]=p1->clip_code; cc[2]=p2->clip_code; @@ -405,7 +398,8 @@ void gl_draw_triangle_fill(GLContext *c, count_triangles_textured++; #endif ZB_setTexture(c->zb,c->current_texture->images[0].pixmap); - ZB_fillTriangleMappingPerspective(c->zb,&p0->zp,&p1->zp,&p2->zp); + //ZB_fillTriangleMappingPerspective(c->zb,&p0->zp,&p1->zp,&p2->zp); + ZB_fillTriangleMappingSmooth(c->zb,&p0->zp,&p1->zp,&p2->zp); } else if (c->current_shade_model == GL_SMOOTH) { ZB_fillTriangleSmooth(c->zb,&p0->zp,&p1->zp,&p2->zp); } else { diff --git a/panda/src/tinydisplay/image_util.c b/panda/src/tinydisplay/image_util.c index 2789a55c6f..bab1226eaf 100644 --- a/panda/src/tinydisplay/image_util.c +++ b/panda/src/tinydisplay/image_util.c @@ -28,12 +28,30 @@ void gl_convertRGB_to_8A8R8G8B(unsigned int *pixmap, unsigned char *rgb, n=xsize*ysize; for(i=0;icurrent_texture->images[level]; im->xsize=width; im->ysize=height; @@ -166,7 +174,11 @@ void glopTexImage2D(GLContext *c,GLParam *p) #elif TGL_FEATURE_RENDER_BITS == 32 im->pixmap=gl_malloc(width*height*4); if(im->pixmap) { + if (components == 4) { + gl_convertRGBA_to_8A8R8G8B(im->pixmap,pixels1,width,height); + } else { gl_convertRGB_to_8A8R8G8B(im->pixmap,pixels1,width,height); + } } #elif TGL_FEATURE_RENDER_BITS == 16 im->pixmap=gl_malloc(width*height*2); diff --git a/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx b/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx index 41af98b414..c931799b99 100644 --- a/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx +++ b/panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx @@ -22,6 +22,11 @@ #include "config_tinydisplay.h" #include "pStatTimer.h" +extern "C" { +#include "zgl.h" +#include "zmath.h" +} + TypeHandle TinyGraphicsStateGuardian::_type_handle; PStatCollector TinyGraphicsStateGuardian::_vertices_immediate_pcollector("Vertices:Immediate mode"); @@ -160,6 +165,67 @@ restructure_image(Texture *tex) { return new_image; } +static inline void tgl_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); +} + //////////////////////////////////////////////////////////////////// // Function: TinyGraphicsStateGuardian::Constructor // Access: Public @@ -170,6 +236,9 @@ TinyGraphicsStateGuardian(GraphicsPipe *pipe, TinyGraphicsStateGuardian *share_with) : GraphicsStateGuardian(CS_yup_right, pipe) { + _c = NULL; + _vertices = NULL; + _vertices_size = 0; } //////////////////////////////////////////////////////////////////// @@ -192,6 +261,11 @@ reset() { free_pointers(); GraphicsStateGuardian::reset(); + _c = gl_get_context(); + + _c->draw_triangle_front = gl_draw_triangle_fill; + _c->draw_triangle_back = gl_draw_triangle_fill; + _supported_geom_rendering = Geom::GR_point | Geom::GR_indexed_other | @@ -212,6 +286,21 @@ reset() { add_gsg(this); } +//////////////////////////////////////////////////////////////////// +// Function: TinyGraphicsStateGuardian::free_pointers +// Access: Protected, Virtual +// Description: Frees some memory that was explicitly allocated +// within the glgsg. +//////////////////////////////////////////////////////////////////// +void TinyGraphicsStateGuardian:: +free_pointers() { + if (_vertices != (GLVertex *)NULL) { + PANDA_FREE_ARRAY(_vertices); + _vertices = NULL; + } + _vertices_size = 0; +} + //////////////////////////////////////////////////////////////////// // Function: TinyGraphicsStateGuardian::make_geom_munger // Access: Public, Virtual @@ -277,12 +366,31 @@ prepare_display_region(DisplayRegionPipelineReader *dr, int l, b, w, h; dr->get_region_pixels(l, b, w, h); - GLint x = GLint(l); - GLint y = GLint(b); - GLsizei width = GLsizei(w); - GLsizei height = GLsizei(h); + int xmin = GLint(l); + int ymin = GLint(b); + int xsize = GLsizei(w); + int ysize = GLsizei(h); - glViewport(x, y, width, height); + int xsize_req=xmin+xsize; + int ysize_req=ymin+ysize; + + if (_c->gl_resize_viewport && + _c->gl_resize_viewport(_c,&xsize_req,&ysize_req) != 0) { + gl_fatal_error("glViewport: error while resizing display"); + } + + xsize=xsize_req-xmin; + ysize=ysize_req-ymin; + if (xsize <= 0 || ysize <= 0) { + gl_fatal_error("glViewport: size too small"); + } + + _c->viewport.xmin=xmin; + _c->viewport.ymin=ymin; + _c->viewport.xsize=xsize; + _c->viewport.ysize=ysize; + + gl_eval_viewport(_c); } //////////////////////////////////////////////////////////////////// @@ -341,13 +449,7 @@ calc_projection_mat(const Lens *lens) { //////////////////////////////////////////////////////////////////// bool TinyGraphicsStateGuardian:: prepare_lens() { - if (tinydisplay_cat.is_spam()) { - tinydisplay_cat.spam() - << "glLoadMatrix(GL_PROJECTION): " << _projection_mat->get_mat() << endl; - } - glMatrixMode(GL_PROJECTION); - glLoadMatrixf(_projection_mat->get_mat().get_data()); - + _transform_stale = true; return true; } @@ -451,47 +553,191 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader, } nassertr(_data_reader != (GeomVertexDataPipelineReader *)NULL, false); - // We must use immediate mode to render primitives. - _sender.clear(); - - _sender.add_column(_data_reader, InternalName::get_normal(), - NULL, NULL, glNormal3f, NULL); - if (!_sender.add_column(_data_reader, InternalName::get_color(), - NULL, NULL, glColor3f, glColor4f)) { - // If we didn't have a color column, the item color is white. - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - } - - // TinyGL only supports single-texturing, so only bother with the - // first texture stage. - int max_stage_index = _effective_texture->get_num_on_ff_stages(); - if (max_stage_index > 0) { - TextureStage *stage = _effective_texture->get_on_ff_stage(0); - const InternalName *name = stage->get_texcoord_name(); - _sender.add_column(_data_reader, name, - NULL, glTexCoord2f, NULL, NULL); - } - - // We must add vertex last, because glVertex3f() is the key - // function call that actually issues the vertex. - _sender.add_column(_data_reader, InternalName::get_vertex(), - NULL, glVertex2f, glVertex3f, glVertex4f); - - if (_transform_stale) { - glMatrixMode(GL_MODELVIEW); - glLoadMatrixf(_internal_transform->get_mat().get_data()); - } - + // Set up the proper transform. if (_data_reader->is_vertex_transformed()) { // If the vertex data claims to be already transformed into clip // coordinates, wipe out the current projection and modelview // matrix (so we don't attempt to transform it again). - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); + const TransformState *ident = TransformState::make_identity(); + load_matrix(_c->matrix_stack_ptr[0], ident); + load_matrix(_c->matrix_stack_ptr[1], ident); + load_matrix(&_c->matrix_model_view_inv, ident); + load_matrix(&_c->matrix_model_projection, ident); + _c->matrix_model_projection_no_w_transform = 1; + _transform_stale = true; + + } else if (_transform_stale) { + // Load the actual transform. + + if (_c->lighting_enabled) { + // With the lighting equation, we need to keep the modelview and + // projection matrices separate. + + load_matrix(_c->matrix_stack_ptr[0], _internal_transform); + load_matrix(_c->matrix_stack_ptr[1], _projection_mat); + + /* precompute inverse modelview */ + M4 tmp; + gl_M4_Inv(&tmp, _c->matrix_stack_ptr[0]); + gl_M4_Transpose(&_c->matrix_model_view_inv, &tmp); + + } else { + // If we're not using lighting, go ahead and compose the + // modelview and projection matrices. + load_matrix(&_c->matrix_model_projection, + _projection_mat->compose(_internal_transform)); + + /* test to accelerate computation */ + _c->matrix_model_projection_no_w_transform = 0; + float *m = &_c->matrix_model_projection.m[0][0]; + if (m[12] == 0.0 && m[13] == 0.0 && m[14] == 0.0) { + _c->matrix_model_projection_no_w_transform = 1; + } + } + _transform_stale = false; + } + + /* test if the texture matrix is not Identity */ + // _c->apply_texture_matrix = !gl_M4_IsId(_c->matrix_stack_ptr[2]); + + // Figure out the subset of vertices we will be using in this + // operation. + int num_vertices = data_reader->get_num_rows(); + _min_vertex = num_vertices; + _max_vertex = 0; + int num_prims = geom_reader->get_num_primitives(); + int i; + for (i = 0; i < num_prims; ++i) { + CPT(GeomPrimitive) prim = geom_reader->get_primitive(i); + int nv = prim->get_min_vertex(); + _min_vertex = min(_min_vertex, nv); + int xv = prim->get_max_vertex(); + _max_vertex = max(_max_vertex, xv); + } + if (_min_vertex > _max_vertex) { + return false; + } + + // Now copy all of those vertices into our working table, + // transforming into screen space them as we go. + int num_used_vertices = _max_vertex - _min_vertex + 1; + if (_vertices_size < num_used_vertices) { + if (_vertices_size == 0) { + _vertices_size = 1; + } + while (_vertices_size < num_used_vertices) { + _vertices_size *= 2; + } + if (_vertices != (GLVertex *)NULL) { + PANDA_FREE_ARRAY(_vertices); + } + _vertices = (GLVertex *)PANDA_MALLOC_ARRAY(_vertices_size * sizeof(GLVertex)); + } + + GeomVertexReader rtexcoord, rcolor, rnormal; + + // We only support single-texturing, so only bother with the first + // texture stage. + bool needs_texcoord = false; + const InternalName *texcoord_name = InternalName::get_texcoord(); + int max_stage_index = _effective_texture->get_num_on_ff_stages(); + if (max_stage_index > 0) { + TextureStage *stage = _effective_texture->get_on_ff_stage(0); + rtexcoord = GeomVertexReader(data_reader, stage->get_texcoord_name()); + rtexcoord.set_row(_min_vertex); + needs_texcoord = rtexcoord.has_column(); + } + + bool needs_color = false; + if (_vertex_colors_enabled) { + rcolor = GeomVertexReader(data_reader, InternalName::get_color()); + rcolor.set_row(_min_vertex); + needs_color = rcolor.has_column(); + } + + if (!needs_color) { + if (_has_scene_graph_color) { + cerr << "sg color\n"; + const Colorf &d = _scene_graph_color; + _c->current_color.X = d[0]; + _c->current_color.Y = d[1]; + _c->current_color.Z = d[2]; + _c->current_color.W = d[3]; + + } else { + _c->current_color.X = 1.0f; + _c->current_color.Y = 1.0f; + _c->current_color.Z = 1.0f; + _c->current_color.W = 1.0f; + } + } + + bool needs_normal = false; + if (_c->lighting_enabled) { + rnormal = GeomVertexReader(data_reader, InternalName::get_normal()); + rnormal.set_row(_min_vertex); + needs_normal = rnormal.has_column(); + } + + GeomVertexReader rvertex(data_reader, InternalName::get_vertex()); + rvertex.set_row(_min_vertex); + + for (i = 0; i < num_used_vertices; ++i) { + GLVertex *v = &_vertices[i]; + const LVecBase4f &d = rvertex.get_data4f(); + + v->coord.X = d[0]; + v->coord.Y = d[1]; + v->coord.Z = d[2]; + v->coord.W = d[3]; + + if (needs_texcoord) { + const LVecBase2f &d = rtexcoord.get_data2f(); + v->tex_coord.X = d[0]; + v->tex_coord.Y = d[1]; + } + + if (needs_color) { + const Colorf &d = rcolor.get_data4f(); + _c->current_color.X = d[0]; + _c->current_color.Y = d[1]; + _c->current_color.Z = d[2]; + _c->current_color.W = d[3]; + + 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 = d[0]; + q[4].f = d[1]; + q[5].f = d[2]; + q[6].f = d[3]; + glopMaterial(_c, q); + } + } + + v->color = _c->current_color; + + if (needs_normal) { + const LVecBase3f &d = rnormal.get_data3f(); + _c->current_normal.X = d[0]; + _c->current_normal.Y = d[1]; + _c->current_normal.Z = d[2]; + _c->current_normal.W = 0.0f; + } + + tgl_vertex_transform(_c, v); + + if (_c->lighting_enabled) { + gl_shade_vertex(_c, v); + } + + if (v->clip_code == 0) { + gl_transform_to_viewport(_c, v); + } + + v->edge_flag = 0; } return true; @@ -512,7 +758,27 @@ draw_triangles(const GeomPrimitivePipelineReader *reader, bool force) { } #endif // NDEBUG - draw_immediate_simple_primitives(reader, GL_TRIANGLES); + int num_vertices = reader->get_num_vertices(); + _vertices_immediate_pcollector.add_level(num_vertices); + + if (reader->is_indexed()) { + for (int i = 0; i < num_vertices; i += 3) { + GLVertex *v0 = &_vertices[reader->get_vertex(i) - _min_vertex]; + GLVertex *v1 = &_vertices[reader->get_vertex(i + 1) - _min_vertex]; + GLVertex *v2 = &_vertices[reader->get_vertex(i + 2) - _min_vertex]; + gl_draw_triangle(_c, v0, v1, v2); + } + + } else { + int delta = reader->get_first_vertex() - _min_vertex; + for (int vi = 0; vi < num_vertices; vi += 3) { + GLVertex *v0 = &_vertices[vi + delta]; + GLVertex *v1 = &_vertices[vi + delta + 1]; + GLVertex *v2 = &_vertices[vi + delta + 2]; + gl_draw_triangle(_c, v0, v1, v2); + } + } + return true; } @@ -530,7 +796,25 @@ draw_lines(const GeomPrimitivePipelineReader *reader, bool force) { } #endif // NDEBUG - draw_immediate_simple_primitives(reader, GL_LINES); + int num_vertices = reader->get_num_vertices(); + _vertices_immediate_pcollector.add_level(num_vertices); + + if (reader->is_indexed()) { + for (int i = 0; i < num_vertices; i += 2) { + GLVertex *v0 = &_vertices[reader->get_vertex(i) - _min_vertex]; + GLVertex *v1 = &_vertices[reader->get_vertex(i + 1) - _min_vertex]; + gl_draw_line(_c, v0, v1); + } + + } else { + int delta = reader->get_first_vertex() - _min_vertex; + for (int vi = 0; vi < num_vertices; vi += 2) { + GLVertex *v0 = &_vertices[vi + delta]; + GLVertex *v1 = &_vertices[vi + delta + 1]; + gl_draw_line(_c, v0, v1); + } + } + return true; } @@ -548,7 +832,23 @@ draw_points(const GeomPrimitivePipelineReader *reader, bool force) { } #endif // NDEBUG - draw_immediate_simple_primitives(reader, GL_POINTS); + int num_vertices = reader->get_num_vertices(); + _vertices_immediate_pcollector.add_level(num_vertices); + + if (reader->is_indexed()) { + for (int i = 0; i < num_vertices; ++i) { + GLVertex *v0 = &_vertices[reader->get_vertex(i) - _min_vertex]; + gl_draw_point(_c, v0); + } + + } else { + int delta = reader->get_first_vertex() - _min_vertex; + for (int vi = 0; vi < num_vertices; ++vi) { + GLVertex *v0 = &_vertices[vi + delta]; + gl_draw_point(_c, v0); + } + } + return true; } @@ -561,19 +861,6 @@ draw_points(const GeomPrimitivePipelineReader *reader, bool force) { //////////////////////////////////////////////////////////////////// void TinyGraphicsStateGuardian:: end_draw_primitives() { - if (_transform_stale) { - glMatrixMode(GL_MODELVIEW); - glLoadMatrixf(_internal_transform->get_mat().get_data()); - } - - if (_data_reader->is_vertex_transformed()) { - // Restore the matrices that we pushed above. - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - } - GraphicsStateGuardian::end_draw_primitives(); } @@ -854,9 +1141,11 @@ begin_bind_lights() { CPT(TransformState) render_transform = _cs_transform->compose(_scene_setup->get_world_transform()); + /* glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadMatrixf(render_transform->get_mat().get_data()); + */ } //////////////////////////////////////////////////////////////////// @@ -872,9 +1161,11 @@ void TinyGraphicsStateGuardian:: end_bind_lights() { static PStatCollector _draw_set_state_light_end_bind_pcollector("Draw:Set State:Light:End bind"); PStatTimer timer(_draw_set_state_light_end_bind_pcollector); - + + /* glMatrixMode(GL_MODELVIEW); glPopMatrix(); + */ } //////////////////////////////////////////////////////////////////// @@ -888,16 +1179,8 @@ end_bind_lights() { //////////////////////////////////////////////////////////////////// void TinyGraphicsStateGuardian:: do_issue_transform() { - const TransformState *transform = _internal_transform; - if (tinydisplay_cat.is_spam()) { - tinydisplay_cat.spam() - << "glLoadMatrix(GL_MODELVIEW): " << transform->get_mat() << endl; - } - _transform_state_pcollector.add_level(1); - glMatrixMode(GL_MODELVIEW); - glLoadMatrixf(transform->get_mat().get_data()); - _transform_stale = false; + _transform_stale = true; } //////////////////////////////////////////////////////////////////// @@ -931,15 +1214,18 @@ do_issue_render_mode() { switch (attrib->get_mode()) { case RenderModeAttrib::M_unchanged: case RenderModeAttrib::M_filled: - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + _c->draw_triangle_front = gl_draw_triangle_fill; + _c->draw_triangle_back = gl_draw_triangle_fill; break; case RenderModeAttrib::M_wireframe: - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + _c->draw_triangle_front = gl_draw_triangle_line; + _c->draw_triangle_back = gl_draw_triangle_line; break; case RenderModeAttrib::M_point: - glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); + _c->draw_triangle_front = gl_draw_triangle_point; + _c->draw_triangle_back = gl_draw_triangle_point; break; default: @@ -1281,29 +1567,19 @@ upload_texture(TinyTextureContext *gtc) { } //////////////////////////////////////////////////////////////////// -// Function: TinyGraphicsStateGuardian::draw_immediate_simple_primitives -// Access: Private -// Description: Uses the ImmediateModeSender to draw a series of -// primitives of the indicated type. +// Function: TinyGraphicsStateGuardian::load_matrix +// Access: Private, Static +// Description: Copies the Panda matrix stored in the indicated +// TransformState object into the indicated TinyGL +// matrix. //////////////////////////////////////////////////////////////////// void TinyGraphicsStateGuardian:: -draw_immediate_simple_primitives(const GeomPrimitivePipelineReader *reader, GLenum mode) { - int num_vertices = reader->get_num_vertices(); - _vertices_immediate_pcollector.add_level(num_vertices); - glBegin(mode); - - if (reader->is_indexed()) { - for (int v = 0; v < num_vertices; ++v) { - _sender.set_vertex(reader->get_vertex(v)); - _sender.issue_vertex(); - } - - } else { - _sender.set_vertex(reader->get_first_vertex()); - for (int v = 0; v < num_vertices; ++v) { - _sender.issue_vertex(); - } +load_matrix(M4 *matrix, const TransformState *transform) { + const LMatrix4f &pm = transform->get_mat(); + for (int i = 0; i < 4; ++i) { + matrix->m[0][i] = pm.get_cell(i, 0); + matrix->m[1][i] = pm.get_cell(i, 1); + matrix->m[2][i] = pm.get_cell(i, 2); + matrix->m[3][i] = pm.get_cell(i, 3); } - - glEnd(); } diff --git a/panda/src/tinydisplay/tinyGraphicsStateGuardian.h b/panda/src/tinydisplay/tinyGraphicsStateGuardian.h index 2786d8a724..bae6bc9dd3 100644 --- a/panda/src/tinydisplay/tinyGraphicsStateGuardian.h +++ b/panda/src/tinydisplay/tinyGraphicsStateGuardian.h @@ -26,7 +26,14 @@ #include "tinyImmediateModeSender.h" #include "tinygl.h" +extern "C" { + #include "zmath.h" +} + class TinyTextureContext; +struct GLContext; +struct GLVertex; + //////////////////////////////////////////////////////////////////// // Class : TinyGraphicsStateGuardian @@ -41,6 +48,7 @@ public: virtual ~TinyGraphicsStateGuardian(); virtual void reset(); + virtual void free_pointers(); virtual PT(GeomMunger) make_geom_munger(const RenderState *state, Thread *current_thread); @@ -98,12 +106,18 @@ private: void apply_texture(TextureContext *tc); bool upload_texture(TinyTextureContext *gtc); - void draw_immediate_simple_primitives(const GeomPrimitivePipelineReader *reader, GLenum mode); + static void load_matrix(M4 *matrix, const TransformState *transform); INLINE static GLenum get_light_id(int index); private: - TinyImmediateModeSender _sender; + GLContext *_c; + + // Used during being_draw_primitives() .. end_draw_primitives(). + int _min_vertex; + int _max_vertex; + GLVertex *_vertices; + int _vertices_size; static PStatCollector _vertices_immediate_pcollector; diff --git a/panda/src/tinydisplay/zbuffer.h b/panda/src/tinydisplay/zbuffer.h index b73e59fb41..42fcbe8a8b 100644 --- a/panda/src/tinydisplay/zbuffer.h +++ b/panda/src/tinydisplay/zbuffer.h @@ -34,6 +34,9 @@ #define RGB_TO_PIXEL(r,g,b) \ ((((r) >> 1) & 0x7c00) | (((g) >> 6) & 0x03e0) | ((b) >> 11)) +#define PIXEL_R(p) (((p) & 0x7c00) << 1) +#define PIXEL_G(p) (((p) & 0x03e0) << 6) +#define PIXEL_B(p) (((p) & 0x001f) << 11) typedef unsigned short PIXEL; /* bytes per pixel */ #define PSZB 2 @@ -45,6 +48,9 @@ typedef unsigned short PIXEL; /* 16 bit mode */ #define RGB_TO_PIXEL(r,g,b) \ (((r) & 0xF800) | (((g) >> 5) & 0x07E0) | ((b) >> 11)) +#define PIXEL_R(p) (((p) & 0xf800)) +#define PIXEL_G(p) (((p) & 0x07e0) << 5) +#define PIXEL_B(p) (((p) & 0x001f) << 11) typedef unsigned short PIXEL; #define PSZB 2 #define PSZSH 4 @@ -61,6 +67,9 @@ typedef unsigned char PIXEL; #define RGB_TO_PIXEL(r,g,b) \ ((((r) << 8) & 0xff0000) | ((g) & 0xff00) | ((b) >> 8)) +#define PIXEL_R(p) (((p) & 0xff0000) >> 8) +#define PIXEL_G(p) ((p) & 0xff00) +#define PIXEL_B(p) (((p) & 0x00ff) << 8) typedef unsigned int PIXEL; #define PSZB 4 #define PSZSH 5 @@ -71,6 +80,12 @@ typedef unsigned int PIXEL; #endif +#define PIXEL_MULT(p1, p2) \ + RGB_TO_PIXEL((PIXEL_R(p1) * PIXEL_R(p2)) >> 16, \ + (PIXEL_G(p1) * PIXEL_G(p2)) >> 16, \ + (PIXEL_B(p1) * PIXEL_B(p2)) >> 16) + + typedef struct { int xsize,ysize; int linesize; /* line size, in bytes */ @@ -140,6 +155,8 @@ void ZB_fillTriangleMapping(ZBuffer *zb, void ZB_fillTriangleMappingPerspective(ZBuffer *zb, ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2); +void ZB_fillTriangleMappingSmooth(ZBuffer *zb, + ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2); typedef void (*ZB_fillTriangleFunc)(ZBuffer *, diff --git a/panda/src/tinydisplay/zfeatures.h b/panda/src/tinydisplay/zfeatures.h index 43c86a647a..07c9ac543b 100644 --- a/panda/src/tinydisplay/zfeatures.h +++ b/panda/src/tinydisplay/zfeatures.h @@ -1,11 +1,11 @@ #ifndef _tgl_features_h_ #define _tgl_features_h_ - -/* Define BYTE_ORDER correctly where missing */ -#ifndef BYTE_ORDER + +/* Define BYTE_ORDER correctly where missing */ +#ifndef BYTE_ORDER #define LITTLE_ENDIAN 1234 #define BIG_ENDIAN 4321 - + #if (defined(__i386__) || defined(__i386)) || \ defined(__ia64__) || defined(WIN32) || \ (defined(__alpha__) || defined(__alpha)) || \ @@ -19,8 +19,8 @@ #define BYTE_ORDER BIG_ENDIAN #endif -#endif - +#endif + /* It is possible to enable/disable (compile time) features in this header file. */ @@ -57,8 +57,8 @@ //#define TGL_FEATURE_RENDER_BITS 15 -#define TGL_FEATURE_RENDER_BITS 16 +//#define TGL_FEATURE_RENDER_BITS 16 //#define TGL_FEATURE_RENDER_BITS 24 -//#define TGL_FEATURE_RENDER_BITS 32 +#define TGL_FEATURE_RENDER_BITS 32 #endif /* _tgl_features_h_ */ diff --git a/panda/src/tinydisplay/zgl.h b/panda/src/tinydisplay/zgl.h index ddfe4173cb..b242627ded 100644 --- a/panda/src/tinydisplay/zgl.h +++ b/panda/src/tinydisplay/zgl.h @@ -310,6 +310,9 @@ void glInitTextures(GLContext *c); void glEndTextures(GLContext *c); GLTexture *alloc_texture(GLContext *c,int h); +/* vertex.c */ +void gl_eval_viewport(GLContext *c); + /* image_util.c */ void gl_convertRGB_to_5R6G5B(unsigned short *pixmap,unsigned char *rgb, int xsize,int ysize); diff --git a/panda/src/tinydisplay/ztriangle.c b/panda/src/tinydisplay/ztriangle.c index 366d75c57d..0bcc73ef67 100644 --- a/panda/src/tinydisplay/ztriangle.c +++ b/panda/src/tinydisplay/ztriangle.c @@ -6,37 +6,10 @@ void ZB_fillTriangleFlat(ZBuffer *zb, ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2) { -#if TGL_FEATURE_RENDER_BITS == 24 - unsigned char colorR, colorG, colorB; -#else int color; -#endif #define INTERP_Z -#if TGL_FEATURE_RENDER_BITS == 24 - -#define DRAW_INIT() \ -{ \ - colorR=p2->r>>8; \ - colorG=p2->g>>8; \ - colorB=p2->b>>8; \ -} - -#define PUT_PIXEL(_a) \ -{ \ - zz=z >> ZB_POINT_Z_FRAC_BITS; \ - if (ZCMP(zz,pz[_a])) { \ - pp[3 * _a]=colorR;\ - pp[3 * _a + 1]=colorG;\ - pp[3 * _a + 2]=colorB;\ - pz[_a]=zz; \ - }\ - z+=dzdx; \ -} - -#else - #define DRAW_INIT() \ { \ color=RGB_TO_PIXEL(p2->r,p2->g,p2->b); \ @@ -51,7 +24,6 @@ void ZB_fillTriangleFlat(ZBuffer *zb, } \ z+=dzdx; \ } -#endif /* TGL_FEATURE_RENDER_BITS == 24 */ #include "ztriangle.h" } @@ -64,91 +36,11 @@ void ZB_fillTriangleFlat(ZBuffer *zb, void ZB_fillTriangleSmooth(ZBuffer *zb, ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2) { -#if TGL_FEATURE_RENDER_BITS == 16 - int _drgbdx; -#endif - #define INTERP_Z #define INTERP_RGB #define SAR_RND_TO_ZERO(v,n) (v / (1<> ZB_POINT_Z_FRAC_BITS; \ - if (ZCMP(zz,pz[_a])) { \ - pp[3 * _a]=or1 >> 8;\ - pp[3 * _a + 1]=og1 >> 8;\ - pp[3 * _a + 2]=ob1 >> 8;\ - pz[_a]=zz; \ - }\ - z+=dzdx; \ - og1+=dgdx; \ - or1+=drdx; \ - ob1+=dbdx; \ -} - -#elif TGL_FEATURE_RENDER_BITS == 16 - -#define DRAW_INIT() \ -{ \ - _drgbdx=(SAR_RND_TO_ZERO(drdx,6) << 22) & 0xFFC00000; \ - _drgbdx|=SAR_RND_TO_ZERO(dgdx,5) & 0x000007FF; \ - _drgbdx|=(SAR_RND_TO_ZERO(dbdx,7) << 12) & 0x001FF000; \ -} - - -#define PUT_PIXEL(_a) \ -{ \ - zz=z >> ZB_POINT_Z_FRAC_BITS; \ - if (ZCMP(zz,pz[_a])) { \ - tmp=rgb & 0xF81F07E0; \ - pp[_a]=tmp | (tmp >> 16); \ - pz[_a]=zz; \ - } \ - z+=dzdx; \ - rgb=(rgb+drgbdx) & ( ~ 0x00200800); \ -} - -#define DRAW_LINE() \ -{ \ - register unsigned short *pz; \ - register PIXEL *pp; \ - register unsigned int tmp,z,zz,rgb,drgbdx; \ - register int n; \ - n=(x2 >> 16) - x1; \ - pp=pp1+x1; \ - pz=pz1+x1; \ - z=z1; \ - rgb=(r1 << 16) & 0xFFC00000; \ - rgb|=(g1 >> 5) & 0x000007FF; \ - rgb|=(b1 << 5) & 0x001FF000; \ - drgbdx=_drgbdx; \ - while (n>=3) { \ - PUT_PIXEL(0); \ - PUT_PIXEL(1); \ - PUT_PIXEL(2); \ - PUT_PIXEL(3); \ - pz+=4; \ - pp+=4; \ - n-=4; \ - } \ - while (n>=0) { \ - PUT_PIXEL(0); \ - pz+=1; \ - pp+=1; \ - n-=1; \ - } \ -} - -#else - #define DRAW_INIT() \ { \ } @@ -166,8 +58,6 @@ void ZB_fillTriangleSmooth(ZBuffer *zb, ob1+=dbdx; \ } -#endif /* TGL_FEATURE_RENDER_BITS */ - #include "ztriangle.h" } @@ -189,26 +79,6 @@ void ZB_fillTriangleMapping(ZBuffer *zb, texture=zb->current_texture; \ } -#if TGL_FEATURE_RENDER_BITS == 24 - -#define PUT_PIXEL(_a) \ -{ \ - unsigned char *ptr;\ - zz=z >> ZB_POINT_Z_FRAC_BITS; \ - if (ZCMP(zz,pz[_a])) { \ - ptr = texture + (((t & 0x3FC00000) | s) >> 14) * 3; \ - pp[3 * _a]= ptr[0];\ - pp[3 * _a + 1]= ptr[1];\ - pp[3 * _a + 2]= ptr[2];\ - pz[_a]=zz; \ - } \ - z+=dzdx; \ - s+=dsdx; \ - t+=dtdx; \ -} - -#else - #define PUT_PIXEL(_a) \ { \ zz=z >> ZB_POINT_Z_FRAC_BITS; \ @@ -221,8 +91,6 @@ void ZB_fillTriangleMapping(ZBuffer *zb, t+=dtdx; \ } -#endif - #include "ztriangle.h" } @@ -231,8 +99,6 @@ void ZB_fillTriangleMapping(ZBuffer *zb, * We use the gradient method to make less divisions. * TODO: pipeline the division */ -#if 1 - void ZB_fillTriangleMappingPerspective(ZBuffer *zb, ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2) { @@ -254,26 +120,6 @@ void ZB_fillTriangleMappingPerspective(ZBuffer *zb, } -#if TGL_FEATURE_RENDER_BITS == 24 - -#define PUT_PIXEL(_a) \ -{ \ - unsigned char *ptr;\ - zz=z >> ZB_POINT_Z_FRAC_BITS; \ - if (ZCMP(zz,pz[_a])) { \ - ptr = texture + (((t & 0x3FC00000) | (s & 0x003FC000)) >> 14) * 3;\ - pp[3 * _a]= ptr[0];\ - pp[3 * _a + 1]= ptr[1];\ - pp[3 * _a + 2]= ptr[2];\ - pz[_a]=zz; \ - } \ - z+=dzdx; \ - s+=dsdx; \ - t+=dtdx; \ -} - -#else - #define PUT_PIXEL(_a) \ { \ zz=z >> ZB_POINT_Z_FRAC_BITS; \ @@ -287,8 +133,6 @@ void ZB_fillTriangleMappingPerspective(ZBuffer *zb, t+=dtdx; \ } -#endif - #define DRAW_LINE() \ { \ register unsigned short *pz; \ @@ -350,45 +194,111 @@ void ZB_fillTriangleMappingPerspective(ZBuffer *zb, #include "ztriangle.h" } -#endif +/* + * Smooth filled triangle, with perspective-correct mapping. + */ -#if 0 - -/* slow but exact version (only there for reference, incorrect for 24 - bits) */ - -void ZB_fillTriangleMappingPerspective(ZBuffer *zb, - ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2) +void ZB_fillTriangleMappingSmooth(ZBuffer *zb, + ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2) { PIXEL *texture; + float fdzdx,fndzdx,ndszdx,ndtzdx; #define INTERP_Z #define INTERP_STZ +#define INTERP_RGB -#define DRAW_INIT() \ +#define SAR_RND_TO_ZERO(v,n) (v / (1<current_texture; \ + texture=zb->current_texture;\ + fdzdx=(float)dzdx;\ + fndzdx=NB_INTERP * fdzdx;\ + ndszdx=NB_INTERP * dszdx;\ + ndtzdx=NB_INTERP * dtzdx;\ } #define PUT_PIXEL(_a) \ { \ - float zinv; \ - int s,t; \ - zz=z >> ZB_POINT_Z_FRAC_BITS; \ - if (ZCMP(zz,pz[_a])) { \ - zinv= 1.0 / (float) z; \ - s= (int) (sz * zinv); \ - t= (int) (tz * zinv); \ - pp[_a]=texture[((t & 0x3FC00000) | s) >> 14]; \ - pz[_a]=zz; \ - } \ + zz=z >> ZB_POINT_Z_FRAC_BITS; \ + if (ZCMP(zz,pz[_a])) { \ + tmp=*(PIXEL *)((char *)texture+ \ + (((t & 0x3FC00000) | (s & 0x003FC000)) >> (17 - PSZSH))); \ + pp[_a] = RGB_TO_PIXEL(or1 * PIXEL_R(tmp) >> 16, \ + og1 * PIXEL_G(tmp) >> 16, \ + ob1 * PIXEL_B(tmp) >> 16); \ + pz[_a]=zz; \ + }\ z+=dzdx; \ - sz+=dszdx; \ - tz+=dtzdx; \ + og1+=dgdx; \ + or1+=drdx; \ + ob1+=dbdx; \ + s+=dsdx; \ + t+=dtdx; \ +} + +#define DRAW_LINE() \ +{ \ + register unsigned short *pz; \ + register PIXEL *pp; \ + register unsigned int s,t,z,zz; \ + register int n,dsdx,dtdx; \ + register unsigned int or1,og1,ob1; \ + float sz,tz,fz,zinv; \ + n=(x2>>16)-x1; \ + fz=(float)z1;\ + zinv=1.0 / fz;\ + pp=(PIXEL *)((char *)pp1 + x1 * PSZB); \ + pz=pz1+x1; \ + z=z1; \ + sz=sz1;\ + tz=tz1;\ + or1 = r1;\ + og1 = g1;\ + ob1 = b1;\ + while (n>=(NB_INTERP-1)) { \ + {\ + float ss,tt;\ + ss=(sz * zinv);\ + tt=(tz * zinv);\ + s=(int) ss;\ + t=(int) tt;\ + dsdx= (int)( (dszdx - ss*fdzdx)*zinv );\ + dtdx= (int)( (dtzdx - tt*fdzdx)*zinv );\ + fz+=fndzdx;\ + zinv=1.0 / fz;\ + }\ + PUT_PIXEL(0); \ + PUT_PIXEL(1); \ + PUT_PIXEL(2); \ + PUT_PIXEL(3); \ + PUT_PIXEL(4); \ + PUT_PIXEL(5); \ + PUT_PIXEL(6); \ + PUT_PIXEL(7); \ + pz+=NB_INTERP; \ + pp=(PIXEL *)((char *)pp + NB_INTERP * PSZB);\ + n-=NB_INTERP; \ + sz+=ndszdx;\ + tz+=ndtzdx;\ + } \ + {\ + float ss,tt;\ + ss=(sz * zinv);\ + tt=(tz * zinv);\ + s=(int) ss;\ + t=(int) tt;\ + dsdx= (int)( (dszdx - ss*fdzdx)*zinv );\ + dtdx= (int)( (dtzdx - tt*fdzdx)*zinv );\ + }\ + while (n>=0) { \ + PUT_PIXEL(0); \ + pz+=1; \ + pp=(PIXEL *)((char *)pp + PSZB);\ + n-=1; \ + } \ } #include "ztriangle.h" } - - -#endif