ref: e0cafbd6a4156ab0b4167465a422ee6d135cf2c3
parent: 770d4ada9a6a3baaf508d8e7db6e418d3c8695e3
author: David <gek@katherine>
date: Mon Feb 22 16:51:08 EST 2021
Compliance and bug fix update
--- a/README.md
+++ b/README.md
@@ -158,6 +158,8 @@
* Point smoothing is not implemented, points are always squares of a solid color.
+* glCopyTexImage2D only works with the size of texture you decided at compile time.
+
* <Undocumented limitations that have not been tested>
### HOW DO I USE THIS LIBRARY???
@@ -178,7 +180,7 @@
//Tell TinyGL to initialize on that framebuffer
glInit(frameBuffer);
-//Begin making OpenGL calls!
+//Begin making TinyGL calls!
//At the end of your application, when you want to clean up.
ZB_close(frameBuffer);
glClose();
@@ -201,8 +203,8 @@
* 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
-* memcpy
-* assert in assert.h
+* memcpy in string.h
+* assert in assert.h (for debugging only, it can be stubbed)
* a minimal C stdlib
* A memory allocator of some sort with some equivalents or replacements for malloc, calloc, and free.
@@ -398,8 +400,12 @@
High: 917 FPS
Average: around 842 FPS
```
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+_______________________________________________________________________________________
+
# Here is the old description of TinyGL, saved for historical/attribution purposes:
+
+### I do not endorse or promote its contents, they are here for attribution only.
### General Description:
--------------------
--- a/SDL_Examples/helloworld.c
+++ b/SDL_Examples/helloworld.c
@@ -26,6 +26,7 @@
#endif
#include <SDL/SDL.h>
int noSDL = 0;
+int do2 = 0;
#ifndef M_PI
#define M_PI 3.14159265
#endif
@@ -36,6 +37,7 @@
int winSizeY = 480;
void draw() {
+ //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// glEnable(GL_TEXTURE_2D);
// glBindTexture(GL_TEXTURE_2D,tex);
// time_passed += 0.0166666;
@@ -59,7 +61,7 @@
}
void draw2() {
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
int x = 0;
// Select and setup the projection matrix
glMatrixMode(GL_PROJECTION);
@@ -130,6 +132,8 @@
fps = strtoull(argv[i], 0, 10);
if (!strcmp(argv[i],"-nosdl"))
noSDL = 1;
+ if (!strcmp(argv[i],"-2"))
+ do2 = 1;
larg = argv[i];
}
}
@@ -262,8 +266,10 @@
// draw scene:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- //draw2();
- draw();
+ if(do2)
+ draw2();
+ else
+ draw();
glDrawText((unsigned char*)"Hello World!\nFrom TinyGL", 0, 0, 0x00FFFFFF);
// swap buffers:
if(!noSDL)
--- a/SDL_Examples/model.c
+++ b/SDL_Examples/model.c
@@ -41,6 +41,7 @@
int ModelArrayLoaded = 0;
int testingModelArrays = 0;
+int testingCopyImage2D = 0;
struct {
float* points;
uint npoints;
@@ -312,6 +313,8 @@
doTextures = 0;
if(!strcmp(argv[i],"-arrays"))
testingModelArrays = 1;
+ if(!strcmp(argv[i],"-copy"))
+ testingCopyImage2D = 1;
larg = argv[i];
}
}
@@ -634,6 +637,19 @@
if (SDL_MUSTLOCK(screen) && (SDL_LockSurface(screen) < 0)) {
fprintf(stderr, "SDL ERROR: Can't lock screen: %s\n", SDL_GetError());
return 1;
+ }
+ if(testingCopyImage2D && doTextures){
+ glBindTexture(GL_TEXTURE_2D, tex);
+ glReadBuffer(GL_FRONT);
+ glCopyTexImage2D(
+ GL_TEXTURE_2D, //1
+ 0,//2
+ GL_RGBA, //3
+ 0,//4
+ 256,//5
+ 256,//6
+ 256,
+ 0);
}
/*
printf("\nRMASK IS %u",screen->format->Rmask);
--- a/include/zbuffer.h
+++ b/include/zbuffer.h
@@ -321,9 +321,17 @@
ZBufferPoint *,ZBufferPoint *,ZBufferPoint *);
/* memory.c */
+#if TGL_FEATURE_CUSTOM_MALLOC == 1
void gl_free(void *p);
void *gl_malloc(GLint size);
void *gl_zalloc(GLint size);
+#else
+#include<string.h>
+#include<stdlib.h>
+inline void gl_free(void* p) { free(p); }
+inline void* gl_malloc(GLint size) { return malloc(size); }
+inline void* gl_zalloc(GLint size) { return calloc(1, size); }
+#endif
void gl_memcpy(void* dest, void* src, GLuint size);
#endif /* _tgl_zbuffer_h_ */
--- a/include/zfeatures.h
+++ b/include/zfeatures.h
@@ -10,6 +10,11 @@
//The checks slow down the renderer so it is not recommended , but
//it's in the GL spec that this should occur.
#define TGL_FEATURE_STRICT_OOM_CHECKS 1
+
+//Swap between using the inline'd malloc(), calloc(), and free() in zbuffer.h, or
+//a replacement gl_malloc(), gl_zalloc(), and gl_free() in memory.c
+#define TGL_FEATURE_CUSTOM_MALLOC 0
+
//Use Fast Inverse Square Root. Toggleable because it's actually slower on some systems, i've heard.
#define TGL_FEATURE_FISR 1
//Clientside Arrays
--- a/src/arrays.c
+++ b/src/arrays.c
@@ -268,7 +268,7 @@
}
if(buf->data) gl_free(buf->data);
buf->data = NULL; buf->size = 0;
- if(size == 0 || data == NULL) return; //Allow the user to delete buffer data with glBufferData.
+ if(size == 0) return; //Allow the user to delete buffer data with glBufferData.
buf->data = gl_malloc(size);
buf->size = size;
if(!(buf->data)){
@@ -279,7 +279,8 @@
gl_fatal_error("GL_OUT_OF_MEMORY");
#endif
}
- memcpy(buf->data, data, size);
+ if(data != NULL)
+ memcpy(buf->data, data, size);
}
--- a/src/get.c
+++ b/src/get.c
@@ -63,6 +63,9 @@
#if TGL_FEATURE_STRICT_OOM_CHECKS == 1
"TGL_FEATURE_STRICT_OOM_CHECKS "
#endif
+#if TGL_FEATURE_CUSTOM_MALLOC == 1
+"TGL_FEATURE_CUSTOM_MALLOC "
+#endif
#if TGL_FEATURE_FISR == 1
"TGL_FEATURE_FISR "
#endif
--- a/src/memory.c
+++ b/src/memory.c
@@ -1,9 +1,13 @@
/*
* Memory allocator for TinyGL
*/
+
+#if TGL_FEATURE_CUSTOM_MALLOC == 1
#include "zgl.h"
/* modify these functions so that they suit your needs */
+
+
#include<string.h>
void gl_free(void* p) { free(p); }
@@ -10,3 +14,4 @@
void* gl_malloc(GLint size) { return malloc(size); }
void* gl_zalloc(GLint size) { return calloc(1, size); }
+#endif
--- a/src/specbuf.c
+++ b/src/specbuf.c
@@ -38,8 +38,7 @@
#define RETVAL NULL
#include "error_check.h"
#else
-// if (!buf)
-// gl_fatal_error("GL_OUT_OF_MEMORY: CANNOT ALLOCATE SPECBUF");
+ if (!buf) gl_fatal_error("GL_OUT_OF_MEMORY");
#endif
c->specbuf_num_buffers++;
buf->next = c->specbuf_first;
--- a/src/texture.c
+++ b/src/texture.c
@@ -178,30 +178,100 @@
#define ERROR_FLAG GL_OUT_OF_MEMORY
#include "error_check.h"
#else
- {}//gl_fatal_error("GL_OUT_OF_MEMORY");
+ gl_fatal_error("GL_OUT_OF_MEMORY");
#endif
}
c->current_texture = t;
}
+//
+
+
//TODO: Write this, then
//Write something to test this. This function is useful for doing render targets in TinyGL
//- not that you couldn't do that
//already by manually copying pixels around. But, this is a nifty utility, eh?
-void glCopyTexImage2D( GLenum target,
- GLint level,
- GLenum internalformat,
- GLint x,
- GLint y,
- GLsizei width,
+void glCopyTexImage2D(
+ GLenum target, //1
+ GLint level,//2
+ GLenum internalformat, //3
+ GLint x,//4
+ GLint y,//5
+ GLsizei width,//6
GLsizei height,
- GLint border){
+ GLint border)
+{
GLContext* c = gl_get_context();
#include "error_check.h"
- //TODO
+ GLParam p[9];
+ p[0].op = OP_CopyTexImage2D;
+ p[1].i = target;
+ p[2].i = level;
+ p[3].i = internalformat;
+ p[4].i = x;
+ p[5].i = y;
+ p[6].i = width;
+ p[7].i = height;
+ p[8].i = border;
+ gl_add_op(p);
}
void glopCopyTexImage2D(GLContext* c, GLParam* p){
- //TODO
+ GLint target = p[1].i;
+ GLint level = p[2].i;
+ //GLenum internalformat = p[3].i;
+ GLint x = p[4].i;
+ GLint y = p[5].i;
+ GLsizei w = p[6].i;
+ GLsizei h = p[7].i;
+ y -= h; //Spec says LOWER left corner. So, let's change it to top left, for our purposes, eh?
+ GLint border = p[8].i;
+ //todo
+ if(c->readbuffer != GL_FRONT ||
+ c->current_texture == NULL ||
+ target != GL_TEXTURE_2D ||
+ border != 0 ||
+ w != TGL_FEATURE_TEXTURE_DIM || //TODO Implement image interp
+ h != TGL_FEATURE_TEXTURE_DIM
+ )
+ {
+#if TGL_FEATURE_ERROR_CHECK == 1
+#define ERROR_FLAG GL_INVALID_OPERATION
+#include "error_check.h"
+#else
+ return;
+#endif
+ }
+ PIXEL* data = gl_malloc(TGL_FEATURE_TEXTURE_DIM * TGL_FEATURE_TEXTURE_DIM * sizeof(PIXEL)); //GUARDED
+ if(!data){
+#if TGL_FEATURE_ERROR_CHECK == 1
+#define ERROR_FLAG GL_OUT_OF_MEMORY
+#include "error_check.h"
+#else
+ gl_fatal_error("GL_OUT_OF_MEMORY");
+#endif
+ }
+ //sample the buffer.
+ //TODO implement the scaling and stuff that the GL spec says it should have.
+ for(GLint j = 0; j < h; j++)
+ for(GLint i = 0; i < w; i++){
+ /*
+ GLfloat dx = (GLfloat)i/(GLfloat)w;
+ GLfloat dy = (GLfloat)j/(GLfloat)h;
+ dx *= TGL_FEATURE_TEXTURE_DIM;
+ dy *= TGL_FEATURE_TEXTURE_DIM;
+ GLuint xdest = (dx<0)?0:((dx>TGL_FEATURE_TEXTURE_DIM-1)?TGL_FEATURE_TEXTURE_DIM-1:dx);
+ GLuint ydest = (dy<0)?0:((dy>TGL_FEATURE_TEXTURE_DIM-1)?TGL_FEATURE_TEXTURE_DIM-1:dy);
+ */
+ data[i+j*w] = c->zb->pbuf[ ((i+x)%(c->zb->xsize))
+ + ((j+y)%(c->zb->ysize))*(c->zb->xsize)];
+ }
+ //TODO: Load this into a texture.
+ GLImage* im = &c->current_texture->images[level];
+ im->xsize = TGL_FEATURE_TEXTURE_DIM;
+ im->ysize = TGL_FEATURE_TEXTURE_DIM;
+ if (im->pixmap != NULL) gl_free(im->pixmap);
+ im->pixmap = data;
+ //if(data)gl_free(data);
}
void glopTexImage1D(GLContext* c, GLParam* p){
@@ -219,19 +289,27 @@
GLubyte* pixels1;
GLint do_free;
- {
+ {
#if TGL_FEATURE_ERROR_CHECK == 1
- if (!(target == GL_TEXTURE_1D && level == 0 && components == 3 && border == 0 && format == GL_RGB && type == GL_UNSIGNED_BYTE))
+ if (!(c->current_texture != NULL && target == GL_TEXTURE_1D && level == 0 && components == 3 && border == 0 && format == GL_RGB && type == GL_UNSIGNED_BYTE))
#define ERROR_FLAG GL_INVALID_ENUM
#include "error_check.h"
#else
- if (!(target == GL_TEXTURE_1D && level == 0 && components == 3 && border == 0 && format == GL_RGB && type == GL_UNSIGNED_BYTE))
+ if (!(c->current_texture != NULL && target == GL_TEXTURE_1D && level == 0 && components == 3 && border == 0 && format == GL_RGB && type == GL_UNSIGNED_BYTE))
gl_fatal_error("glTexImage2D: combination of parameters not handled!!");
#endif
}
if (width != TGL_FEATURE_TEXTURE_DIM || height != TGL_FEATURE_TEXTURE_DIM) {
- pixels1 = gl_malloc(TGL_FEATURE_TEXTURE_DIM * TGL_FEATURE_TEXTURE_DIM * 3);
+ pixels1 = gl_malloc(TGL_FEATURE_TEXTURE_DIM * TGL_FEATURE_TEXTURE_DIM * 3);//GUARDED
+ if(pixels1 == NULL){
+#if TGL_FEATURE_ERROR_CHECK == 1
+#define ERROR_FLAG GL_OUT_OF_MEMORY
+#include "error_check.h"
+#else
+ gl_fatal_error("GL_OUT_OF_MEMORY");
+#endif
+ }
/* no GLinterpolation is done here to respect the original image aliasing ! */
//TODO: Make this more efficient.
gl_resizeImageNoInterpolate(pixels1, TGL_FEATURE_TEXTURE_DIM, TGL_FEATURE_TEXTURE_DIM, pixels, width, height);
@@ -248,10 +326,10 @@
im->ysize = height;
if (im->pixmap != NULL) gl_free(im->pixmap);
#if TGL_FEATURE_RENDER_BITS == 32
- im->pixmap = gl_malloc(width * height * 4);
+ im->pixmap = gl_malloc(width * height * 4); //GUARDED
if (im->pixmap) {
gl_convertRGB_to_8A8R8G8B(im->pixmap, pixels1, width, height);
- }else {
+ }else { //failed malloc of im->pixmap, glopteximage1d
#if TGL_FEATURE_ERROR_CHECK == 1
#define ERROR_FLAG GL_OUT_OF_MEMORY
#include "error_check.h"
@@ -260,7 +338,7 @@
#endif
}
#elif TGL_FEATURE_RENDER_BITS == 16
- im->pixmap = gl_malloc(width * height * 2);
+ im->pixmap = gl_malloc(width * height * 2);//GUARDED
if (im->pixmap) {
gl_convertRGB_to_5R6G5B(im->pixmap, pixels1, width, height);
}else {
@@ -299,12 +377,12 @@
{
#if TGL_FEATURE_ERROR_CHECK == 1
- if (!(target == GL_TEXTURE_2D && level == 0 && components == 3 && border == 0 && format == GL_RGB && type == GL_UNSIGNED_BYTE))
+ if (!(c->current_texture != NULL && target == GL_TEXTURE_2D && level == 0 && components == 3 && border == 0 && format == GL_RGB && type == GL_UNSIGNED_BYTE))
#define ERROR_FLAG GL_INVALID_ENUM
#include "error_check.h"
#else
- if (!(target == GL_TEXTURE_2D && level == 0 && components == 3 && border == 0 && format == GL_RGB && type == GL_UNSIGNED_BYTE))
+ if (!(c->current_texture != NULL && target == GL_TEXTURE_2D && level == 0 && components == 3 && border == 0 && format == GL_RGB && type == GL_UNSIGNED_BYTE))
gl_fatal_error("glTexImage2D: combination of parameters not handled!!");
#endif
}
@@ -311,7 +389,15 @@
do_free = 0;
if (width != TGL_FEATURE_TEXTURE_DIM || height != TGL_FEATURE_TEXTURE_DIM) {
- pixels1 = gl_malloc(TGL_FEATURE_TEXTURE_DIM * TGL_FEATURE_TEXTURE_DIM * 3);
+ pixels1 = gl_malloc(TGL_FEATURE_TEXTURE_DIM * TGL_FEATURE_TEXTURE_DIM * 3);//GUARDED
+ if(pixels1 == NULL){
+#if TGL_FEATURE_ERROR_CHECK == 1
+#define ERROR_FLAG GL_OUT_OF_MEMORY
+#include "error_check.h"
+#else
+ gl_fatal_error("GL_OUT_OF_MEMORY");
+#endif
+ }
/* no GLinterpolation is done here to respect the original image aliasing ! */
//printf("\nYes this is being called.");
gl_resizeImageNoInterpolate(pixels1, TGL_FEATURE_TEXTURE_DIM, TGL_FEATURE_TEXTURE_DIM, pixels, width, height);
@@ -327,7 +413,7 @@
im->ysize = height;
if (im->pixmap != NULL) gl_free(im->pixmap);
#if TGL_FEATURE_RENDER_BITS == 32
- im->pixmap = gl_malloc(width * height * 4);
+ im->pixmap = gl_malloc(width * height * 4);//GUARDED
if (im->pixmap) {
gl_convertRGB_to_8A8R8G8B(im->pixmap, pixels1, width, height);
}else {
@@ -339,7 +425,7 @@
#endif
}
#elif TGL_FEATURE_RENDER_BITS == 16
- im->pixmap = gl_malloc(width * height * 2);
+ im->pixmap = gl_malloc(width * height * 2);//GUARDED
if (im->pixmap) {
gl_convertRGB_to_5R6G5B(im->pixmap, pixels1, width, height);
}else {
--- a/src/zbuffer.c
+++ b/src/zbuffer.c
@@ -9,7 +9,7 @@
#include <string.h>
//#include "../include/GL/gl.h"
#include "../include/zbuffer.h"
-
+#include "msghandling.h"
ZBuffer* ZB_open(GLint xsize, GLint ysize, GLint mode,
// GLint nb_colors, GLubyte* color_indexes, GLint* color_table,
void* frame_buffer) {
@@ -27,20 +27,11 @@
zb->linesize = (xsize * PSZB);
switch (mode) {
-#if TGL_FEATURE_8_BITS ==1
- case ZB_MODE_INDEX:
- ZB_initDither(zb, nb_colors, color_indexes, color_table);
- break;
-#endif
#if TGL_FEATURE_32_BITS == 1
case ZB_MODE_RGBA: break;
#endif
-#if TGL_FEATURE_24_BITS == 1
- case ZB_MODE_RGB24: break;
-#endif
#if TGL_FEATURE_16_BITS == 1
case ZB_MODE_5R6G5B:
-// zb->nb_colors = 0;
break;
#endif
@@ -101,7 +92,7 @@
gl_free(zb->zbuf);
zb->zbuf = gl_malloc(size);
-
+ if(zb->zbuf == NULL) exit(1);
if (zb->frame_buffer_allocated)
gl_free(zb->pbuf);