ref: 5a4e2a659d7f460b962909e49b524d8292c96728
parent: 75e55346c70c831fe17df3f57379b280680e039e
author: David <gek@katherine>
date: Fri Feb 19 16:01:51 EST 2021
Almost cracked how the texture sampling works.
--- a/README.md
+++ b/README.md
@@ -7,8 +7,6 @@
Valgrind'd for memory leaks in the demos.
-It's also lightning fast.
-
Without Polygon Stipple:
![GIF Video of demo](capture.gif)
@@ -77,8 +75,11 @@
* Added glGetString() for GL_VENDOR, GL_RENDERER, GL_VERSION, and GL_LICENSE
+* Added comprehensive glGetError() functionality
+
* Fixed a myriad of bugs and... weirdnesses
+* Tuned the triangle rasterizer to near-perfection.
Note that this Softrast **is not GL 1.1 compliant** and does not constitute a complete GL implementation.
@@ -97,6 +98,10 @@
The "implementation specific multiplier" is 0.
* There is no stencil buffer.
+
+* There is no mipmapping, antialiasing, or any form of texture filtering.
+
+* The only wrap mode is wrapping. You cannot change it.
* Lit triangles will use the current material properties, even if they are textures. If the diffuse color is black, then your
textured triangles will appear black.
--- a/SDL_Examples/texture.c
+++ b/SDL_Examples/texture.c
@@ -30,7 +30,7 @@
#endif
GLuint tex = 0;
-
+GLfloat texture_mult = 1.0;
GLuint loadRGBTexture(unsigned char* buf, unsigned int w, unsigned int h) {
GLuint t = 0;
glGenTextures(1, &t);
@@ -61,19 +61,19 @@
glTexCoord2f(0, 0);
glVertex3f(-1, -1, 0.5);
- glTexCoord2f(1, -1);
+ glTexCoord2f(1 * texture_mult, -1 * texture_mult);
glVertex3f(1, 1, 0.5);
- glTexCoord2f(0, -1);
+ glTexCoord2f(0, -1* texture_mult);
glVertex3f(-1, 1, 0.5);
// TRIANGLE 2
glTexCoord2f(0, 0);
glVertex3f(-1, -1, 0.5);
- glTexCoord2f(1, 0);
+ glTexCoord2f(1 * texture_mult, 0);
glVertex3f(1, -1, 0.5);
- glTexCoord2f(1, -1);
+ glTexCoord2f(1 * texture_mult, -1 * texture_mult);
glVertex3f(1, 1, 0.5);
glEnd();
}
@@ -125,6 +125,8 @@
winSizeY = atoi(argv[i]);
if (!strcmp(larg, "-fps"))
fps = strtoull(argv[i], 0, 10);
+ if (!strcmp(larg, "-texscale"))
+ texture_mult = atof(argv[i]);
larg = argv[i];
}
}
--- a/include/zbuffer.h
+++ b/include/zbuffer.h
@@ -13,10 +13,29 @@
#define ZB_POINT_Z_FRAC_BITS 14
-#define ZB_POINT_S_MIN ( (1<<13) )
-#define ZB_POINT_S_MAX ( (1<<22)-(1<<13) )
-#define ZB_POINT_T_MIN ( (1<<21) )
-#define ZB_POINT_T_MAX ( (1<<30)-(1<<21) )
+//a "1" in bit FRAC_BITS+1 (starting at zero) = 1.
+
+#define ZB_POINT_S_MIN ( (1<<ZB_POINT_S_FRAC_BITS) )
+#define ZB_POINT_S_MAX ( (1<<(1+TGL_FEATURE_TEXTURE_POW2+ZB_POINT_S_FRAC_BITS))-(1<<ZB_POINT_S_FRAC_BITS) )
+#define ZB_POINT_T_MIN ( (1<<ZB_POINT_T_FRAC_BITS) )
+#define ZB_POINT_T_MAX ( (1<<(1+TGL_FEATURE_TEXTURE_POW2+ZB_POINT_T_FRAC_BITS))-(1<<ZB_POINT_T_FRAC_BITS) )
+#define ZB_POINT_S_VALUE (ZB_POINT_S_FRAC_BITS + TGL_FEATURE_TEXTURE_POW2_HALF)
+#define ZB_POINT_T_VALUE (ZB_POINT_T_FRAC_BITS - TGL_FEATURE_TEXTURE_POW2_HALF)
+#define ZB_S_MASK ((TGL_FEATURE_TEXTURE_DIM-1)<<(ZB_POINT_S_FRAC_BITS+1))
+#define ZB_T_MASK ((TGL_FEATURE_TEXTURE_DIM-1)<<(ZB_POINT_T_FRAC_BITS+1))
+//PSZSH is 5 at 32 bit, or 4 at 16 bit.
+//Basically what's happening here is this:
+//0x3FC000 is 255<<14
+///0x3FC00000 is 255<<22
+//22-14 = 8 (The number of )
+//a single factor of 2 separates 32 bit and 16 bit rendering, and this is reflected here.
+//Twice as many bytes need to be skipped in 32 bit rendering mode.
+//If you chose
+#if ZB_POINT_T_FRAC_BITS == (ZB_POINT_S_FRAC_BITS + TGL_FEATURE_TEXTURE_POW2)
+#define ST_TO_TEXTURE_BYTE_OFFSET(s,t) ( ((s & ZB_S_MASK) | (t & ZB_T_MASK)) >> (ZB_POINT_S_VALUE-PSZSH))
+#else
+#define ST_TO_TEXTURE_BYTE_OFFSET(s,t) ( ((s & ZB_S_MASK)>>(ZB_POINT_S_VALUE-PSZSH)) | ((t & ZB_T_MASK)>>(ZB_POINT_T_VALUE-PSZSH)) )
+#endif
/*
#define ZB_POINT_RED_MIN ( (1<<10) )
#define ZB_POINT_RED_MAX ( (1<<16)-(1<<10) )
--- a/include/zfeatures.h
+++ b/include/zfeatures.h
@@ -25,7 +25,15 @@
#define TGL_FEATURE_POLYGON_STIPPLE 0
//Enable GL_BLEND functionality
#define TGL_FEATURE_BLEND 1
+//The width of textures as a power of 2. Must be divisible by 2.
+#define TGL_FEATURE_TEXTURE_POW2 8
+#define TGL_FEATURE_TEXTURE_DIM (1<<TGL_FEATURE_TEXTURE_POW2)
+#define TGL_FEATURE_TEXTURE_POW2_HALF (TGL_FEATURE_TEXTURE_POW2>>1)
+#if TGL_FEATURE_TEXTURE_POW2%2 != 0
+#error "bad TGL_FEATURE_TEXTURE_POW2"
+#endif
+
//A stipple pattern is 128 bytes in size.
#define TGL_POLYGON_STIPPLE_BYTES 128
//A stipple pattern is 2^5 (32) bits wide.
@@ -71,6 +79,10 @@
#error "Unsupported TGL_FEATURE_XX_BITS"
#endif
+
+//The fraction bits in the fixed point values used for S and T in interpolatiion.
+#define ZB_POINT_S_FRAC_BITS 10
+#define ZB_POINT_T_FRAC_BITS (ZB_POINT_S_FRAC_BITS + TGL_FEATURE_TEXTURE_POW2)
#endif
/* _tgl_features_h_ */
--- a/src/arrays.c
+++ b/src/arrays.c
@@ -19,7 +19,7 @@
p[1].f = c->color_array[i];
p[2].f = c->color_array[i + 1];
p[3].f = c->color_array[i + 2];
- p[4].f = size > 3 ? c->color_array[i + 3] : 1.0f;
+ p[4].f = (size > 3) ? c->color_array[i + 3] : 1.0f;
glopColor(c, p);
}
if (states & NORMAL_ARRAY) {
@@ -34,8 +34,8 @@
i = idx * (size + c->texcoord_array_stride);
c->current_tex_coord.X = c->texcoord_array[i];
c->current_tex_coord.Y = c->texcoord_array[i + 1];
- c->current_tex_coord.Z = size > 2 ? c->texcoord_array[i + 2] : 0.0f;
- c->current_tex_coord.W = size > 3 ? c->texcoord_array[i + 3] : 1.0f;
+ c->current_tex_coord.Z = (size > 2) ? c->texcoord_array[i + 2] : 0.0f;
+ c->current_tex_coord.W = (size > 3) ? c->texcoord_array[i + 3] : 1.0f;
}
if (states & VERTEX_ARRAY) {
GLParam p[5];
@@ -43,8 +43,8 @@
i = idx * (size + c->vertex_array_stride);
p[1].f = c->vertex_array[i];
p[2].f = c->vertex_array[i + 1];
- p[3].f = size > 2 ? c->vertex_array[i + 2] : 0.0f;
- p[4].f = size > 3 ? c->vertex_array[i + 3] : 1.0f;
+ p[3].f = (size > 2) ? c->vertex_array[i + 2] : 0.0f;
+ p[4].f = (size > 3) ? c->vertex_array[i + 3] : 1.0f;
glopVertex(c, p);
}
}
--- a/src/clip.c
+++ b/src/clip.c
@@ -27,8 +27,8 @@
/* 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);
- v->zp.t = (GLint)(v->tex_coord.Y * (ZB_POINT_T_MAX - ZB_POINT_T_MIN) + ZB_POINT_T_MIN);
+ 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
}
}
@@ -199,24 +199,6 @@
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;
-// q->zp.r = p0->zp.r + (p1->zp.r - p0->zp.r) * t;
-// q->zp.g = p0->zp.g + (p1->zp.g - p0->zp.g) * t;
-// q->zp.b = p0->zp.b + (p1->zp.b - p0->zp.b) * t;
-
-/*
- v->zp.r = (GLuint)(v->color.v[0] * 65535) & 65535;
- v->zp.g = (GLuint)(v->color.v[1] * 65535) & 65535;
- v->zp.b = (GLuint)(v->color.v[2] * 65535) & 65535;
-
-*/
-/*
- q->zp.r = 0xffFF * p0->color.v[0];
- q->zp.g = 0xffFF * p0->color.v[1];
- q->zp.b = 0xffFF * p0->color.v[2];
-*/
-// q->zp.r = (GLuint)(p0->color.v[0] * 65535) & 65535;
-// q->zp.g = (GLuint)(p0->color.v[1] * 65535) & 65535;
-// q->zp.b = (GLuint)(p0->color.v[2] * 65535) & 65535;
}
// */
if (c->texture_2d_enabled) {
--- a/src/get.c
+++ b/src/get.c
@@ -1,7 +1,6 @@
#include "msghandling.h"
#include "zgl.h"
#define TINYGL_VERSION 0.8
-#define TINYGL_USE_DATE_TIME 0
void glGetIntegerv(GLint pname, GLint* params) {
GLContext* c = gl_get_context();
#include "error_check.h"
@@ -38,7 +37,7 @@
*params = MAX_LIGHTS;
break;
case GL_MAX_TEXTURE_SIZE:
- *params = 256; /* not completely true, but... */
+ *params = TGL_FEATURE_TEXTURE_DIM; /* not completely true, but... */
break;
case GL_CULL_FACE:
*params = c->cull_face_enabled;
@@ -124,7 +123,11 @@
#if TGL_FEATURE_DISPLAYLISTS == 1
"TGL_FEATURE_DISPLAYLISTS "
#endif
-
+#if ZB_POINT_T_FRAC_BITS == (ZB_POINT_S_FRAC_BITS + TGL_FEATURE_TEXTURE_POW2)
+"TGL_FEATURE_OPTIMIZED_TEXTURE_ACCESS "
+#endif
+"TGL_FEATURE_TEXTURE_POW2=" xstr(TGL_FEATURE_TEXTURE_POW2) " "
+"TGL_FEATURE_TEXTURE_DIM=" xstr(xstr(TGL_FEATURE_TEXTURE_DIM)) " "
#if TGL_FEATURE_LIT_TEXTURES == 1
"TGL_FEATURE_LIT_TEXTURES "
#endif
--- a/src/image_util.c
+++ b/src/image_util.c
@@ -1,5 +1,6 @@
#include "zgl.h"
-
+//#warning STDIO INCLUDE!!! REMOVE!!!
+//#include <stdio.h>
/*
* image conversion
*/
@@ -52,7 +53,7 @@
pix = dest;
pix_src = src;
-
+// puts("\nIn here\n");
x1inc = (GLfloat)(xsize_src - 1) / (GLfloat)(xsize_dest - 1);
y1inc = (GLfloat)(ysize_src - 1) / (GLfloat)(ysize_dest - 1);
@@ -84,6 +85,7 @@
}
y1 += y1inc;
}
+// puts("\nNot here\n");
}
#define FRAC_BITS 16
--- a/src/msghandling.c
+++ b/src/msghandling.c
@@ -1,11 +1,11 @@
#include "../include/GL/gl.h"
#include "zgl.h"
#include <stdarg.h>
-//#include <stdio.h>
+#include <stdio.h>
//#define NDEBUG
#ifdef NDEBUG
-#define NO_DEBUG_OUTPUT
+//#define NO_DEBUG_OUTPUT
#endif
/* Use this function to output messages when something unexpected
--- a/src/texture.c
+++ b/src/texture.c
@@ -25,7 +25,7 @@
#define RETVAL NULL
#include "error_check.h"
#else
- //assert(text >= 0 && level < MAX_TEXTURE_LEVELS);
+ assert(text >= 0 && level < MAX_TEXTURE_LEVELS);
#endif
tex = find_texture(c, text);
if (!tex)
@@ -76,7 +76,7 @@
#define RETVAL NULL
#include "error_check.h"
#else
- {}//gl_fatal_error("GL_OUT_OF_MEMORY");
+ gl_fatal_error("GL_OUT_OF_MEMORY");
#endif
ht = &c->shared_state.texture_hash_table[h % TEXTURE_HASH_TABLE_SIZE];
@@ -190,13 +190,13 @@
}
do_free = 0;
- if (width != 256 || height != 256) {
- pixels1 = gl_malloc(256 * 256 * 3);
+ if (width != TGL_FEATURE_TEXTURE_DIM || height != TGL_FEATURE_TEXTURE_DIM) {
+ pixels1 = gl_malloc(TGL_FEATURE_TEXTURE_DIM * TGL_FEATURE_TEXTURE_DIM * 3);
/* no GLinterpolation is done here to respect the original image aliasing ! */
- gl_resizeImageNoInterpolate(pixels1, 256, 256, pixels, width, height);
+ gl_resizeImageNoInterpolate(pixels1, TGL_FEATURE_TEXTURE_DIM, TGL_FEATURE_TEXTURE_DIM, pixels, width, height);
do_free = 1;
- width = 256;
- height = 256;
+ width = TGL_FEATURE_TEXTURE_DIM;
+ height = TGL_FEATURE_TEXTURE_DIM;
} else {
pixels1 = pixels;
}
@@ -242,6 +242,7 @@
gl_fatal_error("GL_OUT_OF_MEMORY");
#endif
}
+
#else
#error TODO
#endif
--- a/src/vertex.c
+++ b/src/vertex.c
@@ -211,7 +211,7 @@
#include "error_check.h"
#else
- //Assume it went alright.
+ assert(0);
#endif
memcpy(newarray, c->vertex, n * sizeof(GLVertex));
gl_free(c->vertex);
--- a/src/zgl.h
+++ b/src/zgl.h
@@ -22,7 +22,8 @@
};
/* initially # of allocated GLVertexes (will grow when necessary) */
-#define POLYGON_MAX_VERTEX 16
+/* Just large enough to hold a quad... because most users will never render anything larger. */
+#define POLYGON_MAX_VERTEX 4
/* Max # of specular light pow buffers */
#define MAX_SPECULAR_BUFFERS 32
@@ -36,13 +37,13 @@
#define MAX_PROJECTION_STACK_DEPTH 8
#define MAX_TEXTURE_STACK_DEPTH 8
#define MAX_NAME_STACK_DEPTH 64
-#define MAX_TEXTURE_LEVELS 11
+#define MAX_TEXTURE_LEVELS 1
#define MAX_LIGHTS 16
-#define VERTEX_HASH_SIZE 1031
+//#define VERTEX_HASH_SIZE 1031
#define MAX_DISPLAY_LISTS 1024
-#define OP_BUFFER_MAX_SIZE 1024
+#define OP_BUFFER_MAX_SIZE 4096
#define TGL_OFFSET_FILL 0x1
#define TGL_OFFSET_LINE 0x2
--- a/src/ztriangle.c
+++ b/src/ztriangle.c
@@ -244,20 +244,6 @@
#define DRAW_INIT() \
{}
- /*
- #define PUT_PIXEL(_a) \
- { \
- zz=z >> ZB_POINT_Z_FRAC_BITS; \
- if (ZCMP(zz,pz[_a],_a)) { \
- pp[_a] = RGB_TO_PIXEL(or1, og1, ob1);\
- pz[_a]=zz; \
- }\
- z+=dzdx; \
- og1+=dgdx; \
- or1+=drdx; \
- ob1+=dbdx; \
- }
- */
#if TGL_FEATURE_NO_DRAW_COLOR != 1
#define PUT_PIXEL(_a) \
@@ -363,6 +349,12 @@
#if 1 // IF 1
+
+#define TEXTURE_SAMPLE(texture, s, t) \
+ (*(PIXEL*)( (GLbyte*)texture + \
+ ST_TO_TEXTURE_BYTE_OFFSET(s,t) \
+ ))
+
#define DRAW_LINE_TRI_TEXTURED() \
{ \
register GLushort* pz; \
@@ -474,9 +466,8 @@
{ \
register GLuint zz =z >> ZB_POINT_Z_FRAC_BITS; \
if (ZCMP(zz, pz[_a], _a, 0)) { \
- /*pp[_a] = RGB_MIX_FUNC(or1, og1, ob1, *(PIXEL*)((GLbyte*)texture + (((t & 0x3FC00000) | (s & 0x003FC000)) >> (17 - PSZSH))));*/ \
- TGL_BLEND_FUNC(RGB_MIX_FUNC(or1, og1, ob1, *(PIXEL*)((GLbyte*)texture + (((t & 0x3FC00000) | (s & 0x003FC000)) >> (17 - PSZSH)))), pp[_a]) \
- if(zbdw) pz[_a] = zz; \
+ TGL_BLEND_FUNC(RGB_MIX_FUNC(or1, og1, ob1, TEXTURE_SAMPLE(texture, s, t)), pp[_a]); \
+ if(zbdw) pz[_a] = zz; \
} \
z += dzdx; \
s += dsdx; \
@@ -486,8 +477,8 @@
#else
#define PUT_PIXEL(_a) \
{ \
- register GLuint zz =z >> ZB_POINT_Z_FRAC_BITS; \
- c = *(PIXEL*)((GLbyte*)texture + (((t & 0x3FC00000) | (s & 0x003FC000)) >> (17 - PSZSH))); \
+ register GLuint zz =z >> ZB_POINT_Z_FRAC_BITS; \
+ c = TEXTURE_SAMPLE(texture, s, t); \
if (ZCMP(zz, pz[_a], _a, c)) { \
/*pp[_a] = RGB_MIX_FUNC(or1, og1, ob1, c);*/ \
TGL_BLEND_FUNC(RGB_MIX_FUNC(or1, og1, ob1, c), (pp[_a])); \
@@ -555,7 +546,7 @@
{ \
register GLuint zz =z >> ZB_POINT_Z_FRAC_BITS; \
if (ZCMP(zz, pz[_a], _a, 0)) { \
- pp[_a] = RGB_MIX_FUNC(or1, og1, ob1, *(PIXEL*)((GLbyte*)texture + (((t & 0x3FC00000) | (s & 0x003FC000)) >> (17 - PSZSH)))); \
+ pp[_a] = RGB_MIX_FUNC(or1, og1, ob1, TEXTURE_SAMPLE(texture, s, t)); \
if(zbdw) pz[_a] = zz; \
} \
z += dzdx; \
@@ -567,7 +558,7 @@
#define PUT_PIXEL(_a) \
{ \
register GLuint zz =z >> ZB_POINT_Z_FRAC_BITS; \
- c = *(PIXEL*)((GLbyte*)texture + (((t & 0x3FC00000) | (s & 0x003FC000)) >> (17 - PSZSH))); \
+ c = TEXTURE_SAMPLE(texture, s, t); \
if (ZCMP(zz, pz[_a], _a, c)) { \
pp[_a] = RGB_MIX_FUNC(or1, og1, ob1, c); \
/*TGL_BLEND_FUNC(RGB_MIX_FUNC(or1, og1, ob1, c), (pp[_a]));*/ \