blobt 5 years ago
parent
commit
1e7eebdea6
  1. 9
      CMakeLists.txt
  2. BIN
      image/1.jpg
  3. BIN
      image/bg.png
  4. BIN
      image/bg.psd
  5. BIN
      image/colorKey.bmp
  6. BIN
      image/colorKey.png
  7. BIN
      image/grass.png
  8. BIN
      image/scale.jpg
  9. BIN
      image/test.bmp
  10. 0
      src/raster/CELLMath.hpp
  11. 6
      src/raster/CMakeLists.txt
  12. 0
      src/raster/Image.cc
  13. 0
      src/raster/Image.h
  14. 30
      src/raster/Raster.cc
  15. 2
      src/raster/Raster.h
  16. 0
      src/raster/Rgba.cc
  17. 0
      src/raster/Rgba.h
  18. 0
      src/raster/common.h
  19. 0
      src/raster/draw_filled_rect.cc
  20. 26
      src/raster/draw_image.cc
  21. 0
      src/raster/draw_rect.cc
  22. 0
      src/raster/draw_triangle.cc
  23. 0
      src/raster/drawbezzier.cc
  24. 0
      src/raster/drawline.cc
  25. 0
      src/raster/gtktest.cc
  26. 0
      src/raster/timer.cc
  27. 0
      src/raster/tt.cc
  28. 8
      src/texture/CMakeLists.txt
  29. 44
      src/texture/Image.cc
  30. 78
      src/texture/Image.h
  31. 205
      src/texture/Raster.cc
  32. 132
      src/texture/Raster.h
  33. 76
      src/texture/Rgba.cc
  34. 44
      src/texture/Rgba.h
  35. 99
      src/texture/common.h
  36. 94
      src/texture/texture.cc
  37. 38
      src/texture/tt.cc

9
CMakeLists.txt

@ -16,11 +16,6 @@ link_directories(${GTK2_LIBRARY_DIRS})
list(APPEND FC_DEP_LIBS ${GTK2_LIBRARIES})
list(APPEND FC_DEP_LIBS freeimage)
set(commom_src
Rgba.cc
Raster.cc
Image.cc
)
add_subdirectory(src)
#add_subdirectory(src/raster)
add_subdirectory(src/texture)

BIN
image/1.jpg

After

Width: 64  |  Height: 64  |  Size: 1.3 KiB

BIN
image/bg.png

After

Width: 800  |  Height: 600  |  Size: 443 KiB

BIN
image/bg.psd

BIN
image/colorKey.bmp

BIN
image/colorKey.png

After

Width: 256  |  Height: 210  |  Size: 59 KiB

BIN
image/grass.png

After

Width: 128  |  Height: 128  |  Size: 29 KiB

BIN
image/scale.jpg

After

Width: 100  |  Height: 100  |  Size: 15 KiB

BIN
image/test.bmp

src/CELLMath.hpp → src/raster/CELLMath.hpp

src/CMakeLists.txt → src/raster/CMakeLists.txt

src/Image.cc → src/raster/Image.cc

src/Image.h → src/raster/Image.h

src/Raster.cc → src/raster/Raster.cc

src/Raster.h → src/raster/Raster.h

src/Rgba.cc → src/raster/Rgba.cc

src/Rgba.h → src/raster/Rgba.h

src/common.h → src/raster/common.h

src/draw_filled_rect.cc → src/raster/draw_filled_rect.cc

src/draw_image.cc → src/raster/draw_image.cc

src/draw_rect.cc → src/raster/draw_rect.cc

src/draw_triangle.cc → src/raster/draw_triangle.cc

src/drawbezzier.cc → src/raster/drawbezzier.cc

src/drawline.cc → src/raster/drawline.cc

src/gtktest.cc → src/raster/gtktest.cc

src/timer.cc → src/raster/timer.cc

src/tt.cc → src/raster/tt.cc

8
src/texture/CMakeLists.txt

@ -0,0 +1,8 @@
set(commom_src
Rgba.cc
Raster.cc
Image.cc
)
add_executable(texture texture.cc ${commom_src})
target_link_libraries (texture ${FC_DEP_LIBS})

44
src/texture/Image.cc

@ -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;
return pixelAt(x, y);
//return Rgba(255,0,0);
}

78
src/texture/Image.h

@ -0,0 +1,78 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/*
* File: Image.h
* Author: Blobt
*
* Created on February 10, 2020, 5:55 PM
*/
#ifndef IMAGE_H
#define IMAGE_H
#include "common.h"
#include "Rgba.h"
#include "FreeImage.h"
#include "stdio.h"
class Image {
public:
Image(int width, int height, void* data);
virtual ~Image();
int width() const {
return _width;
}
int height() const {
return _height;
}
Rgba pixelAt(int x, int y) const;
Rgba pixelUv(float u, float v) const;
static Image* loadFromFile(const char* fileName) {
//
FREE_IMAGE_FORMAT fifmt = FreeImage_GetFileType(fileName, 0);
if (fifmt == FIF_UNKNOWN) {
die("FreeImage_GetFileType");
}
//
FIBITMAP* dib = FreeImage_Load(fifmt, fileName, 0);
//
FIBITMAP* temp = dib;
dib = FreeImage_ConvertTo32Bits(dib);
FreeImage_Unload(temp);
BYTE* pixels = (BYTE*) FreeImage_GetBits(dib);
int width = FreeImage_GetWidth(dib);
int height = FreeImage_GetHeight(dib);
//
for (int i = 0; i < width * height * 4; i += 4) {
BYTE temp = pixels[i];
pixels[i] = pixels[i + 2];
pixels[i + 2] = temp;
}
Image* image = new Image(width, height, (void*) pixels);
FreeImage_Unload(dib);
return image;
}
private:
int _width;
int _height;
unsigned int* _pixel;
};
#endif /* IMAGE_H */

205
src/texture/Raster.cc

@ -0,0 +1,205 @@
/*
* 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;
buffer = new Rgba[width * height];
}
Raster::~Raster() {
delete buffer;
}
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;
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;
}
uv = uvLerp(span.uvStart, span.uvEnd, scale);
color = image->pixelUv(uv.x, uv.y);
setPixel(i, span.y, color);
}
}
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;
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;
}
uvE2 = uvLerp(e2.uv2, e2.uv1, scale2);
scale2 += setp2;
//setPixel(x2, y, e2.color2);
int x1;
if (e1.x2 < e1.x1) {
x1 = e1.x2 + xOffset1 * scale1;
} else {
x1 = e1.x2 - xOffset1 * scale1;
}
uvE1 = uvLerp(e1.uv2, e1.uv1, scale1);
scale1 += setp1;
//setPixel(x1, y, e1.color2);
Span span(x1, x2, y, Rgba(255,255,255), Rgba(255,255,255), uvE1, uvE2);
drawSpan(span, 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) {
iMax = i;
}
}
int iShort1 = (iMax + 1) % 3;
int iShort2 = (iMax + 2) % 3;
drawEge(eges[iMax], eges[iShort1], image);
drawEge(eges[iMax], eges[iShort2], 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;
}

132
src/texture/Raster.h

@ -0,0 +1,132 @@
/*
* 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
};
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 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);
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;
};
#endif /* RESTER_H */

76
src/texture/Rgba.cc

@ -0,0 +1,76 @@
/*
* 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 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;
}

44
src/texture/Rgba.h

@ -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: 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 = 0, unsigned char g = 0, unsigned char b = 0, unsigned char a = 255);
Rgba(unsigned int rgba);
friend bool operator==(Rgba &left, Rgba &right);
friend bool 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 */

99
src/texture/common.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 */

94
src/texture/texture.cc

@ -0,0 +1,94 @@
#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);
/**
*
*/
void example() {
Image* image = Image::loadFromFile("/home/blobt/Documents/dev/cpp/3dbase/image/scale.jpg");
Raster::Vertex ver1 = {
int2(10, 10), float2(0.0f, 0.0f), Rgba(),
int2(10, 110), float2(0.0f, 1.0f), Rgba(),
int2(110, 10), float2(1.0f, 0.0f), Rgba()
};
raster.drawTriangle(ver1, image);
Raster::Vertex ver2 = {
int2(10, 110), float2(0.0f, 1.0f), Rgba(),
int2(110, 110), float2(1.0f, 1.0f), Rgba(),
int2(110, 10), float2(1.0f, 0.0f), Rgba()
};
raster.drawTriangle(ver2, image);
delete image;
}
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;
}

38
src/texture/tt.cc

@ -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;
}
Loading…
Cancel
Save