From 3e7c5fe34018f062fbd7a2ab49168aeeffb4cf8c Mon Sep 17 00:00:00 2001 From: Ivan Mahonin Date: Aug 15 2020 12:38:50 +0000 Subject: image functions --- diff --git a/doc/helianthus-doc-ru.odt b/doc/helianthus-doc-ru.odt index 85f56d2..88321de 100644 Binary files a/doc/helianthus-doc-ru.odt and b/doc/helianthus-doc-ru.odt differ diff --git a/src/animation.c b/src/animation.c index b789864..aafc90e 100644 --- a/src/animation.c +++ b/src/animation.c @@ -5,7 +5,6 @@ #include "world.h" #include "animation.h" - static HeliArray cache; static Animation first, last; @@ -275,6 +274,27 @@ int imageFromGLTexture(unsigned int texid, int *outWidth, int *outHeight, unsign return outPixels != NULL; } +unsigned int imageGetPixel(int width, int height, const void *pixels, int x, int y) { + if (x < 0 || x >= width || y < 0 || y >= height || !pixels) return 0; + const unsigned char *p = (const unsigned char *)pixels + 4*((size_t)width*y + x); + return (((unsigned int)p[0]) << 24) + | (((unsigned int)p[1]) << 16) + | (((unsigned int)p[2]) << 8) + | (((unsigned int)p[3]) << 0); +} + +void imageSetPixel(int width, int height, void *pixels, int x, int y, unsigned int color) { + if (x < 0 || x >= width || y < 0 || y >= height || !pixels) return; + unsigned char *p = (unsigned char *)pixels + 4*((size_t)width*y + x); + p[0] = (color >> 24); + p[1] = (color >> 16) & 0xFF; + p[2] = (color >> 24) & 0xFF; + p[3] = (color ) & 0xFF; +} + +void imageSetPixel(int width, int height, void *pixels, int x, int y, unsigned int color); + + static void unloadTexture(HeliTexture *texture) { assert(!texture->refcount); @@ -387,6 +407,11 @@ void animationGLTexIdSetOwnership(unsigned int texid, int own) { } } +Animation createAnimationFromImageEx(int width, int height, const void *pixels, int horWrap, int vertWrap, int smooth, int mipMap) + { return createAnimationFromGLTexId(imageToGLTextureEx(width, height, pixels, horWrap, vertWrap, smooth, mipMap)); } + +Animation createAnimationFromImage(int width, int height, const void *pixels, int wrap) + { return createAnimationFromGLTexId(imageToGLTexture(width, height, pixels, wrap)); } Animation createAnimation(const char *path) { return createAnimationEx(path, TRUE, FALSE, FALSE); } @@ -423,13 +448,16 @@ Animation animationCloneEx(Animation animation, int from, int to) { Animation animationClone(Animation animation) { return animationCloneEx(animation, 0, animationGetFramesCount(animation)); } -unsigned int animationGetGLTexId(Animation animation) { - if (animationGetFramesCount(animation) <= 0) return 0; - int i = animationGetFrame(animation); - HeliTexture *texture = (HeliTexture*)animation->frames.items[i].value; +unsigned int animationGetFrameGLTexId(Animation animation, int frame) { + int count = animationGetFramesCount(animation); + if (frame < 0 || frame >= count) return 0; + HeliTexture *texture = (HeliTexture*)animation->frames.items[frame].value; return texture->id; } +unsigned int animationGetGLTexId(Animation animation) + { return animationGetFrameGLTexId(animation, animationGetFrame(animation)); } + int animationGetFramesCount(Animation animation) { return animation->frames.count; } diff --git a/src/animation.h b/src/animation.h index c68f635..5fb9740 100644 --- a/src/animation.h +++ b/src/animation.h @@ -13,6 +13,10 @@ unsigned int imageToGLTexture(int width, int height, const void *pixels, int wra unsigned int imageToGLTextureEx(int width, int height, const void *pixels, int horWrap, int vertWrap, int smooth, int mipMap); int imageFromGLTexture(unsigned int texid, int *outWidth, int *outHeight, unsigned char **outPixels); +unsigned int imageGetPixel(int width, int height, const void *pixels, int x, int y); +void imageSetPixel(int width, int height, void *pixels, int x, int y, unsigned int color); + + Animation createAnimation(const char *path); Animation createAnimationEx(const char *path, int smooth, int horWrap, int vertWrap); Animation createAnimationFromGLTexId(unsigned int texid); @@ -25,6 +29,7 @@ Animation animationClone(Animation animation); Animation animationCloneEx(Animation animation, int start, int count); unsigned int animationGetGLTexId(Animation animation); +unsigned int animationGetFrameGLTexId(Animation animation, int frame); void animationGLTexIdSetOwnership(unsigned int texid, int own); int animationGetFramesCount(Animation animation); diff --git a/src/drawing.c b/src/drawing.c index fe27909..4cbd4dd 100644 --- a/src/drawing.c +++ b/src/drawing.c @@ -9,15 +9,8 @@ static double *path; static size_t pathSize; static size_t pathAllocated; -static HeliDrawingState statesStack[1024] = {{ - 0, // flags - {0.5, 0.5, 0.5, 1}, // fillColor - {0, 0, 0, 1}, // strokeColor - 1, // lineWidth - HALIGN_LEFT, // horAlign - VALIGN_TOP, // vertAlign - 24 // fontSize -}}; + +static HeliDrawingState statesStack[1024]; static int statesStackIndex = 0; @@ -85,8 +78,12 @@ void fillTexture(Animation animation, double x, double y, double width, double h s->height = height; s->fixed = fixed != 0; } +void noFillColor() + { fill(0); } +void noFillTexture() + { fillTexture(NULL, 0, 0, 1, 1, FALSE); } void noFill() - { fill(0); fillTexture(NULL, 0, 0, 1, 1, FALSE); } + { noFillColor(); noFillTexture(); } void stroke(unsigned int colorCode) { heliColorToDouble(colorCode, heliDrawingGetState()->strokeColor); } @@ -99,8 +96,12 @@ void strokeTexture(Animation animation, double x, double y, double width, double s->height = height; s->fixed = fixed != 0; } +void noStrokeColor() + { stroke(0); } +void noStrokeTexture() + { strokeTexture(NULL, 0, 0, 1, 1, FALSE); } void noStroke() - { stroke(0); strokeTexture(NULL, 0, 0, 1, 1, FALSE); } + { noStrokeColor(); noStrokeTexture(); } void strokeWidth(double width) { heliDrawingGetState()->strokeWidth = width; } @@ -713,7 +714,22 @@ HeliDrawingState *heliDrawingGetState() HeliDrawingState *heliDrawingGetStateStack() { return statesStack; } -void saveState(unsigned int flags) +void resetState() + { resetStateEx(STATE_ALL); } + +void resetStateEx(unsigned int flags) { + if (flags & STATE_FILL_COLOR ) fill(colorByRGBA(0.5, 0.5, 0.5, 1)); + if (flags & STATE_FILL_TEXTURE ) noFillTexture(); + if (flags & STATE_STROKE_COLOR ) stroke(colorByRGBA(0, 0, 0, 1)); + if (flags & STATE_STROKE_TEXTURE) noStrokeTexture(); + if (flags & STATE_STROKE_WIDTH ) strokeWidth(1); + if (flags & STATE_TEXT_ALIGN ) textAlign(HALIGN_LEFT, VALIGN_TOP); + if (flags & STATE_TEXT_SIZE ) textSize(24); + if (flags & STATE_TRANSFORM ) noTransform(); + if (flags & STATE_CLIP ) noClip(); +} + +void saveState() { saveStateEx(STATE_ALL); } void saveStateEx(unsigned int flags) { diff --git a/src/drawing.h b/src/drawing.h index 5768946..e06cbb1 100644 --- a/src/drawing.h +++ b/src/drawing.h @@ -58,6 +58,8 @@ void noTransform(); void cliprect(double x, double y, double width, double height); void noClip(); +void resetState(); +void resetStateEx(unsigned int flags); void saveState(); void saveStateEx(unsigned int flags); void restoreState(); diff --git a/src/world.c b/src/world.c index 8ad6a9d..a58fe0a 100644 --- a/src/world.c +++ b/src/world.c @@ -4,7 +4,7 @@ #include #include "private.h" - +#include "drawing.h" #include "world.h" @@ -536,6 +536,7 @@ void worldRun() { if (init()) { heliInitialized = TRUE; + resetState(); heliDoTests(); if (initCallback) initCallback();