Add Library
This commit is contained in:
parent
e365b9dbd9
commit
3c47103b39
318 changed files with 56465 additions and 0 deletions
86
libraries/bitluni_ESP32Lib/src/Graphics/Animation.h
Normal file
86
libraries/bitluni_ESP32Lib/src/Graphics/Animation.h
Normal file
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include "Entity.h"
|
||||
|
||||
class Animation : public Entity
|
||||
{
|
||||
public:
|
||||
int start, end, frameDuration;
|
||||
int time;
|
||||
int drawMode;
|
||||
|
||||
Animation(Sprites &sprites, int x, int y, int start, int end, int frameDuration, int drawMode = 0)
|
||||
{
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
this->sprites = &sprites;
|
||||
this->start = start;
|
||||
this->end = end;
|
||||
this->frameDuration = frameDuration;
|
||||
time = 0;
|
||||
this->drawMode = drawMode;
|
||||
}
|
||||
|
||||
virtual ~Animation()
|
||||
{
|
||||
}
|
||||
|
||||
bool act(int dt)
|
||||
{
|
||||
time += dt;
|
||||
return time < (end - start + 1) * frameDuration;
|
||||
}
|
||||
/*
|
||||
void draw(Graphics &g)
|
||||
{
|
||||
int current = time / frameDuration + start;
|
||||
if (drawMode == 0)
|
||||
this->sprites->drawMix(g, current, this->x, this->y);
|
||||
else if (drawMode == 1)
|
||||
this->sprites->drawAdd(g, current, this->x, this->y);
|
||||
}
|
||||
*/
|
||||
static void animationsAct(Animation **animations, int dt, int maxCount = 100)
|
||||
{
|
||||
for (int i = 0; i < maxCount; i++)
|
||||
{
|
||||
if (animations[i])
|
||||
if (!animations[i]->act(dt))
|
||||
{
|
||||
delete animations[i];
|
||||
animations[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
void animationsDraw(Graphics &g, Animation **animations, int maxCount = 100)
|
||||
{
|
||||
for (int i = 0; i < maxCount; i++)
|
||||
if (animations[i])
|
||||
if (animations[i])
|
||||
animations[i]->draw(g);
|
||||
}
|
||||
*/
|
||||
void animationsEmit(Animation **animations, Animation *e, int maxCount = 100)
|
||||
{
|
||||
for (int i = 0; i < maxCount; i++)
|
||||
{
|
||||
if (!animations[i])
|
||||
{
|
||||
animations[i] = e;
|
||||
return;
|
||||
}
|
||||
}
|
||||
delete e;
|
||||
}
|
||||
};
|
69
libraries/bitluni_ESP32Lib/src/Graphics/Engine3D.h
Normal file
69
libraries/bitluni_ESP32Lib/src/Graphics/Engine3D.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include <stdlib.h>
|
||||
#include "TriangleTree.h"
|
||||
#include "../Tools/Log.h"
|
||||
template<class Graphics>
|
||||
class Engine3D
|
||||
{
|
||||
public:
|
||||
typedef typename Graphics::Color Color;
|
||||
TriangleTree *triangleBuffer;
|
||||
TriangleTree *triangleRoot;
|
||||
int trinagleBufferSize;
|
||||
int triangleCount;
|
||||
|
||||
Engine3D(const int initialTrinagleBufferSize = 1)
|
||||
{
|
||||
trinagleBufferSize = initialTrinagleBufferSize;
|
||||
triangleBuffer = (TriangleTree*)malloc(sizeof(TriangleTree) * trinagleBufferSize);
|
||||
if(!triangleBuffer)
|
||||
ERROR("Not enough memory for triangleBuffer");
|
||||
triangleRoot = 0;
|
||||
triangleCount = 0;
|
||||
}
|
||||
|
||||
|
||||
void enqueueTriangle(short *v0, short *v1, short *v2, Color color)
|
||||
{
|
||||
if (triangleCount >= trinagleBufferSize)
|
||||
return;
|
||||
TriangleTree &t = triangleBuffer[triangleCount++];
|
||||
t.set(v0, v1, v2, color);
|
||||
if (triangleRoot)
|
||||
triangleRoot->add(&triangleRoot, t);
|
||||
else
|
||||
triangleRoot = &t;
|
||||
}
|
||||
|
||||
void drawTriangleTree(Graphics &g, TriangleTree *t)
|
||||
{
|
||||
if (t->left)
|
||||
drawTriangleTree(g, t->left);
|
||||
g.triangle(t->v[0], t->v[1], t->v[2], t->color);
|
||||
if (t->right)
|
||||
drawTriangleTree(g, t->right);
|
||||
}
|
||||
|
||||
virtual void begin()
|
||||
{
|
||||
triangleCount = 0;
|
||||
triangleRoot = 0;
|
||||
}
|
||||
|
||||
virtual void end(Graphics &g)
|
||||
{
|
||||
if (triangleRoot)
|
||||
drawTriangleTree(g, triangleRoot);
|
||||
}
|
||||
};
|
26
libraries/bitluni_ESP32Lib/src/Graphics/Entity.h
Normal file
26
libraries/bitluni_ESP32Lib/src/Graphics/Entity.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include "Graphics.h"
|
||||
#include "Sprites.h"
|
||||
|
||||
class Entity
|
||||
{
|
||||
public:
|
||||
int x, y;
|
||||
int vx, vy;
|
||||
int life;
|
||||
int faction;
|
||||
Sprites *sprites;
|
||||
virtual bool act(int dt);
|
||||
virtual void draw() = 0;
|
||||
};
|
35
libraries/bitluni_ESP32Lib/src/Graphics/Font.h
Normal file
35
libraries/bitluni_ESP32Lib/src/Graphics/Font.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
class Font
|
||||
{
|
||||
public:
|
||||
const int firstChar;
|
||||
const int charCount;
|
||||
const unsigned char *pixels;
|
||||
const int charWidth;
|
||||
const int charHeight;
|
||||
Font(int charWidth, int charHeight, const unsigned char *pixels, int firstChar = 32, int charCount = 96)
|
||||
:firstChar(firstChar),
|
||||
charCount(charCount),
|
||||
pixels(pixels),
|
||||
charWidth(charWidth),
|
||||
charHeight(charHeight)
|
||||
{
|
||||
}
|
||||
|
||||
bool valid(char ch) const
|
||||
{
|
||||
return ch >= firstChar && ch < firstChar + charCount;
|
||||
}
|
||||
};
|
698
libraries/bitluni_ESP32Lib/src/Graphics/Graphics.h
Normal file
698
libraries/bitluni_ESP32Lib/src/Graphics/Graphics.h
Normal file
|
@ -0,0 +1,698 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "Font.h"
|
||||
#include "ImageDrawer.h"
|
||||
|
||||
template<typename Color>
|
||||
class Graphics: public ImageDrawer
|
||||
{
|
||||
public:
|
||||
int cursorX, cursorY, cursorBaseX;
|
||||
long frontColor, backColor;
|
||||
Font *font;
|
||||
int frameBufferCount;
|
||||
int currentFrameBuffer;
|
||||
Color **frameBuffers[3];
|
||||
Color **frontBuffer;
|
||||
Color **backBuffer;
|
||||
bool autoScroll;
|
||||
|
||||
int xres;
|
||||
int yres;
|
||||
|
||||
virtual void dotFast(int x, int y, Color color) = 0;
|
||||
virtual void dot(int x, int y, Color color) = 0;
|
||||
virtual void dotAdd(int x, int y, Color color) = 0;
|
||||
virtual void dotMix(int x, int y, Color color) = 0;
|
||||
virtual Color get(int x, int y) = 0;
|
||||
virtual Color** allocateFrameBuffer() = 0;
|
||||
virtual Color** allocateFrameBuffer(int xres, int yres, Color value)
|
||||
{
|
||||
Color** frame = (Color **)malloc(yres * sizeof(Color *));
|
||||
if(!frame)
|
||||
ERROR("Not enough memory for frame buffer");
|
||||
for (int y = 0; y < yres; y++)
|
||||
{
|
||||
frame[y] = (Color *)malloc(xres * sizeof(Color));
|
||||
if(!frame[y])
|
||||
ERROR("Not enough memory for frame buffer");
|
||||
for (int x = 0; x < xres; x++)
|
||||
frame[y][x] = value;
|
||||
}
|
||||
return frame;
|
||||
}
|
||||
virtual Color RGBA(int r, int g, int b, int a = 255) const = 0;
|
||||
virtual int R(Color c) const = 0;
|
||||
virtual int G(Color c) const = 0;
|
||||
virtual int B(Color c) const = 0;
|
||||
virtual int A(Color c) const = 0;
|
||||
Color RGB(unsigned long rgb) const
|
||||
{
|
||||
return RGBA(rgb & 255, (rgb >> 8) & 255, (rgb >> 16) & 255);
|
||||
}
|
||||
Color RGBA(unsigned long rgba) const
|
||||
{
|
||||
return RGBA(rgba & 255, (rgba >> 8) & 255, (rgba >> 16) & 255, rgba >> 24);
|
||||
}
|
||||
Color RGB(int r, int g, int b) const
|
||||
{
|
||||
return RGBA(r, g, b);
|
||||
}
|
||||
|
||||
void setFrameBufferCount(unsigned char i)
|
||||
{
|
||||
frameBufferCount = i > 3 ? 3 : i;
|
||||
}
|
||||
|
||||
virtual void show(bool vSync = false)
|
||||
{
|
||||
if(!frameBufferCount)
|
||||
return;
|
||||
currentFrameBuffer = (currentFrameBuffer + 1) % frameBufferCount;
|
||||
frontBuffer = frameBuffers[currentFrameBuffer];
|
||||
backBuffer = frameBuffers[(currentFrameBuffer + frameBufferCount - 1) % frameBufferCount];
|
||||
}
|
||||
|
||||
Graphics(int xres = 0, int yres = 0)
|
||||
{
|
||||
this->xres = xres;
|
||||
this->yres = yres;
|
||||
font = 0;
|
||||
cursorX = cursorY = cursorBaseX = 0;
|
||||
frontColor = -1;
|
||||
backColor = 0;
|
||||
frameBufferCount = 1;
|
||||
for(int i = 0; i < 3; i++)
|
||||
frameBuffers[i] = 0;
|
||||
frontBuffer = 0;
|
||||
backBuffer = 0;
|
||||
autoScroll = true;
|
||||
}
|
||||
|
||||
virtual bool allocateFrameBuffers()
|
||||
{
|
||||
if(yres <= 0 || xres <= 0)
|
||||
return false;
|
||||
for(int i = 0; i < frameBufferCount; i++)
|
||||
frameBuffers[i] = allocateFrameBuffer();
|
||||
currentFrameBuffer = 0;
|
||||
show();
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void setResolution(int xres, int yres)
|
||||
{
|
||||
this->xres = xres;
|
||||
this->yres = yres;
|
||||
allocateFrameBuffers();
|
||||
}
|
||||
|
||||
virtual float pixelAspect() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void setTextColor(long front, long back = 0)
|
||||
{
|
||||
frontColor = front;
|
||||
backColor = back;
|
||||
}
|
||||
|
||||
void setFont(Font &font)
|
||||
{
|
||||
this->font = &font;
|
||||
}
|
||||
|
||||
void setCursor(int x, int y)
|
||||
{
|
||||
cursorX = cursorBaseX = x;
|
||||
cursorY = y;
|
||||
}
|
||||
|
||||
virtual void drawChar(int x, int y, int ch)
|
||||
{
|
||||
if (!font)
|
||||
return;
|
||||
if (!font->valid(ch))
|
||||
return;
|
||||
const unsigned char *pix = &font->pixels[font->charWidth * font->charHeight * (ch - font->firstChar)];
|
||||
for (int py = 0; py < font->charHeight; py++)
|
||||
for (int px = 0; px < font->charWidth; px++)
|
||||
if (*(pix++))
|
||||
dotMix(px + x, py + y, frontColor);
|
||||
else
|
||||
dotMix(px + x, py + y, backColor);
|
||||
}
|
||||
|
||||
void print(const char ch)
|
||||
{
|
||||
if (!font)
|
||||
return;
|
||||
if (font->valid(ch))
|
||||
drawChar(cursorX, cursorY, ch);
|
||||
else
|
||||
drawChar(cursorX, cursorY, ' ');
|
||||
cursorX += font->charWidth;
|
||||
if (cursorX + font->charWidth > xres)
|
||||
{
|
||||
cursorX = cursorBaseX;
|
||||
cursorY += font->charHeight;
|
||||
if(autoScroll && cursorY + font->charHeight > yres)
|
||||
scroll(cursorY + font->charHeight - yres, backColor);
|
||||
}
|
||||
}
|
||||
|
||||
void println(const char ch)
|
||||
{
|
||||
print(ch);
|
||||
print("\n");
|
||||
}
|
||||
|
||||
void print(const char *str)
|
||||
{
|
||||
if (!font)
|
||||
return;
|
||||
while (*str)
|
||||
{
|
||||
if(*str == '\n')
|
||||
{
|
||||
cursorX = cursorBaseX;
|
||||
cursorY += font->charHeight;
|
||||
}
|
||||
else
|
||||
print(*str);
|
||||
str++;
|
||||
}
|
||||
}
|
||||
|
||||
void println(const char *str)
|
||||
{
|
||||
print(str);
|
||||
print("\n");
|
||||
}
|
||||
|
||||
void print(long number, int base = 10, int minCharacters = 1)
|
||||
{
|
||||
if(minCharacters < 1)
|
||||
minCharacters = 1;
|
||||
bool sign = number < 0;
|
||||
if (sign)
|
||||
number = -number;
|
||||
const char baseChars[] = "0123456789ABCDEF";
|
||||
char temp[33];
|
||||
temp[32] = 0;
|
||||
int i = 31;
|
||||
do
|
||||
{
|
||||
temp[i--] = baseChars[number % base];
|
||||
number /= base;
|
||||
} while (number > 0);
|
||||
if (sign)
|
||||
temp[i--] = '-';
|
||||
for (; i > 31 - minCharacters; i--)
|
||||
temp[i] = ' ';
|
||||
print(&temp[i + 1]);
|
||||
}
|
||||
|
||||
void print(unsigned long number, int base = 10, int minCharacters = 1)
|
||||
{
|
||||
if(minCharacters < 1)
|
||||
minCharacters = 1;
|
||||
const char baseChars[] = "0123456789ABCDEF";
|
||||
char temp[33];
|
||||
temp[32] = 0;
|
||||
int i = 31;
|
||||
do
|
||||
{
|
||||
temp[i--] = baseChars[number % base];
|
||||
number /= base;
|
||||
} while (number > 0);
|
||||
for (; i > 31 - minCharacters; i--)
|
||||
temp[i] = ' ';
|
||||
print(&temp[i + 1]);
|
||||
}
|
||||
|
||||
void println(long number, int base = 10, int minCharacters = 1)
|
||||
{
|
||||
print(number, base, minCharacters); print("\n");
|
||||
}
|
||||
|
||||
void println(unsigned long number, int base = 10, int minCharacters = 1)
|
||||
{
|
||||
print(number, base, minCharacters); print("\n");
|
||||
}
|
||||
|
||||
void print(int number, int base = 10, int minCharacters = 1)
|
||||
{
|
||||
print(long(number), base, minCharacters);
|
||||
}
|
||||
|
||||
void println(int number, int base = 10, int minCharacters = 1)
|
||||
{
|
||||
println(long(number), base, minCharacters);
|
||||
}
|
||||
|
||||
void print(unsigned int number, int base = 10, int minCharacters = 1)
|
||||
{
|
||||
print((unsigned long)(number), base, minCharacters);
|
||||
}
|
||||
|
||||
void println(unsigned int number, int base = 10, int minCharacters = 1)
|
||||
{
|
||||
println((unsigned long)(number), base, minCharacters);
|
||||
}
|
||||
|
||||
void print(short number, int base = 10, int minCharacters = 1)
|
||||
{
|
||||
print(long(number), base, minCharacters);
|
||||
}
|
||||
|
||||
void println(short number, int base = 10, int minCharacters = 1)
|
||||
{
|
||||
println(long(number), base, minCharacters);
|
||||
}
|
||||
|
||||
void print(unsigned short number, int base = 10, int minCharacters = 1)
|
||||
{
|
||||
print(long(number), base, minCharacters);
|
||||
}
|
||||
|
||||
void println(unsigned short number, int base = 10, int minCharacters = 1)
|
||||
{
|
||||
println(long(number), base, minCharacters);
|
||||
}
|
||||
|
||||
void print(unsigned char number, int base = 10, int minCharacters = 1)
|
||||
{
|
||||
print(long(number), base, minCharacters);
|
||||
}
|
||||
|
||||
void println(unsigned char number, int base = 10, int minCharacters = 1)
|
||||
{
|
||||
println(long(number), base, minCharacters);
|
||||
}
|
||||
|
||||
void println()
|
||||
{
|
||||
print("\n");
|
||||
}
|
||||
|
||||
void print(double number, int fractionalDigits = 2, int minCharacters = 1)
|
||||
{
|
||||
long p = long(pow(10, fractionalDigits));
|
||||
long long n = (double(number) * p + 0.5f);
|
||||
print(long(n / p), 10, minCharacters - 1 - fractionalDigits);
|
||||
if(fractionalDigits)
|
||||
{
|
||||
print(".");
|
||||
for(int i = 0; i < fractionalDigits; i++)
|
||||
{
|
||||
p /= 10;
|
||||
print(long(n / p) % 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void println(double number, int fractionalDigits = 2, int minCharacters = 1)
|
||||
{
|
||||
print(number, fractionalDigits, minCharacters);
|
||||
print("\n");
|
||||
}
|
||||
|
||||
virtual void clear(Color color = 0)
|
||||
{
|
||||
for (int y = 0; y < yres; y++)
|
||||
for (int x = 0; x < xres; x++)
|
||||
dotFast(x, y, color);
|
||||
}
|
||||
|
||||
virtual void xLine(int x0, int x1, int y, Color color)
|
||||
{
|
||||
if (y < 0 || y >= yres)
|
||||
return;
|
||||
if (x0 > x1)
|
||||
{
|
||||
int xb = x0;
|
||||
x0 = x1;
|
||||
x1 = xb;
|
||||
}
|
||||
if (x0 < 0)
|
||||
x0 = 0;
|
||||
if (x1 > xres)
|
||||
x1 = xres;
|
||||
for (int x = x0; x < x1; x++)
|
||||
dotFast(x, y, color);
|
||||
}
|
||||
|
||||
void triangle(short *v0, short *v1, short *v2, Color color)
|
||||
{
|
||||
short *v[3] = {v0, v1, v2};
|
||||
if (v[1][1] < v[0][1])
|
||||
{
|
||||
short *vb = v[0];
|
||||
v[0] = v[1];
|
||||
v[1] = vb;
|
||||
}
|
||||
if (v[2][1] < v[1][1])
|
||||
{
|
||||
short *vb = v[1];
|
||||
v[1] = v[2];
|
||||
v[2] = vb;
|
||||
}
|
||||
if (v[1][1] < v[0][1])
|
||||
{
|
||||
short *vb = v[0];
|
||||
v[0] = v[1];
|
||||
v[1] = vb;
|
||||
}
|
||||
int y = v[0][1];
|
||||
int xac = v[0][0] << 16;
|
||||
int xab = v[0][0] << 16;
|
||||
int xbc = v[1][0] << 16;
|
||||
int xaci = 0;
|
||||
int xabi = 0;
|
||||
int xbci = 0;
|
||||
if (v[1][1] != v[0][1])
|
||||
xabi = ((v[1][0] - v[0][0]) << 16) / (v[1][1] - v[0][1]);
|
||||
if (v[2][1] != v[0][1])
|
||||
xaci = ((v[2][0] - v[0][0]) << 16) / (v[2][1] - v[0][1]);
|
||||
if (v[2][1] != v[1][1])
|
||||
xbci = ((v[2][0] - v[1][0]) << 16) / (v[2][1] - v[1][1]);
|
||||
|
||||
for (; y < v[1][1] && y < yres; y++)
|
||||
{
|
||||
if (y >= 0)
|
||||
xLine(xab >> 16, xac >> 16, y, color);
|
||||
xab += xabi;
|
||||
xac += xaci;
|
||||
}
|
||||
for (; y < v[2][1] && y < yres; y++)
|
||||
{
|
||||
if (y >= 0)
|
||||
xLine(xbc >> 16, xac >> 16, y, color);
|
||||
xbc += xbci;
|
||||
xac += xaci;
|
||||
}
|
||||
}
|
||||
|
||||
void line(int x1, int y1, int x2, int y2, Color color)
|
||||
{
|
||||
int x, y, xe, ye;
|
||||
int dx = x2 - x1;
|
||||
int dy = y2 - y1;
|
||||
int dx1 = labs(dx);
|
||||
int dy1 = labs(dy);
|
||||
int px = 2 * dy1 - dx1;
|
||||
int py = 2 * dx1 - dy1;
|
||||
if (dy1 <= dx1)
|
||||
{
|
||||
if (dx >= 0)
|
||||
{
|
||||
x = x1;
|
||||
y = y1;
|
||||
xe = x2;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = x2;
|
||||
y = y2;
|
||||
xe = x1;
|
||||
}
|
||||
dot(x, y, color);
|
||||
for (int i = 0; x < xe; i++)
|
||||
{
|
||||
x = x + 1;
|
||||
if (px < 0)
|
||||
{
|
||||
px = px + 2 * dy1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((dx < 0 && dy < 0) || (dx > 0 && dy > 0))
|
||||
{
|
||||
y = y + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
y = y - 1;
|
||||
}
|
||||
px = px + 2 * (dy1 - dx1);
|
||||
}
|
||||
dot(x, y, color);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dy >= 0)
|
||||
{
|
||||
x = x1;
|
||||
y = y1;
|
||||
ye = y2;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = x2;
|
||||
y = y2;
|
||||
ye = y1;
|
||||
}
|
||||
dot(x, y, color);
|
||||
for (int i = 0; y < ye; i++)
|
||||
{
|
||||
y = y + 1;
|
||||
if (py <= 0)
|
||||
{
|
||||
py = py + 2 * dx1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((dx < 0 && dy < 0) || (dx > 0 && dy > 0))
|
||||
{
|
||||
x = x + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = x - 1;
|
||||
}
|
||||
py = py + 2 * (dx1 - dy1);
|
||||
}
|
||||
dot(x, y, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fillRect(int x, int y, int w, int h, Color color)
|
||||
{
|
||||
if (x < 0)
|
||||
{
|
||||
w += x;
|
||||
x = 0;
|
||||
}
|
||||
if (y < 0)
|
||||
{
|
||||
h += y;
|
||||
y = 0;
|
||||
}
|
||||
if (x + w > xres)
|
||||
w = xres - x;
|
||||
if (y + h > yres)
|
||||
h = yres - y;
|
||||
for (int j = y; j < y + h; j++)
|
||||
for (int i = x; i < x + w; i++)
|
||||
dotFast(i, j, color);
|
||||
}
|
||||
|
||||
void rect(int x, int y, int w, int h, Color color)
|
||||
{
|
||||
fillRect(x, y, w, 1, color);
|
||||
fillRect(x, y, 1, h, color);
|
||||
fillRect(x, y + h - 1, w, 1, color);
|
||||
fillRect(x + w - 1, y, 1, h, color);
|
||||
}
|
||||
|
||||
void circle(int x, int y, int r, Color color)
|
||||
{
|
||||
int oxr = r;
|
||||
for(int i = 0; i < r + 1; i++)
|
||||
{
|
||||
int xr = (int)sqrt(r * r - i * i);
|
||||
xLine(x - oxr, x - xr + 1, y + i, color);
|
||||
xLine(x + xr, x + oxr + 1, y + i, color);
|
||||
if(i)
|
||||
{
|
||||
xLine(x - oxr, x - xr + 1, y - i, color);
|
||||
xLine(x + xr, x + oxr + 1, y - i, color);
|
||||
}
|
||||
oxr = xr;
|
||||
}
|
||||
}
|
||||
|
||||
void fillCircle(int x, int y, int r, Color color)
|
||||
{
|
||||
for(int i = 0; i < r + 1; i++)
|
||||
{
|
||||
int xr = (int)sqrt(r * r - i * i);
|
||||
xLine(x - xr, x + xr + 1, y + i, color);
|
||||
if(i)
|
||||
xLine(x - xr, x + xr + 1, y - i, color);
|
||||
}
|
||||
}
|
||||
|
||||
void ellipse(int x, int y, int rx, int ry, Color color)
|
||||
{
|
||||
if(ry == 0)
|
||||
return;
|
||||
int oxr = rx;
|
||||
float f = float(rx) / ry;
|
||||
f *= f;
|
||||
for(int i = 0; i < ry + 1; i++)
|
||||
{
|
||||
float s = rx * rx - i * i * f;
|
||||
int xr = (int)sqrt(s <= 0 ? 0 : s);
|
||||
xLine(x - oxr, x - xr + 1, y + i, color);
|
||||
xLine(x + xr, x + oxr + 1, y + i, color);
|
||||
if(i)
|
||||
{
|
||||
xLine(x - oxr, x - xr + 1, y - i, color);
|
||||
xLine(x + xr, x + oxr + 1, y - i, color);
|
||||
}
|
||||
oxr = xr;
|
||||
}
|
||||
}
|
||||
|
||||
void fillEllipse(int x, int y, int rx, int ry, Color color)
|
||||
{
|
||||
if(ry == 0)
|
||||
return;
|
||||
float f = float(rx) / ry;
|
||||
f *= f;
|
||||
for(int i = 0; i < ry + 1; i++)
|
||||
{
|
||||
float s = rx * rx - i * i * f;
|
||||
int xr = (int)sqrt(s <= 0 ? 0 : s);
|
||||
xLine(x - xr, x + xr + 1, y + i, color);
|
||||
if(i)
|
||||
xLine(x - xr, x + xr + 1, y - i, color);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void scroll(int dy, Color color)
|
||||
{
|
||||
if(dy > 0)
|
||||
{
|
||||
for(int d = 0; d < dy; d++)
|
||||
{
|
||||
Color *l = backBuffer[0];
|
||||
for(int i = 0; i < yres - 1; i++)
|
||||
{
|
||||
backBuffer[i] = backBuffer[i + 1];
|
||||
}
|
||||
backBuffer[yres - 1] = l;
|
||||
xLine(0, xres, yres - 1, color);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int d = 0; d < -dy; d++)
|
||||
{
|
||||
Color *l = backBuffer[yres - 1];
|
||||
for(int i = 1; i < yres; i++)
|
||||
{
|
||||
backBuffer[i] = backBuffer[i - 1];
|
||||
}
|
||||
backBuffer[0] = l;
|
||||
xLine(0, xres, 0, color);
|
||||
}
|
||||
}
|
||||
cursorY -= dy;
|
||||
}
|
||||
|
||||
virtual Color R5G5B4A2ToColor(unsigned short c)
|
||||
{
|
||||
int r = (((c << 1) & 0x3e) * 255 + 1) / 0x3e;
|
||||
int g = (((c >> 4) & 0x3e) * 255 + 1) / 0x3e;
|
||||
int b = (((c >> 9) & 0x1e) * 255 + 1) / 0x1e;
|
||||
int a = (((c >> 13) & 6) * 255 + 1) / 6;
|
||||
return RGBA(r, g, b, a);
|
||||
}
|
||||
|
||||
virtual Color R2G2B2A2ToColor(unsigned char c)
|
||||
{
|
||||
int r = ((int(c) & 3) * 255 + 1) / 3;
|
||||
int g = (((int(c) >> 2) & 3) * 255 + 1) / 3;
|
||||
int b = (((int(c) >> 4) & 3) * 255 + 1) / 3;
|
||||
int a = (((int(c) >> 6) & 3) * 255 + 1) / 3;
|
||||
return RGBA(r, g, b, a);
|
||||
}
|
||||
|
||||
virtual void imageR5G5B4A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
|
||||
{
|
||||
for (int py = 0; py < srcYres; py++)
|
||||
{
|
||||
int i = srcX + (py + srcY) * image.xres;
|
||||
for (int px = 0; px < srcXres; px++)
|
||||
dot(px + x, py + y, R5G5B4A2ToColor(((unsigned short*)image.pixels)[i++]));
|
||||
}
|
||||
}
|
||||
|
||||
virtual void imageAddR5G5B4A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
|
||||
{
|
||||
for (int py = 0; py < srcYres; py++)
|
||||
{
|
||||
int i = srcX + (py + srcY) * image.xres;
|
||||
for (int px = 0; px < srcXres; px++)
|
||||
dotAdd(px + x, py + y, R5G5B4A2ToColor(((unsigned short*)image.pixels)[i++]));
|
||||
}
|
||||
}
|
||||
|
||||
virtual void imageMixR5G5B4A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
|
||||
{
|
||||
for (int py = 0; py < srcYres; py++)
|
||||
{
|
||||
int i = srcX + (py + srcY) * image.xres;
|
||||
for (int px = 0; px < srcXres; px++)
|
||||
dotMix(px + x, py + y, R5G5B4A2ToColor(((unsigned short*)image.pixels)[i++]));
|
||||
}
|
||||
}
|
||||
|
||||
virtual void imageR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
|
||||
{
|
||||
for (int py = 0; py < srcYres; py++)
|
||||
{
|
||||
int i = srcX + (py + srcY) * image.xres;
|
||||
for (int px = 0; px < srcXres; px++)
|
||||
dot(px + x, py + y, R2G2B2A2ToColor(((unsigned char*)image.pixels)[i++]));
|
||||
}
|
||||
}
|
||||
|
||||
virtual void imageAddR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
|
||||
{
|
||||
for (int py = 0; py < srcYres; py++)
|
||||
{
|
||||
int i = srcX + (py + srcY) * image.xres;
|
||||
for (int px = 0; px < srcXres; px++)
|
||||
dotAdd(px + x, py + y, R2G2B2A2ToColor(((unsigned char*)image.pixels)[i++]));
|
||||
}
|
||||
}
|
||||
|
||||
virtual void imageMixR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
|
||||
{
|
||||
for (int py = 0; py < srcYres; py++)
|
||||
{
|
||||
int i = srcX + (py + srcY) * image.xres;
|
||||
for (int px = 0; px < srcXres; px++)
|
||||
dotMix(px + x, py + y, R2G2B2A2ToColor(((unsigned char*)image.pixels)[i++]));
|
||||
}
|
||||
}
|
||||
};
|
110
libraries/bitluni_ESP32Lib/src/Graphics/GraphicsR1G1B1A1.h
Normal file
110
libraries/bitluni_ESP32Lib/src/Graphics/GraphicsR1G1B1A1.h
Normal file
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include "Graphics.h"
|
||||
|
||||
class GraphicsR1G1B1A1: public Graphics<unsigned char>
|
||||
{
|
||||
public:
|
||||
typedef unsigned char Color;
|
||||
GraphicsR1G1B1A1()
|
||||
{
|
||||
frontColor = 0xf;
|
||||
}
|
||||
|
||||
virtual int R(Color c) const
|
||||
{
|
||||
return (c & 1) * 255;
|
||||
}
|
||||
virtual int G(Color c) const
|
||||
{
|
||||
return (c & 2) ? 255 : 0;
|
||||
}
|
||||
virtual int B(Color c) const
|
||||
{
|
||||
return (c & 4) ? 255 : 0;
|
||||
}
|
||||
virtual int A(Color c) const
|
||||
{
|
||||
return (c & 8) ? 255 : 0;
|
||||
}
|
||||
|
||||
virtual Color RGBA(int r, int g, int b, int a = 255) const
|
||||
{
|
||||
return ((r >> 7) & 1) | ((g >> 6) & 2) | ((b >> 5) & 4) | ((a >> 4) & 8);
|
||||
}
|
||||
|
||||
virtual void dotFast(int x, int y, Color color)
|
||||
{
|
||||
if(x & 1)
|
||||
backBuffer[y][x >> 1] = (backBuffer[y][x >> 1] & 0xf) | (color << 4);
|
||||
else
|
||||
backBuffer[y][x >> 1] = (backBuffer[y][x >> 1] & 0xf0) | (color & 0xf);
|
||||
}
|
||||
|
||||
virtual void dot(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
{
|
||||
if(x & 1)
|
||||
backBuffer[y][x >> 1] = (backBuffer[y][x >> 1] & 0xf) | (color << 4);
|
||||
else
|
||||
backBuffer[y][x >> 1] = (backBuffer[y][x >> 1] & 0xf0) | (color & 0xf);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void dotAdd(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
{
|
||||
if(x & 1)
|
||||
backBuffer[y][x >> 1] = backBuffer[y][x >> 1] | (color << 4);
|
||||
else
|
||||
backBuffer[y][x >> 1] = backBuffer[y][x >> 1] | (color & 0xf);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void dotMix(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres && (color & 8) != 0)
|
||||
{
|
||||
if(x & 1)
|
||||
backBuffer[y][x >> 1] = (backBuffer[y][x >> 1] & 0xf) | (color << 4);
|
||||
else
|
||||
backBuffer[y][x >> 1] = (backBuffer[y][x >> 1] & 0xf0) | (color & 0xf);
|
||||
}
|
||||
}
|
||||
|
||||
virtual Color get(int x, int y)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
{
|
||||
if(x & 1)
|
||||
return backBuffer[y][x >> 1] = backBuffer[y][x >> 1] >> 4;
|
||||
else
|
||||
return backBuffer[y][x >> 1] = backBuffer[y][x >> 1] & 0xf;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void clear(Color color = 0)
|
||||
{
|
||||
for (int y = 0; y < this->yres; y++)
|
||||
for (int x = 0; x < this->xres / 2; x++)
|
||||
this->backBuffer[y][x] = color | (color << 4);
|
||||
}
|
||||
|
||||
virtual Color** allocateFrameBuffer()
|
||||
{
|
||||
return Graphics<Color>::allocateFrameBuffer(xres / 2, yres, (Color)0);
|
||||
}
|
||||
};
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include "Graphics.h"
|
||||
|
||||
class GraphicsR1G1B1A1X2S2Swapped: public Graphics<unsigned char>
|
||||
{
|
||||
public:
|
||||
typedef unsigned char Color;
|
||||
static const Color RGBAXMask = 0x3f;
|
||||
Color SBits;
|
||||
|
||||
GraphicsR1G1B1A1X2S2Swapped()
|
||||
{
|
||||
SBits = 0xc0;
|
||||
frontColor = 0xf;
|
||||
}
|
||||
|
||||
virtual int R(Color c) const
|
||||
{
|
||||
return (c & 1) * 255;
|
||||
}
|
||||
virtual int G(Color c) const
|
||||
{
|
||||
return (c & 2) ? 255 : 0;
|
||||
}
|
||||
virtual int B(Color c) const
|
||||
{
|
||||
return (c & 4) ? 255 : 0;
|
||||
}
|
||||
virtual int A(Color c) const
|
||||
{
|
||||
return (c & 8) ? 255 : 0;
|
||||
}
|
||||
|
||||
virtual Color RGBA(int r, int g, int b, int a = 255) const
|
||||
{
|
||||
return ((r >> 7) & 1) | ((g >> 6) & 2) | ((b >> 5) & 4) | ((a >> 4) & 8);
|
||||
}
|
||||
|
||||
virtual void dotFast(int x, int y, Color color)
|
||||
{
|
||||
backBuffer[y][x^2] = (color & RGBAXMask) | SBits;
|
||||
}
|
||||
|
||||
virtual void dot(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
backBuffer[y][x^2] = (color & RGBAXMask) | SBits;
|
||||
}
|
||||
|
||||
virtual void dotAdd(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
backBuffer[y][x^2] = backBuffer[y][x^2] | (color & RGBAXMask);
|
||||
}
|
||||
|
||||
virtual void dotMix(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres && (color & 8) != 0)
|
||||
backBuffer[y][x^2] = (color & RGBAXMask) | SBits;
|
||||
}
|
||||
|
||||
virtual Color get(int x, int y)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
return backBuffer[y][x^2] & RGBAXMask;
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void clear(Color color = 0)
|
||||
{
|
||||
for (int y = 0; y < this->yres; y++)
|
||||
for (int x = 0; x < this->xres; x++)
|
||||
backBuffer[y][x^2] = (color & RGBAXMask) | SBits;
|
||||
}
|
||||
|
||||
virtual Color** allocateFrameBuffer()
|
||||
{
|
||||
return Graphics<Color>::allocateFrameBuffer(xres, yres, (Color)SBits);
|
||||
}
|
||||
};
|
142
libraries/bitluni_ESP32Lib/src/Graphics/GraphicsR2G2B2A2.h
Normal file
142
libraries/bitluni_ESP32Lib/src/Graphics/GraphicsR2G2B2A2.h
Normal file
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include "Graphics.h"
|
||||
|
||||
class GraphicsR2G2B2A2: public Graphics<unsigned char>
|
||||
{
|
||||
public:
|
||||
typedef unsigned char Color;
|
||||
static const Color RGBAXMask = 0x3f;
|
||||
Color SBits;
|
||||
|
||||
GraphicsR2G2B2A2()
|
||||
{
|
||||
SBits = 0xc0;
|
||||
frontColor = 0xff;
|
||||
}
|
||||
|
||||
virtual int R(Color c) const
|
||||
{
|
||||
return (((int)c & 3) * 255 + 1) / 3;
|
||||
}
|
||||
virtual int G(Color c) const
|
||||
{
|
||||
return (((int)(c >> 2) & 3) * 255 + 1) / 3;
|
||||
}
|
||||
virtual int B(Color c) const
|
||||
{
|
||||
return (((int)(c >> 4) & 3) * 255 + 1) / 3;
|
||||
}
|
||||
virtual int A(Color c) const
|
||||
{
|
||||
return (((int)(c >> 6) & 3) * 255 + 1) / 3;
|
||||
}
|
||||
|
||||
virtual Color RGBA(int r, int g, int b, int a = 255) const
|
||||
{
|
||||
return ((r >> 6) & 0b11) | ((g >> 4) & 0b1100) | ((b >> 2) & 0b110000) | (a & 0b11000000);
|
||||
}
|
||||
|
||||
virtual void dotFast(int x, int y, Color color)
|
||||
{
|
||||
backBuffer[y][x] = (color & RGBAXMask) | SBits;
|
||||
}
|
||||
|
||||
virtual void dot(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
backBuffer[y][x] = (color & RGBAXMask) | SBits;
|
||||
}
|
||||
|
||||
virtual void dotAdd(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
{
|
||||
int c0 = backBuffer[y][x^2];
|
||||
int c1 = color;
|
||||
int r = (c0 & 0b11) + (c1 & 0b11);
|
||||
if(r > 0b11) r = 0b11;
|
||||
int g = (c0 & 0b1100) + (c1 & 0b1100);
|
||||
if(g > 0b1100) g = 0b1100;
|
||||
int b = (c0 & 0b110000) + (c1 & 0b110000);
|
||||
if(b > 0b110000) b = 0b110000;
|
||||
backBuffer[y][x] = r | (g & 0b1100) | (b & 0b110000) | SBits;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void dotMix(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres && (color >> 6) != 0)
|
||||
{
|
||||
unsigned int ai = (3 - ((int)color >> 6)) * (65536 / 3);
|
||||
unsigned int a = 65536 - ai;
|
||||
unsigned int co = backBuffer[y][x^2];
|
||||
unsigned int ro = (co & 0b11) * ai;
|
||||
unsigned int go = (co & 0b1100) * ai;
|
||||
unsigned int bo = (co & 0b110000) * ai;
|
||||
unsigned int r = (color & 0b11) * a + ro;
|
||||
unsigned int g = ((color & 0b1100) * a + go) & 0b11000000000000000000;
|
||||
unsigned int b = ((color & 0b110000) * a + bo) & 0b1100000000000000000000;
|
||||
backBuffer[y][x] = ((r | g | b) >> 16) | SBits;
|
||||
}
|
||||
}
|
||||
|
||||
virtual Color get(int x, int y)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
return backBuffer[y][x] & RGBAXMask;
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void clear(Color color = 0)
|
||||
{
|
||||
for (int y = 0; y < this->yres; y++)
|
||||
for (int x = 0; x < this->xres; x++)
|
||||
backBuffer[y][x] = (color & RGBAXMask) | SBits;
|
||||
}
|
||||
|
||||
virtual void imageR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
|
||||
{
|
||||
for (int py = 0; py < srcYres; py++)
|
||||
{
|
||||
int i = srcX + (py + srcY) * image.xres;
|
||||
for (int px = 0; px < srcXres; px++)
|
||||
dot(px + x, py + y, ((unsigned char*)image.pixels)[i++]);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void imageAddR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
|
||||
{
|
||||
for (int py = 0; py < srcYres; py++)
|
||||
{
|
||||
int i = srcX + (py + srcY) * image.xres;
|
||||
for (int px = 0; px < srcXres; px++)
|
||||
dotAdd(px + x, py + y, ((unsigned char*)image.pixels)[i++]);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void imageMixR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
|
||||
{
|
||||
for (int py = 0; py < srcYres; py++)
|
||||
{
|
||||
int i = srcX + (py + srcY) * image.xres;
|
||||
for (int px = 0; px < srcXres; px++)
|
||||
dotMix(px + x, py + y, ((unsigned char*)image.pixels)[i++]);
|
||||
}
|
||||
}
|
||||
|
||||
virtual Color** allocateFrameBuffer()
|
||||
{
|
||||
return Graphics<Color>::allocateFrameBuffer(xres, yres, (Color)SBits);
|
||||
}
|
||||
};
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include "Graphics.h"
|
||||
|
||||
class GraphicsR2G2B2S2Swapped: public Graphics<unsigned char>
|
||||
{
|
||||
public:
|
||||
typedef unsigned char Color;
|
||||
static const Color RGBAXMask = 0x3f;
|
||||
Color SBits;
|
||||
|
||||
GraphicsR2G2B2S2Swapped()
|
||||
{
|
||||
SBits = 0xc0;
|
||||
frontColor = 0xff;
|
||||
}
|
||||
|
||||
virtual int R(Color c) const
|
||||
{
|
||||
return (((int)c & 3) * 255 + 1) / 3;
|
||||
}
|
||||
virtual int G(Color c) const
|
||||
{
|
||||
return (((int)(c >> 2) & 3) * 255 + 1) / 3;
|
||||
}
|
||||
virtual int B(Color c) const
|
||||
{
|
||||
return (((int)(c >> 4) & 3) * 255 + 1) / 3;
|
||||
}
|
||||
virtual int A(Color c) const
|
||||
{
|
||||
return (((int)(c >> 6) & 3) * 255 + 1) / 3;
|
||||
}
|
||||
|
||||
virtual Color RGBA(int r, int g, int b, int a = 255) const
|
||||
{
|
||||
return ((r >> 6) & 0b11) | ((g >> 4) & 0b1100) | ((b >> 2) & 0b110000) | (a & 0b11000000);
|
||||
}
|
||||
|
||||
virtual void dotFast(int x, int y, Color color)
|
||||
{
|
||||
backBuffer[y][x^2] = (color & RGBAXMask) | SBits;
|
||||
}
|
||||
|
||||
virtual void dot(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
backBuffer[y][x^2] = (color & RGBAXMask) | SBits;
|
||||
}
|
||||
|
||||
virtual void dotAdd(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
{
|
||||
int c0 = backBuffer[y][x^2];
|
||||
int c1 = color;
|
||||
int r = (c0 & 0b11) + (c1 & 0b11);
|
||||
if(r > 0b11) r = 0b11;
|
||||
int g = (c0 & 0b1100) + (c1 & 0b1100);
|
||||
if(g > 0b1100) g = 0b1100;
|
||||
int b = (c0 & 0b110000) + (c1 & 0b110000);
|
||||
if(b > 0b110000) b = 0b110000;
|
||||
backBuffer[y][x^2] = r | (g & 0b1100) | (b & 0b110000) | SBits;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void dotMix(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres && (color >> 6) != 0)
|
||||
{
|
||||
unsigned int ai = (3 - ((int)color >> 6)) * (65536 / 3);
|
||||
unsigned int a = 65536 - ai;
|
||||
unsigned int co = backBuffer[y][x^2];
|
||||
unsigned int ro = (co & 0b11) * ai;
|
||||
unsigned int go = (co & 0b1100) * ai;
|
||||
unsigned int bo = (co & 0b110000) * ai;
|
||||
unsigned int r = (color & 0b11) * a + ro;
|
||||
unsigned int g = ((color & 0b1100) * a + go) & 0b11000000000000000000;
|
||||
unsigned int b = ((color & 0b110000) * a + bo) & 0b1100000000000000000000;
|
||||
backBuffer[y][x^2] = ((r | g | b) >> 16) | SBits;
|
||||
}
|
||||
}
|
||||
|
||||
virtual Color get(int x, int y)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
return backBuffer[y][x^2] & RGBAXMask;
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void clear(Color color = 0)
|
||||
{
|
||||
for (int y = 0; y < this->yres; y++)
|
||||
for (int x = 0; x < this->xres; x++)
|
||||
backBuffer[y][x^2] = (color & RGBAXMask) | SBits;
|
||||
}
|
||||
|
||||
virtual void imageR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
|
||||
{
|
||||
for (int py = 0; py < srcYres; py++)
|
||||
{
|
||||
int i = srcX + (py + srcY) * image.xres;
|
||||
for (int px = 0; px < srcXres; px++)
|
||||
dot(px + x, py + y, ((unsigned char*)image.pixels)[i++]);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void imageAddR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
|
||||
{
|
||||
for (int py = 0; py < srcYres; py++)
|
||||
{
|
||||
int i = srcX + (py + srcY) * image.xres;
|
||||
for (int px = 0; px < srcXres; px++)
|
||||
dotAdd(px + x, py + y, ((unsigned char*)image.pixels)[i++]);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void imageMixR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
|
||||
{
|
||||
for (int py = 0; py < srcYres; py++)
|
||||
{
|
||||
int i = srcX + (py + srcY) * image.xres;
|
||||
for (int px = 0; px < srcXres; px++)
|
||||
dotMix(px + x, py + y, ((unsigned char*)image.pixels)[i++]);
|
||||
}
|
||||
}
|
||||
|
||||
virtual Color** allocateFrameBuffer()
|
||||
{
|
||||
return Graphics<Color>::allocateFrameBuffer(xres, yres, (Color)SBits);
|
||||
}
|
||||
};
|
108
libraries/bitluni_ESP32Lib/src/Graphics/GraphicsR5G5B4A2.h
Normal file
108
libraries/bitluni_ESP32Lib/src/Graphics/GraphicsR5G5B4A2.h
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include "Graphics.h"
|
||||
|
||||
class GraphicsR5G5B4A2: public Graphics<unsigned short>
|
||||
{
|
||||
public:
|
||||
typedef unsigned short Color;
|
||||
GraphicsR5G5B4A2()
|
||||
{
|
||||
frontColor = 0xffff;
|
||||
}
|
||||
|
||||
virtual int R(Color c) const
|
||||
{
|
||||
return (((c << 1) & 0x3e) * 255 + 1) / 0x3e;
|
||||
}
|
||||
virtual int G(Color c) const
|
||||
{
|
||||
return (((c >> 4) & 0x3e) * 255 + 1) / 0x3e;
|
||||
}
|
||||
virtual int B(Color c) const
|
||||
{
|
||||
return (((c >> 9) & 0x1e) * 255 + 1) / 0x1e;
|
||||
}
|
||||
virtual int A(Color c) const
|
||||
{
|
||||
return (((c >> 13) & 6) * 255 + 1) / 6;
|
||||
}
|
||||
|
||||
virtual Color RGBA(int r, int g, int b, int a = 255) const
|
||||
{
|
||||
return ((r >> 3) & 0b11111) | ((g << 2) & 0b1111100000) | ((b << 6) & 0b11110000000000) | ((a << 8) & 0xc000);
|
||||
}
|
||||
|
||||
virtual void dotFast(int x, int y, Color color)
|
||||
{
|
||||
backBuffer[y][x] = color;
|
||||
}
|
||||
|
||||
virtual void dot(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
backBuffer[y][x] = color;
|
||||
}
|
||||
|
||||
virtual void dotAdd(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
{
|
||||
int c0 = backBuffer[y][x];
|
||||
int c1 = color;
|
||||
int r = (c0 & 0b11111) + (c1 & 0b11111);
|
||||
if(r > 0b11111) r = 0b11111;
|
||||
int g = (c0 & 0b1111100000) + (c1 & 0b1111100000);
|
||||
if(g > 0b1111100000) g = 0b1111100000;
|
||||
int b = (c0 & 0b11110000000000) + (c1 & 0b11110000000000);
|
||||
if(b > 0b11110000000000) b = 0b11110000000000;
|
||||
backBuffer[y][x] = r | (g & 0b1111100000) | (b & 0b11110000000000);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void dotMix(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres && (color >> 14) != 0)
|
||||
{
|
||||
unsigned int ai = (3 - (color >> 14)) * (65536 / 3);
|
||||
unsigned int a = 65536 - ai;
|
||||
unsigned int co = backBuffer[y][x];
|
||||
unsigned int ro = (co & 0b11111) * ai;
|
||||
unsigned int go = (co & 0b1111100000) * ai;
|
||||
unsigned int bo = (co & 0b11110000000000) * ai;
|
||||
unsigned int r = (color & 0b11111) * a + ro;
|
||||
unsigned int g = ((color & 0b1111100000) * a + go) & 0b11111000000000000000000000;
|
||||
unsigned int b = ((color & 0b11110000000000) * a + bo) & 0b111100000000000000000000000000;
|
||||
backBuffer[y][x] = (r | g | b) >> 16;
|
||||
}
|
||||
}
|
||||
|
||||
virtual Color get(int x, int y)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
return backBuffer[y][x];
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void clear(Color color = 0)
|
||||
{
|
||||
for (int y = 0; y < this->yres; y++)
|
||||
for (int x = 0; x < this->xres; x++)
|
||||
backBuffer[y][x] = color;
|
||||
}
|
||||
|
||||
virtual Color** allocateFrameBuffer()
|
||||
{
|
||||
return Graphics<Color>::allocateFrameBuffer(xres, yres, (Color)0);
|
||||
}
|
||||
};
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include "Graphics.h"
|
||||
|
||||
class GraphicsR5G5B4S2Swapped: public Graphics<unsigned short>
|
||||
{
|
||||
public:
|
||||
typedef unsigned short Color;
|
||||
static const Color RGBMask = 0x3fff;
|
||||
Color SBits;
|
||||
|
||||
GraphicsR5G5B4S2Swapped()
|
||||
{
|
||||
SBits = 0xc000;
|
||||
frontColor = 0xffff;
|
||||
}
|
||||
|
||||
virtual int R(Color c) const
|
||||
{
|
||||
return (((c << 1) & 0x3e) * 255 + 1) / 0x3e;
|
||||
}
|
||||
virtual int G(Color c) const
|
||||
{
|
||||
return (((c >> 4) & 0x3e) * 255 + 1) / 0x3e;
|
||||
}
|
||||
virtual int B(Color c) const
|
||||
{
|
||||
return (((c >> 9) & 0x1e) * 255 + 1) / 0x1e;
|
||||
}
|
||||
virtual int A(Color c) const
|
||||
{
|
||||
return (((c >> 13) & 6) * 255 + 1) / 6;
|
||||
}
|
||||
|
||||
virtual Color RGBA(int r, int g, int b, int a = 255) const
|
||||
{
|
||||
return ((r >> 3) & 0b11111) | ((g << 2) & 0b1111100000) | ((b << 6) & 0b11110000000000) | ((a << 8) & 0xc000);
|
||||
}
|
||||
|
||||
virtual void dotFast(int x, int y, Color color)
|
||||
{
|
||||
backBuffer[y][x^1] = (color & RGBMask) | SBits;
|
||||
}
|
||||
|
||||
virtual void dot(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
backBuffer[y][x^1] = (color & RGBMask) | SBits;
|
||||
}
|
||||
|
||||
virtual void dotAdd(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
{
|
||||
int c0 = backBuffer[y][x^1];
|
||||
int c1 = color;
|
||||
int r = (c0 & 0b11111) + (c1 & 0b11111);
|
||||
if(r > 0b11111) r = 0b11111;
|
||||
int g = (c0 & 0b1111100000) + (c1 & 0b1111100000);
|
||||
if(g > 0b1111100000) g = 0b1111100000;
|
||||
int b = (c0 & 0b11110000000000) + (c1 & 0b11110000000000);
|
||||
if(b > 0b11110000000000) b = 0b11110000000000;
|
||||
backBuffer[y][x^1] = r | (g & 0b1111100000) | (b & 0b11110000000000) | SBits;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void dotMix(int x, int y, Color color)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres && (color >> 14) != 0)
|
||||
{
|
||||
unsigned int ai = (3 - (color >> 14)) * (65536 / 3);
|
||||
unsigned int a = 65536 - ai;
|
||||
unsigned int co = backBuffer[y][x^1];
|
||||
unsigned int ro = (co & 0b11111) * ai;
|
||||
unsigned int go = (co & 0b1111100000) * ai;
|
||||
unsigned int bo = (co & 0b11110000000000) * ai;
|
||||
unsigned int r = (color & 0b11111) * a + ro;
|
||||
unsigned int g = ((color & 0b1111100000) * a + go) & 0b11111000000000000000000000;
|
||||
unsigned int b = ((color & 0b11110000000000) * a + bo) & 0b111100000000000000000000000000;
|
||||
backBuffer[y][x^1] = ((r | g | b) >> 16) | SBits;
|
||||
}
|
||||
}
|
||||
|
||||
virtual Color get(int x, int y)
|
||||
{
|
||||
if ((unsigned int)x < xres && (unsigned int)y < yres)
|
||||
return backBuffer[y][x^1] & RGBMask;
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void clear(Color color = 0)
|
||||
{
|
||||
for (int y = 0; y < this->yres; y++)
|
||||
for (int x = 0; x < this->xres; x++)
|
||||
backBuffer[y][x^1] = (color & RGBMask) | SBits;
|
||||
}
|
||||
|
||||
virtual Color** allocateFrameBuffer()
|
||||
{
|
||||
return Graphics<Color>::allocateFrameBuffer(xres, yres, (Color)SBits);
|
||||
}
|
||||
};
|
52
libraries/bitluni_ESP32Lib/src/Graphics/Image.h
Normal file
52
libraries/bitluni_ESP32Lib/src/Graphics/Image.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
class Image
|
||||
{
|
||||
public:
|
||||
enum PixelFormat
|
||||
{
|
||||
R8G8B8A8 = 1,
|
||||
R1G1B1A1 = 2,
|
||||
R2G2B2A2 = 3,
|
||||
R4G4B4A4 = 4,
|
||||
R5G5B5A1 = 5,
|
||||
R5G5B4A2 = 6
|
||||
};
|
||||
|
||||
int xres;
|
||||
int yres;
|
||||
PixelFormat pixelFormat;
|
||||
const void *pixels;
|
||||
|
||||
void init(int xres, int yres, const void *pixels, PixelFormat pixelFormat)
|
||||
{
|
||||
this->xres = xres;
|
||||
this->yres = yres;
|
||||
this->pixels = pixels;
|
||||
this->pixelFormat = pixelFormat;
|
||||
}
|
||||
|
||||
Image(){};
|
||||
|
||||
Image(int xres, int yres, const void *pixels, PixelFormat pixelFormat)
|
||||
{
|
||||
init(xres, yres, pixels, pixelFormat);
|
||||
}
|
||||
|
||||
/*
|
||||
Color get(int x, int y) const
|
||||
{
|
||||
return pixels[y * xres + x];
|
||||
}*/
|
||||
};
|
113
libraries/bitluni_ESP32Lib/src/Graphics/ImageDrawer.h
Normal file
113
libraries/bitluni_ESP32Lib/src/Graphics/ImageDrawer.h
Normal file
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include "Image.h"
|
||||
class ImageDrawer
|
||||
{
|
||||
public:
|
||||
virtual void imageR5G5B4A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres) = 0;
|
||||
virtual void imageAddR5G5B4A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres) = 0;
|
||||
virtual void imageMixR5G5B4A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres) = 0;
|
||||
virtual void imageR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres) = 0;
|
||||
virtual void imageAddR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres) = 0;
|
||||
virtual void imageMixR2G2B2A2(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres) = 0;
|
||||
|
||||
void image(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
|
||||
{
|
||||
switch(image.pixelFormat)
|
||||
{
|
||||
case Image::R5G5B4A2:
|
||||
imageR5G5B4A2(image, x, y, srcX, srcY, srcXres, srcYres);
|
||||
break;
|
||||
case Image::R2G2B2A2:
|
||||
imageR2G2B2A2(image, x, y, srcX, srcY, srcXres, srcYres);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void imageAdd(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
|
||||
{
|
||||
switch(image.pixelFormat)
|
||||
{
|
||||
case Image::R5G5B4A2:
|
||||
imageAddR5G5B4A2(image, x, y, srcX, srcY, srcXres, srcYres);
|
||||
break;
|
||||
case Image::R2G2B2A2:
|
||||
imageAddR2G2B2A2(image, x, y, srcX, srcY, srcXres, srcYres);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void imageMix(Image &image, int x, int y, int srcX, int srcY, int srcXres, int srcYres)
|
||||
{
|
||||
switch(image.pixelFormat)
|
||||
{
|
||||
case Image::R5G5B4A2:
|
||||
imageMixR5G5B4A2(image, x, y, srcX, srcY, srcXres, srcYres);
|
||||
break;
|
||||
case Image::R2G2B2A2:
|
||||
imageMixR2G2B2A2(image, x, y, srcX, srcY, srcXres, srcYres);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void image(Image &image, int x, int y)
|
||||
{
|
||||
switch(image.pixelFormat)
|
||||
{
|
||||
case Image::R5G5B4A2:
|
||||
imageR5G5B4A2(image, x, y, 0, 0, image.xres, image.yres);
|
||||
break;
|
||||
case Image::R2G2B2A2:
|
||||
imageR2G2B2A2(image, x, y, 0, 0, image.xres, image.yres);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void imageAdd(Image &image, int x, int y)
|
||||
{
|
||||
switch(image.pixelFormat)
|
||||
{
|
||||
case Image::R5G5B4A2:
|
||||
imageAddR5G5B4A2(image, x, y, 0, 0, image.xres, image.yres);
|
||||
break;
|
||||
case Image::R2G2B2A2:
|
||||
imageAddR2G2B2A2(image, x, y, 0, 0, image.xres, image.yres);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void imageMix(Image &image, int x, int y)
|
||||
{
|
||||
switch(image.pixelFormat)
|
||||
{
|
||||
case Image::R5G5B4A2:
|
||||
imageMixR5G5B4A2(image, x, y, 0, 0, image.xres, image.yres);
|
||||
break;
|
||||
case Image::R2G2B2A2:
|
||||
imageMixR2G2B2A2(image, x, y, 0, 0, image.xres, image.yres);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
137
libraries/bitluni_ESP32Lib/src/Graphics/Mesh.h
Normal file
137
libraries/bitluni_ESP32Lib/src/Graphics/Mesh.h
Normal file
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include "../Math/Matrix.h"
|
||||
#include "Engine3D.h"
|
||||
#include "../Tools/Log.h"
|
||||
|
||||
template <typename Graphics>
|
||||
class Mesh
|
||||
{
|
||||
public:
|
||||
typedef typename Graphics::Color Color;
|
||||
int vertexCount;
|
||||
int edgeCount;
|
||||
int triangleCount;
|
||||
const float (*vertices)[3];
|
||||
const unsigned short (*edges)[2];
|
||||
const unsigned short (*triangles)[3];
|
||||
const float (*triangleNormals)[3];
|
||||
short (*tvertices)[3];
|
||||
signed char (*tTriNormals)[3];
|
||||
|
||||
typedef Color (*triangleShader)(int trinangleNo, short *v0, short *v1, short *v2, const signed char *normal, Color color);
|
||||
|
||||
Mesh(int vertCount, const float verts[][3], int edgeCount_ = 0, const unsigned short edges_[][2] = 0, int triCount = 0, const unsigned short tris[][3] = 0, const float triNorms[][3] = 0)
|
||||
: vertexCount(vertCount),
|
||||
edgeCount(edgeCount_),
|
||||
triangleCount(triCount),
|
||||
vertices(verts),
|
||||
edges(edges_),
|
||||
triangles(tris),
|
||||
triangleNormals(triNorms)
|
||||
{
|
||||
tvertices = (short(*)[3])malloc(sizeof(short) * 3 * vertexCount);
|
||||
if(!tvertices)
|
||||
ERROR("Not enough memory for vertices");
|
||||
if (triangleNormals)
|
||||
{
|
||||
tTriNormals = (signed char(*)[3])malloc(sizeof(signed char) * 3 * triangleCount);
|
||||
if(!tTriNormals)
|
||||
ERROR("Not enough memory for triangle normals");
|
||||
}
|
||||
}
|
||||
|
||||
~Mesh()
|
||||
{
|
||||
delete (tvertices);
|
||||
}
|
||||
|
||||
static Color basicTriangleShader(int trinangleNo, short *v0, short *v1, short *v2, const signed char *normal, Color color)
|
||||
{
|
||||
return color;
|
||||
}
|
||||
|
||||
static Color basicTriangleShaderNormals(int trinangleNo, short *v0, short *v1, short *v2, const signed char *normal, Color color)
|
||||
{
|
||||
const float scaleN = 1.0f / 127.0f;
|
||||
const float nx = normal[0] * scaleN;
|
||||
const float ny = normal[1] * scaleN;
|
||||
const float nz = normal[2] * scaleN;
|
||||
|
||||
const float L[3] = {0, 0, -1};
|
||||
|
||||
float NdotL = nx * L[0] + ny * L[1] + nz * L[2];
|
||||
if(NdotL < 0) NdotL = 0;
|
||||
return int(NdotL * (color & 0x1f)) | (int(NdotL * ((color >> 5) & 0x1f)) << 5) | (int(NdotL * ((color >> 10) & 0xf)) << 10);
|
||||
}
|
||||
|
||||
void drawTriangles(Engine3D<Graphics> &e, Color color = -1, triangleShader ts = 0)
|
||||
{
|
||||
if(ts == 0)
|
||||
{
|
||||
if(tTriNormals)
|
||||
ts = basicTriangleShaderNormals;
|
||||
else
|
||||
ts = basicTriangleShader;
|
||||
}
|
||||
|
||||
for (int i = 0; i < triangleCount; i++)
|
||||
{
|
||||
short *v0 = tvertices[triangles[i][0]];
|
||||
short *v1 = tvertices[triangles[i][1]];
|
||||
short *v2 = tvertices[triangles[i][2]];
|
||||
int dx1 = v1[0] - v0[0];
|
||||
int dy1 = v1[1] - v0[1];
|
||||
int dx2 = v2[0] - v0[0];
|
||||
int dy2 = v2[1] - v0[1];
|
||||
if (dx1 * dy2 - dx2 * dy1 < 0)
|
||||
{
|
||||
Color c = ts(i, v0, v1, v2, tTriNormals ? tTriNormals[i] : 0, color);
|
||||
e.enqueueTriangle(tvertices[triangles[i][0]], tvertices[triangles[i][1]], tvertices[triangles[i][2]], c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawEdges(Graphics &g, Color color)
|
||||
{
|
||||
for (int i = 0; i < edgeCount; i++)
|
||||
{
|
||||
g.line(tvertices[edges[i][0]][0], tvertices[edges[i][0]][1], tvertices[edges[i][1]][0], tvertices[edges[i][1]][1], color);
|
||||
}
|
||||
}
|
||||
|
||||
void drawVertices(Graphics &g, Color color)
|
||||
{
|
||||
for (int i = 0; i < vertexCount; i++)
|
||||
g.dot(tvertices[i][0], tvertices[i][1], color);
|
||||
}
|
||||
|
||||
void transform(Matrix m, Matrix normTrans = Matrix())
|
||||
{
|
||||
for (int i = 0; i < vertexCount; i++)
|
||||
{
|
||||
Vector v = m * Vector(vertices[i][0], vertices[i][1], vertices[i][2]);
|
||||
tvertices[i][0] = v[0] / v[3];
|
||||
tvertices[i][1] = v[1] / v[3];
|
||||
tvertices[i][2] = v[2];
|
||||
}
|
||||
if (triangleNormals)
|
||||
for (int i = 0; i < triangleCount; i++)
|
||||
{
|
||||
Vector v = normTrans * Vector(triangleNormals[i][0], triangleNormals[i][1], triangleNormals[i][2]);
|
||||
tTriNormals[i][0] = v[0] * 127;
|
||||
tTriNormals[i][1] = v[1] * 127;
|
||||
tTriNormals[i][2] = v[2] * 127;
|
||||
}
|
||||
}
|
||||
};
|
108
libraries/bitluni_ESP32Lib/src/Graphics/Sprites.h
Normal file
108
libraries/bitluni_ESP32Lib/src/Graphics/Sprites.h
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
#include "ImageDrawer.h"
|
||||
#include "Image.h"
|
||||
|
||||
class Sprite : public Image
|
||||
{
|
||||
public:
|
||||
typedef Image::PixelFormat PixelFormat;
|
||||
unsigned char pointCount;
|
||||
const signed short (*points)[2];
|
||||
|
||||
void init(int xres, int yres, const void *pixels, unsigned char pointCount, const signed short points[][2], PixelFormat pixelFormat)
|
||||
{
|
||||
static const signed short zeroPoint[][2] = {0, 0};
|
||||
Image::init(xres, yres, pixels, pixelFormat);
|
||||
if (pointCount)
|
||||
{
|
||||
this->pointCount = pointCount;
|
||||
this->points = points;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->pointCount = 1;
|
||||
this->points = zeroPoint;
|
||||
}
|
||||
}
|
||||
void draw(ImageDrawer &g, int x, int y)
|
||||
{
|
||||
g.image(*this, x - points[0][0], y - points[0][1]);
|
||||
}
|
||||
|
||||
void drawMix(ImageDrawer &g, int x, int y)
|
||||
{
|
||||
g.imageMix(*this, x - points[0][0], y - points[0][1]);
|
||||
}
|
||||
|
||||
void drawAdd(ImageDrawer &g, int x, int y)
|
||||
{
|
||||
g.imageAdd(*this, x - points[0][0], y - points[0][1]);
|
||||
}
|
||||
};
|
||||
|
||||
class Sprites
|
||||
{
|
||||
public:
|
||||
typedef Image::PixelFormat PixelFormat;
|
||||
int count;
|
||||
Sprite *sprites;
|
||||
|
||||
Sprites(int count, const void* pixels, const int offsets[], const unsigned short resolutions[][2], const signed short points[][2], const short pointOffsets[], PixelFormat pixelFormat)
|
||||
{
|
||||
this->count = count;
|
||||
this->sprites = new Sprite[count];
|
||||
for (int i = 0; i < count; i++)
|
||||
this->sprites[i].init(resolutions[i][0], resolutions[i][1], (unsigned char*)pixels + offsets[i], pointOffsets[i + 1] - pointOffsets[i], &points[pointOffsets[i]], pixelFormat);
|
||||
}
|
||||
|
||||
void draw(ImageDrawer &g, int sprite, int x, int y)
|
||||
{
|
||||
sprites[sprite].draw(g, x, y);
|
||||
}
|
||||
|
||||
void drawMix(ImageDrawer &g, int sprite, int x, int y)
|
||||
{
|
||||
sprites[sprite].drawMix(g, x, y);
|
||||
}
|
||||
|
||||
void drawAdd(ImageDrawer &g, int sprite, int x, int y)
|
||||
{
|
||||
sprites[sprite].drawAdd(g, x, y);
|
||||
}
|
||||
|
||||
int xres(int sprite) const
|
||||
{
|
||||
return sprites[sprite].xres;
|
||||
}
|
||||
|
||||
int yres(int sprite) const
|
||||
{
|
||||
return sprites[sprite].yres;
|
||||
}
|
||||
|
||||
const short (*points(int sprite) const)[2]
|
||||
{
|
||||
return sprites[sprite].points;
|
||||
}
|
||||
|
||||
const short *point(int sprite, int point) const
|
||||
{
|
||||
return sprites[sprite].points[point];
|
||||
}
|
||||
|
||||
/*unsigned short get(int sprite, int x, int y) const
|
||||
{
|
||||
return sprites[sprite].get(x, y);
|
||||
}*/
|
||||
};
|
126
libraries/bitluni_ESP32Lib/src/Graphics/TriangleTree.h
Normal file
126
libraries/bitluni_ESP32Lib/src/Graphics/TriangleTree.h
Normal file
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
Author: bitluni 2019
|
||||
License:
|
||||
Creative Commons Attribution ShareAlike 4.0
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
For further details check out:
|
||||
https://youtube.com/bitlunislab
|
||||
https://github.com/bitluni
|
||||
http://bitluni.net
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
class TriangleTree
|
||||
{
|
||||
public:
|
||||
short *v[3];
|
||||
int z;
|
||||
TriangleTree *left, *right;
|
||||
int depth;
|
||||
long color;
|
||||
|
||||
void set(short *v0, short *v1, short *v2, long color)
|
||||
{
|
||||
v[0] = v0;
|
||||
v[1] = v1;
|
||||
v[2] = v2;
|
||||
z = v[0][2] + v[1][2] + v[2][2];
|
||||
this->color = color;
|
||||
left = right = 0;
|
||||
depth = 1;
|
||||
}
|
||||
|
||||
int leftDepth() const
|
||||
{
|
||||
return left ? left->depth : 0;
|
||||
}
|
||||
|
||||
int rightDepth() const
|
||||
{
|
||||
return right ? right->depth : 0;
|
||||
}
|
||||
|
||||
void recalcDepth()
|
||||
{
|
||||
int l = leftDepth();
|
||||
int r = rightDepth();
|
||||
depth = l > r ? l : r;
|
||||
}
|
||||
|
||||
int add(TriangleTree **origin, TriangleTree &t)
|
||||
{
|
||||
int d = 1;
|
||||
if (t.z < z)
|
||||
{
|
||||
if (left)
|
||||
d = left->add(&left, t);
|
||||
else
|
||||
left = &t;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (right)
|
||||
d = right->add(&right, t);
|
||||
else
|
||||
right = &t;
|
||||
}
|
||||
if (depth < d + 1)
|
||||
depth = d + 1;
|
||||
int l = leftDepth();
|
||||
int r = rightDepth();
|
||||
if (l > r + 1)
|
||||
{
|
||||
int ll = left->leftDepth();
|
||||
int lr = left->rightDepth();
|
||||
if (ll < lr)
|
||||
{
|
||||
TriangleTree *tl = left;
|
||||
left = tl->right;
|
||||
tl->right = left->left;
|
||||
left->left = tl;
|
||||
left->left->recalcDepth();
|
||||
left->recalcDepth();
|
||||
ll = left->leftDepth();
|
||||
lr = left->rightDepth();
|
||||
l = leftDepth();
|
||||
recalcDepth();
|
||||
}
|
||||
{
|
||||
*origin = left;
|
||||
left = left->right;
|
||||
(*origin)->right = this;
|
||||
depth = lr > r ? lr + 1 : r + 1;
|
||||
(*origin)->depth = ll > depth ? ll + 1 : depth + 1;
|
||||
return (*origin)->depth + 1;
|
||||
}
|
||||
}
|
||||
if (r > l + 1)
|
||||
{
|
||||
int rl = right->leftDepth();
|
||||
int rr = right->rightDepth();
|
||||
if (rr < rl)
|
||||
{
|
||||
TriangleTree *tr = right;
|
||||
right = tr->left;
|
||||
tr->left = right->right;
|
||||
right->right = tr;
|
||||
right->right->recalcDepth();
|
||||
right->recalcDepth();
|
||||
rr = right->rightDepth();
|
||||
rl = right->leftDepth();
|
||||
r = rightDepth();
|
||||
recalcDepth();
|
||||
}
|
||||
{
|
||||
*origin = right;
|
||||
right = right->left;
|
||||
(*origin)->left = this;
|
||||
depth = rl > l ? rl + 1 : l + 1;
|
||||
(*origin)->depth = rr > depth ? rr + 1 : depth + 1;
|
||||
return (*origin)->depth + 1;
|
||||
}
|
||||
}
|
||||
return depth;
|
||||
}
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue