ref: 12e7574c2cfaaa85ba947512670fc64cba6a51c3
parent: 2298e130a5cf4bbf8d828cca6ed3902da8faaa83
author: David <gek@katherine>
date: Tue Feb 16 15:33:25 EST 2021
Bug fix update- Memory leaks
--- a/README.md
+++ b/README.md
@@ -3,6 +3,8 @@
A rework of Fabrice Bellard's TinyGL (still compiling with -std=c99) to be
more useful as a software rasterizer.
+Valgrind'd for memory leaks in the demos.
+
It's also lightning fast.
Without Polygon Stipple:
@@ -82,7 +84,52 @@
* Lit textured triangles are smoothly shaded, irrespective of glShadeModel (Untextured triangles do not have this bug)
+* the X dimension of the rendering window with must be a multiple of 4.
+
* <Undocumented limitations that have not been tested>
+
+### HOW DO I USE THIS LIBRARY???
+
+```c
+//First you have to include
+#include "../include/GL/gl.h"
+#include "../include/zbuffer.h"
+
+/*
+ Somewhere in your program...
+*/
+
+//Next, open a framebuffer.
+ZBuffer* frameBuffer = ZB_open(winSizeX, winSizeY, mode, 0, 0, 0, 0);
+//Tell TinyGL to init on that framebuffer
+glInit(frameBuffer);
+
+//Begin making OpenGL calls!
+//At the end of your application, when you want to clean up.
+ZB_close(frameBuffer);
+glClose();
+
+```
+
+### WHAT ARE THE MINIMUM REQUIREMENTS OF THIS LIBRARY?
+
+SDL 1.2 is required to run the demos I've written.
+
+SDL is by no means required to compile or use this library.
+SDL is used as a reasonable means of displaying the output of TinyGL for testing.
+
+(I also included some bonus libraries that work well with SDL in the SDL examples if you want to write games using TinyGL!)
+(Try compiling the demos with -D PLAY_MUSIC if you have mixer!)
+* A c99 compiler
+* 32 bit signed and unsigned integer types
+* 32 bit binary float type (IEEE 754)
+* Some floating point type at least as large as a 32 bit float
+* sin and cos functions in math.h
+* assert in assert.h
+* a minimal C stdlib
+* A memory allocator of some sort with some equivalents or replacements for malloc, calloc, and free.
+
+There is no FILE* usage, or I/O outside of 'msghandling.c' so if you want to remove all stdio dependency, just stub out the calls there.
### NEW FUNCTIONS
--- a/SDL_Examples/Makefile
+++ b/SDL_Examples/Makefile
@@ -4,17 +4,17 @@
GL_INCLUDES= -I../include/
ALL_T= gears texture model helloworld
LIB= ../lib/libTinyGL.a
+SDL_LIBS= -lSDL
+#SDL_MIXERLIBS= -lSDL_mixer -lmad -logg -lmikmod -logg
+SDL_MIXERLIBS=
all: $(ALL_T)
clean:
rm -f $(ALL_T) *.exe
texture:
- gcc texture.c $(LIB) -o texture $(GL_INCLUDES) $(GL_LIBS) $(CFLAGS) -lSDL -lSDL_mixer -lmad -logg -lmikmod -logg -lm
-#triangle:
-# gcc triangle.c $(LIB) -o triangle $(GL_INCLUDES) $(GL_LIBS) $(CFLAGS) -lSDL -lGLU -lSDL_mixer -lmad -logg -lmikmod -logg -lm
+ gcc texture.c $(LIB) -o texture $(GL_INCLUDES) $(SDL_LIBS) $(SDL_MIXERLIBS) $(GL_LIBS) $(CFLAGS) -lm
helloworld:
- gcc helloworld.c $(LIB) -o helloworld $(GL_INCLUDES) $(GL_LIBS) $(CFLAGS) -lSDL -lSDL_mixer -lmad -logg -lmikmod -logg -lm
-
+ gcc helloworld.c $(LIB) -o helloworld $(GL_INCLUDES) $(GL_LIBS) $(CFLAGS) $(SDL_LIBS) $(SDL_MIXERLIBS) -lm
model:
- gcc model.c $(LIB) -o model $(GL_INCLUDES) $(GL_LIBS) $(CFLAGS) -lSDL -lSDL_mixer -lmad -logg -lmikmod -logg -lm
+ gcc model.c $(LIB) -o model $(GL_INCLUDES) $(GL_LIBS) $(CFLAGS) $(SDL_LIBS) $(SDL_MIXERLIBS) -lm
gears:
- gcc gears.c $(LIB) -o gears $(GL_INCLUDES) $(GL_LIBS) $(CFLAGS) -lSDL -lSDL_mixer -lmad -logg -lmikmod -logg -lm
+ gcc gears.c $(LIB) -o gears $(GL_INCLUDES) $(GL_LIBS) $(CFLAGS) $(SDL_LIBS) $(SDL_MIXERLIBS) -lm
--- a/SDL_Examples/gears.c
+++ b/SDL_Examples/gears.c
@@ -13,9 +13,16 @@
#include <string.h>
#include "../include/GL/gl.h"
-#define CHAD_API_IMPL
+
#include "../include/zbuffer.h"
+#define CHAD_API_IMPL
+#define CHAD_MATH_IMPL
+#include "include/3dMath.h"
+#ifdef PLAY_MUSIC
#include "include/api_audio.h"
+#else
+typedef unsigned char uchar;
+#endif
#include <SDL/SDL.h>
#ifndef M_PI
@@ -252,7 +259,11 @@
larg = argv[i];
}
}
+#ifdef PLAY_MUSIC
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) {
+#else
+ if (SDL_Init(SDL_INIT_VIDEO) < 0) {
+#endif
fprintf(stderr, "ERROR: cannot initialize SDL video.\n");
return 1;
}
@@ -280,8 +291,9 @@
printf("\nBSHIFT IS %u", screen->format->Bshift);
printf("\nASHIFT IS %u\n", screen->format->Ashift);
fflush(stdout);
- track* myTrack = NULL;
+
#ifdef PLAY_MUSIC
+ track* myTrack = NULL;
myTrack = lmus("WWGW.mp3");
mplay(myTrack, -1, 1000);
#endif
@@ -421,10 +433,11 @@
}
printf("%i frames in %f secs, %f frames per second.\n", frames, (float)(tNow - tLastFps) * 0.001f, (float)frames * 1000.0f / (float)(tNow - tLastFps));
// cleanup:
- glDeleteList(gear1);
- glDeleteList(gear2);
- glDeleteList(gear3);
+ //glDeleteList(gear1);
+ //glDeleteList(gear2);
+ //glDeleteList(gear3);
ZB_close(frameBuffer);
+ glClose();
if (SDL_WasInit(SDL_INIT_VIDEO))
SDL_QuitSubSystem(SDL_INIT_VIDEO);
#ifdef PLAY_MUSIC
--- a/SDL_Examples/helloworld.c
+++ b/SDL_Examples/helloworld.c
@@ -13,11 +13,17 @@
#include <stdlib.h>
#include <string.h>
//#include <GL/glu.h>
+#include "../include/GL/gl.h"
+
+#include "../include/zbuffer.h"
#define CHAD_API_IMPL
+#define CHAD_MATH_IMPL
+#include "include/3dMath.h"
+#ifdef PLAY_MUSIC
#include "include/api_audio.h"
-#define STB_IMAGE_IMPLEMENTATION
-#include "../include/zbuffer.h"
-#include "include/stb_image.h"
+#else
+typedef unsigned char uchar;
+#endif
#include <SDL/SDL.h>
#ifndef M_PI
@@ -125,7 +131,11 @@
larg = argv[i];
}
}
+#ifdef PLAY_MUSIC
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) {
+#else
+ if (SDL_Init(SDL_INIT_VIDEO) < 0) {
+#endif
fprintf(stderr, "ERROR: cannot initialize SDL video.\n");
return 1;
}
@@ -154,8 +164,8 @@
printf("\nBSHIFT IS %u", screen->format->Bshift);
printf("\nASHIFT IS %u\n", screen->format->Ashift);
fflush(stdout);
- track* myTrack = NULL;
#ifdef PLAY_MUSIC
+ track* myTrack = NULL;
myTrack = lmus("WWGW.mp3");
mplay(myTrack, -1, 1000);
#endif
@@ -285,6 +295,7 @@
printf("%i frames in %f secs, %f frames per second.\n", frames, (float)(tNow - tLastFps) * 0.001f, (float)frames * 1000.0f / (float)(tNow - tLastFps));
// cleanup:
ZB_close(frameBuffer);
+ glClose();
if (SDL_WasInit(SDL_INIT_VIDEO))
SDL_QuitSubSystem(SDL_INIT_VIDEO);
#ifdef PLAY_MUSIC
--- a/SDL_Examples/model.c
+++ b/SDL_Examples/model.c
@@ -19,7 +19,11 @@
#include "include/tobjparse.h"
#define CHAD_API_IMPL
#include "../include/zbuffer.h"
+#ifdef PLAY_MUSIC
#include "include/api_audio.h"
+#else
+typedef unsigned char uchar;
+#endif
#include <SDL/SDL.h>
#include <time.h>
@@ -226,7 +230,9 @@
int dlExists = 0;
int doTextures = 1;
char* modelName = "extrude.obj";
+#ifdef PLAY_MUSIC
track* myTrack = NULL;
+#endif
unsigned int fps = 0;
if (argc > 2) {
char* larg = argv[1];
@@ -246,7 +252,11 @@
larg = argv[i];
}
}
+#ifdef PLAY_MUSIC
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) {
+#else
+ if (SDL_Init(SDL_INIT_VIDEO) < 0) {
+#endif
fprintf(stderr, "ERROR: cannot initialize SDL video.\n");
return 1;
}
@@ -525,7 +535,7 @@
// glDeleteList(modelDisplayList);
glDeleteLists(modelDisplayList, 1);
ZB_close(frameBuffer);
-
+ glClose();
if (SDL_WasInit(SDL_INIT_VIDEO))
SDL_QuitSubSystem(SDL_INIT_VIDEO);
#ifdef PLAY_MUSIC
--- a/SDL_Examples/texture.c
+++ b/SDL_Examples/texture.c
@@ -12,10 +12,17 @@
#include <string.h>
#include "../include/GL/gl.h"
+
+#include "../include/zbuffer.h"
#define CHAD_API_IMPL
+#define CHAD_MATH_IMPL
+#include "include/3dMath.h"
+#ifdef PLAY_MUSIC
#include "include/api_audio.h"
+#else
+typedef unsigned char uchar;
+#endif
#define STB_IMAGE_IMPLEMENTATION
-#include "../include/zbuffer.h"
#include "include/stb_image.h"
#include <SDL/SDL.h>
@@ -121,7 +128,11 @@
larg = argv[i];
}
}
+#ifdef PLAY_MUSIC
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) {
+#else
+ if (SDL_Init(SDL_INIT_VIDEO) < 0) {
+#endif
fprintf(stderr, "ERROR: cannot initialize SDL video.\n");
return 1;
}
@@ -150,8 +161,9 @@
printf("\nBSHIFT IS %u", screen->format->Bshift);
printf("\nASHIFT IS %u\n", screen->format->Ashift);
fflush(stdout);
- track* myTrack = NULL;
+
#ifdef PLAY_MUSIC
+ track* myTrack = NULL;
myTrack = lmus("WWGW.mp3");
mplay(myTrack, -1, 1000);
#endif
@@ -271,6 +283,7 @@
printf("%i frames in %f secs, %f frames per second.\n", frames, (float)(tNow - tLastFps) * 0.001f, (float)frames * 1000.0f / (float)(tNow - tLastFps));
// cleanup:
ZB_close(frameBuffer);
+ glClose();
if (SDL_WasInit(SDL_INIT_VIDEO))
SDL_QuitSubSystem(SDL_INIT_VIDEO);
#ifdef PLAY_MUSIC
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,7 +1,7 @@
include config.mk
OBJS= api.o list.o vertex.o init.o matrix.o texture.o \
- misc.o clear.o light.o clip.o select.o get.o error.o \
+ misc.o clear.o light.o clip.o select.o get.o \
zbuffer.o zline.o zdither.o ztriangle.o \
zmath.o image_util.o msghandling.o \
arrays.o specbuf.o memory.o ztext.o
--- a/src/api.c
+++ b/src/api.c
@@ -1,5 +1,5 @@
#include "zgl.h"
-#include <stdio.h>
+//#include <stdio.h>
/* glVertex */
void glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
--- a/src/arrays.c
+++ b/src/arrays.c
@@ -1,6 +1,6 @@
#include "zgl.h"
#include <assert.h>
-#include <stdio.h>
+//#include <stdio.h>
#define VERTEX_ARRAY 0x0001
#define COLOR_ARRAY 0x0002
--- a/src/error.c
+++ /dev/null
@@ -1,15 +1,0 @@
-#include "zgl.h"
-#include <stdarg.h>
-
-void gl_fatal_error(char* format, ...) {
- va_list ap;
-
- va_start(ap, format);
-
- fprintf(stderr, "TinyGL: fatal error: ");
- vfprintf(stderr, format, ap);
- fprintf(stderr, "\n");
- exit(1);
-
- va_end(ap);
-}
--- a/src/get.c
+++ b/src/get.c
@@ -1,5 +1,5 @@
#include "zgl.h"
-
+#include "msghandling.h"
void glGetIntegerv(GLint pname, GLint* params) {
GLContext* c = gl_get_context();
@@ -63,7 +63,7 @@
case GL_POINT_SIZE_RANGE:
v[0] = v[1] = 1.0f;
default:
- fprintf(stderr, "warning: unknown pname in glGetFloatv()\n");
+ tgl_warning("warning: unknown pname in glGetFloatv()\n");
break;
}
}
--- a/src/init.c
+++ b/src/init.c
@@ -7,18 +7,56 @@
s->lists = gl_zalloc(sizeof(GLList*) * MAX_DISPLAY_LISTS);
s->texture_hash_table = gl_zalloc(sizeof(GLTexture*) * TEXTURE_HASH_TABLE_SIZE);
- alloc_texture(c, 0);
+ alloc_texture(c, 0); //MEMORY LEAK
}
void endSharedState(GLContext* c) {
GLSharedState* s = &c->shared_state;
GLint i;
-
- for (i = 0; i < MAX_DISPLAY_LISTS; i++) {
- /* TODO */
+ GLList* l;
+ GLParamBuffer *pb, *pb1;
+ GLTexture* t, *n;
+ for (i = 0; i < MAX_DISPLAY_LISTS; i++)
+ if(s->lists[i]){
+ l = s->lists[i];
+ pb = l->first_op_buffer;
+ while (pb != NULL) {
+ pb1 = pb->next;
+ gl_free(pb);
+ pb = pb1;
+ }
+ gl_free(l);
+ s->lists[i] = NULL;
}
gl_free(s->lists);
-
+ for(i = 0; i < TEXTURE_HASH_TABLE_SIZE; i++)
+ {
+ t = s->texture_hash_table[i];
+ while(t){
+ GLTexture **ht;
+ GLImage* im;
+ GLint inner_i;
+
+ //t = find_texture(c, h);
+ if (t->prev == NULL) {
+ ht = &c->shared_state.texture_hash_table[t->handle % TEXTURE_HASH_TABLE_SIZE];
+ *ht = t->next;
+ } else {
+ t->prev->next = t->next;
+ }
+ n=t->next;
+ if (t->next != NULL)
+ t->next->prev = t->prev;
+
+ for (inner_i = 0; inner_i < MAX_TEXTURE_LEVELS; inner_i++) {
+ im = &t->images[inner_i];
+ if (im->pixmap != NULL)
+ gl_free(im->pixmap);
+ }
+ gl_free(t);
+ t=n;
+ }
+ }
gl_free(s->texture_hash_table);
}
@@ -181,7 +219,22 @@
}
void glClose(void) {
- GLContext* c = gl_get_context();
+ GLContext* c = gl_get_context();GLuint i;
+ gl_free(c->vertex);
+ for (i = 0; i < 3; i++) {
+ //c->matrix_stack[i] = gl_zalloc(c->matrix_stack_depth_max[i] * sizeof(M4));
+ gl_free(c->matrix_stack[i]);
+ //c->matrix_stack_ptr[i] = c->matrix_stack[i];
+ }
+ i = 0;
+ GLSpecBuf* n = NULL;
+ for(
+ GLSpecBuf* b = c->specbuf_first; b != NULL; b = n)
+ {
+ n = b->next;
+ gl_free(b);
+ i++;
+ }
endSharedState(c);
gl_free(c);
}
--- a/src/list.c
+++ b/src/list.c
@@ -1,5 +1,5 @@
#include "zgl.h"
-
+#include "msghandling.h"
static char* op_table_str[] = {
#define ADD_OP(a, b, c) "gl" #a " " #c,
@@ -28,7 +28,7 @@
l = find_list(c, list);
if (l == NULL)
- puts("\nAttempted to delete NULL list!!!!\n");
+ {tgl_warning("\nAttempted to delete NULL list!!!!\n");return;}
assert(l != NULL);
/* free param buffer */
@@ -63,7 +63,7 @@
c->shared_state.lists[list] = l;
return l;
}
-
+/*
void gl_print_op(FILE* f, GLParam* p) {
GLint op;
char* s;
@@ -88,9 +88,9 @@
s++;
}
}
- fprintf(f, "\n");
+ tgl_warning(f, "\n");
}
-
+*/
void gl_compile_op(GLContext* c, GLParam* p) {
GLint op, op_size;
GLParamBuffer *ob, *ob1;
@@ -135,7 +135,7 @@
gl_compile_op(c, p);
}
if (c->print_flag) {
- gl_print_op(stderr, p);
+// gl_print_op(stderr, p);
}
}
--- a/src/matrix.c
+++ b/src/matrix.c
@@ -1,10 +1,10 @@
#include "zgl.h"
-
+#include "msghandling.h"
void gl_print_matrix(const GLfloat* m) {
GLint i;
for (i = 0; i < 4; i++) {
- fprintf(stderr, "%f %f %f %f\n", m[i], m[4 + i], m[8 + i], m[12 + i]);
+ tgl_warning("%f %f %f %f\n", m[i], m[4 + i], m[8 + i], m[12 + i]);
}
}
--- a/src/msghandling.c
+++ b/src/msghandling.c
@@ -1,6 +1,7 @@
#include "../include/GL/gl.h"
#include <stdarg.h>
#include <stdio.h>
+#include "zgl.h"
//#define NDEBUG
#ifdef NDEBUG
@@ -43,4 +44,17 @@
vfprintf(stderr, format, args);
va_end(args);
#endif /* !NO_DEBUG_OUTPUT */
+}
+
+
+void gl_fatal_error(char* format, ...) {
+ va_list ap;
+
+ va_start(ap, format);
+
+ fprintf(stderr, "TinyGL: fatal error: ");
+ vfprintf(stderr, format, ap);
+ fprintf(stderr, "\n");
+ exit(1);
+ va_end(ap);
}
--- a/src/zbuffer.c
+++ b/src/zbuffer.c
@@ -4,7 +4,7 @@
*
*/
#include <assert.h>
-#include <stdio.h>
+//#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include "../include/GL/gl.h"
--- a/src/zdither.c
+++ b/src/zdither.c
@@ -5,7 +5,7 @@
#include "../include/zbuffer.h"
#include <assert.h>
-#include <stdio.h>
+//#include <stdio.h>
#include <stdlib.h>
#if defined(TGL_FEATURE_8_BITS)
@@ -34,7 +34,7 @@
GLint c, r, g, b, i, index, r1, g1, b1;
if (nb_colors < (_R * _G * _B)) {
- fprintf(stderr, "zdither: not enough colors\n");
+// fprintf(stderr, "zdither: not enough colors\n");
exit(1);
}
--- a/src/zgl.h
+++ b/src/zgl.h
@@ -7,7 +7,7 @@
#include "zmath.h"
#include <assert.h>
#include <math.h>
-#include <stdio.h>
+//#include <stdio.h>
#include <stdlib.h>
#ifndef M_PI
#define M_PI 3.14159265358979323
@@ -27,7 +27,7 @@
#define POLYGON_MAX_VERTEX 16
/* Max # of specular light pow buffers */
-#define MAX_SPECULAR_BUFFERS 8
+#define MAX_SPECULAR_BUFFERS 32
//#define MAX_SPECULAR_BUFFERS 16
/* # of entries in specular buffer */
#define SPECULAR_BUFFER_SIZE 1024
@@ -44,7 +44,7 @@
#define VERTEX_HASH_SIZE 1031
#define MAX_DISPLAY_LISTS 1024
-#define OP_BUFFER_MAX_SIZE 512
+#define OP_BUFFER_MAX_SIZE 1024
#define TGL_OFFSET_FILL 0x1
#define TGL_OFFSET_LINE 0x2
--- a/src/ztext.c
+++ b/src/ztext.c
@@ -3,9 +3,9 @@
#include "font8x8_basic.h"
#include "zgl.h"
#include <assert.h>
-#include <stdio.h>
+//#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
+//#include <string.h>
GLTEXTSIZE textsize = 1;
void glTextSize(GLTEXTSIZE mode) {