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;