blobt
5 years ago
21 changed files with 772 additions and 1971 deletions
-
2CMakeLists.txt
-
2src/6threed/Image.h
-
649src/6threed/Raster.cc
-
522src/6threed/Raster.h
-
159src/6threed/struct/common.h
-
175src/6threed/struct/plane.h
-
87src/6threed/struct/tfrustum.h
-
174src/6threed/struct/tmat3x3.h
-
387src/6threed/struct/tmat4x4.h
-
57src/6threed/struct/tvec2.h
-
172src/6threed/struct/tvec3.h
-
183src/6threed/struct/tvec4.h
-
77src/6threed/threed.cc
-
7src/7camera/CMakeLists.txt
-
0src/7camera/Image.cc
-
0src/7camera/Image.h
-
0src/7camera/Raster.cc
-
0src/7camera/Raster.h
-
83src/7camera/camera.cc
-
0src/7camera/common.h
-
7src/7threed/CMakeLists.txt
@ -1,210 +1,527 @@ |
|||||
|
/*
|
||||
|
* 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 "Raster.h"
|
#include "Raster.h"
|
||||
#include "FreeImage.h"
|
|
||||
|
#include "Image.h"
|
||||
|
#include <stdio.h>
|
||||
|
#include <iostream>
|
||||
#include <string.h>
|
#include <string.h>
|
||||
|
#include <math.h>
|
||||
|
|
||||
|
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); |
||||
|
_matView = matrix4(1); |
||||
|
_matProj = 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); |
||||
|
} |
||||
|
|
||||
namespace CELL { |
|
||||
|
|
||||
Raster::Raster(int w, int h, void* buffer) { |
|
||||
_texture = 0; |
|
||||
_width = w; |
|
||||
_height = h; |
|
||||
_buffer = (uint*) buffer; |
|
||||
memset(&_poitionPointer, 0, sizeof (_poitionPointer)); |
|
||||
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 = _detaultUVArray; |
|
||||
|
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; |
||||
|
} |
||||
|
|
||||
_matModel = CELL::matrix4(1); |
|
||||
_matView = CELL::matrix4(1); |
|
||||
_matProj = CELL::matrix4(1); |
|
||||
|
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); |
||||
|
} |
||||
} |
} |
||||
|
|
||||
Raster::~Raster(void) { |
|
||||
|
} |
||||
|
|
||||
|
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; |
||||
} |
} |
||||
|
} |
||||
|
|
||||
void Raster::clear() { |
|
||||
memset(_buffer, 0, _width * _height * sizeof (Rgba)); |
|
||||
} |
|
||||
|
/**
|
||||
|
* 画一条平行于x轴的直线 |
||||
|
* @param span |
||||
|
*/ |
||||
|
void Raster::drawSpan(const Span &span, Image* image) { |
||||
|
//float length = tmax<int>(span.xStart - span.xEnd, 1); //取保length不为0
|
||||
|
|
||||
void Raster::drawImage(int startX, int startY, const Image* image) { |
|
||||
int left = tmax<int>(startX, 0); |
|
||||
int top = tmax<int>(startY, 0); |
|
||||
|
Rgba color; |
||||
|
Rgba blendColor; |
||||
|
Rgba dstColor; |
||||
|
float2 uv; |
||||
|
float scale; |
||||
|
float length = span.xEnd - span.xStart; |
||||
|
|
||||
int right = tmin<int>(startX + image->width(), _width); |
|
||||
int bottom = tmin<int>(startY + image->height(), _height); |
|
||||
|
|
||||
for (int x = left; x < right; ++x) { |
|
||||
for (int y = top; y < bottom; ++y) { |
|
||||
Rgba color = image->pixelAt(x - left, y - top); |
|
||||
setPixelEx(x, y, color); |
|
||||
} |
|
||||
|
//TODO 这里越界和texture不兼容,没有解决
|
||||
|
//int startX = tmax<int>(span.xStart, 0);
|
||||
|
//int endX = tmin<int>(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, blendColor); |
||||
} |
} |
||||
|
} |
||||
|
|
||||
void Raster::drawArrays(DRAWMODE pri, int start, int count) { |
|
||||
if (_poitionPointer._data == 0) { |
|
||||
return; |
|
||||
} |
|
||||
|
void Raster::drawEge(const Ege& e1, const Ege& e2, Image* image) { |
||||
|
|
||||
DateElementDes colorPointerdesc = _colorPointer; |
|
||||
DateElementDes uvPointerdesc = _uvPointer; |
|
||||
if (colorPointerdesc._data == 0) { |
|
||||
colorPointerdesc = _defaultColorPointer; |
|
||||
} |
|
||||
if (uvPointerdesc._data == 0) { |
|
||||
uvPointerdesc = _defaultUVPointer; |
|
||||
|
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<int>(e2.y2, _height); |
||||
|
int endY2 = tmax<int>(e2.y1, 0); |
||||
|
scale2 = (e2.y2 - startY2) / yOffset2; |
||||
|
|
||||
|
int startY1 = tmin<int>(e1.y2, _height); |
||||
|
float s = (e1.y2 - startY1) / yOffset1; |
||||
|
scale1 = tmax<float>(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; |
||||
} |
} |
||||
char* posData = (char*) _poitionPointer._data; |
|
||||
char* cData = (char*) colorPointerdesc._data; |
|
||||
char* uvData = (char*) uvPointerdesc._data; |
|
||||
|
|
||||
_matProjView = _matProj * _matView; |
|
||||
|
|
||||
matrix4 matPVT = _matProjView.transpose(); |
|
||||
|
|
||||
_frust.loadFrustum(matPVT); |
|
||||
|
|
||||
for (int i = start; i < start + count; i += 3) { |
|
||||
float* fData = (float*) posData; |
|
||||
float3 p01(fData[0], fData[1], fData[2]); |
|
||||
|
|
||||
posData += _poitionPointer._stride; |
|
||||
fData = (float*) (posData); |
|
||||
|
|
||||
|
|
||||
float3 p11(fData[0], fData[1], fData[2]); |
|
||||
posData += _poitionPointer._stride; |
|
||||
fData = (float*) (posData); |
|
||||
|
|
||||
|
|
||||
|
|
||||
float3 p21(fData[0], fData[1], fData[2]); |
|
||||
posData += _poitionPointer._stride; |
|
||||
|
|
||||
p01 = p01 * _matModel; |
|
||||
p11 = p11 * _matModel; |
|
||||
p21 = p21 * _matModel; |
|
||||
|
|
||||
printf("%f,%f,%f\n",fData[0], fData[1], fData[2]); |
|
||||
|
|
||||
if (_frust.pointInFrustum(p01) |
|
||||
|| _frust.pointInFrustum(p11) |
|
||||
|| _frust.pointInFrustum(p21) |
|
||||
) {printf("sasa"); |
|
||||
p01 = piplineTransform(p01); |
|
||||
p11 = piplineTransform(p11); |
|
||||
p21 = piplineTransform(p21); |
|
||||
//! ת��Ϊ��Ļ����
|
|
||||
int2 p0(p01.x, p01.y); |
|
||||
int2 p1(p11.x, p11.y); |
|
||||
int2 p2(p21.x, p21.y); |
|
||||
|
|
||||
Rgba c0(*(Rgba*) cData); |
|
||||
cData += _colorPointer._stride; |
|
||||
Rgba c1(*(Rgba*) cData); |
|
||||
cData += _colorPointer._stride; |
|
||||
Rgba c2(*(Rgba*) cData); |
|
||||
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, c0, uv0, p1.x, p1.y, c1, uv1), |
|
||||
Ege(p1.x, p1.y, c1, uv1, p2.x, p2.y, c2, uv2), |
|
||||
Ege(p2.x, p2.y, c2, uv2, p0.x, p0.y, c0, uv0), |
|
||||
}; |
|
||||
drawTrianle(eges); |
|
||||
|
|
||||
if (_colorPointer._data == 0) { |
|
||||
cData = (char*) colorPointerdesc._data; |
|
||||
} |
|
||||
if (_uvPointer._data == 0) { |
|
||||
|
|
||||
uvData = (char*) uvPointerdesc._data; |
|
||||
} |
|
||||
} |
|
||||
|
color2 = colorLerp(e2.color2, e2.color1, 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.color2, e1.color1, scale1); |
||||
|
uvE1 = uvLerp(e1.uv2, e1.uv1, scale1); |
||||
|
scale1 += setp1; |
||||
|
//setPixel(x1, y, Rgba(255,0,0));
|
||||
|
|
||||
void Raster::bindTexture(Image* image) { |
|
||||
_texture = image; |
|
||||
|
Span span(x1, x2, y, color1, color2, uvE1, uvE2); |
||||
|
drawSpan(span, image); |
||||
} |
} |
||||
|
} |
||||
|
|
||||
void Raster::textureCoordPointer(int size, DATETYPE type, int stride, const void* data) { |
|
||||
_uvPointer._size = size; |
|
||||
_uvPointer._type = type; |
|
||||
_uvPointer._stride = stride; |
|
||||
_uvPointer._data = data; |
|
||||
} |
|
||||
|
void Raster::drawTriangle(Ege eges[3], Image* image) { |
||||
|
int iMax = 0; |
||||
|
int length = eges[0].y2 - eges[0].y1; |
||||
|
|
||||
void Raster::colorPointer(int size, DATETYPE type, int stride, const void* data) { |
|
||||
_colorPointer._size = size; |
|
||||
_colorPointer._type = type; |
|
||||
_colorPointer._stride = stride; |
|
||||
_colorPointer._data = data; |
|
||||
} |
|
||||
|
int curLength = 0; |
||||
|
|
||||
void Raster::vertexPointer(int size, DATETYPE type, int stride, const void* data) { |
|
||||
_poitionPointer._size = size; |
|
||||
_poitionPointer._type = type; |
|
||||
_poitionPointer._stride = stride; |
|
||||
_poitionPointer._data = data; |
|
||||
|
for (int i = 1; i < 3; i++) { |
||||
|
curLength = eges[i].y2 - eges[i].y1; |
||||
|
if (curLength > length) { |
||||
|
length = curLength; |
||||
|
iMax = i; |
||||
|
} |
||||
} |
} |
||||
|
|
||||
void Raster::loadMatrix(const CELL::matrix4& mat) { |
|
||||
_matModel = mat; |
|
||||
} |
|
||||
|
int iShort1 = (iMax + 1) % 3; |
||||
|
int iShort2 = (iMax + 2) % 3; |
||||
|
|
||||
|
|
||||
|
//printf("max:%d (%d,%d) (%d,%d) (%d,%d,%d) (%d,%d,%d)\n", iMax,eges[iMax].x1, eges[iMax].y1, eges[iMax].x2, eges[iMax].y2, eges[iMax].color1._r, eges[iMax].color1._g, eges[iMax].color1._b, eges[iMax].color2._r, eges[iMax].color2._g, eges[iMax].color2._b);
|
||||
|
//printf("sho:%d (%d,%d) (%d,%d) (%d,%d,%d) (%d,%d,%d)\n", iShort1,eges[iShort1].x1, eges[iShort1].y1, eges[iShort1].x2, eges[iShort1].y2, eges[iShort1].color1._r, eges[iShort1].color1._g, eges[iShort1].color1._b, eges[iShort1].color2._r, eges[iShort1].color2._g, eges[iShort1].color2._b);
|
||||
|
|
||||
void Raster::loadIdentity() { |
|
||||
_matModel = CELL::matrix4(1); |
|
||||
|
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; |
||||
} |
} |
||||
|
|
||||
void Raster::loadProjMatrix(const CELL::matrix4& mat) { |
|
||||
_matProj = mat; |
|
||||
|
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; |
||||
|
} |
||||
} |
} |
||||
|
|
||||
void Raster::loadProjIdentity(const CELL::matrix4& mat) { |
|
||||
_matProj = CELL::matrix4(1); |
|
||||
|
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; |
||||
} |
} |
||||
|
|
||||
void Raster::loadViewMatrix(const CELL::matrix4& mat) { |
|
||||
_matView = mat; |
|
||||
|
DataElementDes colorPointerdesc = _colorPointer; |
||||
|
DataElementDes uvPointerdesc = _uvPointer; |
||||
|
|
||||
|
if (colorPointerdesc.data == 0) { |
||||
|
colorPointerdesc = _defaultColorPointer; |
||||
} |
} |
||||
|
|
||||
void Raster::loadViewIdentity(const CELL::matrix4& mat) { |
|
||||
_matView = CELL::matrix4(1); |
|
||||
|
if (uvPointerdesc.data == 0) { |
||||
|
uvPointerdesc = _defaultUvPointer; |
||||
} |
} |
||||
|
|
||||
void Raster::setPerspective(float fovy, float aspect, float zNear, float zFar) { |
|
||||
_matProj = CELL::perspective<float>(fovy, aspect, zNear, zFar); |
|
||||
|
char* posData = (char*) _positionPointer.data; |
||||
|
char* cData = (char*) colorPointerdesc.data; |
||||
|
char* uvData = (char*) uvPointerdesc.data; |
||||
|
|
||||
|
_matProjView = _matProj * _matView; |
||||
|
matrix4 matPVT = _matProjView.transpose(); |
||||
|
_frust.loadFrustum(matPVT); |
||||
|
|
||||
|
for (int i = start; i < start + count; i += 3) { |
||||
|
|
||||
|
float* pp = (float*) posData; |
||||
|
float3 mp0(pp[0], pp[1], pp[2]); |
||||
|
|
||||
|
posData += _positionPointer.stride; |
||||
|
pp = (float*) posData; |
||||
|
float3 mp1(pp[0], pp[1], pp[2]); |
||||
|
|
||||
|
posData += _positionPointer.stride; |
||||
|
pp = (float*) posData; |
||||
|
float3 mp2(pp[0], pp[1], pp[2]); |
||||
|
|
||||
|
|
||||
|
|
||||
|
mp0 = mp0 * _matModel; |
||||
|
mp1 = mp1 * _matModel; |
||||
|
mp2 = mp2 * _matModel; |
||||
|
|
||||
|
if (_frust.pointInFrustum(mp0) || _frust.pointInFrustum(mp1) || _frust.pointInFrustum(mp2)) { |
||||
|
|
||||
|
mp0 = piplineTransform(mp0); |
||||
|
mp1 = piplineTransform(mp1); |
||||
|
mp2 = piplineTransform2(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::lookat(float3 const & eye, float3 const & center, float3 const & up) { |
|
||||
_matView = CELL::lookAt(eye, center, up); |
|
||||
|
} |
||||
|
|
||||
|
float3 Raster::piplineTransform2(float3 pos) { |
||||
|
float4 world(pos.x, pos.y, pos.z, 1); |
||||
|
|
||||
|
float4 screen = _matProjView * world; |
||||
|
if (screen.w == 0.0f) { |
||||
|
return false; |
||||
} |
} |
||||
|
|
||||
void Raster::setViewPort(int x, int y, int w, int h) { |
|
||||
_viewPort.x = w; |
|
||||
_viewPort.y = h; |
|
||||
|
//printf("1 %f %f %f\n",screen.x, screen.y, screen.z);
|
||||
|
|
||||
|
screen.x /= screen.w; |
||||
|
screen.y /= screen.w; |
||||
|
screen.z /= screen.w; |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
// map to range 0 - 1
|
||||
|
screen.x = screen.x * 0.5f + 0.5f; |
||||
|
screen.y = screen.y * 0.5f + 0.5f; |
||||
|
screen.z = screen.z * 0.5f + 0.5f; |
||||
|
|
||||
|
// map to viewport
|
||||
|
screen.x = screen.x * _viewPort.x; |
||||
|
screen.y = screen.y * _viewPort.y; |
||||
|
//screen.y = _viewPort.y - (screen.y * _viewPort.y);
|
||||
|
|
||||
|
|
||||
|
|
||||
|
return float3(screen.x, screen.y, screen.z); |
||||
|
} |
||||
|
|
||||
|
float3 Raster::piplineTransform(float3 pos) { |
||||
|
float4 world(pos.x, pos.y, pos.z, 1); |
||||
|
|
||||
|
float4 screen = _matProjView * world; |
||||
|
if (screen.w == 0.0f) { |
||||
|
return false; |
||||
|
} |
||||
|
screen.x /= screen.w; |
||||
|
screen.y /= screen.w; |
||||
|
screen.z /= screen.w; |
||||
|
|
||||
|
// map to range 0 - 1
|
||||
|
screen.x = screen.x * 0.5f + 0.5f; |
||||
|
screen.y = screen.y * 0.5f + 0.5f; |
||||
|
screen.z = screen.z * 0.5f + 0.5f; |
||||
|
|
||||
|
// map to viewport
|
||||
|
screen.x = screen.x * _viewPort.x; |
||||
|
screen.y = screen.y * _viewPort.y; |
||||
|
//screen.y = _viewPort.y - (screen.y * _viewPort.y);
|
||||
|
|
||||
|
return float3(screen.x, screen.y, screen.z); |
||||
|
} |
||||
|
|
||||
|
void Raster::loadProjMatrix(const matrix4& mat) { |
||||
|
_matProj = mat; |
||||
|
} |
||||
|
|
||||
|
void Raster::loadProjIdentity() { |
||||
|
_matProj = matrix4(1); |
||||
|
} |
||||
|
|
||||
|
void Raster::loadViewMatrix(const matrix4& mat) { |
||||
|
_matView = mat; |
||||
|
} |
||||
|
|
||||
|
void Raster::loadViewIdentity() { |
||||
|
_matView = matrix4(1); |
||||
|
} |
||||
|
|
||||
|
void Raster::loadMatrix(const matrix4& mat) { |
||||
|
_matModel = mat; |
||||
|
} |
||||
|
|
||||
|
void Raster::loadIdentity() { |
||||
|
_matModel = matrix4(1); |
||||
|
} |
||||
|
|
||||
|
void Raster::setPerspective(float fovy, float aspect, float zNear, float zFar) { |
||||
|
_matProj = perspective<float>(fovy, aspect, zNear, zFar); |
||||
|
} |
||||
|
|
||||
|
void Raster::lookat(float3 const & eye, float3 const & center, float3 const & up) { |
||||
|
_matView = lookAt(eye, center, up); |
||||
|
} |
||||
|
|
||||
|
void Raster::setViewPort(int x, int y, int w, int h) { |
||||
|
_viewPort.x = w; |
||||
|
_viewPort.y = h; |
||||
|
} |
||||
|
|
||||
|
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; |
||||
} |
} |
@ -1,361 +1,185 @@ |
|||||
#pragma once |
|
||||
|
/* |
||||
|
* 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 "common.h" |
||||
|
|
||||
#include "Image.h" |
#include "Image.h" |
||||
|
|
||||
namespace CELL |
|
||||
{ |
|
||||
enum DRAWMODE |
|
||||
{ |
|
||||
DM_POINTS = 0, |
|
||||
DM_LINES = 1, |
|
||||
DM_LINE_LOOP = 2, |
|
||||
DM_LINE_STRIP = 3, |
|
||||
DM_TRIANGES = 4, |
|
||||
}; |
|
||||
|
|
||||
enum DATETYPE |
|
||||
{ |
|
||||
DT_BYTE, |
|
||||
DT_FLOAT, |
|
||||
DT_DOUBLE, |
|
||||
}; |
|
||||
|
|
||||
struct DateElementDes |
|
||||
{ |
|
||||
int _size; |
|
||||
DATETYPE _type; |
|
||||
int _stride; |
|
||||
const void* _data; |
|
||||
}; |
|
||||
|
|
||||
class Span |
|
||||
{ |
|
||||
public: |
|
||||
int _xStart; |
|
||||
int _xEnd; |
|
||||
Rgba _colorStart; |
|
||||
Rgba _colorEnd; |
|
||||
|
|
||||
float2 _uvStart; |
|
||||
float2 _uvEnd; |
|
||||
|
|
||||
int _y; |
|
||||
|
|
||||
public: |
|
||||
Span(int xStart,int xEnd,int y,Rgba colorStart,Rgba colorEnd,float2 uvStart,float2 uvEnd) |
|
||||
{ |
|
||||
if (xStart < xEnd) |
|
||||
{ |
|
||||
_xStart = xStart; |
|
||||
_xEnd = xEnd; |
|
||||
_colorStart = colorStart; |
|
||||
_colorEnd = colorEnd; |
|
||||
|
|
||||
_uvStart = uvStart; |
|
||||
_uvEnd = uvEnd; |
|
||||
|
|
||||
_y = y; |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
_xStart = xEnd; |
|
||||
_xEnd = xStart; |
|
||||
|
|
||||
_colorStart = colorEnd; |
|
||||
_colorEnd = colorStart; |
|
||||
|
|
||||
_uvStart = uvEnd; |
|
||||
_uvEnd = uvStart; |
|
||||
_y = y; |
|
||||
} |
|
||||
|
using namespace CELL; |
||||
|
|
||||
|
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; |
||||
} |
} |
||||
}; |
|
||||
|
|
||||
class Ege |
|
||||
{ |
|
||||
public: |
|
||||
int _x1; |
|
||||
int _y1; |
|
||||
float2 _uv1; |
|
||||
Rgba _color1; |
|
||||
|
|
||||
int _x2; |
|
||||
int _y2; |
|
||||
float2 _uv2; |
|
||||
Rgba _color2; |
|
||||
|
|
||||
Ege(int x1,int y1,Rgba color1,float2 uv1,int x2,int y2,Rgba color2,float2 uv2) |
|
||||
{ |
|
||||
if (y1 < y2) |
|
||||
{ |
|
||||
_x1 = x1; |
|
||||
_y1 = y1; |
|
||||
_uv1 = uv1; |
|
||||
_color1 = color1; |
|
||||
|
|
||||
_x2 = x2; |
|
||||
_y2 = y2; |
|
||||
_uv2 = uv2; |
|
||||
_color2 = color2; |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
_x1 = x2; |
|
||||
_y1 = y2; |
|
||||
_uv1 = uv2; |
|
||||
_color1 = color2; |
|
||||
|
|
||||
_x2 = x1; |
|
||||
_y2 = y1; |
|
||||
_uv2 = uv1; |
|
||||
_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: |
|
||||
uint* _buffer; |
|
||||
int _width; |
|
||||
int _height; |
|
||||
Rgba _color; |
|
||||
|
|
||||
Image* _texture; |
|
||||
|
|
||||
matrix4 _matModel; |
|
||||
matrix4 _matView; |
|
||||
matrix4 _matProj; |
|
||||
matrix4 _matProjView; |
|
||||
float2 _viewPort; |
|
||||
Frustum _frust; |
|
||||
|
|
||||
DateElementDes _poitionPointer; |
|
||||
DateElementDes _colorPointer; |
|
||||
DateElementDes _uvPointer; |
|
||||
|
|
||||
DateElementDes _defaultColorPointer; |
|
||||
DateElementDes _defaultUVPointer; |
|
||||
Rgba _defaultColorArray[3]; |
|
||||
float2 _detaultUVArray[3]; |
|
||||
|
|
||||
public: |
|
||||
Raster(int w,int h,void* buffer); |
|
||||
~Raster(void); |
|
||||
|
|
||||
void clear(); |
|
||||
|
|
||||
struct Vertex |
|
||||
{ |
|
||||
int2 p0; |
|
||||
float2 uv0; |
|
||||
Rgba c0; |
|
||||
|
|
||||
int2 p1; |
|
||||
float2 uv1; |
|
||||
Rgba c1; |
|
||||
|
|
||||
int2 p2; |
|
||||
float2 uv2; |
|
||||
Rgba c2; |
|
||||
|
|
||||
}; |
|
||||
|
|
||||
void drawImage(int startX,int startY,const Image* image); |
|
||||
public: |
|
||||
|
|
||||
|
|
||||
void loadViewMatrix(const CELL::matrix4& mat); |
|
||||
void loadViewIdentity(const CELL::matrix4& mat); |
|
||||
|
|
||||
void loadProjMatrix(const CELL::matrix4& mat); |
|
||||
void loadProjIdentity(const CELL::matrix4& mat); |
|
||||
|
|
||||
/** |
|
||||
* ����ͶӰ���� |
|
||||
*/ |
|
||||
void setPerspective(float fovy, float aspect, float zNear, float zFar); |
|
||||
/** |
|
||||
* ���ɹ۲���� |
|
||||
*/ |
|
||||
void lookat(float3 const & eye,float3 const & center,float3 const & up); |
|
||||
|
|
||||
void setViewPort(int x,int y,int w,int h); |
|
||||
/** |
|
||||
* ģ�;���������� |
|
||||
*/ |
|
||||
|
|
||||
void loadMatrix(const CELL::matrix4& mat); |
|
||||
|
|
||||
void loadIdentity(); |
|
||||
|
|
||||
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); |
|
||||
|
class Raster { |
||||
|
public: |
||||
|
|
||||
void bindTexture(Image* image); |
|
||||
|
struct Vertex { |
||||
|
int2 p0; |
||||
|
float2 uv0; |
||||
|
Rgba c0; |
||||
|
|
||||
void drawArrays(DRAWMODE pri,int start,int count); |
|
||||
|
int2 p1; |
||||
|
float2 uv1; |
||||
|
Rgba c1; |
||||
|
|
||||
protected: |
|
||||
|
|
||||
float3 piplineTransform(float3 pos) |
|
||||
{ |
|
||||
float4 world(pos.x,pos.y,pos.z,1); |
|
||||
|
|
||||
float4 screen = _matProjView * world; |
|
||||
if (screen.w == 0.0f) |
|
||||
{ |
|
||||
return false; |
|
||||
} |
|
||||
screen.x /= screen.w; |
|
||||
screen.y /= screen.w; |
|
||||
screen.z /= screen.w; |
|
||||
|
|
||||
// map to range 0 - 1 |
|
||||
screen.x = screen.x * 0.5f + 0.5f; |
|
||||
screen.y = screen.y * 0.5f + 0.5f; |
|
||||
screen.z = screen.z * 0.5f + 0.5f; |
|
||||
|
|
||||
// map to viewport |
|
||||
screen.x = screen.x * _viewPort.x; |
|
||||
screen.y = _height - screen.y * _viewPort.y; |
|
||||
|
|
||||
return float3(screen.x,screen.y,screen.z); |
|
||||
} |
|
||||
void drawTrianle(Ege eges[3]) |
|
||||
{ |
|
||||
int iMax = 0; |
|
||||
int length = eges[0]._y2 - eges[0]._y1; |
|
||||
|
|
||||
for (int i = 1 ;i < 3 ; ++ i) |
|
||||
{ |
|
||||
int len = eges[i]._y2 - eges[i]._y1; |
|
||||
if (len > length) |
|
||||
{ |
|
||||
length = len; |
|
||||
iMax = i; |
|
||||
} |
|
||||
} |
|
||||
int iShort1 = (iMax + 1)%3; |
|
||||
int iShort2 = (iMax + 2)%3; |
|
||||
|
|
||||
drawEge(eges[iMax],eges[iShort1],_texture); |
|
||||
drawEge(eges[iMax],eges[iShort2],_texture); |
|
||||
} |
|
||||
void drawTriangle(const Vertex& vertex,Image* image) |
|
||||
{ |
|
||||
Ege eges[3] = |
|
||||
{ |
|
||||
Ege(vertex.p0.x,vertex.p0.y,vertex.c0, vertex.uv0, vertex.p1.x,vertex.p1.y,vertex.c1, vertex.uv1), |
|
||||
Ege(vertex.p1.x,vertex.p1.y,vertex.c1, vertex.uv1, vertex.p2.x,vertex.p2.y,vertex.c2, vertex.uv2), |
|
||||
Ege(vertex.p2.x,vertex.p2.y,vertex.c2, vertex.uv2, vertex.p0.x,vertex.p0.y,vertex.c0, vertex.uv0), |
|
||||
}; |
|
||||
int iMax = 0; |
|
||||
int length = eges[0]._y2 - eges[0]._y1; |
|
||||
|
|
||||
for (int i = 1 ;i < 3 ; ++ i) |
|
||||
{ |
|
||||
int len = eges[i]._y2 - eges[i]._y1; |
|
||||
if (len > length) |
|
||||
{ |
|
||||
length = len; |
|
||||
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 drawEge(const Ege& e1,const Ege& e2,Image* image) |
|
||||
{ |
|
||||
float yOffset1 = e1._y2 - e1._y1; |
|
||||
if (yOffset1 == 0) |
|
||||
{ |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
float yOffset = e2._y2 - e2._y1; |
|
||||
if (yOffset == 0) |
|
||||
{ |
|
||||
return; |
|
||||
} |
|
||||
float xOffset = e2._x2 - e2._x1; |
|
||||
float scale = 0; |
|
||||
float step = 1.0f/yOffset; |
|
||||
|
|
||||
|
|
||||
float xOffset1 = e1._x2 - e1._x1; |
|
||||
float scale1 = (float)(e2._y1 - e1._y1)/yOffset1; |
|
||||
float step1 = 1.0f/yOffset1; |
|
||||
|
|
||||
for (int y = e2._y1 ; y < e2._y2 ; ++ y) |
|
||||
{ |
|
||||
int x1 = e1._x1 + (int)(scale1 * xOffset1); |
|
||||
int x2 = e2._x1 + (int)(scale * xOffset); |
|
||||
Rgba color2 = colorLerp(e2._color1,e2._color2,scale); |
|
||||
Rgba color1 = colorLerp(e1._color1,e1._color2,scale1); |
|
||||
|
|
||||
float2 uvStart = uvLerp(e1._uv1,e1._uv2,scale1); |
|
||||
float2 uvEnd = uvLerp(e2._uv1,e2._uv2,scale); |
|
||||
|
|
||||
Span span(x1,x2,y,color1,color2,uvStart,uvEnd); |
|
||||
drawSpan(span,image); |
|
||||
|
|
||||
scale += step; |
|
||||
scale1 += step1; |
|
||||
|
|
||||
} |
|
||||
} |
|
||||
|
|
||||
void drawSpan(const Span& span,Image* image) |
|
||||
{ |
|
||||
float length = span._xEnd - span._xStart; |
|
||||
float scale = 0; |
|
||||
float step = 1.0f/length; |
|
||||
for (int x = span._xStart ; x < span._xEnd; ++ x) |
|
||||
{ |
|
||||
Rgba color = colorLerp(span._colorStart,span._colorEnd,scale); |
|
||||
|
|
||||
float2 uv = uvLerp(span._uvStart,span._uvEnd,scale); |
|
||||
|
|
||||
Rgba pixel = image->pixelUv(uv.x,uv.y); |
|
||||
|
|
||||
//Rgba dst = color + pixel; |
|
||||
scale += step; |
|
||||
|
|
||||
setPixel(x,span._y,color); |
|
||||
} |
|
||||
} |
|
||||
void drawLine(float2 pt1,float2 pt2,Rgba color1,Rgba color2); |
|
||||
|
|
||||
void drawPoints(float2 pt1,Rgba4Byte color) |
|
||||
{ |
|
||||
|
|
||||
} |
|
||||
inline void setPixelEx(unsigned x,unsigned y,Rgba color) |
|
||||
{ |
|
||||
_buffer[y * _width + x] = color._color; |
|
||||
} |
|
||||
|
|
||||
inline Rgba getPixel(unsigned x,unsigned y) |
|
||||
{ |
|
||||
return Rgba(_buffer[y * _width + x]); |
|
||||
} |
|
||||
inline void setPixel(unsigned x,unsigned y,Rgba color) |
|
||||
{ |
|
||||
if (x >= _width || y >= _height) |
|
||||
{ |
|
||||
return; |
|
||||
} |
|
||||
_buffer[y * _width + x] = color._color; |
|
||||
} |
|
||||
|
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); |
||||
|
float3 piplineTransform(float3 pos); |
||||
|
float3 piplineTransform2(float3 pos); |
||||
|
void bindTexture(Image* image); |
||||
|
void loadViewMatrix(const matrix4 &mat); |
||||
|
void loadViewIdentity(); |
||||
|
void loadProjMatrix(const matrix4 &mat); |
||||
|
void loadProjIdentity(); |
||||
|
void loadMatrix(const matrix4& mat); |
||||
|
void loadIdentity(); |
||||
|
void setPerspective(float fovy, float aspect, float zNear, float zFar); |
||||
|
void lookat(float3 const & eye, float3 const & center, float3 const & up); |
||||
|
void setViewPort(int x, int y, int w, int h); |
||||
|
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; |
||||
|
matrix4 _matView; |
||||
|
matrix4 _matProj; |
||||
|
matrix4 _matProjView; // _matProj * _matView |
||||
|
float2 _viewPort; |
||||
|
Frustum _frust; //台体 |
||||
|
|
||||
|
|
||||
|
DataElementDes _positionPointer; |
||||
|
DataElementDes _colorPointer; |
||||
|
DataElementDes _uvPointer; |
||||
|
|
||||
|
//默认值 |
||||
|
DataElementDes _defaultColorPointer; |
||||
|
DataElementDes _defaultUvPointer; |
||||
|
Rgba _defaultColorArray[3]; |
||||
|
float2 _defaultUvArray[3]; |
||||
|
}; |
||||
|
|
||||
|
#endif /* RESTER_H */ |
||||
|
|
@ -1,159 +0,0 @@ |
|||||
/* |
|
||||
* 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 <assert.h> |
|
||||
#include <cstddef> |
|
||||
#include <stdlib.h> |
|
||||
#include <cmath> |
|
||||
#include "Rgba.h" |
|
||||
#include "struct/tvec2.h" |
|
||||
#include "struct/tvec3.h" |
|
||||
#include "struct/tmat3x3.h" |
|
||||
#include "struct/tvec4.h" |
|
||||
#include "struct/tmat4x4.h" |
|
||||
#include "struct/tfrustum.h" |
|
||||
|
|
||||
#define die(m) do { perror(m); exit(EXIT_FAILURE); } while(0) |
|
||||
#define def2rad(theta) (0.01745329251994329 * (theta)) //每个角度所对应的弧度 |
|
||||
|
|
||||
typedef tvec2<float> float2; |
|
||||
typedef tvec2<int> int2; |
|
||||
typedef tvec3<float> float3; |
|
||||
typedef tvec4<float> float4; |
|
||||
typedef unsigned char byte; |
|
||||
typedef tmat3x3<float> matrix3; |
|
||||
typedef tmat4x4<float> matrix4; |
|
||||
typedef tfrustum<float> Frustum; |
|
||||
|
|
||||
template<class T> inline T tmin(T a, T b) { |
|
||||
return a < b ? a : b; |
|
||||
} |
|
||||
|
|
||||
template<class T> 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; |
|
||||
} |
|
||||
|
|
||||
template <typename T> |
|
||||
tvec3<T> cross(tvec3<T> const & x, tvec3<T> const & y) { |
|
||||
return tvec3<T> |
|
||||
( |
|
||||
x.y * y.z - y.y * x.z, |
|
||||
x.z * y.x - y.z * x.x, |
|
||||
x.x * y.y - y.x * x.y |
|
||||
); |
|
||||
} |
|
||||
|
|
||||
template <typename T> |
|
||||
typename tvec3<T>::value_type dot(tvec3<T> const & x, tvec3<T> const & y) { |
|
||||
return x.x * y.x + x.y * y.y + x.z * y.z; |
|
||||
} |
|
||||
|
|
||||
template <typename T> |
|
||||
T inversesqrt(T x) { |
|
||||
return T(1) / sqrt(x); |
|
||||
} |
|
||||
|
|
||||
template <typename T> |
|
||||
tvec2<T> normalize(tvec2<T> const & x) { |
|
||||
typename tvec2<T>::value_type sqr = x.x * x.x + x.y * x.y; |
|
||||
return x * inversesqrt(sqr); |
|
||||
} |
|
||||
|
|
||||
template <typename T> |
|
||||
tvec3<T> normalize(tvec3<T> const & x) { |
|
||||
typename tvec3<T>::value_type sqr = x.x * x.x + x.y * x.y + x.z * x.z; |
|
||||
return x * inversesqrt(sqr); |
|
||||
} |
|
||||
|
|
||||
template <typename T> |
|
||||
tvec4<T> normalize(tvec4<T> const & x) { |
|
||||
typename tvec4<T>::value_type sqr = x.x * x.x + x.y * x.y + x.z * x.z + x.w * x.w; |
|
||||
return x * inversesqrt(sqr); |
|
||||
} |
|
||||
|
|
||||
template <typename valType> |
|
||||
tmat4x4<valType> perspective(valType fovy, valType aspect, valType zNear, valType zFar) { |
|
||||
valType range = tan(fovy * valType(DEG2RAD(0.5))) * zNear; |
|
||||
valType left = -range * aspect; |
|
||||
valType right = range * aspect; |
|
||||
valType bottom = -range; |
|
||||
valType top = range; |
|
||||
|
|
||||
tmat4x4<valType> res(valType(0)); |
|
||||
res[0][0] = (valType(2) * zNear) / (right - left); |
|
||||
res[1][1] = (valType(2) * zNear) / (top - bottom); |
|
||||
res[2][2] = -(zFar + zNear) / (zFar - zNear); |
|
||||
res[2][3] = -valType(1); |
|
||||
res[3][2] = -(valType(2) * zFar * zNear) / (zFar - zNear); |
|
||||
return res; |
|
||||
} |
|
||||
|
|
||||
template <typename T> |
|
||||
tmat4x4<T> lookAt |
|
||||
( |
|
||||
tvec3<T> const & eye, |
|
||||
tvec3<T> const & center, |
|
||||
tvec3<T> const & up |
|
||||
) { |
|
||||
tvec3<T> f = normalize(center - eye); |
|
||||
tvec3<T> u = normalize(up); |
|
||||
tvec3<T> s = normalize(cross(f, u)); |
|
||||
u = cross(s, f); |
|
||||
|
|
||||
tmat4x4<T> res(1); |
|
||||
res[0][0] = s.x; |
|
||||
res[1][0] = s.y; |
|
||||
res[2][0] = s.z; |
|
||||
res[0][1] = u.x; |
|
||||
res[1][1] = u.y; |
|
||||
res[2][1] = u.z; |
|
||||
res[0][2] = -f.x; |
|
||||
res[1][2] = -f.y; |
|
||||
res[2][2] = -f.z; |
|
||||
res[3][0] = -dot(s, eye); |
|
||||
res[3][1] = -dot(u, eye); |
|
||||
res[3][2] = dot(f, eye); |
|
||||
return res; |
|
||||
} |
|
||||
|
|
||||
#endif /* COMMON_H */ |
|
||||
|
|
@ -1,175 +0,0 @@ |
|||||
/* |
|
||||
* 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: plane.h |
|
||||
* Author: Blobt |
|
||||
* |
|
||||
* Created on February 23, 2020, 11:33 AM |
|
||||
*/ |
|
||||
|
|
||||
#ifndef PLANE_H |
|
||||
#define PLANE_H |
|
||||
#include "../common.h" |
|
||||
|
|
||||
template<class T> |
|
||||
class Plane { |
|
||||
public: |
|
||||
tvec3<T> _normal; |
|
||||
T _distance; |
|
||||
public: |
|
||||
|
|
||||
Plane() { |
|
||||
_normal = tvec3<T>(0, 0, 0); |
|
||||
_distance = 0.0f; |
|
||||
} |
|
||||
|
|
||||
Plane(const Plane& right) { |
|
||||
_normal = right._normal; |
|
||||
_distance = right._distance; |
|
||||
} |
|
||||
|
|
||||
/** Construct a plane through a normal, and a distance to move the plane along the normal.*/ |
|
||||
Plane(const tvec3<T>& rkNormal, T fConstant) { |
|
||||
_normal = rkNormal; |
|
||||
_distance = -fConstant; |
|
||||
} |
|
||||
|
|
||||
/** Construct a plane using the 4 constants directly **/ |
|
||||
Plane(T x, T y, T z, T o) { |
|
||||
_normal = tvec3<T>(x, y, z); |
|
||||
T invLen = 1.0f / (_normal).length(); |
|
||||
_normal *= invLen; |
|
||||
_distance = o * invLen; |
|
||||
} |
|
||||
|
|
||||
Plane(const tvec3<T>& rkNormal, const tvec3<T>& rkPoint) { |
|
||||
redefine(rkNormal, rkPoint); |
|
||||
} |
|
||||
|
|
||||
Plane(const tvec3<T>& rkPoint0, const tvec3<T>& rkPoint1, const tvec3<T>& rkPoint2) { |
|
||||
redefine(rkPoint0, rkPoint1, rkPoint2); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* ����ľ��� |
|
||||
*/ |
|
||||
float distance(const tvec3<T> &pos) const { |
|
||||
return dot(_normal, pos) + _distance; |
|
||||
} |
|
||||
|
|
||||
/** The "positive side" of the plane is the half space to which the |
|
||||
plane normal points. The "negative side" is the other half |
|
||||
space. The flag "no side" indicates the plane itself. |
|
||||
*/ |
|
||||
enum Side { |
|
||||
NO_SIDE, |
|
||||
POSITIVE_SIDE, |
|
||||
NEGATIVE_SIDE, |
|
||||
BOTH_SIDE |
|
||||
}; |
|
||||
|
|
||||
Side getSide(const tvec3<T>& rkPoint) const { |
|
||||
float fDistance = getDistance(rkPoint); |
|
||||
|
|
||||
if (fDistance < 0.0) |
|
||||
return Plane::NEGATIVE_SIDE; |
|
||||
|
|
||||
if (fDistance > 0.0) |
|
||||
return Plane::POSITIVE_SIDE; |
|
||||
|
|
||||
return Plane::NO_SIDE; |
|
||||
} |
|
||||
|
|
||||
Side getSide(const tvec3<T>& centre, const tvec3<T>& halfSize) const { |
|
||||
// Calculate the distance between box centre and the plane |
|
||||
float dist = getDistance(centre); |
|
||||
|
|
||||
// Calculate the maximise allows absolute distance for |
|
||||
// the distance between box centre and plane |
|
||||
float maxAbsDist = _normal.absDot(halfSize); |
|
||||
|
|
||||
if (dist < -maxAbsDist) |
|
||||
return Plane::NEGATIVE_SIDE; |
|
||||
|
|
||||
if (dist > +maxAbsDist) |
|
||||
return Plane::POSITIVE_SIDE; |
|
||||
|
|
||||
return Plane::BOTH_SIDE; |
|
||||
} |
|
||||
|
|
||||
float getDistance(const tvec3<T>& rkPoint) const { |
|
||||
return _normal.dot(rkPoint) + _distance; |
|
||||
} |
|
||||
|
|
||||
void redefine(const tvec3<T>& rkPoint0, const tvec3<T>& rkPoint1, |
|
||||
const tvec3<T>& rkPoint2) { |
|
||||
tvec3<T> kEdge1 = rkPoint1 - rkPoint0; |
|
||||
tvec3<T> kEdge2 = rkPoint2 - rkPoint0; |
|
||||
_normal = cross(kEdge1, kEdge2); |
|
||||
_normal.normalise(); |
|
||||
_distance = -dot(_normal, rkPoint0); |
|
||||
} |
|
||||
|
|
||||
/** Redefine this plane based on a normal and a point. */ |
|
||||
void redefine(const tvec3<T>& rkNormal, const tvec3<T>& rkPoint) { |
|
||||
_normal = rkNormal; |
|
||||
_distance = -dot(rkNormal, rkPoint); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
// tvec3<T> projectVector(const tvec3<T>& p) const |
|
||||
// { |
|
||||
// matrix3 xform; |
|
||||
// xform[0][0] = 1.0f - _normal.x * _normal.x; |
|
||||
// xform[0][1] = -_normal.x * _normal.y; |
|
||||
// xform[0][2] = -_normal.x * _normal.z; |
|
||||
// xform[1][0] = -_normal.y * _normal.x; |
|
||||
// xform[1][1] = 1.0f - _normal.y * _normal.y; |
|
||||
// xform[1][2] = -_normal.y * _normal.z; |
|
||||
// xform[2][0] = -_normal.z * _normal.x; |
|
||||
// xform[2][1] = -_normal.z * _normal.y; |
|
||||
// xform[2][2] = 1.0f - _normal.z * _normal.z; |
|
||||
// return xform * p; |
|
||||
// } |
|
||||
|
|
||||
/** Normalises the plane. |
|
||||
@remarks |
|
||||
This method normalises the plane's normal and the length scale of d |
|
||||
is as well. |
|
||||
@note |
|
||||
This function will not crash for zero-sized vectors, but there |
|
||||
will be no changes made to their components. |
|
||||
@returns The previous length of the plane's normal. |
|
||||
*/ |
|
||||
float normalise(void) { |
|
||||
float fLength = _normal.length(); |
|
||||
|
|
||||
// Will also work for zero-sized vectors, but will change nothing |
|
||||
if (fLength > 1e-08f) { |
|
||||
float fInvLength = 1.0f / fLength; |
|
||||
_normal *= fInvLength; |
|
||||
_distance *= fInvLength; |
|
||||
} |
|
||||
|
|
||||
return fLength; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
|
|
||||
/// Comparison operator |
|
||||
|
|
||||
bool operator==(const Plane& right) const { |
|
||||
return (right._distance == _distance && right._normal == _normal); |
|
||||
} |
|
||||
|
|
||||
bool operator!=(const Plane& right) const { |
|
||||
return (right._distance != _distance && right._normal != _normal); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
#endif /* PLANE_H */ |
|
||||
|
|
@ -1,87 +0,0 @@ |
|||||
/* |
|
||||
* 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: tfrustum.h |
|
||||
* Author: Blobt |
|
||||
* |
|
||||
* Created on February 23, 2020, 11:22 AM |
|
||||
*/ |
|
||||
|
|
||||
#ifndef TFRUSTUM_H |
|
||||
#define TFRUSTUM_H |
|
||||
#include "../common.h" |
|
||||
#include "plane.h" |
|
||||
|
|
||||
template<class T> |
|
||||
class tfrustum { |
|
||||
public: |
|
||||
|
|
||||
enum { |
|
||||
FRUSTUM_LEFT = 0, |
|
||||
FRUSTUM_RIGHT = 1, |
|
||||
FRUSTUM_TOP = 2, |
|
||||
FRUSTUM_BOTTOM = 3, |
|
||||
FRUSTUM_FAR = 4, |
|
||||
FRUSTUM_NEAR = 5, |
|
||||
}; |
|
||||
public: |
|
||||
|
|
||||
/** |
|
||||
* project * view |
|
||||
*/ |
|
||||
void loadFrustum(const tmat4x4<T> &mvp) { |
|
||||
const T* dataPtr = mvp.data(); |
|
||||
_planes[FRUSTUM_LEFT ] = Plane<T>(dataPtr[12] - dataPtr[0], dataPtr[13] - dataPtr[1], dataPtr[14] - dataPtr[2], dataPtr[15] - dataPtr[3]); |
|
||||
_planes[FRUSTUM_RIGHT ] = Plane<T>(dataPtr[12] + dataPtr[0], dataPtr[13] + dataPtr[1], dataPtr[14] + dataPtr[2], dataPtr[15] + dataPtr[3]); |
|
||||
|
|
||||
_planes[FRUSTUM_TOP ] = Plane<T>(dataPtr[12] - dataPtr[4], dataPtr[13] - dataPtr[5], dataPtr[14] - dataPtr[6], dataPtr[15] - dataPtr[7]); |
|
||||
_planes[FRUSTUM_BOTTOM] = Plane<T>(dataPtr[12] + dataPtr[4], dataPtr[13] + dataPtr[5], dataPtr[14] + dataPtr[6], dataPtr[15] + dataPtr[7]); |
|
||||
|
|
||||
_planes[FRUSTUM_FAR ] = Plane<T>(dataPtr[12] - dataPtr[8], dataPtr[13] - dataPtr[9], dataPtr[14] - dataPtr[10], dataPtr[15] - dataPtr[11]); |
|
||||
_planes[FRUSTUM_NEAR ] = Plane<T>(dataPtr[12] + dataPtr[8], dataPtr[13] + dataPtr[9], dataPtr[14] + dataPtr[10], dataPtr[15] + dataPtr[11]); |
|
||||
} |
|
||||
|
|
||||
bool pointInFrustum(const tvec3<T> &pos) const { |
|
||||
for (int i = 0; i < 6; i++) { |
|
||||
if (_planes[i].distance(pos) <= 0) |
|
||||
return false; |
|
||||
} |
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
bool sphereInFrustum(const tvec3<T> &pos, const float radius) const { |
|
||||
for (int i = 0; i < 6; i++) { |
|
||||
if (_planes[i].distance(pos) <= -radius) |
|
||||
return false; |
|
||||
} |
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
bool cubeInFrustum(T minX, T maxX, T minY, T maxY, T minZ, T maxZ) const { |
|
||||
for (int i = 0; i < 6; i++) { |
|
||||
if (_planes[i].distance(tvec3<T>(minX, minY, minZ)) > 0) continue; |
|
||||
if (_planes[i].distance(tvec3<T>(minX, minY, maxZ)) > 0) continue; |
|
||||
if (_planes[i].distance(tvec3<T>(minX, maxY, minZ)) > 0) continue; |
|
||||
if (_planes[i].distance(tvec3<T>(minX, maxY, maxZ)) > 0) continue; |
|
||||
if (_planes[i].distance(tvec3<T>(maxX, minY, minZ)) > 0) continue; |
|
||||
if (_planes[i].distance(tvec3<T>(maxX, minY, maxZ)) > 0) continue; |
|
||||
if (_planes[i].distance(tvec3<T>(maxX, maxY, minZ)) > 0) continue; |
|
||||
if (_planes[i].distance(tvec3<T>(maxX, maxY, maxZ)) > 0) continue; |
|
||||
return false; |
|
||||
} |
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
const Plane<T> &getPlane(const int plane) const { |
|
||||
return _planes[plane]; |
|
||||
} |
|
||||
protected: |
|
||||
Plane<T> _planes[6]; |
|
||||
}; |
|
||||
|
|
||||
#endif /* TFRUSTUM_H */ |
|
||||
|
|
@ -1,174 +0,0 @@ |
|||||
/* |
|
||||
* 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 <typename T> |
|
||||
struct tmat3x3 { |
|
||||
typedef T value_type; |
|
||||
typedef std::size_t size_type; |
|
||||
typedef tvec3<T> col_type; |
|
||||
typedef tvec3<T> row_type; |
|
||||
typedef tmat3x3<T> type; |
|
||||
typedef tmat3x3<T> 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<T> 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<T> operator*(const tvec3<T> &s) const { |
|
||||
tvec3<T> 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<T> 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 */ |
|
||||
|
|
@ -1,387 +0,0 @@ |
|||||
/* |
|
||||
* 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 <typename T> |
|
||||
struct tmat4x4 { |
|
||||
typedef T value_type; |
|
||||
typedef std::size_t size_type; |
|
||||
typedef tvec4<T> col_type; |
|
||||
typedef tvec4<T> row_type; |
|
||||
typedef tmat4x4<T> type; |
|
||||
typedef tmat4x4<T> 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<T> 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 <typename U> |
|
||||
tmat4x4(tmat4x4<U> 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]); |
|
||||
} |
|
||||
|
|
||||
T const * data() const { |
|
||||
return &this->value[0][0]; |
|
||||
} |
|
||||
|
|
||||
tmat4x4<T>& 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<typename U> |
|
||||
tmat4x4<T>& 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<T>& translate(tvec3<T> 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<typename U> |
|
||||
tmat4x4<T>& translate(tvec3<U> 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<T>& rotate(value_type angle, tvec3<T> const & v) { |
|
||||
T a = DEG2RAD(angle); |
|
||||
T c = cos(a); |
|
||||
T s = sin(a); |
|
||||
|
|
||||
tvec3<T> axis = normalize(v); |
|
||||
|
|
||||
tvec3<T> temp = (T(1) - c) * axis; |
|
||||
|
|
||||
tmat4x4<T> 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<T>& 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<typename U> |
|
||||
tmat4x4<T>& 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<T>& 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<typename U> |
|
||||
tmat4x4<T>& 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<T>& 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<typename U> |
|
||||
tmat4x4<T>& 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<T>& scale(tvec3<T> 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<T>& 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<typename U> |
|
||||
tmat4x4<T>& 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<typename U, typename V, typename W> |
|
||||
tmat4x4<T>& 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<T> transpose() const { |
|
||||
return tmat4x4<T>( |
|
||||
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<T> extractMatrixRotation() const { |
|
||||
return tmat4x4<T>( |
|
||||
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 |
|
||||
); |
|
||||
} |
|
||||
|
|
||||
private: |
|
||||
col_type value[4]; |
|
||||
}; |
|
||||
|
|
||||
template <typename T> |
|
||||
tvec3<T> operator*(tvec3<T> const& v, tmat4x4<T> const& mat) { |
|
||||
return tvec3<T> |
|
||||
( |
|
||||
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 <typename T> |
|
||||
tmat4x4<T> operator*(tmat4x4<T> const & m, typename tmat4x4<T>::value_type s) { |
|
||||
return tmat4x4<T>( |
|
||||
m[0] * s, |
|
||||
m[1] * s, |
|
||||
m[2] * s, |
|
||||
m[3] * s); |
|
||||
} |
|
||||
|
|
||||
template <typename T> |
|
||||
tmat4x4<T> operator*(typename tmat4x4<T>::value_type s, tmat4x4<T> const & m) { |
|
||||
return tmat4x4<T>( |
|
||||
m[0] * s, |
|
||||
m[1] * s, |
|
||||
m[2] * s, |
|
||||
m[3] * s); |
|
||||
} |
|
||||
|
|
||||
template <typename T> |
|
||||
typename tmat4x4<T>::col_type operator*(tmat4x4<T> const & m, typename tmat4x4<T>::row_type const & v) { |
|
||||
return typename tmat4x4<T>::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 T> |
|
||||
typename tmat4x4<T>::row_type operator*(typename tmat4x4<T>::col_type const & v, tmat4x4<T> const & m) { |
|
||||
return typename tmat4x4<T>::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 <typename T> |
|
||||
tmat4x4<T> operator*(tmat4x4<T> const & m1, tmat4x4<T> const & m2) { |
|
||||
typename tmat4x4<T>::col_type const srcA0 = m1[0]; |
|
||||
typename tmat4x4<T>::col_type const srcA1 = m1[1]; |
|
||||
typename tmat4x4<T>::col_type const srcA2 = m1[2]; |
|
||||
typename tmat4x4<T>::col_type const srcA3 = m1[3]; |
|
||||
|
|
||||
typename tmat4x4<T>::col_type const srcB0 = m2[0]; |
|
||||
typename tmat4x4<T>::col_type const srcB1 = m2[1]; |
|
||||
typename tmat4x4<T>::col_type const srcB2 = m2[2]; |
|
||||
typename tmat4x4<T>::col_type const srcB3 = m2[3]; |
|
||||
|
|
||||
tmat4x4<T> 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 */ |
|
||||
|
|
@ -1,57 +0,0 @@ |
|||||
/* |
|
||||
* 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<typename T> |
|
||||
struct tvec2 { |
|
||||
typedef T value_type; |
|
||||
typedef std::size_t size_type; |
|
||||
typedef tvec2<T> 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 */ |
|
||||
|
|
@ -1,172 +0,0 @@ |
|||||
/* |
|
||||
* 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 <cstdio> |
|
||||
|
|
||||
template<typename T> |
|
||||
struct tvec3 { |
|
||||
typedef T value_type; |
|
||||
typedef std::size_t size_type; |
|
||||
typedef tvec3<T> 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; |
|
||||
} |
|
||||
|
|
||||
inline tvec3(tvec3<T> const & v) : |
|
||||
x(v.x), |
|
||||
y(v.y), |
|
||||
z(v.z) { |
|
||||
} |
|
||||
|
|
||||
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 <typename U>起到用来配备其它类型做参数的情况 |
|
||||
* 例如tvec3<int> n(3.1f); |
|
||||
*/ |
|
||||
template <typename U> |
|
||||
tvec3(U s) { |
|
||||
x = value_type(s); |
|
||||
y = value_type(s); |
|
||||
z = value_type(s); |
|
||||
} |
|
||||
|
|
||||
template <typename A, typename B, typename C> |
|
||||
tvec3(A s1, B s2, C s3) { |
|
||||
x = value_type(s1); |
|
||||
y = value_type(s2); |
|
||||
z = value_type(s3); |
|
||||
} |
|
||||
|
|
||||
tvec3<T>& operator=(tvec3<T> &s) { |
|
||||
x = s.x; |
|
||||
y = s.y; |
|
||||
z = s.z; |
|
||||
|
|
||||
return *this; |
|
||||
} |
|
||||
|
|
||||
tvec3<T> const & operator=(tvec3<T> const &s) { |
|
||||
x = s.x; |
|
||||
y = s.y; |
|
||||
z = s.z; |
|
||||
|
|
||||
return *this; |
|
||||
} |
|
||||
|
|
||||
template <typename U> |
|
||||
tvec3<T>& operator=(tvec3<U> const & v) { |
|
||||
this->x = T(v.x); |
|
||||
this->y = T(v.y); |
|
||||
this->z = T(v.z); |
|
||||
return *this; |
|
||||
} |
|
||||
|
|
||||
tvec3<T> & operator++() { |
|
||||
++x; |
|
||||
++y; |
|
||||
++z; |
|
||||
return *this; |
|
||||
} |
|
||||
|
|
||||
template <typename U> |
|
||||
tvec3<T> & operator*=(U const & s) { |
|
||||
this->x *= T(s); |
|
||||
this->y *= T(s); |
|
||||
this->z *= T(s); |
|
||||
return *this; |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
template <typename T> |
|
||||
tvec3<T> operator-(tvec3<T> const & v, T const & s) { |
|
||||
return tvec3<T>( |
|
||||
v.x - T(s), |
|
||||
v.y - T(s), |
|
||||
v.z - T(s)); |
|
||||
} |
|
||||
|
|
||||
template <typename T> |
|
||||
tvec3<T> operator-(T const & s, tvec3<T> const & v) { |
|
||||
return tvec3<T>( |
|
||||
T(s) - v.x, |
|
||||
T(s) - v.y, |
|
||||
T(s) - v.z); |
|
||||
} |
|
||||
|
|
||||
template <typename T> |
|
||||
tvec3<T> operator-(tvec3<T> const & v1, tvec3<T> const & v2) { |
|
||||
return tvec3<T>( |
|
||||
v1.x - T(v2.x), |
|
||||
v1.y - T(v2.y), |
|
||||
v1.z - T(v2.z)); |
|
||||
} |
|
||||
|
|
||||
template <typename T> |
|
||||
tvec3<T> operator*(tvec3<T> const & v, T const & s) { |
|
||||
return tvec3<T>( |
|
||||
v.x * T(s), |
|
||||
v.y * T(s), |
|
||||
v.z * T(s)); |
|
||||
} |
|
||||
|
|
||||
template <typename T> |
|
||||
tvec3<T> operator*(T const & s, tvec3<T> const & v) { |
|
||||
return tvec3<T>( |
|
||||
T(s) * v.x, |
|
||||
T(s) * v.y, |
|
||||
T(s) * v.z); |
|
||||
} |
|
||||
|
|
||||
#endif /* TVEC3_H */ |
|
||||
|
|
@ -1,183 +0,0 @@ |
|||||
/* |
|
||||
* 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 <typename T> |
|
||||
struct tvec4 { |
|
||||
typedef T value_type; |
|
||||
typedef std::size_t size_type; |
|
||||
typedef tvec4<T> 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<T> const & v) : |
|
||||
x(v.x), |
|
||||
y(v.y), |
|
||||
z(v.z), |
|
||||
w(v.w) { |
|
||||
} |
|
||||
|
|
||||
template<typename U> |
|
||||
tvec4(tvec4<U> 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<T> & operator=(tvec4<T> const & v) { |
|
||||
this->x = v.x; |
|
||||
this->y = v.y; |
|
||||
this->z = v.z; |
|
||||
this->w = v.w; |
|
||||
return *this; |
|
||||
} |
|
||||
|
|
||||
template <typename U> |
|
||||
tvec4<T> & operator=(tvec4<U> 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 <typename U> |
|
||||
tvec4<T> & operator*=(U const & s) { |
|
||||
this->x *= T(s); |
|
||||
this->y *= T(s); |
|
||||
this->z *= T(s); |
|
||||
this->w *= T(s); |
|
||||
return *this; |
|
||||
} |
|
||||
|
|
||||
template <typename U> |
|
||||
tvec4<T> & operator*=(tvec4<U> 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<T> & operator++() { |
|
||||
++this->x; |
|
||||
++this->y; |
|
||||
++this->z; |
|
||||
++this->w; |
|
||||
return *this; |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
template <typename T> |
|
||||
tvec4<T> operator+(tvec4<T> const & v, T const & s) { |
|
||||
return tvec4<T>( |
|
||||
v.x + s, |
|
||||
v.y + s, |
|
||||
v.z + s, |
|
||||
v.w + s); |
|
||||
} |
|
||||
|
|
||||
template <typename T> |
|
||||
tvec4<T> operator+(T const & s, tvec4<T> const & v) { |
|
||||
return tvec4<T>( |
|
||||
s + v.x, |
|
||||
s + v.y, |
|
||||
s + v.z, |
|
||||
s + v.w); |
|
||||
} |
|
||||
|
|
||||
template <typename T> |
|
||||
tvec4<T> operator+(tvec4<T> const & v1, tvec4<T> const & v2) { |
|
||||
return tvec4<T>( |
|
||||
v1.x + v2.x, |
|
||||
v1.y + v2.y, |
|
||||
v1.z + v2.z, |
|
||||
v1.w + v2.w); |
|
||||
} |
|
||||
|
|
||||
template <typename T> |
|
||||
tvec4<T> operator*(tvec4<T> const & v, T const & s) { |
|
||||
return tvec4<T>( |
|
||||
v.x * s, |
|
||||
v.y * s, |
|
||||
v.z * s, |
|
||||
v.w * s); |
|
||||
} |
|
||||
|
|
||||
template <typename T> |
|
||||
tvec4<T> operator*(T const & s, tvec4<T> const & v) { |
|
||||
return tvec4<T>( |
|
||||
s * v.x, |
|
||||
s * v.y, |
|
||||
s * v.z, |
|
||||
s * v.w); |
|
||||
} |
|
||||
|
|
||||
template <typename T> |
|
||||
tvec4<T> operator*(tvec4<T> const & v1, tvec4<T> const & v2) { |
|
||||
return tvec4<T>( |
|
||||
v1.x * v2.x, |
|
||||
v1.y * v2.y, |
|
||||
v1.z * v2.z, |
|
||||
v1.w * v2.w); |
|
||||
} |
|
||||
#endif /* TVEC4_H */ |
|
||||
|
|
@ -0,0 +1,7 @@ |
|||||
|
set(commom_src |
||||
|
Raster.cc |
||||
|
Image.cc |
||||
|
) |
||||
|
|
||||
|
add_executable(camera camera.cc ${commom_src}) |
||||
|
target_link_libraries (camera ${FC_DEP_LIBS}) |
@ -1,7 +0,0 @@ |
|||||
set(commom_src |
|
||||
Raster.cc |
|
||||
Image.cc |
|
||||
) |
|
||||
|
|
||||
add_executable(threed threed.cc ${commom_src}) |
|
||||
target_link_libraries (threed ${FC_DEP_LIBS}) |
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue