diff --git a/graphics/tinygl/.gitignore b/graphics/tinygl/.gitignore new file mode 100644 index 000000000..5723a78b8 --- /dev/null +++ b/graphics/tinygl/.gitignore @@ -0,0 +1,2 @@ +/tinygl +/tinygl-*.tar.gz diff --git a/graphics/tinygl/0001-zfeatures-allow-overriding-the-feature-switches-at-b.patch b/graphics/tinygl/0001-zfeatures-allow-overriding-the-feature-switches-at-b.patch new file mode 100644 index 000000000..06ed1760f --- /dev/null +++ b/graphics/tinygl/0001-zfeatures-allow-overriding-the-feature-switches-at-b.patch @@ -0,0 +1,228 @@ +From 7b0dd7f5ccc8826f8c49977b1d26f640fd959738 Mon Sep 17 00:00:00 2001 +From: Alan Carvalho de Assis +Date: Thu, 24 Sep 2026 09:45:18 -0300 +Subject: [PATCH 1/2] zfeatures: allow overriding the feature switches at build + time + +Wrap every tunable TGL_FEATURE_* (and related) definition in +include/zfeatures.h, and POLYGON_MAX_VERTEX in src/zgl.h, with #ifndef +so that a build system can select the features with -D compiler flags +instead of editing the header. + +NuttX uses this to drive the TinyGL features from Kconfig +(CONFIG_TINYGL_*). The defaults are unchanged. +--- + include/zfeatures.h | 66 +++++++++++++++++++++++++++++++++++++++++++++ + src/zgl.h | 2 ++ + 2 files changed, 68 insertions(+) + +diff --git a/include/zfeatures.h b/include/zfeatures.h +index aa7a14c..a67249e 100644 +--- a/include/zfeatures.h ++++ b/include/zfeatures.h +@@ -6,80 +6,134 @@ + Enables setting the error flags when there's an error, so you can check it with glGetError + Disabling this has slight performance gains. + */ ++#ifndef TGL_FEATURE_ERROR_CHECK + #define TGL_FEATURE_ERROR_CHECK 0 ++#endif + /* + Strict out-of-memory checking. All OpenGL function calls are invalidated (ALL OF THEM) if a GL_OUT_OF_MEMORY error occurs. + This means that TinyGL has to constantly check all gl_malloc() attempts for errors and the state of the error state variable. + The checks slow down the renderer so it is not recommended , but + it's in the GL spec that this should occur. + */ ++#ifndef TGL_FEATURE_STRICT_OOM_CHECKS + #define TGL_FEATURE_STRICT_OOM_CHECKS 0 ++#endif + + /* + 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 + */ ++#ifndef TGL_FEATURE_CUSTOM_MALLOC + #define TGL_FEATURE_CUSTOM_MALLOC 0 ++#endif + + /* + Use Fast Inverse Square Root. Toggleable because it's actually slower on some platforms, + And because some systems may have float types which are incompatible with it. + */ ++#ifndef TGL_FEATURE_FISR + #define TGL_FEATURE_FISR 0 ++#endif + ++#ifndef TGL_FEATURE_ARRAYS + #define TGL_FEATURE_ARRAYS 1 ++#endif + ++#ifndef TGL_FEATURE_DISPLAYLISTS + #define TGL_FEATURE_DISPLAYLISTS 1 ++#endif + ++#ifndef TGL_FEATURE_LIT_TEXTURES + #define TGL_FEATURE_LIT_TEXTURES 1 ++#endif + /*Enable the patternized "discard"-ing of pixels.*/ ++#ifndef TGL_FEATURE_POLYGON_STIPPLE + #define TGL_FEATURE_POLYGON_STIPPLE 1 ++#endif + /*Enable the use of GL_SELECT and GL_FEEDBACK*/ ++#ifndef TGL_FEATURE_ALT_RENDERMODES + #define TGL_FEATURE_ALT_RENDERMODES 0 ++#endif + /* + Enable the rendering of large polygons (in terms of vertex count) + Also enabled the rendering of line loops. + the maximum number of vertices in a polygon is defined in zgl.h + */ ++#ifndef TGL_FEATURE_GL_POLYGON + #define TGL_FEATURE_GL_POLYGON 0 ++#endif + ++#ifndef TGL_FEATURE_BLEND + #define TGL_FEATURE_BLEND 1 ++#endif + ++#ifndef TGL_FEATURE_BLEND_DRAW_PIXELS + #define TGL_FEATURE_BLEND_DRAW_PIXELS 0 ++#endif + /*The width of textures as a power of 2. The default is 8, or 256x256 textures.*/ ++#ifndef TGL_FEATURE_TEXTURE_POW2 + #define TGL_FEATURE_TEXTURE_POW2 8 ++#endif + #define TGL_FEATURE_TEXTURE_DIM (1< +Date: Thu, 24 Sep 2026 09:47:19 -0300 +Subject: [PATCH 2/2] Fix -Wstrict-prototypes warnings + +Declare functions that take no arguments as (void) instead of (). In +C, () means "unspecified arguments", which newer compilers warn about +and which C23 changes meaning of. The public glGetError() declaration +in is included by every application, so the warning showed +up in all users of the library too. +--- + include/GL/gl.h | 2 +- + src/init.c | 2 +- + src/matrix.c | 2 +- + src/memory.c | 2 +- + src/misc.c | 4 ++-- + src/texture.c | 2 +- + src/zgl.h | 6 +++--- + 7 files changed, 10 insertions(+), 10 deletions(-) + +diff --git a/include/GL/gl.h b/include/GL/gl.h +index da16f81..ab4a10b 100644 +--- a/include/GL/gl.h ++++ b/include/GL/gl.h +@@ -932,7 +932,7 @@ void glHint(GLint target,GLint mode); + void glGetIntegerv(GLint pname,GLint *params); + void glGetFloatv(GLint pname, GLfloat *v); + const GLubyte* glGetString(GLenum name); +-GLenum glGetError(); ++GLenum glGetError(void); + void glFrontFace(GLint mode); + + /* opengl 1.2 arrays */ +diff --git a/src/init.c b/src/init.c +index a394759..9220904 100644 +--- a/src/init.c ++++ b/src/init.c +@@ -69,7 +69,7 @@ static void endSharedState(GLContext* c) { + #if TGL_FEATURE_TINYGL_RUNTIME_COMPAT_TEST == 1 + + #define TGL_FLOAT_ERR(a, b) ((a - b) / b) +-static int TinyGLRuntimeCompatibilityTest() { ++static int TinyGLRuntimeCompatibilityTest(void) { + GLfloat t = -0, tf2; + GLint t2 = 1 << 31; + memcpy(&tf2, &t2, 4); +diff --git a/src/matrix.c b/src/matrix.c +index 6234352..2bba0c6 100644 +--- a/src/matrix.c ++++ b/src/matrix.c +@@ -8,7 +8,7 @@ void gl_print_matrix(const GLfloat* m) { + } + } + +-static void gl_matrix_update() { ++static void gl_matrix_update(void) { + GLContext* c = gl_get_context(); + c->matrix_model_projection_updated = (c->matrix_mode <= 1); + } +diff --git a/src/memory.c b/src/memory.c +index 7cf44c5..5d9ae8a 100644 +--- a/src/memory.c ++++ b/src/memory.c +@@ -2,7 +2,7 @@ + * Memory allocator for TinyGL + */ + +-static inline void required_for_compilation_(){ ++static inline void required_for_compilation_(void){ + return; + } + +diff --git a/src/misc.c b/src/misc.c +index c7f1bb7..1b48fa2 100644 +--- a/src/misc.c ++++ b/src/misc.c +@@ -192,7 +192,7 @@ void glopPolygonOffset(GLParam* p) { + c->offset_units = p[2].f; + } + +-GLenum glGetError() { ++GLenum glGetError(void) { + #if TGL_FEATURE_ERROR_CHECK == 1 + GLContext* c = gl_get_context(); + GLenum eflag = c->error_flag; +@@ -256,4 +256,4 @@ void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format + /* TODO: implement read pixels.*/ + } + +-void glFinish() { return; } ++void glFinish(void) { return; } +diff --git a/src/texture.c b/src/texture.c +index c2e5364..470a621 100644 +--- a/src/texture.c ++++ b/src/texture.c +@@ -109,7 +109,7 @@ GLTexture* alloc_texture(GLint h) { + return t; + } + +-void glInitTextures() { ++void glInitTextures(void) { + /* textures */ + GLContext* c = gl_get_context(); + c->texture_2d_enabled = 0; +diff --git a/src/zgl.h b/src/zgl.h +index aa1ea70..cd82c00 100644 +--- a/src/zgl.h ++++ b/src/zgl.h +@@ -429,8 +429,8 @@ void glopTranslate(GLParam *p);*/ + void gl_enable_disable_light(GLint light, GLint v); + void gl_shade_vertex(GLVertex* v); + +-void glInitTextures(); +-void glEndTextures(); ++void glInitTextures(void); ++void glEndTextures(void); + GLTexture* alloc_texture(GLint h); + + /* image_util.c */ +@@ -456,7 +456,7 @@ GLSpecBuf* specbuf_get_buffer(const GLint shininess_i, const GLfloat shininess); + /* this clip epsilon is needed to avoid some rounding errors after + several clipping stages */ + +-static void gl_eval_viewport() { ++static void gl_eval_viewport(void) { + GLContext* c = gl_get_context(); + GLViewport* v; + GLfloat zsize = (1 << (ZB_Z_BITS + ZB_POINT_Z_FRAC_BITS)); +-- +2.43.0 + diff --git a/graphics/tinygl/0003-zbuffer-do-not-over-read-the-source-in-ZB_copyFrameB.patch b/graphics/tinygl/0003-zbuffer-do-not-over-read-the-source-in-ZB_copyFrameB.patch new file mode 100644 index 000000000..02094b791 --- /dev/null +++ b/graphics/tinygl/0003-zbuffer-do-not-over-read-the-source-in-ZB_copyFrameB.patch @@ -0,0 +1,43 @@ +From cb43569fb11bb988335056622f6f8db4ac2c7a14 Mon Sep 17 00:00:00 2001 +From: Alan Carvalho de Assis +Date: Thu, 24 Sep 2026 09:47:54 -0300 +Subject: [PATCH] zbuffer: do not over-read the source in + ZB_copyFrameBuffer() + +ZB_copyBuffer() copied `linesize` bytes per line, where linesize is the +pitch of the destination buffer. When the destination is wider than +the TinyGL buffer (e.g. a hardware framebuffer whose lines are padded), +this read past the end of every source line and, on the last line, past +the end of the TinyGL pixel buffer. + +Copy zb->linesize bytes, the size of a TinyGL line, and keep using the +destination pitch only to step through the destination. +--- + src/zbuffer.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/zbuffer.c b/src/zbuffer.c +index 6321340..e3e822c 100644 +--- a/src/zbuffer.c ++++ b/src/zbuffer.c +@@ -131,7 +131,7 @@ static void ZB_copyBuffer(ZBuffer* zb, void* buf, GLint linesize) { + *(((PIXEL*)p1) + i) = *(q + i); + } + #else +- memcpy(p1, q, linesize); ++ memcpy(p1, q, zb->linesize); + #endif + + +@@ -148,7 +148,7 @@ static void ZB_copyBuffer(ZBuffer* zb, void* buf, GLint linesize) { + *(((PIXEL*)p1) + i) = *(q + i); + } + #else +- memcpy(p1, q, linesize); ++ memcpy(p1, q, zb->linesize); + #endif + } + #endif +-- +2.43.0 + diff --git a/graphics/tinygl/0004-zbuffer.h-make-the-default-allocator-wrappers-static.patch b/graphics/tinygl/0004-zbuffer.h-make-the-default-allocator-wrappers-static.patch new file mode 100644 index 000000000..22023d898 --- /dev/null +++ b/graphics/tinygl/0004-zbuffer.h-make-the-default-allocator-wrappers-static.patch @@ -0,0 +1,34 @@ +From a3c2ac6a18ef6a91fcbbe6027d7d07f7a15a08f6 Mon Sep 17 00:00:00 2001 +From: Alan Carvalho de Assis +Date: Thu, 24 Sep 2026 09:50:16 -0300 +Subject: [PATCH] zbuffer.h: make the default allocator wrappers static inline + +gl_malloc(), gl_zalloc() and gl_free() are defined in the public + as plain static functions when TGL_FEATURE_CUSTOM_MALLOC is +0. Every application that includes the header but does not call them +then gets three -Wunused-function warnings. Declaring them static +inline keeps the same behaviour without the warnings. +--- + include/zbuffer.h | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/include/zbuffer.h b/include/zbuffer.h +index 886eb72..c54c9bd 100644 +--- a/include/zbuffer.h ++++ b/include/zbuffer.h +@@ -354,9 +354,9 @@ void *gl_zalloc(GLint size); + #else + #include + #include +-static void gl_free(void* p) { free(p); } +-static void* gl_malloc(GLint size) { return malloc(size); } +-static void* gl_zalloc(GLint size) { return calloc(1, size); } ++static inline void gl_free(void* p) { free(p); } ++static inline void* gl_malloc(GLint size) { return malloc(size); } ++static inline void* gl_zalloc(GLint size) { return calloc(1, size); } + #endif + + #endif /* _tgl_zbuffer_h_ */ +-- +2.43.0 + diff --git a/graphics/tinygl/0005-Declare-the-input-array-parameters-const-as-OpenGL-d.patch b/graphics/tinygl/0005-Declare-the-input-array-parameters-const-as-OpenGL-d.patch new file mode 100644 index 000000000..96726ec14 --- /dev/null +++ b/graphics/tinygl/0005-Declare-the-input-array-parameters-const-as-OpenGL-d.patch @@ -0,0 +1,182 @@ +From 202a4eba444f29055174ee33394a608607c4d35a Mon Sep 17 00:00:00 2001 +From: Alan Carvalho de Assis +Date: Sat, 26 Sep 2026 13:51:30 -0300 +Subject: [PATCH] Declare the input array parameters const, as OpenGL does + +glMaterialfv(), glLightfv(), glLightModelfv(), the glVertex*v(), +glColor*v(), glNormal*v(), glTexCoord*v() and glRasterPos*v() families +only read the array they are passed, and OpenGL declares that parameter +const. Do the same, so that callers can pass constant data, for +example "static const GLfloat red[4]", without casts or warnings. +--- + include/GL/gl.h | 28 ++++++++++++++-------------- + src/api.c | 16 ++++++++-------- + src/zraster.c | 6 +++--- + 3 files changed, 25 insertions(+), 25 deletions(-) + +diff --git a/include/GL/gl.h b/include/GL/gl.h +index ab4a10b..1f651fc 100644 +--- a/include/GL/gl.h ++++ b/include/GL/gl.h +@@ -804,26 +804,26 @@ void glPlotPixel(GLint x, GLint y, GLuint pixel); + #define PROTO_GL1(name) \ + void gl ## name ## 1f(GLfloat); \ + void gl ## name ## 1d(GLdouble); \ +-void gl ## name ## 1fv(GLfloat *); \ +-void gl ## name ## 1dv(GLdouble *); ++void gl ## name ## 1fv(const GLfloat *); \ ++void gl ## name ## 1dv(const GLdouble *); + + #define PROTO_GL2(name) \ + void gl ## name ## 2f(GLfloat ,GLfloat); \ + void gl ## name ## 2d(GLdouble ,GLdouble); \ +-void gl ## name ## 2fv(GLfloat *); \ +-void gl ## name ## 2dv(GLdouble *); ++void gl ## name ## 2fv(const GLfloat *); \ ++void gl ## name ## 2dv(const GLdouble *); + + #define PROTO_GL3(name) \ + void gl ## name ## 3f(GLfloat ,GLfloat ,GLfloat); \ + void gl ## name ## 3d(GLdouble ,GLdouble ,GLdouble); \ +-void gl ## name ## 3fv(GLfloat *); \ +-void gl ## name ## 3dv(GLdouble *); ++void gl ## name ## 3fv(const GLfloat *); \ ++void gl ## name ## 3dv(const GLdouble *); + + #define PROTO_GL4(name) \ + void gl ## name ## 4f(GLfloat ,GLfloat ,GLfloat, GLfloat ); \ + void gl ## name ## 4d(GLdouble ,GLdouble ,GLdouble, GLdouble ); \ +-void gl ## name ## 4fv(GLfloat *); \ +-void gl ## name ## 4dv(GLdouble *); ++void gl ## name ## 4fv(const GLfloat *); \ ++void gl ## name ## 4dv(const GLdouble *); + + PROTO_GL2(Vertex) + PROTO_GL3(Vertex) +@@ -915,14 +915,14 @@ GLboolean glAreTexturesResident( GLsizei n, + GLboolean glIsTexture( GLuint texture); + /* lighting */ + +-void glMaterialfv(GLint mode,GLint type,GLfloat *v); ++void glMaterialfv(GLint mode,GLint type,const GLfloat *v); + void glMaterialf(GLint mode,GLint type,GLfloat v); + void glColorMaterial(GLint mode,GLint type); + +-void glLightfv(GLint light,GLint type,GLfloat *v); ++void glLightfv(GLint light,GLint type,const GLfloat *v); + void glLightf(GLint light,GLint type,GLfloat v); + void glLightModeli(GLint pname,GLint param); +-void glLightModelfv(GLint pname,GLfloat *param); ++void glLightModelfv(GLint pname,const GLfloat *param); + + /* misc */ + +@@ -978,9 +978,9 @@ void glRasterPos2f(GLfloat, GLfloat); + void glRasterPos3f(GLfloat, GLfloat, GLfloat); + void glRasterPos4f(GLfloat, GLfloat, GLfloat, GLfloat); + +-void glRasterPos2fv(GLfloat* v); +-void glRasterPos3fv(GLfloat* v); +-void glRasterPos4fv(GLfloat* v); ++void glRasterPos2fv(const GLfloat* v); ++void glRasterPos3fv(const GLfloat* v); ++void glRasterPos4fv(const GLfloat* v); + void glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, void* data); + void glPixelZoom(GLfloat x, GLfloat y); + +diff --git a/src/api.c b/src/api.c +index e310a1b..3f082b5 100644 +--- a/src/api.c ++++ b/src/api.c +@@ -17,7 +17,7 @@ void glVertex2f(GLfloat x, GLfloat y) { glVertex4f(x, y, 0, 1); } + + void glVertex3f(GLfloat x, GLfloat y, GLfloat z) { glVertex4f(x, y, z, 1); } + +-void glVertex3fv(GLfloat* v) { glVertex4f(v[0], v[1], v[2], 1); } ++void glVertex3fv(const GLfloat* v) { glVertex4f(v[0], v[1], v[2], 1); } + + /* glNormal */ + +@@ -40,7 +40,7 @@ void glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) { + glEnd(); + } + +-void glNormal3fv(GLfloat* v) { glNormal3f(v[0], v[1], v[2]); } ++void glNormal3fv(const GLfloat* v) { glNormal3f(v[0], v[1], v[2]); } + + /* glColor */ + +@@ -58,7 +58,7 @@ void glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a) { + gl_add_op(p); + } + +-void glColor4fv(GLfloat* v) { ++void glColor4fv(const GLfloat* v) { + GLParam p[8]; + #include "error_check_no_context.h" + p[0].op = OP_Color; +@@ -75,7 +75,7 @@ void glColor4fv(GLfloat* v) { + + void glColor3f(GLfloat x, GLfloat y, GLfloat z) { glColor4f(x, y, z, 1); } + +-void glColor3fv(GLfloat* v) { glColor4f(v[0], v[1], v[2], 1); } ++void glColor3fv(const GLfloat* v) { glColor4f(v[0], v[1], v[2], 1); } + + /* TexCoord */ + +@@ -93,7 +93,7 @@ void glTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q) { + + void glTexCoord2f(GLfloat s, GLfloat t) { glTexCoord4f(s, t, 0, 1); } + +-void glTexCoord2fv(GLfloat* v) { glTexCoord4f(v[0], v[1], 0, 1); } ++void glTexCoord2fv(const GLfloat* v) { glTexCoord4f(v[0], v[1], 0, 1); } + + void glEdgeFlag(GLint flag) { + GLParam p[2]; +@@ -360,7 +360,7 @@ void glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLd + + /* lightening */ + +-void glMaterialfv(GLint mode, GLint type, GLfloat* v) { ++void glMaterialfv(GLint mode, GLint type, const GLfloat* v) { + GLParam p[7]; + GLint i, n; + #define NEED_CONTEXT +@@ -410,7 +410,7 @@ void glColorMaterial(GLint mode, GLint type) { + gl_add_op(p); + } + +-void glLightfv(GLint light, GLint type, GLfloat* v) { ++void glLightfv(GLint light, GLint type, const GLfloat* v) { + GLParam p[7]; + GLint i; + #include "error_check_no_context.h" +@@ -450,7 +450,7 @@ void glLightModeli(GLint pname, GLint param) { + gl_add_op(p); + } + +-void glLightModelfv(GLint pname, GLfloat* param) { ++void glLightModelfv(GLint pname, const GLfloat* param) { + GLParam p[6]; + GLint i; + #include "error_check_no_context.h" +diff --git a/src/zraster.c b/src/zraster.c +index d19cfb2..334e317 100644 +--- a/src/zraster.c ++++ b/src/zraster.c +@@ -67,9 +67,9 @@ void glopRasterPos(GLParam* p) { + void glRasterPos2f(GLfloat x, GLfloat y) { glRasterPos4f(x, y, 0, 1); } + void glRasterPos3f(GLfloat x, GLfloat y, GLfloat z) { glRasterPos4f(x, y, z, 1); } + +-void glRasterPos2fv(GLfloat* v) { glRasterPos2f(v[0], v[1]); } +-void glRasterPos3fv(GLfloat* v) { glRasterPos3f(v[0], v[1], v[2]); } +-void glRasterPos4fv(GLfloat* v) { glRasterPos4f(v[0], v[1], v[2], v[3]); } ++void glRasterPos2fv(const GLfloat* v) { glRasterPos2f(v[0], v[1]); } ++void glRasterPos3fv(const GLfloat* v) { glRasterPos3f(v[0], v[1], v[2]); } ++void glRasterPos4fv(const GLfloat* v) { glRasterPos4f(v[0], v[1], v[2], v[3]); } + + void glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, void* data) { + /* TODO: Come up with a clever scheme for storing the data to avoid pointer dependency. */ +-- +2.43.0 + diff --git a/graphics/tinygl/CMakeLists.txt b/graphics/tinygl/CMakeLists.txt new file mode 100644 index 000000000..a58cb154c --- /dev/null +++ b/graphics/tinygl/CMakeLists.txt @@ -0,0 +1,153 @@ +# ############################################################################## +# apps/graphics/tinygl/CMakeLists.txt +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more contributor +# license agreements. See the NOTICE file distributed with this work for +# additional information regarding copyright ownership. The ASF licenses this +# file to you under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +# +# ############################################################################## + +if(CONFIG_GRAPHICS_TINYGL) + + # ############################################################################ + # Fetch and patch TinyGL + # ############################################################################ + + set(TINYGL_DIR ${CMAKE_CURRENT_LIST_DIR}/tinygl) + + if(NOT EXISTS ${TINYGL_DIR}) + file(GLOB TINYGL_PATCHES + ${CMAKE_CURRENT_LIST_DIR}/[0-9][0-9][0-9][0-9]-*.patch) + list(SORT TINYGL_PATCHES) + set(TINYGL_PATCH_COMMAND "") + foreach(p ${TINYGL_PATCHES}) + list( + APPEND + TINYGL_PATCH_COMMAND + COMMAND + patch + -s + -N + -p1 + -d + ${TINYGL_DIR} + -i + ${p}) + endforeach() + list(POP_FRONT TINYGL_PATCH_COMMAND) + + FetchContent_Declare( + tinygl_fetch + URL ${CONFIG_TINYGL_URL}/${CONFIG_TINYGL_VERSION}.tar.gz SOURCE_DIR + ${TINYGL_DIR} BINARY_DIR + ${NUTTX_BINARY_DIR}/apps/graphics/tinygl/tinygl + PATCH_COMMAND ${TINYGL_PATCH_COMMAND} + DOWNLOAD_NO_PROGRESS true + TIMEOUT 60) + + FetchContent_GetProperties(tinygl_fetch) + + if(NOT tinygl_fetch_POPULATED) + FetchContent_Populate(tinygl_fetch) + endif() + endif() + + # ############################################################################ + # Feature switches (they change public structures, so export them) + # ############################################################################ + + macro(tinygl_bool var cfg) + if(${cfg}) + set(${var} 1) + else() + set(${var} 0) + endif() + endmacro() + + tinygl_bool(TGL_32 CONFIG_TINYGL_RENDER_BITS_32) + tinygl_bool(TGL_16 CONFIG_TINYGL_RENDER_BITS_16) + tinygl_bool(TGL_SELECT CONFIG_TINYGL_SELECT) + tinygl_bool(TGL_POLYGON CONFIG_TINYGL_GL_POLYGON) + tinygl_bool(TGL_BLEND CONFIG_TINYGL_BLEND) + tinygl_bool(TGL_BLEND_DP CONFIG_TINYGL_BLEND_DRAW_PIXELS) + tinygl_bool(TGL_STIPPLE CONFIG_TINYGL_POLYGON_STIPPLE) + tinygl_bool(TGL_NODRAW CONFIG_TINYGL_NO_DRAW_COLOR) + tinygl_bool(TGL_ERRCHK CONFIG_TINYGL_ERROR_CHECK) + + set(TINYGL_DEFINES + TGL_FEATURE_32_BITS=${TGL_32} + TGL_FEATURE_16_BITS=${TGL_16} + TGL_FEATURE_TEXTURE_POW2=${CONFIG_TINYGL_TEXTURE_POW2} + TGL_FEATURE_ALT_RENDERMODES=${TGL_SELECT} + TGL_FEATURE_GL_POLYGON=${TGL_POLYGON} + TGL_FEATURE_BLEND=${TGL_BLEND} + TGL_FEATURE_BLEND_DRAW_PIXELS=${TGL_BLEND_DP} + TGL_FEATURE_POLYGON_STIPPLE=${TGL_STIPPLE} + TGL_FEATURE_NO_DRAW_COLOR=${TGL_NODRAW} + TGL_FEATURE_ERROR_CHECK=${TGL_ERRCHK}) + + if(CONFIG_TINYGL_POLYGON_MAX_VERTEX) + list(APPEND TINYGL_DEFINES + POLYGON_MAX_VERTEX=${CONFIG_TINYGL_POLYGON_MAX_VERTEX}) + endif() + + # ############################################################################ + # Library + # ############################################################################ + + set(SRCS + ${TINYGL_DIR}/src/accum.c + ${TINYGL_DIR}/src/api.c + ${TINYGL_DIR}/src/arrays.c + ${TINYGL_DIR}/src/clear.c + ${TINYGL_DIR}/src/clip.c + ${TINYGL_DIR}/src/get.c + ${TINYGL_DIR}/src/image_util.c + ${TINYGL_DIR}/src/init.c + ${TINYGL_DIR}/src/light.c + ${TINYGL_DIR}/src/list.c + ${TINYGL_DIR}/src/matrix.c + ${TINYGL_DIR}/src/memory.c + ${TINYGL_DIR}/src/misc.c + ${TINYGL_DIR}/src/msghandling.c + ${TINYGL_DIR}/src/select.c + ${TINYGL_DIR}/src/specbuf.c + ${TINYGL_DIR}/src/texture.c + ${TINYGL_DIR}/src/vertex.c + ${TINYGL_DIR}/src/zbuffer.c + ${TINYGL_DIR}/src/zline.c + ${TINYGL_DIR}/src/zmath.c + ${TINYGL_DIR}/src/zpostprocess.c + ${TINYGL_DIR}/src/zraster.c + ${TINYGL_DIR}/src/ztext.c + ${TINYGL_DIR}/src/ztriangle.c) + + nuttx_add_library(tinygl) + target_sources(tinygl PRIVATE ${SRCS}) + target_compile_options( + tinygl PRIVATE -Wno-shadow -Wno-undef -Wno-unused-function + -Wno-unknown-pragmas -Wno-unused-variable) + target_compile_definitions(tinygl PRIVATE NDEBUG) + + set_property( + TARGET nuttx + APPEND + PROPERTY NUTTX_INCLUDE_DIRECTORIES ${TINYGL_DIR}/include) + set_property( + TARGET nuttx + APPEND + PROPERTY NUTTX_DEFINITIONS ${TINYGL_DEFINES}) +endif() diff --git a/graphics/tinygl/Kconfig b/graphics/tinygl/Kconfig new file mode 100644 index 000000000..f9dda35c7 --- /dev/null +++ b/graphics/tinygl/Kconfig @@ -0,0 +1,108 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +menuconfig GRAPHICS_TINYGL + bool "TinyGL software OpenGL 1.1 subset" + default n + ---help--- + Enable TinyGL, a small software-only implementation of a subset of + OpenGL 1.1 originally written by Fabrice Bellard and maintained by + C-Chads (https://github.com/C-Chads/tinygl). + + TinyGL renders into a memory buffer (struct ZBuffer). The result + can be copied to a NuttX framebuffer device (/dev/fbN) with + ZB_copyFrameBuffer(), or TinyGL can render directly into the + mmap()ed framebuffer memory. + + The sources are downloaded from GitHub at build time and patched + for NuttX (see the patches in apps/graphics/tinygl). + +if GRAPHICS_TINYGL + +config TINYGL_URL + string "TinyGL download URL" + default "https://github.com/C-Chads/tinygl/archive" + ---help--- + Base URL of the TinyGL source archives. The file + .tar.gz is downloaded from here. + +config TINYGL_VERSION + string "TinyGL git revision" + default "36a7987e7bebfda19615ea33341b1cc0ff9c3b13" + ---help--- + Git commit of C-Chads/tinygl to download. The NuttX patches are + made against this revision. + +choice + prompt "TinyGL pixel format" + default TINYGL_RENDER_BITS_32 + +config TINYGL_RENDER_BITS_32 + bool "32 bits per pixel (XRGB8888)" + +config TINYGL_RENDER_BITS_16 + bool "16 bits per pixel (RGB565)" + +endchoice # TinyGL pixel format + +config TINYGL_TEXTURE_POW2 + int "Texture size (log2)" + default 8 + range 4 10 + ---help--- + TinyGL uses a single, fixed texture size set at compile time. All + textures are resized to (1 << TINYGL_TEXTURE_POW2) pixels square. + The default of 8 means 256x256 textures, which use 256KiB each in + 32-bit mode. + +config TINYGL_SELECT + bool "Support GL_SELECT and GL_FEEDBACK render modes" + default n + ---help--- + Enable glRenderMode(GL_SELECT) (object picking with + glSelectBuffer()/glLoadName()) and GL_FEEDBACK. Enabling this makes + all rendering slightly slower. + +config TINYGL_GL_POLYGON + bool "Support GL_POLYGON and GL_LINE_LOOP" + default y + ---help--- + Enable rendering of general polygons (up to + TINYGL_POLYGON_MAX_VERTEX vertices) and line loops. + +config TINYGL_POLYGON_MAX_VERTEX + int "Maximum number of vertices in a GL_POLYGON" + default 16 + depends on TINYGL_GL_POLYGON + +config TINYGL_BLEND + bool "Support blending (glBlendFunc)" + default y + +config TINYGL_BLEND_DRAW_PIXELS + bool "Apply blending to glDrawPixels()" + default n + depends on TINYGL_BLEND + +config TINYGL_POLYGON_STIPPLE + bool "Support polygon stipple (glPolygonStipple)" + default y + +config TINYGL_NO_DRAW_COLOR + bool "Skip texels with the no-draw color (0xff00ff)" + default y + ---help--- + When enabled, texture mapped pixels whose color is exactly + magenta (0xff00ff) are not drawn, which gives cheap cut-out + textures. + +config TINYGL_ERROR_CHECK + bool "Enable glGetError() error checking" + default n + ---help--- + Set GL error flags on invalid calls so that they can be read with + glGetError(). Useful for debugging, slightly slower. + +endif # GRAPHICS_TINYGL diff --git a/graphics/tinygl/Make.defs b/graphics/tinygl/Make.defs new file mode 100644 index 000000000..fdf7e5f77 --- /dev/null +++ b/graphics/tinygl/Make.defs @@ -0,0 +1,55 @@ +############################################################################ +# apps/graphics/tinygl/Make.defs +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ifneq ($(CONFIG_GRAPHICS_TINYGL),) +CONFIGURED_APPS += $(APPDIR)/graphics/tinygl + +# TinyGL public headers: , and + +CFLAGS += ${INCDIR_PREFIX}$(APPDIR)/graphics/tinygl/tinygl/include +CXXFLAGS += ${INCDIR_PREFIX}$(APPDIR)/graphics/tinygl/tinygl/include + +# The TinyGL feature switches change the layout of public structures (for +# example struct ZBuffer and the PIXEL type), so they must be seen by both +# the library and every application that includes the TinyGL headers. + +tgl_bool = $(if $(filter y,$(1)),1,0) + +TINYGL_DEFINES = -DTGL_FEATURE_32_BITS=$(call tgl_bool,$(CONFIG_TINYGL_RENDER_BITS_32)) +TINYGL_DEFINES += -DTGL_FEATURE_16_BITS=$(call tgl_bool,$(CONFIG_TINYGL_RENDER_BITS_16)) +TINYGL_DEFINES += -DTGL_FEATURE_TEXTURE_POW2=$(CONFIG_TINYGL_TEXTURE_POW2) +TINYGL_DEFINES += -DTGL_FEATURE_ALT_RENDERMODES=$(call tgl_bool,$(CONFIG_TINYGL_SELECT)) +TINYGL_DEFINES += -DTGL_FEATURE_GL_POLYGON=$(call tgl_bool,$(CONFIG_TINYGL_GL_POLYGON)) +TINYGL_DEFINES += -DTGL_FEATURE_BLEND=$(call tgl_bool,$(CONFIG_TINYGL_BLEND)) +TINYGL_DEFINES += -DTGL_FEATURE_BLEND_DRAW_PIXELS=$(call tgl_bool,$(CONFIG_TINYGL_BLEND_DRAW_PIXELS)) +TINYGL_DEFINES += -DTGL_FEATURE_POLYGON_STIPPLE=$(call tgl_bool,$(CONFIG_TINYGL_POLYGON_STIPPLE)) +TINYGL_DEFINES += -DTGL_FEATURE_NO_DRAW_COLOR=$(call tgl_bool,$(CONFIG_TINYGL_NO_DRAW_COLOR)) +TINYGL_DEFINES += -DTGL_FEATURE_ERROR_CHECK=$(call tgl_bool,$(CONFIG_TINYGL_ERROR_CHECK)) + +ifneq ($(CONFIG_TINYGL_POLYGON_MAX_VERTEX),) +TINYGL_DEFINES += -DPOLYGON_MAX_VERTEX=$(CONFIG_TINYGL_POLYGON_MAX_VERTEX) +endif + +CFLAGS += $(TINYGL_DEFINES) +CXXFLAGS += $(TINYGL_DEFINES) + +endif diff --git a/graphics/tinygl/Makefile b/graphics/tinygl/Makefile new file mode 100644 index 000000000..ef45a578d --- /dev/null +++ b/graphics/tinygl/Makefile @@ -0,0 +1,100 @@ +############################################################################ +# apps/graphics/tinygl/Makefile +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(APPDIR)/Make.defs + +# TinyGL software OpenGL library + +TINYGL_URL = $(patsubst "%",%,$(strip $(CONFIG_TINYGL_URL))) +TINYGL_VERSION = $(patsubst "%",%,$(strip $(CONFIG_TINYGL_VERSION))) +TINYGL_TARBALL = tinygl-$(TINYGL_VERSION).tar.gz +TINYGL_UNPACK = tinygl +TINYGL_PATCHES = $(sort $(wildcard $(CURDIR)/[0-9][0-9][0-9][0-9]-*.patch)) + +SRC = $(TINYGL_UNPACK)/src + +CSRCS = $(SRC)/accum.c +CSRCS += $(SRC)/api.c +CSRCS += $(SRC)/arrays.c +CSRCS += $(SRC)/clear.c +CSRCS += $(SRC)/clip.c +CSRCS += $(SRC)/get.c +CSRCS += $(SRC)/image_util.c +CSRCS += $(SRC)/init.c +CSRCS += $(SRC)/light.c +CSRCS += $(SRC)/list.c +CSRCS += $(SRC)/matrix.c +CSRCS += $(SRC)/memory.c +CSRCS += $(SRC)/misc.c +CSRCS += $(SRC)/msghandling.c +CSRCS += $(SRC)/select.c +CSRCS += $(SRC)/specbuf.c +CSRCS += $(SRC)/texture.c +CSRCS += $(SRC)/vertex.c +CSRCS += $(SRC)/zbuffer.c +CSRCS += $(SRC)/zline.c +CSRCS += $(SRC)/zmath.c +CSRCS += $(SRC)/zpostprocess.c +CSRCS += $(SRC)/zraster.c +CSRCS += $(SRC)/ztext.c +CSRCS += $(SRC)/ztriangle.c + +# TinyGL is third party code, silence the warnings that the NuttX build +# enables but that upstream does not care about. + +CFLAGS += -Wno-shadow -Wno-undef -Wno-unused-function -Wno-unknown-pragmas +CFLAGS += -Wno-unused-variable -DNDEBUG + +$(TINYGL_TARBALL): + $(ECHO_BEGIN)"Downloading: $(TINYGL_TARBALL)" + $(Q) curl -L $(if $(V),,-Ss) -o $(TINYGL_TARBALL) \ + $(TINYGL_URL)/$(TINYGL_VERSION).tar.gz + $(ECHO_END) + +# The stamp file marks a complete unpack + patch, so that a partially +# created tree (for example an object directory) is never mistaken for +# the sources. + +TINYGL_STAMP = $(TINYGL_UNPACK)/.nuttx_patched + +$(TINYGL_STAMP): $(TINYGL_TARBALL) + $(ECHO_BEGIN)"Unpacking: $(TINYGL_TARBALL) -> $(TINYGL_UNPACK)" + $(Q) rm -rf $(TINYGL_UNPACK) tinygl-$(TINYGL_VERSION) + $(Q) tar zxf $(TINYGL_TARBALL) + $(Q) mv tinygl-$(TINYGL_VERSION) $(TINYGL_UNPACK) + $(Q) for p in $(TINYGL_PATCHES); do \ + patch -s -N -p1 -d $(TINYGL_UNPACK) < $$p || exit 1; \ + done + $(Q) touch $@ + $(ECHO_END) + +# Download and unpack tarball if no git repo found + +ifeq ($(wildcard $(TINYGL_UNPACK)/.git),) +context:: $(TINYGL_STAMP) + +distclean:: + $(call DELDIR, $(TINYGL_UNPACK)) + $(call DELFILE, $(TINYGL_TARBALL)) +endif + +include $(APPDIR)/Application.mk