diff --git a/CMakeLists.txt b/CMakeLists.txt index ce8832c..c325153 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,5 +19,6 @@ list(APPEND FC_DEP_LIBS freeimage) #add_subdirectory(src/1raster) #add_subdirectory(src/2texture) #add_subdirectory(src/3statemachine) -add_subdirectory(src/4matrix) +#add_subdirectory(src/4matrix) +add_subdirectory(src/5threed) diff --git a/src/4matrix/struct/tvec3.h b/src/4matrix/struct/tvec3.h index 9c447e1..7b7a396 100644 --- a/src/4matrix/struct/tvec3.h +++ b/src/4matrix/struct/tvec3.h @@ -70,9 +70,9 @@ struct tvec3 { */ template tvec3(U s) { - // x = value_type(s); - // y = value_type(s); - // z = value_type(s); + x = value_type(s); + y = value_type(s); + z = value_type(s); } template diff --git a/src/5threed/CMakeLists.txt b/src/5threed/CMakeLists.txt new file mode 100644 index 0000000..037ba7d --- /dev/null +++ b/src/5threed/CMakeLists.txt @@ -0,0 +1,8 @@ +set(commom_src + Rgba.cc + Raster.cc + Image.cc +) + +add_executable(threed threed.cc ${commom_src}) +target_link_libraries (threed ${FC_DEP_LIBS}) diff --git a/src/5threed/Image.cc b/src/5threed/Image.cc new file mode 100644 index 0000000..e8f7bf5 --- /dev/null +++ b/src/5threed/Image.cc @@ -0,0 +1,43 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: Image.cc + * Author: Blobt + * + * Created on February 10, 2020, 5:55 PM + */ + +#include "Image.h" +#include + +Image::Image(int width, int height, void* data) { + if (width == 0 || height == 0 || data == 0) { + _width = 0; + _height = 0; + _pixel = 0; + } else { + _width = width; + _height = height; + _pixel = new unsigned int[width * height]; + memcpy(_pixel, data, width * height * sizeof (unsigned int)); + } +} + +Image::~Image() { + delete [] _pixel; +} + +Rgba Image::pixelAt(int x, int y) const { + return Rgba(_pixel[y * _width + x]); +} + +Rgba Image::pixelUv(float u, float v) const { + float x = (u * _width); + float y = (v * _height); //TODO ??? + + return pixelAt((unsigned int) (x) % _width, (unsigned int) (y) % _height); +} diff --git a/src/5threed/Image.h b/src/5threed/Image.h new file mode 100644 index 0000000..15b800e --- /dev/null +++ b/src/5threed/Image.h @@ -0,0 +1,78 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: Image.h + * Author: Blobt + * + * Created on February 10, 2020, 5:55 PM + */ + +#ifndef IMAGE_H +#define IMAGE_H +#include "common.h" +#include "Rgba.h" +#include "FreeImage.h" +#include "stdio.h" + +class Image { +public: + Image(int width, int height, void* data); + virtual ~Image(); + + int width() const { + return _width; + } + + int height() const { + return _height; + } + + Rgba pixelAt(int x, int y) const; + + Rgba pixelUv(float u, float v) const; + + static Image* loadFromFile(const char* fileName) { + + //检查文件类型 + FREE_IMAGE_FORMAT fifmt = FreeImage_GetFileType(fileName, 0); + if (fifmt == FIF_UNKNOWN) { + die("FreeImage_GetFileType"); + } + + //获取 + FIBITMAP* dib = FreeImage_Load(fifmt, fileName, 0); + + //转换 + FIBITMAP* temp = dib; + dib = FreeImage_ConvertTo32Bits(dib); + FreeImage_Unload(temp); + + + BYTE* pixels = (BYTE*) FreeImage_GetBits(dib); + int width = FreeImage_GetWidth(dib); + int height = FreeImage_GetHeight(dib); + + //颜色为数调换 + for (int i = 0; i < width * height * 4; i += 4) { + BYTE temp = pixels[i]; + pixels[i] = pixels[i + 2]; + pixels[i + 2] = temp; + } + + Image* image = new Image(width, height, (void*) pixels); + FreeImage_Unload(dib); + + return image; + + } +private: + int _width; + int _height; + unsigned int* _pixel; +}; +#endif /* IMAGE_H */ + diff --git a/src/5threed/Raster.cc b/src/5threed/Raster.cc new file mode 100644 index 0000000..6e71a73 --- /dev/null +++ b/src/5threed/Raster.cc @@ -0,0 +1,422 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: Raster.cc + * Author: blobt + * + * Created on January 23, 2020, 6:00 PM + */ + +#include "Rgba.h" +#include "Raster.h" +#include "Image.h" +#include +#include +#include +#include + +using namespace std; + +Raster::Raster(int width, int height) { + _width = width; + _height = height; + _color = Rgba(); + _texture = 0; + buffer = new Rgba[width * height]; + + memset(&_positionPointer, 0, sizeof (_positionPointer)); + memset(&_colorPointer, 0, sizeof (_colorPointer)); + memset(&_uvPointer, 0, sizeof (_uvPointer)); + + _defaultColorPointer.size = 4; + _defaultColorPointer.type = DT_BYTE; + _defaultColorPointer.stride = sizeof (Rgba); + _defaultColorPointer.data = _defaultColorArray; + + _defaultUvPointer.size = 2; + _defaultUvPointer.type = DT_FLOAT; + _defaultUvPointer.stride = sizeof (float2); + _defaultUvPointer.data = _defaultUvArray; + + _matModel = matrix4(1); +} + +Raster::~Raster() { + delete buffer; +} + +void Raster::vertexPointer(int size, DATETYPE type, int stride, const void* data) { + this->_positionPointer.size = size; + this->_positionPointer.type = type; + this->_positionPointer.stride = stride; + this->_positionPointer.data = data; +} + +void Raster::colorPointer(int size, DATETYPE type, int stride, const void* data) { + this->_colorPointer.size = size; + this->_colorPointer.type = type; + this->_colorPointer.stride = stride; + this->_colorPointer.data = data; +} + +void Raster::textureCoordPointer(int size, DATETYPE type, int stride, const void* data) { + this->_uvPointer.size = size; + this->_uvPointer.type = type; + this->_uvPointer.stride = stride; + this->_uvPointer.data = data; +} + +void Raster::drawLine(float2 p1, float2 p2, Rgba color) { + + float xOffer = p1.x - p2.x; + float yOffer = p1.y - p2.y; + float xStart, xEnd, yStart, yEnd; + + if (xOffer == 0 && yOffer == 0) { + setPixel(p1.x, p1.y, color); + } + + + if (fabs(xOffer) > fabs(yOffer)) { + if (p1.x < p2.x) { + xStart = p1.x; + xEnd = p2.x; + yEnd = p2.y; + } else { + xStart = p2.x; + xEnd = p1.x; + yEnd = p1.y; + } + + float slope = yOffer / xOffer; + for (float i = xStart; i < xEnd; i += 1.0) { + float q = yEnd - slope * (xEnd - i); + setPixel(i, q, color); + } + } else { + if (p1.y < p2.y) { + yStart = p1.y; + yEnd = p2.y; + xEnd = p2.x; + } else { + yStart = p2.y; + yEnd = p1.y; + xEnd = p1.x; + } + float slope = xOffer / yOffer; + for (float i = yStart; i < yEnd; i += 1.0) { + float q = xEnd - slope * (yEnd - i); + setPixel(q, i, color); + } + } + +} + +void Raster::drawPoint(int x, int y, Rgba color, int pointSize) { + switch (pointSize) { + case 1: + setPixel(x, y, color); + break; + case 2: + setPixel(x, y, color); + setPixel(x + 1, y, color); + setPixel(x, y + 1, color); + setPixel(x + 1, y + 1, color); + break; + case 3: + setPixel(x - 1, y - 1, color); + setPixel(x, y - 1, color); + setPixel(x + 1, y - 1, color); + + setPixel(x - 1, y, color); + setPixel(x, y, color); + setPixel(x + 1, y, color); + + setPixel(x - 1, y + 1, color); + setPixel(x, y + 1, color); + setPixel(x + 1, y + 1, color); + break; + } +} + +/** + * 画一条平行于x轴的直线 + * @param span + */ +void Raster::drawSpan(const Span &span, Image* image) { + //float length = tmax(span.xStart - span.xEnd, 1); //取保length不为0 + + Rgba color; + Rgba blendColor; + Rgba dstColor; + float2 uv; + float scale; + float length = span.xEnd - span.xStart; + + + //TODO 这里越界和texture不兼容,没有解决 + //int startX = tmax(span.xStart, 0); + //int endX = tmin(span.xEnd, _width); + + int startX = span.xStart; + int endX = span.xEnd; + + int t = 0; + //优化3 x轴越界处理 + for (int i = startX; i <= endX; i++) { + + + if (length == 0) { + scale = 0; + } else { + scale = (float) (i - startX) / length; + } + + blendColor = colorLerp(span.color1, span.color2, scale); + uv = uvLerp(span.uvStart, span.uvEnd, scale); + + color = image->pixelUv(uv.x, uv.y); + + //颜色混合 + dstColor = color + blendColor; + + + + setPixel(i, span.y, dstColor); + } +} + +void Raster::drawEge(const Ege& e1, const Ege& e2, Image* image) { + + float xOffset1 = fabs(e1.x2 - e1.x1); + float yOffset1 = fabs(e1.y2 - e1.y1); + float setp1 = 1 / yOffset1; + float scale1 = (e1.y2 - e2.y2) / yOffset1; //TODO:yOffset1 不能为0 + + float xOffset2 = fabs(e2.x2 - e2.x1); + float yOffset2 = fabs(e2.y2 - e2.y1); + float setp2 = 1 / yOffset2; //TODO:yOffset2 不能为0 + float scale2 = 0; + + + //优化2 y轴越界处理 + int startY2 = tmin(e2.y2, _height); + int endY2 = tmax(e2.y1, 0); + scale2 = (e2.y2 - startY2) / yOffset2; + + int startY1 = tmin(e1.y2, _height); + float s = (e1.y2 - startY1) / yOffset1; + scale1 = tmax(scale1, s); + + float2 uvE1; + float2 uvE2; + Rgba color1; + Rgba color2; + + for (int y = startY2; y > endY2; y--) { + + int x2; + if (e2.x2 < e2.x1) { + x2 = e2.x2 + xOffset2 * scale2; + } else { + x2 = e2.x2 - xOffset2 * scale2; + } + color2 = colorLerp(e2.color1, e2.color2, scale2); + uvE2 = uvLerp(e2.uv2, e2.uv1, scale2); + scale2 += setp2; + //setPixel(x2, y, Rgba(255,0,0)); + + + int x1; + if (e1.x2 < e1.x1) { + x1 = e1.x2 + xOffset1 * scale1; + } else { + x1 = e1.x2 - xOffset1 * scale1; + } + color1 = colorLerp(e1.color1, e1.color2, scale1); + uvE1 = uvLerp(e1.uv2, e1.uv1, scale1); + scale1 += setp1; + //setPixel(x1, y, Rgba(255,0,0)); + + Span span(x1, x2, y, color1, color2, uvE1, uvE2); + drawSpan(span, image); + } +} + +void Raster::drawTriangle(Ege eges[3], Image* image) { + int iMax = 0; + int length = eges[0].y2 - eges[0].y1; + + int curLength = 0; + + for (int i = 1; i < 3; i++) { + curLength = eges[i].y2 - eges[i].y1; + if (curLength > length) { + length = curLength; + iMax = i; + } + } + + int iShort1 = (iMax + 1) % 3; + int iShort2 = (iMax + 2) % 3; + + drawEge(eges[iMax], eges[iShort1], image); + drawEge(eges[iMax], eges[iShort2], image); +} + +void Raster::drawTriangle(const Vertex& vertex, Image* image) { + + //优化1 不画3个点都不在坐标内的三角形 + if (!isIn(vertex.p0) && !isIn(vertex.p1) && !isIn(vertex.p2)) { + return; + } + + Ege eges[3] = { + Ege(vertex.p0.x, vertex.p0.y, vertex.p1.x, vertex.p1.y, vertex.c0, vertex.c1, vertex.uv0, vertex.uv1), + Ege(vertex.p1.x, vertex.p1.y, vertex.p2.x, vertex.p2.y, vertex.c1, vertex.c2, vertex.uv1, vertex.uv2), + Ege(vertex.p2.x, vertex.p2.y, vertex.p0.x, vertex.p0.y, vertex.c2, vertex.c0, vertex.uv2, vertex.uv0), + }; + + int iMax = 0; + int length = eges[0].y2 - eges[0].y1; + + int curLength = 0; + + for (int i = 1; i < 3; i++) { + curLength = eges[i].y2 - eges[i].y1; + if (curLength > length) { + length = curLength; + iMax = i; + } + } + + int iShort1 = (iMax + 1) % 3; + int iShort2 = (iMax + 2) % 3; + + drawEge(eges[iMax], eges[iShort1], image); + drawEge(eges[iMax], eges[iShort2], image); +} + +void Raster::drawArrays(DRAWMODE pri, int start, int count) { + if (_positionPointer.data == 0) { + return; + } + + DataElementDes colorPointerdesc = _colorPointer; + DataElementDes uvPointerdesc = _uvPointer; + + if (colorPointerdesc.data == 0) { + colorPointerdesc = _defaultColorPointer; + } + + if (uvPointerdesc.data == 0) { + uvPointerdesc = _defaultUvPointer; + } + + char* posData = (char*) _positionPointer.data; + char* cData = (char*) colorPointerdesc.data; + char* uvData = (char*) uvPointerdesc.data; + + for (int i = start; i < start + count; i += 3) { + float* pp = (float*) posData; + float4 mp0(pp[0], pp[1], pp[2], 1); + mp0 = _matModel * mp0; + + posData += _positionPointer.stride; + pp = (float*) posData; + float4 mp1(pp[0], pp[1], pp[2], 1); + mp1 = _matModel * mp1; + + posData += _positionPointer.stride; + pp = (float*) posData; + float4 mp2(pp[0], pp[1], pp[2], 1); + mp2 = _matModel * mp2; + + int2 p0(mp0.x, mp0.y); + int2 p1(mp1.x, mp1.y); + int2 p2(mp2.x, mp2.y); + + posData += _positionPointer.stride; + + Rgba* pc = (Rgba*) cData; + Rgba c0(*pc); + cData += _colorPointer.stride; + pc = (Rgba*) cData; + Rgba c1(*pc); + cData += _colorPointer.stride; + pc = (Rgba*) cData; + Rgba c2(*pc); + cData += _colorPointer.stride; + + float* puv = (float*) uvData; + float2 uv0(puv[0], puv[1]); + uvData += _uvPointer.stride; + puv = (float*) uvData; + float2 uv1(puv[0], puv[1]); + uvData += _uvPointer.stride; + puv = (float*) uvData; + float2 uv2(puv[0], puv[1]); + uvData += _uvPointer.stride; + + Ege eges[3] = { + Ege(p0.x, p0.y, p1.x, p1.y, c0, c1, uv0, uv1), + Ege(p1.x, p1.y, p2.x, p2.y, c1, c2, uv1, uv2), + Ege(p2.x, p2.y, p0.x, p0.y, c2, c0, uv2, uv0), + }; + + + drawTriangle(eges, _texture); + + if (_colorPointer.data == 0) { + cData = (char*) colorPointerdesc.data; + } + + if (_uvPointer.data == 0) { + uvData = (char*) uvPointerdesc.data; + } + } + +} + +void Raster::loadMatrix(const matrix4& mat) { + _matModel = mat; +} + +void Raster::loadIdentity() { + _matModel = matrix4(1); +} + +void Raster::bindTexture(Image* image) { + _texture = image; +} + +int Raster::size() { + return _width * _height * sizeof (Rgba); +} + +void Raster::clean() { + memset(buffer, 0, size()); +} + +bool Raster::setPixel(int x, int y, Rgba color) { + if (x < 0 || y < 0 || x >= _width || y >= _height) { + return false; + } + //行列是反的 + buffer[ ((_height - 1) - y) * _width + x] = color; +} + +Rgba Raster::getPixel(int x, int y) { + return buffer[ ((_height - 1) - y) * _width + x]; +} + +bool Raster::isIn(int2 point) { + if (point.x >= 0 && point.x <= _width && point.y >= 0 && point.y < _height) { + return true; + } + return false; +} \ No newline at end of file diff --git a/src/5threed/Raster.h b/src/5threed/Raster.h new file mode 100644 index 0000000..e4be465 --- /dev/null +++ b/src/5threed/Raster.h @@ -0,0 +1,169 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: Rester.h + * Author: blobt + * + * Created on January 23, 2020, 6:00 PM + */ + +#ifndef RESTER_H +#define RESTER_H + +#include "common.h" +#include "Rgba.h" +#include "Image.h" + +enum DRAWMODE { + DM_POINTS = 0, + DM_LINES = 1, + DM_LINES_LOOP = 2, + DM_LINES_TRIP = 3, + DM_TRIANGES = 4 +}; + +enum DATETYPE { + DT_BYTE, + DT_FLOAT, + DT_DOUBLE +}; + +struct DataElementDes { + int size; + DATETYPE type; + int stride; + const void* data; +}; + +class Span { +public: + int xStart; + int xEnd; + int y; + + float2 uvStart; + float2 uvEnd; + + Rgba color1; + Rgba color2; + + Span(int xStart, int xEnd, int y, Rgba color1, Rgba color2, float2 uvStart, float2 uvEnd) { + + if (xStart < xEnd) { + this->xStart = xStart; + this->xEnd = xEnd; + this->uvStart = uvStart; + this->uvEnd = uvEnd; + this->color1 = color1; + this->color2 = color2; + } else { + this->xStart = xEnd; + this->xEnd = xStart; + this->uvStart = uvEnd; + this->uvEnd = uvStart; + this->color1 = color2; + this->color2 = color1; + } + + this->y = y; + } +}; + +class Ege { +public: + int x1; + int y1; + float2 uv1; + Rgba color1; + + int x2; + int y2; + float2 uv2; + Rgba color2; + + Ege(int x1, int y1, int x2, int y2, Rgba color1, Rgba color2, float2 uv1, float2 uv2) { + if (y1 < y2) { + this->x1 = x1; + this->y1 = y1; + this->x2 = x2; + this->y2 = y2; + this->uv1 = uv1; + this->uv2 = uv2; + this->color1 = color1; + this->color2 = color2; + } else { + this->x1 = x2; + this->y1 = y2; + this->x2 = x1; + this->y2 = y1; + this->uv1 = uv2; + this->uv2 = uv1; + this->color1 = color2; + this->color2 = color1; + } + } +}; + +class Raster { +public: + + struct Vertex { + int2 p0; + float2 uv0; + Rgba c0; + + int2 p1; + float2 uv1; + Rgba c1; + + int2 p2; + float2 uv2; + Rgba c2; + }; +public: + Rgba* buffer; + Raster(int width, int height); + virtual ~Raster(); + void vertexPointer(int size, DATETYPE type, int stride, const void* data); + void colorPointer(int size, DATETYPE type, int stride, const void* data); + void textureCoordPointer(int size, DATETYPE type, int stride, const void* data); + void drawLine(float2 p1, float2 p2, Rgba color); + void drawPoint(int x, int y, Rgba color = Rgba(255, 0, 0, 0), int pointSize = 1); + void drawSpan(const Span &span, Image* image); + void drawEge(const Ege& e1, const Ege& e2, Image* image); + void drawTriangle(const Vertex& vertex, Image* image); + void drawTriangle(Ege eges[3], Image* image); + void drawArrays(DRAWMODE pri, int start, int count); + void bindTexture(Image* image); + void loadMatrix(const matrix4& mat); + void loadIdentity(); + int size(); + void clean(); + bool setPixel(int x, int y, Rgba color); + Rgba getPixel(int x, int y); + bool isIn(int2 point); +private: + int _width; + int _height; + Rgba _color; + Image* _texture; + + matrix4 _matModel; + + DataElementDes _positionPointer; + DataElementDes _colorPointer; + DataElementDes _uvPointer; + + //默认值 + DataElementDes _defaultColorPointer; + DataElementDes _defaultUvPointer; + Rgba _defaultColorArray[3]; + float2 _defaultUvArray[3]; +}; + +#endif /* RESTER_H */ + diff --git a/src/5threed/Rgba.cc b/src/5threed/Rgba.cc new file mode 100644 index 0000000..a284893 --- /dev/null +++ b/src/5threed/Rgba.cc @@ -0,0 +1,83 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: Rgba.cc + * Author: Blobt + * + * Created on January 22, 2020, 11:36 PM + */ + +#include +#include +#include "Rgba.h" + +using namespace std; + +Rgba::Rgba(unsigned char r, unsigned char g, unsigned char b, unsigned char a) { + _r = r; + _g = g; + _b = b; + _a = a; +} + +Rgba::Rgba(unsigned int rgba) { + _color = rgba; +} + +bool operator==(Rgba &left, Rgba &right) { + return left._a == right._a && left._b == right._b && left._g == right._g && left._r == right._r; +} + +bool operator!=(Rgba &left, Rgba &right) { + return left._a != right._a || left._b != right._b || left._g != right._g || left._r != right._r; +} + +Rgba operator+(Rgba &left, Rgba &right) { + return Rgba(left._r + right._r + ,left._g + right._g + ,left._b + right._b + ,left._a + right._a); +} + +Rgba::operator unsigned() { + unsigned int ret; + + unsigned char* p = (unsigned char*) &ret; + p[0] = _r; + p[1] = _g; + p[2] = _b; + p[3] = _a; + + //bitset<32> set = ret; + //cout << set << endl; + + return ret; +} + +Rgba::operator int() { + int ret; + + unsigned char* p = (unsigned char*) &ret; + p[0] = _r; + p[1] = _g; + p[2] = _b; + p[3] = _a; + + return ret; +} + +Rgba::operator long() { + long ret; + + unsigned char* p = (unsigned char*) &ret; + p[0] = _r; + p[1] = _g; + p[2] = _b; + p[3] = _a; + + return ret; +} \ No newline at end of file diff --git a/src/5threed/Rgba.h b/src/5threed/Rgba.h new file mode 100644 index 0000000..1b20fc8 --- /dev/null +++ b/src/5threed/Rgba.h @@ -0,0 +1,45 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: Rgba.h + * Author: Blobt + * + * Created on January 22, 2020, 11:36 PM + */ + +#ifndef RGBA_H +#define RGBA_H + +#include "stdio.h" + +class Rgba { +public: + Rgba(unsigned char r = 255, unsigned char g = 255, unsigned char b = 255, unsigned char a = 255); + Rgba(unsigned int rgba); + friend bool operator==(Rgba &left, Rgba &right); + friend bool operator!=(Rgba &left, Rgba &righe); + friend Rgba operator+(Rgba &left, Rgba &righe); + operator unsigned(); + operator int(); + operator long(); +public: + + /*这里使用了联合,可以是类能使用unsigned int 直接赋值*/ + union { + + struct { + unsigned char _r; + unsigned char _g; + unsigned char _b; + unsigned char _a; + }; + unsigned int _color; + }; +}; + +#endif /* RGBA_H */ + diff --git a/src/5threed/common.h b/src/5threed/common.h new file mode 100644 index 0000000..bf33036 --- /dev/null +++ b/src/5threed/common.h @@ -0,0 +1,73 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: common.h + * Author: Blobt + * + * Created on October 5, 2019, 4:55 PM + */ + +#ifndef COMMON_H +#define COMMON_H + +#include +#include +#include +#include "Rgba.h" +#include "struct/tvec2.h" +#include "struct/tvec3.h" +#include "struct/tmat3x3.h" +#include "struct/tvec4.h" +#include "struct/tmat4x4.h" + +#define die(m) do { perror(m); exit(EXIT_FAILURE); } while(0) +#define def2rad(theta) (0.01745329251994329 * (theta)) //每个角度所对应的弧度 + +typedef tvec2 float2; +typedef tvec2 int2; +typedef tvec3 float3; +typedef tvec4 float4; +typedef unsigned char byte; +typedef tmat3x3 matrix3; +typedef tmat4x4 matrix4; + +template inline T tmin(T a, T b) { + return a < b ? a : b; +} + +template inline T tmax(T a, T b) { + return a > b ? a : b; +} + +inline Rgba colorLerp(const Rgba& color1, const Rgba& color2, float step) { + Rgba ret; + + ret._r = (unsigned char) color1._r + step * (color2._r - color1._r); + ret._g = (unsigned char) color1._g + step * (color2._g - color1._g); + ret._b = (unsigned char) color1._b + step * (color2._b - color1._b); + ret._a = (unsigned char) color1._a + step * (color2._a - color1._a); + + return ret; +} + +inline float2 uvLerp(const float2& uv1, const float2& uv2, float step) { + + if (step < 0 || step > 1) { + printf("step : %f\n", step); + die("step must more than zero and less than 1"); + } + + float2 ret; + + ret.x = (float) uv1.x + (uv2.x - uv1.x) * step; + ret.y = (float) uv1.y + (uv2.y - uv1.y) * step; + + return ret; +} + +#endif /* COMMON_H */ + diff --git a/src/5threed/struct/tmat3x3.h b/src/5threed/struct/tmat3x3.h new file mode 100644 index 0000000..8039e9a --- /dev/null +++ b/src/5threed/struct/tmat3x3.h @@ -0,0 +1,174 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: tmat3x3.h + * Author: Blobt + * + * Created on February 19, 2020, 2:45 PM + */ + +#ifndef TMAT3X3_H +#define TMAT3X3_H + +#include "../common.h" +#define def2rad(theta) (0.01745329251994329 * (theta)) + +template +struct tmat3x3 { + typedef T value_type; + typedef std::size_t size_type; + typedef tvec3 col_type; + typedef tvec3 row_type; + typedef tmat3x3 type; + typedef tmat3x3 transpose_type; + +private: + col_type value[3]; +public: + + size_type length() const { + return 3; + } + + size_type col_size() { + return 3; + } + + size_type row_size() { + return 3; + } + + tmat3x3() { + value_type const zero(0); + value_type const one(1); + value[0] = col_type(one, zero, zero); + value[1] = col_type(zero, one, zero); + value[2] = col_type(zero, zero, one); + } + + tmat3x3(tmat3x3 const &m) { + value[0] = m.value[0]; + value[1] = m.value[1]; + value[2] = m.value[2]; + } + + tmat3x3(value_type const &s) { + value_type const zero(0); + value[0] = col_type(s, zero, zero); + value[1] = col_type(zero, s, zero); + value[2] = col_type(zero, zero, s); + } + + + tmat3x3( + value_type const &x0, value_type const &y0, value_type const &z0, + value_type const &x1, value_type const &y1, value_type const &z1, + value_type const &x2, value_type const &y2, value_type const &z2 + ) { + value[0] = col_type(x0, y0, z0); + value[1] = col_type(x1, y1, z1); + value[2] = col_type(x2, y2, z2); + } + + tmat3x3(col_type const &v0, col_type const &v1, col_type const &v2) { + value[0] = v0; + value[1] = v1; + value[2] = v2; + } + + col_type& operator[](size_type i) { + assert(i < this->length()); + return value[i]; + } + + col_type const & operator[](size_type i) const { + assert(i < this->length()); + return this->value[i]; + } + + type &operator=(type & s) { + value[0] = s[0]; + value[1] = s[1]; + value[2] = s[2]; + return *this; + } + + type const &operator=(type const & s) { + value[0] = s[0]; + value[1] = s[1]; + value[2] = s[2]; + return *this; + } + + tvec3 operator*(const tvec3 &s) const { + tvec3 ret( + value[0][0] * s[0] + value[1][0] * s[1] + value[2][0] * s[2], + value[0][1] * s[0] + value[1][1] * s[1] + value[2][1] * s[2], + value[0][2] * s[0] + value[1][2] * s[1] + value[2][2] * s[2] + ); + return ret; + } + + type operator*(const type &s) { + + T const srcA00 = value[0][0]; + T const srcA01 = value[0][1]; + T const srcA02 = value[0][2]; + T const srcA10 = value[1][0]; + T const srcA11 = value[1][1]; + T const srcA12 = value[1][2]; + T const srcA20 = value[2][0]; + T const srcA21 = value[2][1]; + T const srcA22 = value[2][2]; + + T const srcB00 = s[0][0]; + T const srcB01 = s[0][1]; + T const srcB02 = s[0][2]; + T const srcB10 = s[1][0]; + T const srcB11 = s[1][1]; + T const srcB12 = s[1][2]; + T const srcB20 = s[2][0]; + T const srcB21 = s[2][1]; + T const srcB22 = s[2][2]; + + tmat3x3 res; + res[0][0] = srcA00 * srcB00 + srcA10 * srcB01 + srcA20 * srcB02; + res[0][1] = srcA01 * srcB00 + srcA11 * srcB01 + srcA21 * srcB02; + res[0][2] = srcA02 * srcB00 + srcA12 * srcB01 + srcA22 * srcB02; + res[1][0] = srcA00 * srcB10 + srcA10 * srcB11 + srcA20 * srcB12; + res[1][1] = srcA01 * srcB10 + srcA11 * srcB11 + srcA21 * srcB12; + res[1][2] = srcA02 * srcB10 + srcA12 * srcB11 + srcA22 * srcB12; + res[2][0] = srcA00 * srcB20 + srcA10 * srcB21 + srcA20 * srcB22; + res[2][1] = srcA01 * srcB20 + srcA11 * srcB21 + srcA21 * srcB22; + res[2][2] = srcA02 * srcB20 + srcA12 * srcB21 + srcA22 * srcB22; + return res; + } + + void translate(T x, T y) { + value[0] = col_type(value_type(1), value_type(0), value_type(0)); + value[1] = col_type(value_type(0), value_type(1), value_type(0)); + value[2] = col_type(value_type(x), value_type(y), value_type(1)); + } + + void scale(T x, T y) { + value[0] = col_type(value_type(x), value_type(0), value_type(0)); + value[1] = col_type(value_type(0), value_type(y), value_type(0)); + value[2] = col_type(value_type(0), value_type(0), value_type(1)); + } + + void rotate(T angle) { + T rad = def2rad(angle); + T c = cos(rad); + T s = sin(rad); + value[0] = col_type(value_type(c), value_type(-s), value_type(0)); + value[1] = col_type(value_type(s), value_type(c), value_type(0)); + value[2] = col_type(value_type(0), value_type(0), value_type(1)); + } +}; + +#endif /* TMAT3X3_H */ + diff --git a/src/5threed/struct/tmat4x4.h b/src/5threed/struct/tmat4x4.h new file mode 100644 index 0000000..8186a90 --- /dev/null +++ b/src/5threed/struct/tmat4x4.h @@ -0,0 +1,383 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: tmat4x4.h + * Author: Blobt + * + * Created on February 22, 2020, 10:11 AM + */ + +#ifndef TMAT4X4_H +#define TMAT4X4_H + +#include "../common.h" +#define DEG2RAD(theta) (0.01745329251994329 * (theta)) + +template +struct tmat4x4 { + typedef T value_type; + typedef std::size_t size_type; + typedef tvec4 col_type; + typedef tvec4 row_type; + typedef tmat4x4 type; + typedef tmat4x4 transpose_type; + +public: + + size_type length() const { + return 4; + } + + size_type col_size() { + return 4; + } + + size_type row_size() { + return 4; + } + + void identify() { + this->value[0] = col_type(1, 0, 0, 0); + this->value[1] = col_type(0, 1, 0, 0); + this->value[2] = col_type(0, 0, 1, 0); + this->value[3] = col_type(0, 0, 0, 1); + } + + col_type & operator[](size_type i) { + assert(i < this->length()); + return this->value[i]; + } + + col_type const & operator[](size_type i) const { + assert(i < this->length()); + return this->value[i]; + } + + tmat4x4() { + } + + tmat4x4(tmat4x4 const & m) { + this->value[0] = m.value[0]; + this->value[1] = m.value[1]; + this->value[2] = m.value[2]; + this->value[3] = m.value[3]; + } + + tmat4x4(value_type s) { + value_type const Zero(0); + this->value[0] = col_type(s, Zero, Zero, Zero); + this->value[1] = col_type(Zero, s, Zero, Zero); + this->value[2] = col_type(Zero, Zero, s, Zero); + this->value[3] = col_type(Zero, Zero, Zero, s); + } + + tmat4x4 + ( + value_type const & x0, value_type const & y0, value_type const & z0, value_type const & w0, + value_type const & x1, value_type const & y1, value_type const & z1, value_type const & w1, + value_type const & x2, value_type const & y2, value_type const & z2, value_type const & w2, + value_type const & x3, value_type const & y3, value_type const & z3, value_type const & w3 + ) { + this->value[0] = col_type(x0, y0, z0, w0); + this->value[1] = col_type(x1, y1, z1, w1); + this->value[2] = col_type(x2, y2, z2, w2); + this->value[3] = col_type(x3, y3, z3, w3); + } + + tmat4x4 + ( + col_type const & v0, + col_type const & v1, + col_type const & v2, + col_type const & v3 + ) { + this->value[0] = v0; + this->value[1] = v1; + this->value[2] = v2; + this->value[3] = v3; + } + + template + tmat4x4(tmat4x4 const & m) { + this->value[0] = col_type(m[0]); + this->value[1] = col_type(m[1]); + this->value[2] = col_type(m[2]); + this->value[3] = col_type(m[3]); + } + + tmat4x4& translate(value_type x, value_type y, value_type z) { + this->value[0] = col_type(1, 0, 0, 0); + this->value[1] = col_type(0, 1, 0, 0); + this->value[2] = col_type(0, 0, 1, 0); + this->value[3] = col_type(x, y, z, 1); + return *this; + } + + template + tmat4x4& translate(U x, U y, U z) { + this->value[0] = col_type(1, 0, 0, 0); + this->value[1] = col_type(0, 1, 0, 0); + this->value[2] = col_type(0, 0, 1, 0); + this->value[3] = col_type(T(x), T(y), T(z), 1); + return *this; + } + + tmat4x4& translate(tvec3 const& pos) { + this->value[0] = col_type(1, 0, 0, 0); + this->value[1] = col_type(0, 1, 0, 0); + this->value[2] = col_type(0, 0, 1, 0); + this->value[3] = col_type(pos.x, pos.y, pos.z, 1); + return *this; + } + + template + tmat4x4& translate(tvec3 const& pos) { + this->value[0] = col_type(1, 0, 0, 0); + this->value[1] = col_type(0, 1, 0, 0); + this->value[2] = col_type(0, 0, 1, 0); + this->value[3] = col_type(T(pos.x), T(pos.y), T(pos.z), 1); + return *this; + } + + tmat4x4& rotate(value_type angle, tvec3 const & v) { + T a = DEG2RAD(angle); + T c = cos(a); + T s = sin(a); + + tvec3 axis = normalize(v); + + tvec3 temp = (T(1) - c) * axis; + + tmat4x4 res; + this->value[0][0] = c + temp[0] * axis[0]; + this->value[0][1] = 0 + temp[0] * axis[1] + s * axis[2]; + this->value[0][2] = 0 + temp[0] * axis[2] - s * axis[1]; + this->value[0][3] = 0; + + this->value[1][0] = 0 + temp[1] * axis[0] - s * axis[2]; + this->value[1][1] = c + temp[1] * axis[1]; + this->value[1][2] = 0 + temp[1] * axis[2] + s * axis[0]; + this->value[1][3] = 0; + + this->value[2][0] = 0 + temp[2] * axis[0] + s * axis[1]; + this->value[2][1] = 0 + temp[2] * axis[1] - s * axis[0]; + this->value[2][2] = c + temp[2] * axis[2]; + this->value[2][3] = 0; + + this->value[3][0] = 0; + this->value[3][1] = 0; + this->value[3][2] = 0; + this->value[3][3] = 1; + return *this; + } + + tmat4x4& rotateX(value_type angle) { + T a = DEG2RAD(angle); + T c = cos(a); + T s = sin(a); + + this->value[0] = col_type(1, 0, 0, 0); + this->value[1] = col_type(0, c, s, 0); + this->value[2] = col_type(0, -s, c, 0); + this->value[3] = col_type(0, 0, 0, 1); + + return *this; + } + + template + tmat4x4& rotateX(U angle) { + T a = DEG2RAD(angle); + T c = cos(a); + T s = sin(a); + + this->value[0] = col_type(1, 0, 0, 0); + this->value[1] = col_type(0, c, s, 0); + this->value[2] = col_type(0, -s, c, 0); + this->value[3] = col_type(0, 0, 0, 1); + + return *this; + } + + tmat4x4& rotateY(value_type angle) { + T a = DEG2RAD(angle); + T c = cos(a); + T s = sin(a); + + this->value[0] = col_type(c, 0, -s, 0); + this->value[1] = col_type(0, 1, 0, 0); + this->value[2] = col_type(s, 0, c, 0); + this->value[3] = col_type(0, 0, 0, 1); + return *this; + + } + + template + tmat4x4& rotateY(U angle) { + T a = DEG2RAD(angle); + T c = cos(a); + T s = sin(a); + + this->value[0] = col_type(c, 0, -s, 0); + this->value[1] = col_type(0, 1, 0, 0); + this->value[2] = col_type(s, 0, c, 0); + this->value[3] = col_type(0, 0, 0, 1); + return *this; + + } + + tmat4x4& rotateZ(value_type angle) { + T a = T(DEG2RAD(angle)); + T c = cos(a); + T s = sin(a); + + this->value[0] = col_type(c, s, 0, 0); + this->value[1] = col_type(-s, c, 0, 0); + this->value[2] = col_type(0, 0, 1, 0); + this->value[3] = col_type(0, 0, 0, 1); + return *this; + } + + template + tmat4x4& rotateZ(U angle) { + T a = DEG2RAD(angle); + + T c = cos(a); + T s = sin(a); + + this->value[0] = col_type(c, s, 0, 0); + this->value[1] = col_type(-s, c, 0, 0); + this->value[2] = col_type(0, 0, 1, 0); + this->value[3] = col_type(0, 0, 0, 1); + return *this; + } + + tmat4x4& scale(tvec3 const& s) { + this->value[0] = col_type(s[0], 0, 0, 0); + this->value[1] = col_type(0, s[1], 0, 0); + this->value[2] = col_type(0, 0, s[2], 0); + this->value[3] = col_type(0, 0, 0, 1); + + return *this; + } + + tmat4x4& scale(value_type x, value_type y, value_type z) { + this->value[0] = col_type(x, 0, 0, 0); + this->value[1] = col_type(0, y, 0, 0); + this->value[2] = col_type(0, 0, z, 0); + this->value[3] = col_type(0, 0, 0, 1); + + return *this; + } + + template + tmat4x4& scale(U x, U y, U z) { + this->value[0] = col_type(value_type(x), 0, 0, 0); + this->value[1] = col_type(0, value_type(y), 0, 0); + this->value[2] = col_type(0, 0, value_type(z), 0); + this->value[3] = col_type(0, 0, 0, 1); + + return *this; + } + + template + tmat4x4& scale(U x, V y, W z) { + this->value[0] = col_type(value_type(x), 0, 0, 0); + this->value[1] = col_type(0, value_type(y), 0, 0); + this->value[2] = col_type(0, 0, value_type(z), 0); + this->value[3] = col_type(0, 0, 0, 1); + return *this; + } + + tmat4x4 transpose() const { + return tmat4x4( + this->value[0][0], this->value[1][0], this->value[2][0], this->value[3][0], + this->value[0][1], this->value[1][1], this->value[2][1], this->value[3][1], + this->value[0][2], this->value[1][2], this->value[2][2], this->value[3][2], + this->value[0][3], this->value[1][3], this->value[2][3], this->value[3][3] + ); + } + + tmat4x4 extractMatrixRotation() const { + return tmat4x4( + this->value[0][0], this->value[0][1], this->value[0][2], 0.0, + this->value[1][0], this->value[1][1], this->value[1][2], 0.0, + this->value[2][0], this->value[2][1], this->value[2][2], 0.0, + 0.0, 0.0, 0.0, 1.0 + ); + } + +public: + col_type value[4]; +}; + +template +tvec3 operator*(tvec3 const& v, tmat4x4 const& mat) { + return tvec3 + ( + v.x * mat[0][0] + v.y * mat[1][0] + v.z * mat[2][0] + 1 * mat[3][0], + v.x * mat[0][1] + v.y * mat[1][1] + v.z * mat[2][1] + 1 * mat[3][1], + v.x * mat[0][2] + v.y * mat[1][2] + v.z * mat[2][2] + 1 * mat[3][2] + ); +} + +template +tmat4x4 operator*(tmat4x4 const & m, typename tmat4x4::value_type s) { + return tmat4x4( + m[0] * s, + m[1] * s, + m[2] * s, + m[3] * s); +} + +template +tmat4x4 operator*(typename tmat4x4::value_type s, tmat4x4 const & m) { + return tmat4x4( + m[0] * s, + m[1] * s, + m[2] * s, + m[3] * s); +} + +template +typename tmat4x4::col_type operator*(tmat4x4 const & m, typename tmat4x4::row_type const & v) { + return typename tmat4x4::col_type( + m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z + m[3][0] * v.w, + m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z + m[3][1] * v.w, + m[0][2] * v.x + m[1][2] * v.y + m[2][2] * v.z + m[3][2] * v.w, + m[0][3] * v.x + m[1][3] * v.y + m[2][3] * v.z + m[3][3] * v.w); +} + +template +typename tmat4x4::row_type operator*(typename tmat4x4::col_type const & v, tmat4x4 const & m) { + return typename tmat4x4::row_type( + m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3] * v.w, + m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3] * v.w, + m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3] * v.w, + m[3][0] * v.x + m[3][1] * v.y + m[3][2] * v.z + m[3][3] * v.w); +} + +template +tmat4x4 operator*(tmat4x4 const & m1, tmat4x4 const & m2) { + typename tmat4x4::col_type const srcA0 = m1[0]; + typename tmat4x4::col_type const srcA1 = m1[1]; + typename tmat4x4::col_type const srcA2 = m1[2]; + typename tmat4x4::col_type const srcA3 = m1[3]; + + typename tmat4x4::col_type const srcB0 = m2[0]; + typename tmat4x4::col_type const srcB1 = m2[1]; + typename tmat4x4::col_type const srcB2 = m2[2]; + typename tmat4x4::col_type const srcB3 = m2[3]; + + tmat4x4 res; + res[0] = srcA0 * srcB0[0] + srcA1 * srcB0[1] + srcA2 * srcB0[2] + srcA3 * srcB0[3]; + res[1] = srcA0 * srcB1[0] + srcA1 * srcB1[1] + srcA2 * srcB1[2] + srcA3 * srcB1[3]; + res[2] = srcA0 * srcB2[0] + srcA1 * srcB2[1] + srcA2 * srcB2[2] + srcA3 * srcB2[3]; + res[3] = srcA0 * srcB3[0] + srcA1 * srcB3[1] + srcA2 * srcB3[2] + srcA3 * srcB3[3]; + return res; +} +#endif /* TMAT4X4_H */ + diff --git a/src/5threed/struct/tvec2.h b/src/5threed/struct/tvec2.h new file mode 100644 index 0000000..39d2066 --- /dev/null +++ b/src/5threed/struct/tvec2.h @@ -0,0 +1,57 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: tvec2.h + * Author: Blobt + * + * Created on February 19, 2020, 9:32 AM + */ + +#ifndef TVEC2_H +#define TVEC2_H + +template +struct tvec2 { + typedef T value_type; + typedef std::size_t size_type; + typedef tvec2 type; + + value_type x; + value_type y; + + size_type length() const { + return 2; + } + + value_type operator[](size_type i) { + assert(i < this->length()); + return (&x)[i]; + } + + value_type const operator[](size_type i) const { + assert(i < this->length()); + return (&x)[i]; + } + + tvec2() { + x = 0; + y = 0; + } + + tvec2(const value_type &s) { + x = s; + y = s; + } + + tvec2(const value_type &s1, const value_type &s2) { + x = s1; + y = s2; + } +}; + +#endif /* TVEC2_H */ + diff --git a/src/5threed/struct/tvec3.h b/src/5threed/struct/tvec3.h new file mode 100644 index 0000000..7b7a396 --- /dev/null +++ b/src/5threed/struct/tvec3.h @@ -0,0 +1,111 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: tvec3.h + * Author: Blobt + * + * Created on February 19, 2020, 9:34 AM + */ + +#ifndef TVEC3_H +#define TVEC3_H + +#include + +template +struct tvec3 { + typedef T value_type; + typedef std::size_t size_type; + typedef tvec3 type; + + value_type x; + value_type y; + value_type z; + + size_type length()const { + return 3; + } + + value_type &operator[](size_type i) { + assert(i < this->length()); + return (&x)[i]; + } + + value_type const &operator[](size_type i) const { + assert(i < this->length()); + return (&x)[i]; + } + + tvec3() { + x = 0; + y = 0; + z = 0; + } + + tvec3(type &v) { + x = v.x; + y = v.y; + z = v.z; + } + + tvec3(value_type s0, value_type s1, value_type s2) { + x = s0; + y = s1; + z = s2; + } + + tvec3(value_type s) { + x = s; + y = s; + z = s; + } + + /** + * 这个template 起到用来配备其它类型做参数的情况 + * 例如tvec3 n(3.1f); + */ + template + tvec3(U s) { + x = value_type(s); + y = value_type(s); + z = value_type(s); + } + + template + tvec3(A s1, B s2, C s3) { + x = value_type(s1); + y = value_type(s2); + z = value_type(s3); + } + + tvec3& operator=(tvec3 &s) { + x = s.x; + y = s.y; + z = s.z; + + return *this; + } + + tvec3 const & operator=(tvec3 const &s) { + x = s.x; + y = s.y; + z = s.z; + + return *this; + } + + tvec3 & operator++() { + ++x; + ++y; + ++z; + return *this; + } + +}; + +#endif /* TVEC3_H */ + diff --git a/src/5threed/struct/tvec4.h b/src/5threed/struct/tvec4.h new file mode 100644 index 0000000..bbdb166 --- /dev/null +++ b/src/5threed/struct/tvec4.h @@ -0,0 +1,130 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: tvec4.h + * Author: Blobt + * + * Created on February 22, 2020, 9:12 AM + */ + +#ifndef TVEC4_H +#define TVEC4_H + +#include "../common.h" + +template +struct tvec4 { + typedef T value_type; + typedef std::size_t size_type; + typedef tvec4 type; + + + + value_type x, y, z, w; + + size_type length() const { + return 4; + } + + value_type & operator[](size_type i) { + assert(i < this->length()); + return (&x)[i]; + } + + value_type const & operator[](size_type i) const { + assert(i < this->length()); + return (&x)[i]; + } + + tvec4() : + x(value_type(0)), + y(value_type(0)), + z(value_type(0)), + w(value_type(0)) { + } + + tvec4(T s) : + x(s), + y(s), + z(s), + w(s) { + } + + tvec4(tvec4 const & v) : + x(v.x), + y(v.y), + z(v.z), + w(v.w) { + } + + template + tvec4(tvec4 const & v) : + x(value_type(v.x)), + y(value_type(v.y)), + z(value_type(v.z)), + w(value_type(v.w)) { + } + + tvec4 + ( + value_type s1, + value_type s2, + value_type s3, + value_type s4 + ) : + x(s1), + y(s2), + z(s3), + w(s4) { + } + + tvec4 & operator=(tvec4 const & v) { + this->x = v.x; + this->y = v.y; + this->z = v.z; + this->w = v.w; + return *this; + } + + template + tvec4 & operator=(tvec4 const & v) { + this->x = T(v.x); + this->y = T(v.y); + this->z = T(v.z); + this->w = T(v.w); + return *this; + } + + template + tvec4 & operator*=(U const & s) { + this->x *= T(s); + this->y *= T(s); + this->z *= T(s); + this->w *= T(s); + return *this; + } + + template + tvec4 & operator*=(tvec4 const & v) { + this->x *= T(v.x); + this->y *= T(v.y); + this->z *= T(v.z); + this->w *= T(v.w); + return *this; + } + + tvec4 & operator++() { + ++this->x; + ++this->y; + ++this->z; + ++this->w; + return *this; + } +}; + +#endif /* TVEC4_H */ + diff --git a/src/5threed/threed.cc b/src/5threed/threed.cc new file mode 100644 index 0000000..6b63b29 --- /dev/null +++ b/src/5threed/threed.cc @@ -0,0 +1,78 @@ +#include +#include +#include +#include +#include "Rgba.h" +#include "Raster.h" +#include "common.h" + +using namespace std; + + +gint height = 50; +gint width = 50; + +Raster raster(width, height); + +struct Vertex { + float x, y; + float u, v; + Rgba color; +}; + +void example1() { + +} + +unsigned char* makeBitmap() { + raster.clean(); + + example1(); + + return (unsigned char*) raster.buffer; +} + +void render(GtkWidget *widget) { + //允许窗口可以绘图 + gtk_widget_set_app_paintable(widget, TRUE); + gtk_widget_realize(widget); + gtk_widget_queue_draw(widget); + + //模拟一张图片 + unsigned char* data = makeBitmap(); + + GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data(data, GDK_COLORSPACE_RGB, TRUE, 8, width, height, width * 4, NULL, NULL); + + GdkPixmap *pixmap = NULL; + + gdk_pixbuf_render_pixmap_and_mask(pixbuf, &pixmap, NULL, 128); + + gdk_window_set_back_pixmap(widget->window, pixmap, FALSE); + + g_object_unref(pixbuf); + g_object_unref(pixmap); + //delete data; +} + +int main(int argc, char* argv[]) { + + gtk_init(&argc, &argv); + + //创建窗口 + GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_widget_set_size_request(window, width, height); + + gtk_window_set_title(GTK_WINDOW(window), "Gtk testing"); + gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER_ALWAYS); + + //窗口关闭时候,关闭程序 + g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); + //设置渲染 + g_signal_connect(window, "expose-event", G_CALLBACK(render), window); + + + gtk_widget_show_all(window); + gtk_main(); + + return 0; +}