GithubHelp home page GithubHelp logo

erkkah / tigr Goto Github PK

View Code? Open in Web Editor NEW
711.0 22.0 42.0 1.84 MB

TIGR - the TIny GRaphics library for Windows, macOS, Linux, iOS and Android.

License: Other

Makefile 0.12% Perl 0.34% C 99.54%
tigr tiny-graphics-library cross-platform linux windows osx android 2d-graphics ios

tigr's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tigr's Issues

Fullscreen on windows

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.

wglMakeCurrent Very Slow

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:

return wglMakeCurrent(win->gl.dc, win->gl.hglrc) ? 0 : -1;

and especially

return wglMakeCurrent(NULL, NULL) ? 0 : -1;

which seems to be what is causing the slow down.

Thank you!

Drawing Bezier curves

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

test.txt

(Made me do it as a txt file for some reason)

Minimum OpenGL requirements

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.

Possibly related to #13 #12

Changing FPS

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?

Does not build on macOS Big Sur (11.5)

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?

Adding functions for manipulating bitmaps

I want to add some more functions to help people with manipulating bitmaps.

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.

Example program

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!

How To Change Font Size

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?

macOS FPS not capped (like on Linux and Windows)

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!

Problem with custom font

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:

JuliaMono-Bold

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:

  1. I comment the line:
    // tigrPrint(screen, font, 120, 110, tigrRGB(0xff, 0xff, 0xff), "Hello, world.");

and after the window closing, just before the program stops - it crashes.

  1. If I comment also this line:
    tigrFreeFont(font);

There is no crashes, but all works ok.

  1. If I try to start the all example as is shown above - application crashes immediately. I see that the font pointer is NULL, so just for try:
  • I edit (comment two rows) the library source tigr.c - row 1831:

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.

More Mouse functions?

It would be awesome to have

  • IsMouseButtonDown() - or Pressed...
  • IsMouseButtonReleased()

Crash at using external font

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

MacOS problem

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

Additional Blitting Features

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:

  • A colour value that is "added" to the RGB channels of all pixels
  • A bitmask with the options to draw the sprite flipped on either its X or Y axis

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.

headless mode not working on Linux

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

Variable Shadowing Issue in tigr.c

(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.

Mesa Memory Leak

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.

Screen size don't match on linux?

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.

Screenshot_20230701_211808

I'm running this and tested all tests from source.

Crashes on Mac when using more than one window

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.