ref: 36d0422a66ec59a4f61f91a7bb56855fb97017a6
parent: 03f5d05b72f0c07308b2eab32c0c904f63af5799
author: David <gek@katherine>
date: Sun Feb 21 10:21:53 EST 2021
Feedback implemented
--- a/include/GL/gl.h
+++ b/include/GL/gl.h
@@ -834,6 +834,10 @@
void glClearColor(GLfloat r,GLfloat g,GLfloat b,GLfloat a);
void glClearDepth(GLdouble depth);
+/* Feedback */
+void glFeedbackBuffer(GLint size, GLenum type, GLfloat* buf);
+void glPassThrough(GLfloat token);
+
/* selection */
GLint glRenderMode(GLint mode);
void glSelectBuffer(GLint size,GLuint *buf);
--- a/src/clip.c
+++ b/src/clip.c
@@ -53,6 +53,8 @@
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);
}
@@ -109,6 +111,14 @@
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);
@@ -364,6 +374,15 @@
//see vertex.c to see how the draw functions are assigned.
void gl_draw_triangle_select(GLContext* c, GLVertex* p0, GLVertex* p1, GLVertex* p2) {
gl_add_select1(c, p0->zp.z, p1->zp.z, p2->zp.z);
+}
+void gl_draw_triangle_feedback(GLContext* c, GLVertex* p0, GLVertex* p1, GLVertex* p2){
+ gl_add_feedback(
+ c, GL_POLYGON_TOKEN,
+ p0,
+ p1,
+ p2,
+ 0
+ );
}
#ifdef PROFILE
--- a/src/get.c
+++ b/src/get.c
@@ -171,6 +171,8 @@
"TGL_FEATURE_TINYGL_RUNTIME_COMPAT_TEST "
#endif
"TGL_BUFFER_EXT "
+"TGL_FEEDBACK "
+"TGL_SELECT "
"TGL_SOFTWARE_ACCELERATED";
const GLubyte* glGetString(GLenum name){
switch(name){
--- a/src/select.c
+++ b/src/select.c
@@ -1,5 +1,4 @@
#include "zgl.h"
-//Gek does not maintain or test this feature.
GLint glRenderMode(GLint mode) {
GLContext* c = gl_get_context();
@@ -6,8 +5,7 @@
GLint result = 0;
switch (c->render_mode) {
- case GL_RENDER:
- break;
+ case GL_RENDER:break;
case GL_SELECT:
if (c->select_overflow) {
result = -c->select_hits;
@@ -28,7 +26,7 @@
c->feedback_ptr = c->feedback_buffer;
break;
default:
- assert(0);
+ gl_fatal_error("GLContext's Rendermode was somehow erroneously set.");
}
switch (mode) {
case GL_RENDER:
@@ -35,8 +33,16 @@
c->render_mode = GL_RENDER;
break;
case GL_SELECT:
+
+#if TGL_FEATURE_ERROR_CHECK == 1
+ if(c->select_buffer == NULL)
+#define ERROR_FLAG GL_INVALID_OPERATION
+#define RETVAL 0
+#include "error_check.h"
+#else
+ if(c->select_buffer == NULL)return;
+#endif
c->render_mode = GL_SELECT;
- assert(c->select_buffer != NULL);
c->select_ptr = c->select_buffer;
c->select_hits = 0;
c->select_overflow = 0;
@@ -43,12 +49,28 @@
c->select_hit = NULL;
break;
case GL_FEEDBACK:
+#if TGL_FEATURE_ERROR_CHECK == 1
+ if(c->feedback_buffer == NULL)
+#define ERROR_FLAG GL_INVALID_OPERATION
+#define RETVAL 0
+#include "error_check.h"
+#else
+ if(c->feedback_buffer == NULL) return 0;
+#endif
c->render_mode = GL_FEEDBACK;
c->feedback_hits = 0;
c->feedback_ptr = c->feedback_buffer;
+ c->feedback_overflow = 0;
break;
default:
- assert(0);
+#if TGL_FEATURE_ERROR_CHECK == 1
+#define RETVAL 0
+#define ERROR_FLAG GL_INVALID_ENUM
+#include "error_check.h"
+
+#else
+ return 0;
+#endif
}
return result;
}
@@ -60,12 +82,165 @@
#define ERROR_FLAG GL_INVALID_OPERATION
#include "error_check.h"
#else
- assert(c->render_mode != GL_SELECT);
+ if(c->render_mode == GL_SELECT) return;
#endif
c->select_buffer = buf;
c->select_size = size;
}
+void glFeedbackBuffer(GLint size, GLenum type, GLfloat* buf){
+ GLContext* c = gl_get_context();
+#if TGL_FEATURE_ERROR_CHECK == 1
+ if(c->render_mode == GL_FEEDBACK ||
+ !(
+ type == GL_2D ||
+ type == GL_3D ||
+ type == GL_3D_COLOR ||
+ type == GL_3D_COLOR_TEXTURE ||
+ type == GL_4D_COLOR_TEXTURE
+ )
+ )
+#define ERROR_FLAG GL_INVALID_OPERATION
+#include "error_check.h"
+#else
+ if(c->render_mode == GL_FEEDBACK ||
+ !(
+ type == GL_2D ||
+ type == GL_3D ||
+ type == GL_3D_COLOR ||
+ type == GL_3D_COLOR_TEXTURE ||
+ type == GL_4D_COLOR_TEXTURE
+ )
+ )return;
+#endif
+ c->feedback_buffer = buf;
+ c->feedback_size = size;
+ c->feedback_type = type;
+}
+
+void gl_add_feedback(GLContext* c, GLfloat token,
+ GLVertex* v1,
+ GLVertex* v2,
+ GLVertex* v3,
+ GLfloat passthrough_token_value
+){
+ if(c->feedback_overflow) return;
+ GLuint feedback_hits_needed = 2;
+ GLuint vertex_feedback_hits_needed = 0;
+ GLuint vertex_pos_hits_needed = 2;
+ GLuint vertex_color_hits_needed = 4;
+ GLuint vertex_texture_hits_needed = 4;
+ GLuint done = 0;
+ switch(c->feedback_type){
+ case GL_2D: vertex_feedback_hits_needed = 2;
+ vertex_pos_hits_needed = 2;
+ vertex_color_hits_needed = 0;
+ vertex_texture_hits_needed = 0; break;
+ case GL_3D: vertex_feedback_hits_needed = 3;
+ vertex_pos_hits_needed = 3;
+ vertex_color_hits_needed = 0;
+ vertex_texture_hits_needed = 0; break;
+ case GL_3D_COLOR: vertex_feedback_hits_needed = 3 + 4;
+ vertex_pos_hits_needed = 3;
+ vertex_color_hits_needed = 4;
+ vertex_texture_hits_needed = 0; break;
+ case GL_3D_COLOR_TEXTURE: vertex_feedback_hits_needed = 3 + 4 + 4;
+ vertex_pos_hits_needed = 3;
+ vertex_color_hits_needed = 4;
+ vertex_texture_hits_needed = 4; break;
+ case GL_4D_COLOR_TEXTURE: vertex_feedback_hits_needed = 4 + 4 + 4;
+ vertex_pos_hits_needed = 4;
+ vertex_color_hits_needed = 4;
+ vertex_texture_hits_needed = 4; break;
+ default:
+ vertex_feedback_hits_needed = 0;
+ vertex_pos_hits_needed = 0;
+ vertex_color_hits_needed = 0;
+ vertex_texture_hits_needed = 0;
+ break;
+ }
+ if(token == GL_PASS_THROUGH_TOKEN) feedback_hits_needed = 1 + 1; //GL_PASSTHROUGH_TOKEN, value
+ else if(token == GL_POINT_TOKEN) feedback_hits_needed = 1 + 1*vertex_feedback_hits_needed; //GL_POINT_TOKEN vertex
+ else if(token == GL_LINE_TOKEN || token == GL_LINE_RESET_TOKEN) feedback_hits_needed = 1 + 2*vertex_feedback_hits_needed; //2 verts
+ else if(token == GL_POLYGON_TOKEN) feedback_hits_needed = 1 + 1 + 3*vertex_feedback_hits_needed; //GL_POLYGON_TOKEN, "3", v,v,v
+ else if(token == GL_BITMAP_TOKEN) feedback_hits_needed = 1 + 1*vertex_feedback_hits_needed; //GL_BITMAP_TOKEN vertex
+ else if(token == GL_DRAW_PIXEL_TOKEN || token == GL_COPY_PIXEL_TOKEN)
+ feedback_hits_needed = 1 + 1*vertex_feedback_hits_needed; //token vertex
+ else return;
+ c->feedback_hits += feedback_hits_needed;
+ if(c->feedback_hits > (GLint)c->feedback_size){
+ c->feedback_overflow = 1;
+ c->feedback_hits -= feedback_hits_needed;
+ return;
+ }
+ //c->feedback_hits -= feedback_hits_needed;
+#if TGL_FEATURE_ERROR_CHECK == 1
+#define DONE_ERROR_CHECK {if(++done > feedback_hits_needed) {gl_fatal_error("\nBAD FEEDBACK BUFFER WRITE DETECTED\n");}}
+#else
+#define DONE_ERROR_CHECK /* a comment*/
+#endif
+ #define WRITE_FLOAT(f) {DONE_ERROR_CHECK;*(c->feedback_ptr++) = f;}
+ #define WRITE_UINT(u) {DONE_ERROR_CHECK;*( ((GLuint*)c->feedback_ptr++)) = u;}
+ #define WRITE_VERTEX(v){\
+ if(vertex_pos_hits_needed == 2){\
+ WRITE_FLOAT(v->zp.x)\
+ WRITE_FLOAT(v->zp.y)\
+ }\
+ if(vertex_pos_hits_needed == 3){\
+ WRITE_FLOAT(v->zp.x)\
+ WRITE_FLOAT(v->zp.y)\
+ WRITE_FLOAT(v->zp.z)\
+ }\
+ if(vertex_pos_hits_needed == 4){\
+ WRITE_FLOAT(v->zp.x)\
+ WRITE_FLOAT(v->zp.y)\
+ WRITE_FLOAT(v->zp.z)\
+ WRITE_FLOAT(v->pc.W)\
+ }\
+ if(vertex_color_hits_needed == 4){\
+ WRITE_FLOAT(v->color.X)\
+ WRITE_FLOAT(v->color.Y)\
+ WRITE_FLOAT(v->color.Z)\
+ WRITE_FLOAT(v->color.W)\
+ }\
+ if(vertex_texture_hits_needed == 4){\
+ WRITE_FLOAT(v->tex_coord.X)\
+ WRITE_FLOAT(v->tex_coord.Y)\
+ WRITE_FLOAT(v->tex_coord.Z)\
+ WRITE_FLOAT(v->tex_coord.W)\
+ }\
+ }
+ if(token == GL_PASS_THROUGH_TOKEN) {
+ WRITE_UINT(GL_PASS_THROUGH_TOKEN);
+ WRITE_FLOAT(passthrough_token_value);
+ }else if(token == GL_LINE_TOKEN || token == GL_LINE_RESET_TOKEN){
+ WRITE_UINT(token);
+ WRITE_VERTEX(v1);
+ WRITE_VERTEX(v2);
+ } else if(token == GL_POLYGON_TOKEN) {
+ WRITE_UINT(GL_POLYGON_TOKEN);
+ WRITE_UINT(3);
+ WRITE_VERTEX(v1);
+ WRITE_VERTEX(v2);
+ WRITE_VERTEX(v3);
+ } else if(token == GL_BITMAP_TOKEN) {
+ WRITE_UINT(GL_BITMAP_TOKEN);
+ WRITE_VERTEX(v1);
+ } else if(token == GL_DRAW_PIXEL_TOKEN || token == GL_COPY_PIXEL_TOKEN) {
+ WRITE_UINT(token);
+ WRITE_VERTEX(v1);
+ }
+#if TGL_FEATURE_ERROR_CHECK == 1
+ if(done != feedback_hits_needed)
+ gl_fatal_error("Failed to write enough information to the buffer.");
+#endif
+ return;
+}
+void glPassThrough(GLfloat token){
+GLContext* c = gl_get_context();
+#include "error_check.h"
+ gl_add_feedback(c,GL_PASS_THROUGH_TOKEN,NULL,NULL,NULL,token);
+}
void glopInitNames(GLContext* c, GLParam* p) {
if (c->render_mode == GL_SELECT) {
c->name_stack_size = 0;
@@ -80,6 +255,11 @@
c->select_hit = NULL;
}
}
+
+
+
+
+
void glopPopName(GLContext* c, GLParam* p) {
if (c->render_mode == GL_SELECT) {
--- a/src/vertex.c
+++ b/src/vertex.c
@@ -106,6 +106,9 @@
if (c->render_mode == GL_SELECT) {
c->draw_triangle_front = gl_draw_triangle_select;
c->draw_triangle_back = gl_draw_triangle_select;
+ }else if (c->render_mode == GL_FEEDBACK){
+ c->draw_triangle_front = gl_draw_triangle_feedback;
+ c->draw_triangle_back = gl_draw_triangle_feedback;
} else {
switch (c->polygon_mode_front) {
case GL_POINT:
--- a/src/zgl.h
+++ b/src/zgl.h
@@ -238,7 +238,7 @@
GLuint feedback_size;
GLint feedback_hits;
GLubyte feedback_overflow;
-
+ GLenum feedback_type;
/* names */
GLuint name_stack[MAX_NAME_STACK_DEPTH];
GLint name_stack_size;
@@ -301,7 +301,7 @@
GLint rasterpos_zz;
GLubyte rasterposvalid;
GLfloat pzoomx, pzoomy;
-
+ GLVertex rastervertex;
/* text */
GLTEXTSIZE textsize;
@@ -327,6 +327,7 @@
void gl_draw_triangle_line(GLContext* c, GLVertex* p0, GLVertex* p1, GLVertex* p2);
void gl_draw_triangle_fill(GLContext* c, GLVertex* p0, GLVertex* p1, GLVertex* p2);
void gl_draw_triangle_select(GLContext* c, GLVertex* p0, GLVertex* p1, GLVertex* p2);
+void gl_draw_triangle_feedback(GLContext* c, GLVertex* p0, GLVertex* p1, GLVertex* p2);
/* matrix.c */
void gl_print_matrix(const GLfloat* m);
@@ -334,8 +335,16 @@
void glopLoadIdentity(GLContext *c,GLParam *p);
void glopTranslate(GLContext *c,GLParam *p);*/
-/* light.c */
+/* select.c */
void gl_add_select(GLContext* c, GLuint zmin, GLuint zmax);
+void gl_add_feedback(GLContext* c, GLfloat token,
+ GLVertex* v1,
+ GLVertex* v2,
+ GLVertex* v3,
+ GLfloat passthrough_token_value
+);
+
+/* light.c */
void gl_enable_disable_light(GLContext* c, GLint light, GLint v);
void gl_shade_vertex(GLContext* c, GLVertex* v);
--- a/src/zraster.c
+++ b/src/zraster.c
@@ -51,6 +51,7 @@
}
c->rasterpos.v[0] = v.zp.x;
c->rasterpos.v[1] = v.zp.y;
+ c->rastervertex = v;
//c->rasterpos.v[2] = v.zp.z;
c->rasterpos_zz = v.zp.z >> ZB_POINT_Z_FRAC_BITS; //I believe this is it?
c->rasterposvalid = 1;
@@ -123,10 +124,16 @@
TGL_BLEND_VARS
//Looping over the source pixels.
if(c->render_mode == GL_SELECT){
- gl_add_select(c, 0, 0);
+ gl_add_select(c, zz, zz);
return;
} else if(c->render_mode == GL_FEEDBACK){
- //TODO
+ gl_add_feedback(
+ c, GL_DRAW_PIXEL_TOKEN,
+ &(c->rastervertex),
+ NULL,
+ NULL,
+ 0
+ );
return;
}
for(GLint sx = 0; sx < w; sx++)