shithub: tinygl

Download patch

ref: e495ea83113e3d536d95a22666905ca3c45333da
parent: afade9570e1da804507622248a666d1e51f51671
author: David <gek@katherine>
date: Mon Feb 22 05:18:23 EST 2021

Lighting update

--- a/README.md
+++ b/README.md
@@ -112,6 +112,10 @@
 
 * Added glPixelSize (TODO is to implement distance scaling)
 
+* Fixed specular rendering
+
+* Added way more compile time options
+
 
 Note that this Softrast **is not GL 1.1 compliant** and does not constitute a complete GL implementation.
 
--- a/SDL_Examples/gears.c
+++ b/SDL_Examples/gears.c
@@ -228,11 +228,11 @@
 	static GLfloat green[4] = {0.0, 1.0, 0.0, 0.0};
 	static GLfloat blue[4] = {0.0, 0.0, 1.0, 0.0};
 	static GLfloat white[4] = {1.0, 1.0, 1.0, 0.0};
-
+	static GLfloat shininess = 5;
 	glLightfv(GL_LIGHT0, GL_POSITION, pos);
 	glLightfv(GL_LIGHT0, GL_DIFFUSE, white);
 	// glLightfv( GL_LIGHT0, GL_AMBIENT, white);
-	// glLightfv( GL_LIGHT0, GL_SPECULAR, white);
+	glLightfv( GL_LIGHT0, GL_SPECULAR, white);
 	glEnable(GL_CULL_FACE);
 	
 	glEnable(GL_LIGHT0);
@@ -248,6 +248,8 @@
 	gear1 = glGenLists(1);
 	glNewList(gear1, GL_COMPILE);
 	glMaterialfv(GL_FRONT, GL_DIFFUSE, blue);
+	glMaterialfv(GL_FRONT, GL_SPECULAR, white);
+	glMaterialfv(GL_FRONT, GL_SHININESS, &shininess);
 	glColor3fv(blue);
 	gear(1.0, 4.0, 1.0, 20, 0.7); // The largest gear.
 	glEndList();
@@ -255,6 +257,7 @@
 	gear2 = glGenLists(1);
 	glNewList(gear2, GL_COMPILE);
 	glMaterialfv(GL_FRONT, GL_DIFFUSE, red);
+	glMaterialfv(GL_FRONT, GL_SPECULAR, white);
 	glColor3fv(red);
 	gear(0.5, 2.0, 2.0, 10, 0.7); // The small gear with the smaller hole, to the right.
 	glEndList();
@@ -262,6 +265,7 @@
 	gear3 = glGenLists(1);
 	glNewList(gear3, GL_COMPILE);
 	glMaterialfv(GL_FRONT, GL_DIFFUSE, green);
+	glMaterialfv(GL_FRONT, GL_SPECULAR, white);
 	glColor3fv(green);
 	gear(1.3, 2.0, 0.5, 10, 0.7); // The small gear above with the large hole.
 	glEndList();
--- a/include/zfeatures.h
+++ b/include/zfeatures.h
@@ -42,8 +42,9 @@
 #define TGL_POLYGON_STIPPLE_MASK_X 31
 #define TGL_POLYGON_STIPPLE_MASK_Y 31
 
+//Use lookup tables for calculating specular light.
+#define TGL_FEATURE_SPECULAR_BUFFERS 0
 
-
 //Prevent ZB_copyFrameBuffer from copying certain colors.
 #define TGL_FEATURE_NO_COPY_COLOR 0
 //Don't draw (texture mapped) pixels whose color is the NO_DRAW_COLOR
@@ -83,6 +84,7 @@
 #define ZB_POINT_S_FRAC_BITS 10
 #define ZB_POINT_T_FRAC_BITS (ZB_POINT_S_FRAC_BITS + TGL_FEATURE_TEXTURE_POW2)
 
+//Test the compatibility of the target platform at glInit() time.
 #define TGL_FEATURE_TINYGL_RUNTIME_COMPAT_TEST 1
 
 #endif 
--- a/src/api.c
+++ b/src/api.c
@@ -26,6 +26,8 @@
 	GLParam p[4];
 #include "error_check_no_context.h"
 	p[0].op = OP_Normal;
+//NODO: Normalize vector here if it's enabled, so that the display list contains only normalized normals.
+//Redacted because: It would fuck up the matrix math. Dang it!
 	p[1].f = x;
 	p[2].f = y;
 	p[3].f = z;
@@ -378,7 +380,7 @@
 	p[0].op = OP_Material;
 	p[1].i = mode;
 	p[2].i = type;
-	n = 4;
+	n = 4;//This appears to be a hack... to avoid a jump instruction? What the hell?
 	if (type == GL_SHININESS)
 		n = 1;
 	for (i = 0; i < 4; i++)
--- a/src/get.c
+++ b/src/get.c
@@ -79,6 +79,9 @@
 #if TGL_FEATURE_LIT_TEXTURES == 1
 "TGL_FEATURE_LIT_TEXTURES "
 #endif
+#if TGL_FEATURE_SPECULAR_BUFFERS == 1
+"TGL_FEATURE_SPECULAR_BUFFERS "
+#endif 
 
 #if TGL_FEATURE_POLYGON_OFFSET == 1
 "TGL_FEATURE_POLYGON_OFFSET "
--- a/src/init.c
+++ b/src/init.c
@@ -314,9 +314,11 @@
 	c->gl_resize_viewport = NULL;
 
 	/* specular buffer */
+#if TGL_FEATURE_SPECULAR_BUFFERS == 1
 	c->specbuf_first = NULL;
 	c->specbuf_used_counter = 0;
 	c->specbuf_num_buffers = 0;
+#endif
 	c->zEnableSpecular = 0;
 	/* depth test */
 	c->zb->depth_test = 0;
@@ -348,6 +350,7 @@
 		// c->matrix_stack_ptr[i] = c->matrix_stack[i];
 	}
 	i = 0;
+#if TGL_FEATURE_SPECULAR_BUFFERS == 1
 	GLSpecBuf* n = NULL;
 	for (GLSpecBuf* b = c->specbuf_first; b != NULL; b = n) {
 		n = b->next;
@@ -354,6 +357,7 @@
 		gl_free(b);
 		i++;
 	}
+#endif
 	endSharedState(c);
 	gl_free(c);
 }
--- a/src/light.c
+++ b/src/light.c
@@ -50,7 +50,9 @@
 		break;
 	case GL_SHININESS:
 		m->shininess = v[0];
+#if TGL_FEATURE_SPECULAR_BUFFERS == 1
 		m->shininess_i = (v[0] / 128.0f) * SPECULAR_BUFFER_SIZE;
+#endif
 		break;
 	case GL_AMBIENT_AND_DIFFUSE:
 		// printf("\nRECEIVED AMBIENT AND DIFFUSE COLOR %f, %f, %f, %f", v[0], v[1], v[2], v[3]);
@@ -312,7 +314,7 @@
 					/* no contribution */
 					continue;
 				} else {
-					/* TODO: optimize */
+					/* TODO: pow table for spot_exponent?*/
 					if (l->spot_exponent > 0) {
 						att = att * pow(dot_spot, l->spot_exponent);
 					}
@@ -334,16 +336,22 @@
 					s.Y = d.Y - vcoord.X;
 					s.Z = d.Z - vcoord.X;
 				} else {
-					s.X = d.X;
-					s.Y = d.Y;
-					s.Z = d.Z + 1.0;
+					s.X = d.X; //+0.0
+					s.Y = d.Y; //+0.0
+					s.Z = d.Z - 1.0; //BLINN-PHONG SHADING: We're doing lighting calculations in Eye coordinates, this is ViewDir + LightDir
+					//s.Z = d.Z + 1.0; //This is what bellard's code did, which I think is wrong.
+					//s.Z = d.Z;
 				}
+				//dot_spec is dot(surfaceNormal, H)
 				dot_spec = n.X * s.X + n.Y * s.Y + n.Z * s.Z;
 				if (twoside && dot_spec < 0)
 					dot_spec = -dot_spec;
 				if (dot_spec > 0) {
+#if TGL_FEATURE_SPECULAR_BUFFERS == 1
 					GLSpecBuf* specbuf;
 					GLint idx;
+#endif
+					dot_spec = clampf(dot_spec, 0, 1);
 #if TGL_FEATURE_FISR == 1
 					tmp = fastInvSqrt(s.X * s.X + s.Y * s.Y + s.Z * s.Z); //FISR IMPL, MATCHED!
 					if (tmp < 1E+3) {
@@ -356,25 +364,23 @@
 			          dot_spec=dot_spec / tmp;
 			        } else dot_spec = 0;
 #endif
-					
-
-					/* TODO: optimize */
-					/* testing specular buffer code */
 					/* dot_spec= pow(dot_spec,m->shininess);*/
+#if TGL_FEATURE_SPECULAR_BUFFERS == 1
 					specbuf = specbuf_get_buffer(c, m->shininess_i, m->shininess);
+//Check for GL_OUT_OF_MEMORY
 #if TGL_FEATURE_ERROR_CHECK == 1
-//The GL_OUT_OF_MEMORY flag will already be set.
 #include "error_check.h"
+#endif
 #else
-				//As it turns out, this is actually handled inside of specbuf_get_buffer!
-					//if(!specbuf)
-					//	gl_fatal_error("BAD SPECBUF_GET_BUFFER");
+					dot_spec= pow(dot_spec,m->shininess);
 #endif
 
+#if TGL_FEATURE_SPECULAR_BUFFERS == 1
 					idx = (GLint)(dot_spec * SPECULAR_BUFFER_SIZE);
 					if (idx > SPECULAR_BUFFER_SIZE)
 						idx = SPECULAR_BUFFER_SIZE; //NOTE by GEK: this is poorly written, it's actually 1 larger.
 					dot_spec = specbuf->buf[idx];
+#endif
 					lR += dot_spec * l->specular.v[0] * m->specular.v[0];
 					lG += dot_spec * l->specular.v[1] * m->specular.v[1];
 					lB += dot_spec * l->specular.v[2] * m->specular.v[2];
--- a/src/specbuf.c
+++ b/src/specbuf.c
@@ -3,6 +3,8 @@
 #include <math.h>
 #include <stdlib.h>
 
+#if TGL_FEATURE_SPECULAR_BUFFERS == 1
+
 static void calc_buf(GLSpecBuf* buf, const GLfloat shininess) {
 	GLint i;
 	GLfloat val, inc;
@@ -54,3 +56,6 @@
 	calc_buf(oldest, shininess);
 	return oldest;
 }
+
+
+#endif
--- a/src/zgl.h
+++ b/src/zgl.h
@@ -291,9 +291,11 @@
 
 	/* specular buffer. could probably be shared between contexts,
 	  but that wouldn't be 100% thread safe */
+#if TGL_FEATURE_SPECULAR_BUFFERS == 1
 	GLSpecBuf* specbuf_first;
 	GLint specbuf_used_counter;
 	GLint specbuf_num_buffers;
+#endif 
 	GLint zEnableSpecular; // Enable specular lighting
 	/* opaque structure for user's use */
 	void* opaque;