shithub: tinygl

Download patch

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) {