11 changed files with 1070 additions and 1 deletions
-
3CMakeLists.txt
-
8src/statemachine/CMakeLists.txt
-
44src/statemachine/Image.cc
-
78src/statemachine/Image.h
-
405src/statemachine/Raster.cc
-
165src/statemachine/Raster.h
-
83src/statemachine/Rgba.cc
-
45src/statemachine/Rgba.h
-
99src/statemachine/common.h
-
103src/statemachine/statemachine.cc
-
38src/statemachine/tt.cc
@ -0,0 +1,8 @@ |
|||||
|
set(commom_src |
||||
|
Rgba.cc |
||||
|
Raster.cc |
||||
|
Image.cc |
||||
|
) |
||||
|
|
||||
|
add_executable(statemachine statemachine.cc ${commom_src}) |
||||
|
target_link_libraries (statemachine ${FC_DEP_LIBS}) |
@ -0,0 +1,44 @@ |
|||||
|
/*
|
||||
|
* 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 <string.h>
|
||||
|
|
||||
|
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 { |
||||
|
int x = (u * _width) ; |
||||
|
int y = (v * _height) -2;//TODO ???
|
||||
|
|
||||
|
return pixelAt(x, y); |
||||
|
//return Rgba(255,0,0);
|
||||
|
} |
@ -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 */ |
||||
|
|
@ -0,0 +1,405 @@ |
|||||
|
/*
|
||||
|
* 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 <stdio.h>
|
||||
|
#include <iostream>
|
||||
|
#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; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
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<int>(span.xStart - span.xEnd, 1); //取保length不为0
|
||||
|
|
||||
|
Rgba color; |
||||
|
Rgba blendColor; |
||||
|
Rgba dstColor; |
||||
|
float2 uv; |
||||
|
float scale; |
||||
|
float length = span.xEnd - span.xStart; |
||||
|
|
||||
|
|
||||
|
int startX = tmax<int>(span.xStart, 0); |
||||
|
int endX = tmin<int>(span.xEnd, _width); |
||||
|
|
||||
|
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<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; |
||||
|
} |
||||
|
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; |
||||
|
int2 p0(pp[0], pp[1]); |
||||
|
posData += _positionPointer.stride; |
||||
|
pp = (float*) posData; |
||||
|
int2 p1(pp[0], pp[1]); |
||||
|
posData += _positionPointer.stride; |
||||
|
pp = (float*) posData; |
||||
|
int2 p2(pp[0], pp[1]); |
||||
|
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), |
||||
|
}; |
||||
|
|
||||
|
//printf("%d,%d %d,%d %d,%d,%d %d,%d,%d %f,%f %f,%f\n", p0.x, p0.y, p1.x, p1.y, c0._r, c0._g, c0._b, c1._r, c1._g, c1._b, uv0.x, uv0.y, uv1.x, uv1.y);
|
||||
|
//printf("%d,%d %d,%d %d,%d,%d %d,%d,%d %f,%f %f,%f\n", p1.x, p1.y, p2.x, p2.y, c1._r, c1._g, c1._b, c2._r, c2._g, c2._b, uv1.x, uv1.y, uv2.x, uv2.y);
|
||||
|
//
|
||||
|
// return;
|
||||
|
|
||||
|
drawTriangle(eges, _texture); |
||||
|
|
||||
|
if (_colorPointer.data == 0) { |
||||
|
cData = (char*) colorPointerdesc.data; |
||||
|
} |
||||
|
|
||||
|
if (_uvPointer.data == 0) { |
||||
|
uvData = (char*) uvPointerdesc.data; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
//die("stop");
|
||||
|
|
||||
|
} |
||||
|
|
||||
|
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; |
||||
|
} |
@ -0,0 +1,165 @@ |
|||||
|
/* |
||||
|
* 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); |
||||
|
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; |
||||
|
|
||||
|
DataElementDes _positionPointer; |
||||
|
DataElementDes _colorPointer; |
||||
|
DataElementDes _uvPointer; |
||||
|
|
||||
|
//默认值 |
||||
|
DataElementDes _defaultColorPointer; |
||||
|
DataElementDes _defaultUvPointer; |
||||
|
Rgba _defaultColorArray[3]; |
||||
|
float2 _defaultUvArray[3]; |
||||
|
}; |
||||
|
|
||||
|
#endif /* RESTER_H */ |
||||
|
|
@ -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 <bitset>
|
||||
|
#include <iostream>
|
||||
|
#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; |
||||
|
} |
@ -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 */ |
||||
|
|
@ -0,0 +1,99 @@ |
|||||
|
/* |
||||
|
* 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 "Rgba.h" |
||||
|
|
||||
|
#define die(m) do { perror(m); exit(EXIT_FAILURE); } while(0) |
||||
|
#define def2rad(theta) (0.01745329251994329 * (theta)) //每个角度所对应的弧度 |
||||
|
|
||||
|
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; |
||||
|
} |
||||
|
|
||||
|
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]; |
||||
|
} |
||||
|
|
||||
|
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; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
typedef tvec2<float> float2; |
||||
|
typedef tvec2<int> int2; |
||||
|
typedef unsigned char byte; |
||||
|
|
||||
|
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 */ |
||||
|
|
@ -0,0 +1,103 @@ |
|||||
|
#include <iostream>
|
||||
|
#include <math.h>
|
||||
|
#include <cairo.h>
|
||||
|
#include <gtk/gtk.h>
|
||||
|
#include "Rgba.h"
|
||||
|
#include "Raster.h"
|
||||
|
#include "common.h"
|
||||
|
|
||||
|
using namespace std; |
||||
|
|
||||
|
|
||||
|
gint height = 500; |
||||
|
gint width = 500; |
||||
|
|
||||
|
Raster raster(width, height); |
||||
|
|
||||
|
struct Vertex { |
||||
|
float x, y; |
||||
|
float u, v; |
||||
|
Rgba color; |
||||
|
}; |
||||
|
|
||||
|
/**
|
||||
|
* |
||||
|
*/ |
||||
|
void example() { |
||||
|
|
||||
|
Vertex vertexs[] = |
||||
|
{ |
||||
|
{10, 10, 0.0f, 0.0f, Rgba(255,0,0,255)}, |
||||
|
{110, 110, 1.0f, 1.0f, Rgba(255,0,0,255)}, |
||||
|
{110, 10, 1.0f, 0.0f, Rgba(255,0,0,255)}, |
||||
|
|
||||
|
{10, 10, 0.0f, 0.0f, Rgba(255,255,255,255)}, |
||||
|
{110, 110, 1.0f, 1.0f, Rgba(255,255,255,255)}, |
||||
|
{10, 110, 0.0f, 1.0f, Rgba(255,255,255,255)}, |
||||
|
}; |
||||
|
|
||||
|
Image* image = Image::loadFromFile("/home/blobt/Documents/dev/cpp/3dbase/image/scale.jpg"); |
||||
|
|
||||
|
|
||||
|
raster.bindTexture(image); |
||||
|
|
||||
|
raster.vertexPointer(2, DT_FLOAT, sizeof (Vertex), &vertexs[0].x); |
||||
|
raster.colorPointer(4, DT_BYTE, sizeof (Vertex), &vertexs[0].color); |
||||
|
raster.textureCoordPointer(2, DT_FLOAT, sizeof (Vertex), &vertexs[0].u); |
||||
|
|
||||
|
|
||||
|
raster.drawArrays(DM_TRIANGES, 0, 6); |
||||
|
} |
||||
|
|
||||
|
unsigned char* makeBitmap() { |
||||
|
raster.clean(); |
||||
|
|
||||
|
example(); |
||||
|
|
||||
|
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; |
||||
|
} |
@ -0,0 +1,38 @@ |
|||||
|
#include "Rgba.h"
|
||||
|
#include <stdio.h>
|
||||
|
#include <iostream>
|
||||
|
#include <bitset>
|
||||
|
#include <string.h>
|
||||
|
#include "common.h"
|
||||
|
|
||||
|
using namespace std; |
||||
|
|
||||
|
struct Ms { |
||||
|
int x; |
||||
|
int y; |
||||
|
|
||||
|
int operator[](int i) { |
||||
|
return (&x)[i]; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
int main() { |
||||
|
/*tvec2<int> x(2, 6);
|
||||
|
cout << x[0] << endl;*/ |
||||
|
|
||||
|
/*int y = 67305985;
|
||||
|
|
||||
|
bitset<32> set = y; |
||||
|
cout << set << endl; |
||||
|
|
||||
|
unsigned char* p; |
||||
|
|
||||
|
p = (unsigned char*) &y; |
||||
|
|
||||
|
cout << (int) p[3] << endl;*/ |
||||
|
|
||||
|
|
||||
|
float2 x(2.0, 1.2); |
||||
|
|
||||
|
cout << x[0] << endl; |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue