shithub: tinygl

Download patch

ref: d29ae2940e7f7145c6f36426647e5cf462cfeae6
parent: 522b4cd3a8ecf8bd0833a7d41daa408c6493829f
author: David <gek@katherine>
date: Wed Feb 24 04:49:51 EST 2021

Performance fix

--- a/config.mk
+++ b/config.mk
@@ -4,7 +4,7 @@
 CC= gcc
 #CFLAGS= -Wall -w -O3 -g -std=c99 -mtune=native -DNDEBUG
 #CFLAGS= -Wall -w -O3 -g -std=c99 -march=native -DNDEBUG
-CFLAGS= -Wall -w -O3 -g -std=c99 -DNDEBUG
+CFLAGS= -Wall -O3 -g -std=c99 -DNDEBUG
 #CFLAGS= -Wall -O1 -g -std=c99 -Wno-undef -DNDEBUG
 LFLAGS=
 
--- a/src/clip.c
+++ b/src/clip.c
@@ -10,8 +10,48 @@
 #define CLIP_ZMIN (1 << 4)
 #define CLIP_ZMAX (1 << 5)
 
+static inline void gl_transform_to_viewport_clip_c(GLContext* c, GLVertex* v) { //MARK: NOT_INLINED_IN_OG
 
+	/* coordinates */
+	{
+		GLfloat winv = 1.0 / v->pc.W;
+		v->zp.x = (GLint)(v->pc.X * winv * c->viewport.scale.X + c->viewport.trans.X);
+		v->zp.y = (GLint)(v->pc.Y * winv * c->viewport.scale.Y + c->viewport.trans.Y);
+		v->zp.z = (GLint)(v->pc.Z * winv * c->viewport.scale.Z + c->viewport.trans.Z);
+	}
+	/* color */
+	v->zp.r = (GLuint)(v->color.v[0] * COLOR_CORRECTED_MULT_MASK + COLOR_MIN_MULT) & COLOR_MASK;
+	v->zp.g = (GLuint)(v->color.v[1] * COLOR_CORRECTED_MULT_MASK + COLOR_MIN_MULT) & COLOR_MASK;
+	v->zp.b = (GLuint)(v->color.v[2] * COLOR_CORRECTED_MULT_MASK + COLOR_MIN_MULT) & COLOR_MASK;
 
+	/* texture */
+
+	if (c->texture_2d_enabled) {
+		v->zp.s = (GLint)(v->tex_coord.X * (ZB_POINT_S_MAX - ZB_POINT_S_MIN) + ZB_POINT_S_MIN); //MARKED
+		v->zp.t = (GLint)(v->tex_coord.Y * (ZB_POINT_T_MAX - ZB_POINT_T_MIN) + ZB_POINT_T_MIN); //MARKED
+	}
+}
+
+/*
+//MARK <POSSIBLE_PERF_BONUS>
+#define clip_func(name, sign, dir, dir1, dir2) GLfloat name(V4* c, V4* a, V4* b);
+//MARK <POSSIBLE_PERF_BONUS>
+clip_func(clip_xmin, -, X, Y, Z)
+
+	clip_func(clip_xmax, +, X, Y, Z)
+
+		clip_func(clip_ymin, -, Y, X, Z)
+
+			clip_func(clip_ymax, +, Y, X, Z)
+//MARK <POSSIBLE_PERF_BONUS>
+				clip_func(clip_zmin, -, Z, X, Y)
+
+					clip_func(clip_zmax, +, Z, X, Y)
+
+extern GLfloat (*clip_proc[6])(V4*, V4*, V4*);// = {clip_xmin, clip_xmax, clip_ymin, clip_ymax, clip_zmin, clip_zmax};
+
+*/
+
 #define clip_funcdef(name, sign, dir, dir1, dir2)                                                                                                                 \
 	GLfloat name(V4* c, V4* a, V4* b) {                                                                                                                 \
 		GLfloat t, dX, dY, dZ, dW, den;                                                                                                                        \
@@ -45,9 +85,32 @@
 
 GLfloat (*clip_proc[6])(V4*, V4*, V4*) = {clip_xmin, clip_xmax, clip_ymin, clip_ymax, clip_zmin, clip_zmax};
 /* point */
+static void gl_add_select1(GLContext* c, GLint z1, GLint z2, GLint z3) {
+	GLint min, max;
+	min = max = z1;
+	if (z2 < min)
+		min = z2;
+	if (z3 < min)
+		min = z3;
+	if (z2 > max)
+		max = z2;
+	if (z3 > max)
+		max = z3;
 
+	gl_add_select(c, 0xffffffff - min, 0xffffffff - max);
+}
+void gl_draw_point(GLContext* c, GLVertex* p0) {
+	if (p0->clip_code == 0) {
+		if (c->render_mode == GL_SELECT) {
+			gl_add_select(c, p0->zp.z, p0->zp.z);
+		}else if (c->render_mode == GL_FEEDBACK){
+			gl_add_feedback(c,GL_POINT_TOKEN,p0,NULL,NULL,0);
+		} else {
+			ZB_plot(c->zb, &p0->zp);
+		}
+	}
+}
 
-
 /* line */
 //Used only for lines.
 
@@ -56,8 +119,276 @@
  * Line Clipping
  */
 
+
+
+
+
+
+static inline void GLinterpolate(GLVertex* q, GLVertex* p0, GLVertex* p1, GLfloat t) { //MARK: INLINED_IN_OG
+	q->pc.X = p0->pc.X + (p1->pc.X - p0->pc.X) * t;
+	q->pc.Y = p0->pc.Y + (p1->pc.Y - p0->pc.Y) * t;
+	q->pc.Z = p0->pc.Z + (p1->pc.Z - p0->pc.Z) * t;
+	q->pc.W = p0->pc.W + (p1->pc.W - p0->pc.W) * t;
+
+	for(int i = 0; i < 3; i++)
+		q->color.v[i] = p0->color.v[i] + (p1->color.v[i] - p0->color.v[i]) * t;
+}
+
 /* Line Clipping algorithm from 'Computer Graphics', Principles and
    Practice */
+static inline GLint ClipLine1(GLfloat denom, GLfloat num, GLfloat* tmin, GLfloat* tmax) {
+	GLfloat t;
+
+	if (denom > 0) {
+		t = num / denom;
+		if (t > *tmax)
+			return 0;
+		if (t > *tmin)
+			*tmin = t;
+	} else if (denom < 0) {
+		t = num / denom;
+		if (t < *tmin)
+			return 0;
+		if (t < *tmax)
+			*tmax = t;
+	} else if (num > 0)
+		return 0;
+	return 1;
+}
+void gl_draw_line(GLContext* c, GLVertex* p1, GLVertex* p2) {
+	GLfloat dx, dy, dz, dw, x1, y1, z1, w1;
+	
+	GLVertex q1, q2;
+	GLint cc1, cc2;
+
+	cc1 = p1->clip_code;
+	cc2 = p2->clip_code;
+
+	if ((cc1 | cc2) == 0) {
+		if (c->render_mode == GL_SELECT) {
+			gl_add_select1(c, p1->zp.z, p2->zp.z, p2->zp.z);
+		}else if (c->render_mode == GL_FEEDBACK){
+			gl_add_feedback(
+				c,	GL_LINE_TOKEN,
+				p1,
+				p2,
+				NULL,
+				0
+			);
+		} else {
+			if (c->zb->depth_test)
+				ZB_line_z(c->zb, &p1->zp, &p2->zp);
+			else
+				ZB_line(c->zb, &p1->zp, &p2->zp);
+		}
+	} else if ((cc1 & cc2) != 0) {
+		return;
+	} else {
+		dx = p2->pc.X - p1->pc.X;
+		dy = p2->pc.Y - p1->pc.Y;
+		dz = p2->pc.Z - p1->pc.Z;
+		dw = p2->pc.W - p1->pc.W;
+		x1 = p1->pc.X;
+		y1 = p1->pc.Y;
+		z1 = p1->pc.Z;
+		w1 = p1->pc.W;
+
+		GLfloat tmin = 0;
+		GLfloat tmax = 1;
+		if (ClipLine1(dx + dw, -x1 - w1, &tmin, &tmax) && ClipLine1(-dx + dw, x1 - w1, &tmin, &tmax) && ClipLine1(dy + dw, -y1 - w1, &tmin, &tmax) &&
+			ClipLine1(-dy + dw, y1 - w1, &tmin, &tmax) && ClipLine1(dz + dw, -z1 - w1, &tmin, &tmax) && ClipLine1(-dz + dw, z1 - w1, &tmin, &tmax)) {
+
+			GLinterpolate(&q1, p1, p2, tmin);
+			GLinterpolate(&q2, p1, p2, tmax);
+			gl_transform_to_viewport_clip_c(c, &q1);
+			gl_transform_to_viewport_clip_c(c, &q2);
+
+			if (c->zb->depth_test)
+				ZB_line_z(c->zb, &q1.zp, &q2.zp);
+			else
+				ZB_line(c->zb, &q1.zp, &q2.zp);
+		}
+	}
+}
+
+//inline void gl_draw_point(GLContext* c, GLVertex* p0);
+
+
+/*Triangles*/
+
+static inline void updateTmp(GLContext* c, GLVertex* q, GLVertex* p0, GLVertex* p1, GLfloat t) { //MARK: INLINED_IN_OG
+	{
+
+
+		q->color.v[0] = p0->color.v[0] + (p1->color.v[0] - p0->color.v[0]) * t;
+		q->color.v[1] = p0->color.v[1] + (p1->color.v[1] - p0->color.v[1]) * t;
+		q->color.v[2] = p0->color.v[2] + (p1->color.v[2] - p0->color.v[2]) * t;
+	}
+	//	*/
+	if (c->texture_2d_enabled) {
+		q->tex_coord.X = p0->tex_coord.X + (p1->tex_coord.X - p0->tex_coord.X) * t;
+		q->tex_coord.Y = p0->tex_coord.Y + (p1->tex_coord.Y - p0->tex_coord.Y) * t;
+	}
+
+	q->clip_code = gl_clipcode(q->pc.X, q->pc.Y, q->pc.Z, q->pc.W);
+	if (q->clip_code == 0)
+		gl_transform_to_viewport_clip_c(c, q);
+}
+//DO NOT INLINE!!! DO NOT INLINE!!! DO NOT INLINE!!!
+static void gl_draw_triangle_clip(GLContext* c, GLVertex* p0, GLVertex* p1, GLVertex* p2, GLint clip_bit);//MARK: NOT_INLINED_IN_OG
+
+void gl_draw_triangle(GLContext* c, GLVertex* p0, GLVertex* p1, GLVertex* p2) {
+	GLint co, cc[3], front;
+	
+
+	cc[0] = p0->clip_code;
+	cc[1] = p1->clip_code;
+	cc[2] = p2->clip_code;
+
+	co = cc[0] | cc[1] | cc[2];
+
+	/* we handle the non clipped case here to go faster */
+	if (co == 0) {
+		GLfloat norm;
+		norm = (GLfloat)(p1->zp.x - p0->zp.x) * (GLfloat)(p2->zp.y - p0->zp.y) - (GLfloat)(p2->zp.x - p0->zp.x) * (GLfloat)(p1->zp.y - p0->zp.y);
+
+		if (norm == 0) //MARK <POSSIBLE_PERF_BONUS>
+			return;
+
+		front = norm < 0.0;
+		front = front ^ c->current_front_face; //I don't know how this works, but it does, GL_CCW is 0x901 and CW is 900.
+
+		/* back face culling */
+		if (c->cull_face_enabled) {
+			/* most used case first */
+			if (c->current_cull_face == GL_BACK) {
+				if (front == 0)
+					return;
+				c->draw_triangle_front(c, p0, p1, p2);
+			} else if (c->current_cull_face == GL_FRONT) {
+				if (front != 0)
+					return;
+				c->draw_triangle_back(c, p0, p1, p2);
+			} else {
+				return;
+			}
+		} else {
+			/* no culling */
+			if (front) {
+				c->draw_triangle_front(c, p0, p1, p2);
+			} else {
+				c->draw_triangle_back(c, p0, p1, p2);
+			}
+		}
+	} else {
+		//GLint c_and = cc[0] & cc[1] & cc[2];
+		if ((cc[0] & cc[1] & cc[2]) == 0) { // Don't draw a triangle with no points
+			gl_draw_triangle_clip(c, p0, p1, p2, 0);
+		}
+	}
+}
+
+
+static void gl_draw_triangle_clip(GLContext* c, GLVertex* p0, GLVertex* p1, GLVertex* p2, GLint clip_bit) {
+	GLint co, c_and, co1, cc[3], edge_flag_tmp, clip_mask;
+	//GLVertex tmp1, tmp2, *q[3];
+	GLVertex *q[3];
+
+
+	cc[0] = p0->clip_code;
+	cc[1] = p1->clip_code;
+	cc[2] = p2->clip_code;
+
+	co = cc[0] | cc[1] | cc[2];
+	if (co == 0) {
+		gl_draw_triangle(c, p0, p1, p2);
+	} else {
+		
+		c_and = cc[0] & cc[1] & cc[2];
+		/* the triangle is completely outside */
+		if (c_and != 0)
+			return;
+
+		/* find the next direction to clip */
+		while (clip_bit < 6 && (co & (1 << clip_bit)) == 0) {
+			clip_bit++;
+		}
+
+		/* this test can be true only in case of rounding errors */
+		if (clip_bit == 6) { //The 2 bit and the 4 bit.
+#if 0
+      tgl_warning("Error:\n");tgl_warning("%f %f %f %f\n",p0->pc.X,p0->pc.Y,p0->pc.Z,p0->pc.W);tgl_warning("%f %f %f %f\n",p1->pc.X,p1->pc.Y,p1->pc.Z,p1->pc.W);tgl_warning("%f %f %f %f\n",p2->pc.X,p2->pc.Y,p2->pc.Z,p2->pc.W);
+#endif
+			return;
+		}
+
+		clip_mask = 1 << clip_bit;
+		co1 = (cc[0] ^ cc[1] ^ cc[2]) & clip_mask;
+
+		if (co1) {
+			/* one point outside */
+			
+			if (cc[0] & clip_mask) {
+				q[0] = p0;
+				q[1] = p1;
+				q[2] = p2;
+			} else if (cc[1] & clip_mask) {
+				q[0] = p1;
+				q[1] = p2;
+				q[2] = p0;
+			} else {
+				q[0] = p2;
+				q[1] = p0;
+				q[2] = p1;
+			}
+			{GLVertex tmp1, tmp2;GLfloat tt;
+				tt = clip_proc[clip_bit](&tmp1.pc, &q[0]->pc, &q[1]->pc);
+				updateTmp(c, &tmp1, q[0], q[1], tt);
+
+				tt = clip_proc[clip_bit](&tmp2.pc, &q[0]->pc, &q[2]->pc);
+				updateTmp(c, &tmp2, q[0], q[2], tt);
+
+				tmp1.edge_flag = q[0]->edge_flag;
+				edge_flag_tmp = q[2]->edge_flag;
+				q[2]->edge_flag = 0;
+				gl_draw_triangle_clip(c, &tmp1, q[1], q[2], clip_bit + 1);
+
+				tmp2.edge_flag = 1;
+				tmp1.edge_flag = 0;
+				q[2]->edge_flag = edge_flag_tmp;
+				gl_draw_triangle_clip(c, &tmp2, &tmp1, q[2], clip_bit + 1);
+			}
+		} else {
+			/* two points outside */
+			
+			if ((cc[0] & clip_mask) == 0) {
+				q[0] = p0;
+				q[1] = p1;
+				q[2] = p2;
+			} else if ((cc[1] & clip_mask) == 0) {
+				q[0] = p1;
+				q[1] = p2;
+				q[2] = p0;
+			} else {
+				q[0] = p2;
+				q[1] = p0;
+				q[2] = p1;
+			}
+			{GLVertex tmp1, tmp2;GLfloat tt;
+				tt = clip_proc[clip_bit](&tmp1.pc, &q[0]->pc, &q[1]->pc);
+				updateTmp(c, &tmp1, q[0], q[1], tt);
+
+				tt = clip_proc[clip_bit](&tmp2.pc, &q[0]->pc, &q[2]->pc);
+				updateTmp(c, &tmp2, q[0], q[2], tt);
+
+				tmp1.edge_flag = 1;
+				tmp2.edge_flag = q[2]->edge_flag;
+				gl_draw_triangle_clip(c, q[0], &tmp1, &tmp2, clip_bit + 1);
+			}
+		}
+	}
+}
+
 
 
 
--- a/src/vertex.c
+++ b/src/vertex.c
@@ -133,7 +133,7 @@
 		}
 	}
 }
-/*
+
 static inline void gl_transform_to_viewport_vertex_c(GLContext* c, GLVertex* v) {
 
 	
@@ -155,7 +155,7 @@
 		v->zp.t = (GLint)(v->tex_coord.Y * (ZB_POINT_T_MAX - ZB_POINT_T_MIN) + ZB_POINT_T_MIN); //MARKED
 	}
 }
-*/
+
 static inline void gl_vertex_transform(GLContext* c, GLVertex* v) {
 	GLfloat* m;
 	
@@ -274,7 +274,7 @@
 	}
 	/* precompute the mapping to the viewport */
 	if (v->clip_code == 0)
-		gl_transform_to_viewport_clip_c(c, v);
+		gl_transform_to_viewport_vertex_c(c, v);
 
 	/* edge flag */
 	v->edge_flag = c->current_edge_flag;
--- a/src/zgl.h
+++ b/src/zgl.h
@@ -387,27 +387,7 @@
 		return a;
 }
 
-static inline void gl_transform_to_viewport_clip_c(GLContext* c, GLVertex* v) {
 
-	/* coordinates */
-	{
-		GLfloat winv = 1.0 / v->pc.W;
-		v->zp.x = (GLint)(v->pc.X * winv * c->viewport.scale.X + c->viewport.trans.X);
-		v->zp.y = (GLint)(v->pc.Y * winv * c->viewport.scale.Y + c->viewport.trans.Y);
-		v->zp.z = (GLint)(v->pc.Z * winv * c->viewport.scale.Z + c->viewport.trans.Z);
-	}
-	/* color */
-	v->zp.r = (GLuint)(v->color.v[0] * COLOR_CORRECTED_MULT_MASK + COLOR_MIN_MULT) & COLOR_MASK;
-	v->zp.g = (GLuint)(v->color.v[1] * COLOR_CORRECTED_MULT_MASK + COLOR_MIN_MULT) & COLOR_MASK;
-	v->zp.b = (GLuint)(v->color.v[2] * COLOR_CORRECTED_MULT_MASK + COLOR_MIN_MULT) & COLOR_MASK;
-
-	/* texture */
-
-	if (c->texture_2d_enabled) {
-		v->zp.s = (GLint)(v->tex_coord.X * (ZB_POINT_S_MAX - ZB_POINT_S_MIN) + ZB_POINT_S_MIN); //MARKED
-		v->zp.t = (GLint)(v->tex_coord.Y * (ZB_POINT_T_MAX - ZB_POINT_T_MIN) + ZB_POINT_T_MIN); //MARKED
-	}
-}
 //void gl_transform_to_viewport(GLContext* c, GLVertex* v);
 //inline void gl_draw_triangle(GLContext* c, GLVertex* p0, GLVertex* p1, GLVertex* p2);
 
@@ -421,309 +401,15 @@
  * We compute the point 'c' of GLintersection and the value of the parameter 't'
  * of the GLintersection if x=a+t(b-a).
  */
-//MARK <POSSIBLE_PERF_BONUS>
-#define clip_func(name, sign, dir, dir1, dir2) GLfloat name(V4* c, V4* a, V4* b);
-//MARK <POSSIBLE_PERF_BONUS>
-clip_func(clip_xmin, -, X, Y, Z)
 
-	clip_func(clip_xmax, +, X, Y, Z)
 
-		clip_func(clip_ymin, -, Y, X, Z)
 
-			clip_func(clip_ymax, +, Y, X, Z)
-//MARK <POSSIBLE_PERF_BONUS>
-				clip_func(clip_zmin, -, Z, X, Y)
-
-					clip_func(clip_zmax, +, Z, X, Y)
-
-extern GLfloat (*clip_proc[6])(V4*, V4*, V4*);// = {clip_xmin, clip_xmax, clip_ymin, clip_ymax, clip_zmin, clip_zmax};
-
-static inline void updateTmp(GLContext* c, GLVertex* q, GLVertex* p0, GLVertex* p1, GLfloat t) {
-	{
-
-
-		q->color.v[0] = p0->color.v[0] + (p1->color.v[0] - p0->color.v[0]) * t;
-		q->color.v[1] = p0->color.v[1] + (p1->color.v[1] - p0->color.v[1]) * t;
-		q->color.v[2] = p0->color.v[2] + (p1->color.v[2] - p0->color.v[2]) * t;
-	}
-	//	*/
-	if (c->texture_2d_enabled) {
-		q->tex_coord.X = p0->tex_coord.X + (p1->tex_coord.X - p0->tex_coord.X) * t;
-		q->tex_coord.Y = p0->tex_coord.Y + (p1->tex_coord.Y - p0->tex_coord.Y) * t;
-	}
-
-	q->clip_code = gl_clipcode(q->pc.X, q->pc.Y, q->pc.Z, q->pc.W);
-	if (q->clip_code == 0)
-		gl_transform_to_viewport_clip_c(c, q);
-}
-
 //inline void gl_draw_triangle_clip(GLContext* c, GLVertex* p0, GLVertex* p1, GLVertex* p2, GLint clip_bit);
 
-static inline void gl_draw_triangle_clip(GLContext* c, GLVertex* p0, GLVertex* p1, GLVertex* p2, GLint clip_bit);
+void gl_draw_triangle(GLContext* c, GLVertex* p0, GLVertex* p1, GLVertex* p2);
+void gl_draw_line(GLContext* c, GLVertex* p0, GLVertex* p1);
+void gl_draw_point(GLContext* c, GLVertex* p0);
 
-static inline void gl_draw_triangle(GLContext* c, GLVertex* p0, GLVertex* p1, GLVertex* p2) {
-	GLint co, cc[3], front;
-	
-
-	cc[0] = p0->clip_code;
-	cc[1] = p1->clip_code;
-	cc[2] = p2->clip_code;
-
-	co = cc[0] | cc[1] | cc[2];
-
-	/* we handle the non clipped case here to go faster */
-	if (co == 0) {
-		GLfloat norm;
-		norm = (GLfloat)(p1->zp.x - p0->zp.x) * (GLfloat)(p2->zp.y - p0->zp.y) - (GLfloat)(p2->zp.x - p0->zp.x) * (GLfloat)(p1->zp.y - p0->zp.y);
-
-		if (norm == 0) //MARK <POSSIBLE_PERF_BONUS>
-			return;
-
-		front = norm < 0.0;
-		front = front ^ c->current_front_face; //I don't know how this works, but it does, GL_CCW is 0x901 and CW is 900.
-
-		/* back face culling */
-		if (c->cull_face_enabled) {
-			/* most used case first */
-			if (c->current_cull_face == GL_BACK) {
-				if (front == 0)
-					return;
-				c->draw_triangle_front(c, p0, p1, p2);
-			} else if (c->current_cull_face == GL_FRONT) {
-				if (front != 0)
-					return;
-				c->draw_triangle_back(c, p0, p1, p2);
-			} else {
-				return;
-			}
-		} else {
-			/* no culling */
-			if (front) {
-				c->draw_triangle_front(c, p0, p1, p2);
-			} else {
-				c->draw_triangle_back(c, p0, p1, p2);
-			}
-		}
-	} else {
-		//GLint c_and = cc[0] & cc[1] & cc[2];
-		if ((cc[0] & cc[1] & cc[2]) == 0) { // Don't draw a triangle with no points
-			gl_draw_triangle_clip(c, p0, p1, p2, 0);
-		}
-	}
-}
-
-
-static inline void gl_draw_triangle_clip(GLContext* c, GLVertex* p0, GLVertex* p1, GLVertex* p2, GLint clip_bit) {
-	GLint co, c_and, co1, cc[3], edge_flag_tmp, clip_mask;
-	//GLVertex tmp1, tmp2, *q[3];
-	GLVertex *q[3];
-
-
-	cc[0] = p0->clip_code;
-	cc[1] = p1->clip_code;
-	cc[2] = p2->clip_code;
-
-	co = cc[0] | cc[1] | cc[2];
-	if (co == 0) {
-		gl_draw_triangle(c, p0, p1, p2);
-	} else {
-		
-		c_and = cc[0] & cc[1] & cc[2];
-		/* the triangle is completely outside */
-		if (c_and != 0)
-			return;
-
-		/* find the next direction to clip */
-		while (clip_bit < 6 && (co & (1 << clip_bit)) == 0) {
-			clip_bit++;
-		}
-
-		/* this test can be true only in case of rounding errors */
-		if (clip_bit == 6) { //The 2 bit and the 4 bit.
-#if 0
-      tgl_warning("Error:\n");tgl_warning("%f %f %f %f\n",p0->pc.X,p0->pc.Y,p0->pc.Z,p0->pc.W);tgl_warning("%f %f %f %f\n",p1->pc.X,p1->pc.Y,p1->pc.Z,p1->pc.W);tgl_warning("%f %f %f %f\n",p2->pc.X,p2->pc.Y,p2->pc.Z,p2->pc.W);
-#endif
-			return;
-		}
-
-		clip_mask = 1 << clip_bit;
-		co1 = (cc[0] ^ cc[1] ^ cc[2]) & clip_mask;
-
-		if (co1) {
-			/* one point outside */
-			
-			if (cc[0] & clip_mask) {
-				q[0] = p0;
-				q[1] = p1;
-				q[2] = p2;
-			} else if (cc[1] & clip_mask) {
-				q[0] = p1;
-				q[1] = p2;
-				q[2] = p0;
-			} else {
-				q[0] = p2;
-				q[1] = p0;
-				q[2] = p1;
-			}
-			{GLVertex tmp1, tmp2;GLfloat tt;
-				tt = clip_proc[clip_bit](&tmp1.pc, &q[0]->pc, &q[1]->pc);
-				updateTmp(c, &tmp1, q[0], q[1], tt);
-
-				tt = clip_proc[clip_bit](&tmp2.pc, &q[0]->pc, &q[2]->pc);
-				updateTmp(c, &tmp2, q[0], q[2], tt);
-
-				tmp1.edge_flag = q[0]->edge_flag;
-				edge_flag_tmp = q[2]->edge_flag;
-				q[2]->edge_flag = 0;
-				gl_draw_triangle_clip(c, &tmp1, q[1], q[2], clip_bit + 1);
-
-				tmp2.edge_flag = 1;
-				tmp1.edge_flag = 0;
-				q[2]->edge_flag = edge_flag_tmp;
-				gl_draw_triangle_clip(c, &tmp2, &tmp1, q[2], clip_bit + 1);
-			}
-		} else {
-			/* two points outside */
-			
-			if ((cc[0] & clip_mask) == 0) {
-				q[0] = p0;
-				q[1] = p1;
-				q[2] = p2;
-			} else if ((cc[1] & clip_mask) == 0) {
-				q[0] = p1;
-				q[1] = p2;
-				q[2] = p0;
-			} else {
-				q[0] = p2;
-				q[1] = p0;
-				q[2] = p1;
-			}
-			{GLVertex tmp1, tmp2;GLfloat tt;
-				tt = clip_proc[clip_bit](&tmp1.pc, &q[0]->pc, &q[1]->pc);
-				updateTmp(c, &tmp1, q[0], q[1], tt);
-
-				tt = clip_proc[clip_bit](&tmp2.pc, &q[0]->pc, &q[2]->pc);
-				updateTmp(c, &tmp2, q[0], q[2], tt);
-
-				tmp1.edge_flag = 1;
-				tmp2.edge_flag = q[2]->edge_flag;
-				gl_draw_triangle_clip(c, q[0], &tmp1, &tmp2, clip_bit + 1);
-			}
-		}
-	}
-}
-
-//inline void gl_draw_line(GLContext* c, GLVertex* p0, GLVertex* p1);
-static inline void gl_add_select1(GLContext* c, GLint z1, GLint z2, GLint z3) {
-	GLint min, max;
-	min = max = z1;
-	if (z2 < min)
-		min = z2;
-	if (z3 < min)
-		min = z3;
-	if (z2 > max)
-		max = z2;
-	if (z3 > max)
-		max = z3;
-
-	gl_add_select(c, 0xffffffff - min, 0xffffffff - max);
-}
-static inline void GLinterpolate(GLVertex* q, GLVertex* p0, GLVertex* p1, GLfloat t) {
-	q->pc.X = p0->pc.X + (p1->pc.X - p0->pc.X) * t;
-	q->pc.Y = p0->pc.Y + (p1->pc.Y - p0->pc.Y) * t;
-	q->pc.Z = p0->pc.Z + (p1->pc.Z - p0->pc.Z) * t;
-	q->pc.W = p0->pc.W + (p1->pc.W - p0->pc.W) * t;
-
-	for(int i = 0; i < 3; i++)
-		q->color.v[i] = p0->color.v[i] + (p1->color.v[i] - p0->color.v[i]) * t;
-}
-static inline GLint ClipLine1(GLfloat denom, GLfloat num, GLfloat* tmin, GLfloat* tmax) {
-	GLfloat t;
-
-	if (denom > 0) {
-		t = num / denom;
-		if (t > *tmax)
-			return 0;
-		if (t > *tmin)
-			*tmin = t;
-	} else if (denom < 0) {
-		t = num / denom;
-		if (t < *tmin)
-			return 0;
-		if (t < *tmax)
-			*tmax = t;
-	} else if (num > 0)
-		return 0;
-	return 1;
-}
-static inline void gl_draw_line(GLContext* c, GLVertex* p1, GLVertex* p2) {
-	GLfloat dx, dy, dz, dw, x1, y1, z1, w1;
-	
-	GLVertex q1, q2;
-	GLint cc1, cc2;
-
-	cc1 = p1->clip_code;
-	cc2 = p2->clip_code;
-
-	if ((cc1 | cc2) == 0) {
-		if (c->render_mode == GL_SELECT) {
-			gl_add_select1(c, p1->zp.z, p2->zp.z, p2->zp.z);
-		}else if (c->render_mode == GL_FEEDBACK){
-			gl_add_feedback(
-				c,	GL_LINE_TOKEN,
-				p1,
-				p2,
-				NULL,
-				0
-			);
-		} else {
-			if (c->zb->depth_test)
-				ZB_line_z(c->zb, &p1->zp, &p2->zp);
-			else
-				ZB_line(c->zb, &p1->zp, &p2->zp);
-		}
-	} else if ((cc1 & cc2) != 0) {
-		return;
-	} else {
-		dx = p2->pc.X - p1->pc.X;
-		dy = p2->pc.Y - p1->pc.Y;
-		dz = p2->pc.Z - p1->pc.Z;
-		dw = p2->pc.W - p1->pc.W;
-		x1 = p1->pc.X;
-		y1 = p1->pc.Y;
-		z1 = p1->pc.Z;
-		w1 = p1->pc.W;
-
-		GLfloat tmin = 0;
-		GLfloat tmax = 1;
-		if (ClipLine1(dx + dw, -x1 - w1, &tmin, &tmax) && ClipLine1(-dx + dw, x1 - w1, &tmin, &tmax) && ClipLine1(dy + dw, -y1 - w1, &tmin, &tmax) &&
-			ClipLine1(-dy + dw, y1 - w1, &tmin, &tmax) && ClipLine1(dz + dw, -z1 - w1, &tmin, &tmax) && ClipLine1(-dz + dw, z1 - w1, &tmin, &tmax)) {
-
-			GLinterpolate(&q1, p1, p2, tmin);
-			GLinterpolate(&q2, p1, p2, tmax);
-			gl_transform_to_viewport_clip_c(c, &q1);
-			gl_transform_to_viewport_clip_c(c, &q2);
-
-			if (c->zb->depth_test)
-				ZB_line_z(c->zb, &q1.zp, &q2.zp);
-			else
-				ZB_line(c->zb, &q1.zp, &q2.zp);
-		}
-	}
-}
-
-//inline void gl_draw_point(GLContext* c, GLVertex* p0);
-inline void gl_draw_point(GLContext* c, GLVertex* p0) {
-	if (p0->clip_code == 0) {
-		if (c->render_mode == GL_SELECT) {
-			gl_add_select(c, p0->zp.z, p0->zp.z);
-		}else if (c->render_mode == GL_FEEDBACK){
-			gl_add_feedback(c,GL_POINT_TOKEN,p0,NULL,NULL,0);
-		} else {
-			ZB_plot(c->zb, &p0->zp);
-		}
-	}
-}
 
 void gl_draw_triangle_point(GLContext* c, GLVertex* p0, GLVertex* p1, GLVertex* p2); //MUST BE FUNCTION POINTER
 void gl_draw_triangle_line(GLContext* c, GLVertex* p0, GLVertex* p1, GLVertex* p2); //MUST BE FUNCTION POINTER