erkkah / tigr Goto Github PK
View Code? Open in Web Editor NEWTIGR - the TIny GRaphics library for Windows, macOS, Linux, iOS and Android.
License: Other
TIGR - the TIny GRaphics library for Windows, macOS, Linux, iOS and Android.
License: Other
As tiyle says.
Thanks
I use tigr under Windows 10 Pro 64 bit.
Please, say, where the tigr stores the Widow last position and state (is maximized) between the exe restarts?
Hi. Whenever I try to use the fullscreen mode TIGR_FULLSCREEN on windows, it seems like part of the screen is cutoff when I use the maximum resolution. I realized this while trying to blit an image. Instead if I use TIGR_AUTO | TIGR_FULLSCREEN everything is fine but the resolution used is smaller than the actual resolution of my screen. I am not quite sure what the issues is, but it seems like there's some scaling factor that TIGR applies which is off.
Hope more people can use tigr lib :)
https://github.com/Angluca/tigr-nim
Can tigrFont generate support '中文' fonts (>=15MB .ttf) ?
I haven't tried and installed go-lang, So ask you first .
Thank you for tigr! I've been having a lot of fun with it.
One thing I'm having trouble with though is that I have been finding that the call to wglMakeCurrent on Windows is very slow, ~10-15 ms.
I would really like to use tigr for some GUIs at work (small, no dependencies, and responsive!), but I would like the application to not take so much time just to draw.
I have not been able to figure out the root cause here: there are forum threads discussing similar problems, even similar slow downs, but it is not at all clear what is wrong.
I tried to avoid the call to wglMakeCurrent by comparing wglGetCurrentContext and the hglrc field of GLStuff, but I'm not clear enough on the design to know which calls might be omitted if we are already in the current context.
Do you have any thoughts about this? The lines I'm looking at are:
Line 210 in ff7307a
and especially
Line 215 in ff7307a
which seems to be what is causing the slow down.
Thank you!
Hey, I forgot to tell you about this. Maybe you can extract some ideas from this repo and make a pure C solution for Android too, so you merge Android support back into tigr/master.
https://github.com/cnlohr/rawdrawandroid
I made a way to draw quadratic and cubic bezier curves, but I'm not going to bother with making a pull request cause of the problem described here that I had earlier for the pr with the circles.
https://stackoverflow.com/questions/37344280/git-diff-is-showing-full-file-has-changed-for-a-single-line-change-but-only-for
Heres the code for the two bezier drawing functions:
#define lerp(a, b, t) ((a) + ((b) - (a)) * (t))
void tigrQuadBezier(Tigr * screen, int x0, int y0,
int x1, int y1, int x2, int y2,
TPixel color){
float px = x0, py = y0;
for (float t = 0.0; t <= 1.0; t += 0.01){
float lx = lerp(x0, x1, t);
float ly = lerp(y0, y1, t);
float rx = lerp(x1, x2, t);
float ry = lerp(y1, y2, t);
float fx = lerp(lx, rx, t);
float fy = lerp(ly, ry, t);
tigrLine(screen, (int)fx, (int)fy, px, py, color);
px = fx;
py = fy;
}
}
void tigrCubicBezier(Tigr * screen, int x0, int y0,
int x1, int y1, int x2, int y2,
int x3, int y3,
TPixel color){
float px = x0, py = y0;
for (float t = 0.0; t <= 1.0; t += 0.01){
float lx = lerp(x0, x1, t);
float ly = lerp(y0, y1, t);
float mx = lerp(x1, x2, t);
float my = lerp(y1, y2, t);
float rx = lerp(x2, x3, t);
float ry = lerp(y2, y3, t);
float gx = lerp(lx, mx, t);
float gy = lerp(ly, my, t);
float hx = lerp(mx, rx, t);
float hy = lerp(my, ry, t);
float fx = lerp(gx, hx, t);
float fy = lerp(gy, hy, t);
tigrLine(screen, (int)fx, (int)fy, px, py, color);
px = fx;
py = fy;
}
}
I also have a test file attached that shows them in action.
build for that file : g++ tigr.c test.cpp -o test -lopengl32 -lgdi32 -lWinmm
(Made me do it as a txt file for some reason)
I'm assuming that you want the viewport to fit to the window, so I guess this is a bug.
I run this example on MacBook Pro Apple M2 Ventura.
Hello,
on PinePhone (running Mobian, Phosh on Wayland) tigr crashes out with a rather opaque GLXBadFBConfig error.
glxinfo | grep -e "OpenGL version" -e "Core" -e "Compatible"
returns OpenGL version string: 2.1 Mesa 22.3.6
Steps to reproduce with the tigr example:
cd example/demo
make demo
./demo
FWIW MESA_GL_VERSION_OVERRIDE=2.1 ./demo
did not help.
After having spent some time with it, I have to say that I really love the simplicity and size of it. I was wondering though, is it possible to change the FPS limit?
Error:
src/tigr.c:2744:18: error: no matching function for call to 'objc_msgSend'
It looks like they changed the function signature for objc_msgSend, but it's deprecated anyway. Any idea how to fix this?
tigrClone
Tigr * tigrClone(Tigr * bmp){
Tigr * new_bmp = tigrBitmap(bmp->w, bmp->h);
for (int y = 0; y < bmp->h; y++){
memcpy(new_bmp->pix + y*bmp->w, bmp->pix + y*bmp->w, bmp->w*sizeof(TPixel));
}
return new_bmp;
}
This function is pretty simple, it just makes a copy of the bitmap you pass it and returns a reference to it.
tigrGetResized
Tigr * tigrGetResized (Tigr * bmp, int new_width, int new_height){
Tigr * new_bmp = tigrBitmap(new_width, new_height);
for (int y = 0; y < new_height; y++){
for (int x = 0; x < new_width; x++){
new_bmp->pix[(y)*new_width + (x)] = bmp->pix[(y*bmp->h/new_height)*bmp->w + (x*bmp->w/new_width)];
}}
return new_bmp;
}
This function takes a bitmap and returns it resized to the dimensions you pass it.
tigrSetResized
void tigrSetResized (Tigr ** bmp, int new_width, int new_height){
Tigr * new_bmp = tigrBitmap(new_width, new_height);
for (int y = 0; y < new_height; y++){
for (int x = 0; x < new_width; x++){
new_bmp->pix[(y)*new_width + (x)] = (*bmp)->pix[(y*((*bmp)->h)/new_height)*(*bmp)->w + (x*(*bmp)->w/new_width)];
}}
tigrFree(*bmp);
*bmp = new_bmp;
}
Exact same as previous, just modifying the bitmap you pass in. (Not advisable to repeat on the same bitmap more than once)
tigrGetRotated
Tigr * tigrGetRotated (Tigr * bmp, double angle){
// Caching the sine and cosine values of the angle for performance
const double sin_a = sin(angle);
const double cos_a = cos(angle);
// Width and height of rotated bmp
const int new_height = abs(bmp->w * sin_a) + abs(bmp->h * cos_a);
const int new_width = abs(bmp->w * sin_a) + abs(bmp->h * cos_a);
const int new_center_x = new_width/2;
const int new_center_y = new_height/2;
// Getting the center of the bmp
const int old_center_x = bmp->w/2;
const int old_center_y = bmp->h/2;
Tigr * new_bmp = tigrBitmap(new_width, new_height);
for (int y = 0; y < new_height; y++){
for (int x = 0; x < new_width; x++){
int old_x = (x-new_center_x)*cos_a + (y-new_center_y)*sin_a + old_center_x;
int old_y = -(x-new_center_x)*sin_a + (y-new_center_y)*cos_a + old_center_y;
if (old_x >= 0 && old_y >= 0 && old_x < bmp->w && old_y < bmp->h){
new_bmp->pix[y*new_width + x] = bmp->pix[old_y*bmp->w + old_x];
} else {
new_bmp->pix[y*new_width + x] = tigrRGBA(0, 0, 0, 0);
}
}}
return new_bmp;
}
Takes the bitmap you pass it and rotates it the angle you pass it clockwise. It will fill in the whitespace caused by the rotation by a transparent color.
The following is an example displaying the use of all four of these functions:
#include "tigr.h"
#include <math.h>
#include <stdlib.h>
#include <string.h>
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 640
int main () {
Tigr * screen = tigrWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Testing", 0);
Tigr * img = tigrLoadImage("tigr.png");
tigrSetResized(&img, 300, 300);
Tigr * scale_img = tigrClone(img);
Tigr * rotate_img = tigrClone(img);
double scale_angle = 3.1415926535/4;
double dir = 0.01;
double rotate_angle = 0;
while (!tigrClosed(screen)) {
if (scale_angle < 0.01 || scale_angle > 3.1415926535/2 - dir){
dir *= -1;
scale_angle += dir;
}
scale_angle += dir;
rotate_angle += 0.01;
if (rotate_angle > 2*3.1415926535){
rotate_angle -= 2*3.1415926535;
}
tigrClear(screen, tigrRGB(255, 255, 255));
tigrFree(scale_img);
tigrFree(rotate_img);
scale_img = tigrGetResized(img, SCREEN_WIDTH * cos(scale_angle), SCREEN_HEIGHT * sin(scale_angle));
rotate_img = tigrGetRotated(img, rotate_angle);
tigrBlitAlpha(screen, scale_img, 0, 0, 0, 0, scale_img->w, scale_img->h, 1.0);
tigrBlitAlpha(screen, rotate_img, SCREEN_WIDTH - (rotate_img->w/2 + 135), SCREEN_HEIGHT - (rotate_img->h/2 + 135), 0, 0, rotate_img->w, rotate_img->h, 1.0);
tigrUpdate(screen);
}
tigrFree(img);
tigrFree(scale_img);
tigrFree(rotate_img);
tigrFree(screen);
return 0;
}
To use it, add in the definitions of the functions below, and compile. When running you will see the tigr logo being resized to various dimensions and another logo spinning in the corner.
I do believe that these functions are useful enough to be added, and if there is any problems with them feedback would be awesome!
This might just be me not having looked into the source enough, although it feels like I have multiple times. I'm wondering how to print text (e.g. the default font) at a bigger size on screen. Do I have to modify the glyph size or what would I do to increase it? Or can I temporarily modify the scale of what I draw?
On Windows and Linux my game runs ar 60 FPS but on macOS (Sonoma on M2 Mini) the game runs at around 350 FPS. Is there a way to cap the frame rate on macOS to 60 fps as well? Thanks for the library, it's awesome!
Examples don't work.
As a workaround I used MESA_GL_VERSION_OVERRIDE=3.3 ./demo
I apologize, I'm not very good with the system part of the programming, but now I start with this simple graphics library and I want to use cyrillic font. I make such with:
windows>tigrfont -mx -size 20 -encoding utf8 JuliaMono-Bold.ttf JuliaMono-Bold.png
Generated unicode font sheet for 1537 characters from encoding "utf8"
I can show the result png file - it seems ok with all necessary alphabets:
After that I use the slightly modified base example:
`
#include <stdio.h>
#include "tigr.h"
int main(int argc, char *argv[])
{
Tigr *screen = tigrWindow(320, 240, "Hello", TIGR_FIXED);
Tigr* fontImage = tigrLoadImage("../JuliaMono-Bold.png");
TigrFont * font = tigrLoadFont(fontImage, TCP_UTF32);
while (!tigrClosed(screen)){
tigrClear(screen, tigrRGB(0x80, 0x90, 0xa0));
tigrPrint(screen, font, 120, 110, tigrRGB(0xff, 0xff, 0xff), "Проба");
tigrUpdate(screen);
}
tigrFree(screen);
// tigrFreeFont(font);
tigrFree(fontImage);
return 0;
}
`
IMPORTANT notes:
and after the window closing, just before the program stops - it crashes.
There is no crashes, but all works ok.
TigrFont* tigrLoadFont(Tigr* bitmap, int codepage) { TigrFont* font = (TigrFont*)calloc(1, sizeof(TigrFont)); font->bitmap = bitmap; if (!tigrLoadGlyphs(font, codepage)) { //tigrFreeFont(font); //return NULL; } return font; }
I just comment unsuccessful font return - and IT WORKS! The cyrillic word appears perfect on the window!
But:
if I did not also comment the row tigrFreeFont(font);, it crashes at closing.
I know that this is not decision, there are memory leaks, etc., but I'm not ready to inspect the library more, please for help from the author. Thanks, in advance!!!
P.S. I try the example in the /ci folder of the tigr library source - it also crashes immediately with this message in the console:
Create offscreen...OK
Drawing API...
So I think, that the problem is somewhere in the tigr.c source. Please for support.
P.P.S I make experiments on Windows 10 Pro 64 bit with MINGW64 gcc and with MSVC 2022, the results are the same.
It would be awesome to have
Windows 10 Pro 64 bit, both MINGW64 and MSVC 2022 are tried, all updated to the last version.
I apologize, but try to use the new tigrfont-v1.0.1 (Windows exe, precompiled) to generate custom font. This is the minimal code:
`
#include "tigr.h"
int main(int argc, char *argv[]){
Tigr *screen = tigrWindow(320, 240, "Proba1", 0);
Tigr* fontImage = tigrLoadImage("../font/JuliaMono-Bold18.png");
TigrFont * font = tigrLoadFont(fontImage, TCP_UTF32);
while (!tigrClosed(screen) && !tigrKeyDown(screen, TK_ESCAPE)){
tigrClear(screen, tigrRGB(0x80, 0x90, 0xa0));
tigrPrint(screen, font, 120, 110, tigrRGB(0xff, 0xff, 0xff), "Hello, Проба.");
tigrUpdate(screen);
}
tigrFreeFont(font);
tigrFree(fontImage);
tigrFree(screen);
return 0;
}
`
It WORKS fine, all, the Cyrillic symbols are displayed properly, until the the window is closed and exactly at the row:
tigrFreeFont(font);
the program CRASHES.
If I comment this row, the program closes normally, but I check - then there is memory leakage as expected.
Please for advice, may be I do something wrong? I try to change the three "free" rows order, but this did not change anything, the program always crashes exactly on the command:
tigrFreeFont(font);
Seems to be some disagreement about prototypes..
/Users/pete/Dropbox/SoftwareProjects-Working/tigr/tigr/tigr.h:202:15: This function declaration is not a prototype
/Users/pete/Dropbox/SoftwareProjects-Working/tigr/tigr/tigr.c:4:10: In file included from /Users/pete/Dropbox/SoftwareProjects-Working/tigr/tigr/tigr.c:4:
/Users/pete/Dropbox/SoftwareProjects-Working/tigr/tigr/tigr.c:2443:15: Too many arguments to function call, expected 0, have 2
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/usr/include/objc/message.h:62:1: 'objc_msgSend' declared here
/Users/pete/Dropbox/SoftwareProjects-Working/tigr/tigr/tigr.c:2693:25: Too many arguments to function call, expected 0, have 2
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/usr/include/objc/message.h:62:1: 'objc_msgSend' declared here
Would you be open to accepting a pull request adding additional features? I appreciate this is a fork with a specific goal such that I understand this might not be desirable.
I was thinking that in place of the tigrBlitTint
a tigrBlit2
or tigrBlitAdvanced
function could be added. This would work similar to tigrBlitTint
with the addition of two more parameters:
I feel these two features would greatly benefit the use case of the library for small games without adding much weight.
In addition to this I believe the embedded font might work better without the drop shadow -- the same effect is trivial to achieve by drawing the text twice in different colours with a 1 pixel offset, but the inverse, removing the baked-in drop shadow, is less trivial.
examples/headless can't compile
gcc headless.c ../../tigr.c -Os -o headless -fsanitize=undefined -I../.. -Wall -DTIGR_HEADLESS -s -lGLU -lGL -lX11
../../tigr.c:114:5: error: unknown type name ‘GLXContext’
114 | GLXContext glc;
| ^~~~~~~~~~
make: *** [Makefile:14: headless] Error 1
(Apologies if I'm missing something obvious, I'm a novice)
Trying to learn TIGR so I started by building the hello
example in my space. But on running make hello
I get the following error:
tigr/tigr.c:1820:19: error: declaration shadows a local variable [-Werror,-Wshadow]
TigrGlyph g = font->glyphs[i];
^
tigr/tigr.c:1730:16: note: previous declaration is here
TigrGlyph* g;
^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
2 errors generated.
make: *** [Makefile:13: hello] Error 1
Straightforward error, I imagine it's caused by a compiler difference (I'm using Clang). Probably easy to fix.
TIGR seems to cause memory leaks whenever it... runs. Clang Static Analyzer and htop return no issue, but Clang LeakSanitizer and Valgrind both freak out. LeakSanitizer output:
tigr-test/leak/ $ ./leak
==109252==WARNING: invalid path to external symbolizer!
==109252==WARNING: Failed to use and restart external symbolizer!
=================================================================
==109252==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 6720 byte(s) in 1 object(s) allocated from:
#0 0x55ff8ecea592 (/workspaces/160550426/tigr-test/leak/leak+0x33592) (BuildId: b4db616332db8de29c4f8cac38b13bff386a95bb)
#1 0x7d08ceabe7b3 (/lib/x86_64-linux-gnu/libGLX_mesa.so.0+0x317b3) (BuildId: 81f27aa4cfe213187c5a2dda6902a87fd132a76e)
SUMMARY: LeakSanitizer: 6720 byte(s) leaked in 1 allocation(s).
Valgrind's outputs are massive since it seems to print for each loop of the window, but it points in the same direction. Some sample lines:
Edit: It is not printing out errors for every loop, it just prints one massive block of errors on exit.
==96672== 194,880 bytes in 840 blocks are still reachable in loss record 2,689 of 2,692
==96672== at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==96672== by 0x5586802: ??? (in /usr/lib/x86_64-linux-gnu/libGLX_mesa.so.0.0.0)
==96672== by 0x558A0F7: ??? (in /usr/lib/x86_64-linux-gnu/libGLX_mesa.so.0.0.0)
==96672== by 0x50DC79A: glXChooseFBConfig (in /usr/lib/x86_64-linux-gnu/libGLX.so.0.0.0)
==96672== by 0x4AA7D8F: (below main) (libc_start_call_main.h:58)
==96672==
==96672== 265,072 bytes in 1 blocks are indirectly lost in loss record 2,690 of 2,692
==96672== at 0x484DE30: memalign (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==96672== by 0x484DF92: posix_memalign (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==96672== by 0x58428B9: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so)
==96672== by 0x5790660: ??? (in /usr/lib/x86_64-linux-gnu/dri/swrast_dri.so)
==96672== by 0x5587C28: ??? (in /usr/lib/x86_64-linux-gnu/libGLX_mesa.so.0.0.0)
==96672== by 0x5586F28: ??? (in /usr/lib/x86_64-linux-gnu/libGLX_mesa.so.0.0.0)
I'm running on Codespaces. I can't tell if the issue is with TIGR's useage of Mesa or Mesa itself, nor can I tell if this is an actual problematic leak or a false positive, but it seems worth calling attention to. Happens with any useage of TIGR, down to drawing an empty window.
#include "../tigr/tigr.h"
int main(int argc, char *argv[])
{
Tigr *screen = tigrWindow(320, 240, "Hello", 0);
while (!tigrClosed(screen))
{
tigrUpdate(screen);
}
tigrFree(screen);
return 0;
}
Hopefully this helps track something down.
Hi,
I've tried out Tigr on Linux (X11 KDE) and for some reason the screen size for the window doesn't seem to match with what the executable outputs?
From my understanding e.g. demo is 320x240, however. As seen on the screenshot this does not seem to be the case and the window dimensions are much bigger.
I'm running this and tested all tests from source.
Hey @erkkah,
Nice that somebody finally added linux support :D thanks!
I was wondering if you managed to get this PR to work, or planned to merge it, as it switches from d3d9 to opengl and makes the lib (more) multi-platform. It worked flawlessly for me (win64 7, intel ga).
https://bitbucket.org/rmitton/tigr/pull-requests/3/enabling-users-to-run-custom-opengl/
pressing F in examples/flags does nothing
The destruction order of the tigr window and corresponding cocoa object is flawed, causing crashes when using more than one window. This could happen with one window as well, but is less likely to happen.
To make TIGR live alive on MacOS, a Metal implementation should be added and me made the default. The OpenGL version can be kept as a fallback.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.