Browse Source

matrix start

master
blobt 5 years ago
parent
commit
47459ff93f
  1. 7
      CMakeLists.txt
  2. BIN
      example/lesson308-二维操作矩阵/1.ppt
  3. 5978
      example/lesson308-二维操作矩阵/CELLMath.hpp
  4. 53
      example/lesson308-二维操作矩阵/CELLTimestamp.hpp
  5. 80
      example/lesson308-二维操作矩阵/Image.hpp
  6. 77
      example/lesson308-二维操作矩阵/Raster.cpp
  7. 418
      example/lesson308-二维操作矩阵/Raster.h
  8. 223
      example/lesson308-二维操作矩阵/lesson308-二维操作矩阵.vcproj
  9. 201
      example/lesson308-二维操作矩阵/lesson308.cpp
  10. 5978
      example/lesson309-矩阵平移/CELLMath.hpp
  11. 53
      example/lesson309-矩阵平移/CELLTimestamp.hpp
  12. 80
      example/lesson309-矩阵平移/Image.hpp
  13. 77
      example/lesson309-矩阵平移/Raster.cpp
  14. 418
      example/lesson309-矩阵平移/Raster.h
  15. 219
      example/lesson309-矩阵平移/lesson309-矩阵平移.vcproj
  16. 213
      example/lesson309-矩阵平移/lesson309.cpp
  17. 5978
      example/lesson310-矩阵缩放/CELLMath.hpp
  18. 53
      example/lesson310-矩阵缩放/CELLTimestamp.hpp
  19. 80
      example/lesson310-矩阵缩放/Image.hpp
  20. 77
      example/lesson310-矩阵缩放/Raster.cpp
  21. 418
      example/lesson310-矩阵缩放/Raster.h
  22. 223
      example/lesson310-矩阵缩放/lesson310-矩阵缩放.vcproj
  23. 224
      example/lesson310-矩阵缩放/lesson310.cpp
  24. 5978
      example/lesson311-矩阵旋转/CELLMath.hpp
  25. 53
      example/lesson311-矩阵旋转/CELLTimestamp.hpp
  26. 80
      example/lesson311-矩阵旋转/Image.hpp
  27. 77
      example/lesson311-矩阵旋转/Raster.cpp
  28. 418
      example/lesson311-矩阵旋转/Raster.h
  29. 223
      example/lesson311-矩阵旋转/lesson311-矩阵旋转.vcproj
  30. 227
      example/lesson311-矩阵旋转/lesson311.cpp
  31. 5978
      example/lesson312-矩阵复合操作/CELLMath.hpp
  32. 53
      example/lesson312-矩阵复合操作/CELLTimestamp.hpp
  33. 80
      example/lesson312-矩阵复合操作/Image.hpp
  34. 79
      example/lesson312-矩阵复合操作/Raster.cpp
  35. 440
      example/lesson312-矩阵复合操作/Raster.h
  36. 223
      example/lesson312-矩阵复合操作/lesson312-矩阵复合操作.vcproj
  37. 224
      example/lesson312-矩阵复合操作/lesson312.cpp
  38. BIN
      example/lesson400-三维理论/01.ppt
  39. 203
      example/lesson400-三维理论/lesson400-3D理论.vcproj
  40. BIN
      example/lesson401-向量-矩阵/02.ppt
  41. 203
      example/lesson401-向量-矩阵/lesson401-向量-矩阵.vcproj
  42. BIN
      example/lesson402-向量-矩阵/02.ppt
  43. 203
      example/lesson402-向量-矩阵/lesson402-向量-矩阵.vcproj
  44. 5978
      example/lesson403-实现3D的框架/CELLMath.hpp
  45. 53
      example/lesson403-实现3D的框架/CELLTimestamp.hpp
  46. 80
      example/lesson403-实现3D的框架/Image.hpp
  47. 79
      example/lesson403-实现3D的框架/Raster.cpp
  48. 441
      example/lesson403-实现3D的框架/Raster.h
  49. 223
      example/lesson403-实现3D的框架/lesson403-实现3D的框架.vcproj
  50. 186
      example/lesson403-实现3D的框架/lesson403.cpp
  51. 5978
      example/lesson404-固定渲染管线实现/CELLMath.hpp
  52. 53
      example/lesson404-固定渲染管线实现/CELLTimestamp.hpp
  53. 80
      example/lesson404-固定渲染管线实现/Image.hpp
  54. 257
      example/lesson404-固定渲染管线实现/Raster.cpp
  55. 359
      example/lesson404-固定渲染管线实现/Raster.h
  56. 186
      example/lesson404-固定渲染管线实现/lesson403.cpp
  57. 223
      example/lesson404-固定渲染管线实现/lesson404-固定渲染管线实现.vcproj
  58. 5978
      example/lesson405-投影和观察矩阵/CELLMath.hpp
  59. 53
      example/lesson405-投影和观察矩阵/CELLTimestamp.hpp
  60. 80
      example/lesson405-投影和观察矩阵/Image.hpp
  61. 257
      example/lesson405-投影和观察矩阵/Raster.cpp
  62. 363
      example/lesson405-投影和观察矩阵/Raster.h
  63. 223
      example/lesson405-投影和观察矩阵/lesson405-投影和观察矩阵.vcproj
  64. 186
      example/lesson405-投影和观察矩阵/lesson405.cpp
  65. BIN
      example/lesson406-固定渲染管线实现-裁减/04.ppt
  66. 5978
      example/lesson406-固定渲染管线实现-裁减/CELLMath.hpp
  67. 53
      example/lesson406-固定渲染管线实现-裁减/CELLTimestamp.hpp
  68. 80
      example/lesson406-固定渲染管线实现-裁减/Image.hpp
  69. 276
      example/lesson406-固定渲染管线实现-裁减/Raster.cpp
  70. 361
      example/lesson406-固定渲染管线实现-裁减/Raster.h
  71. 223
      example/lesson406-固定渲染管线实现-裁减/lesson406-固定渲染管线实现-裁减.vcproj
  72. 186
      example/lesson406-固定渲染管线实现-裁减/lesson406.cpp
  73. 5988
      example/lesson407-矩阵变换 - 副本/CELLMath.hpp
  74. 53
      example/lesson407-矩阵变换 - 副本/CELLTimestamp.hpp
  75. 80
      example/lesson407-矩阵变换 - 副本/Image.hpp
  76. 280
      example/lesson407-矩阵变换 - 副本/Raster.cpp
  77. 373
      example/lesson407-矩阵变换 - 副本/Raster.h
  78. 222
      example/lesson407-矩阵变换 - 副本/lesson407-矩阵变换.vcproj
  79. 195
      example/lesson407-矩阵变换 - 副本/lesson407.cpp
  80. 5988
      example/lesson407-矩阵变换-y控制完成/CELLMath.hpp
  81. 53
      example/lesson407-矩阵变换-y控制完成/CELLTimestamp.hpp
  82. 80
      example/lesson407-矩阵变换-y控制完成/Image.hpp
  83. 280
      example/lesson407-矩阵变换-y控制完成/Raster.cpp
  84. 373
      example/lesson407-矩阵变换-y控制完成/Raster.h
  85. 222
      example/lesson407-矩阵变换-y控制完成/lesson407-矩阵变换.vcproj
  86. 195
      example/lesson407-矩阵变换-y控制完成/lesson407.cpp
  87. 5988
      example/lesson407-矩阵变换/CELLMath.hpp
  88. 53
      example/lesson407-矩阵变换/CELLTimestamp.hpp
  89. 80
      example/lesson407-矩阵变换/Image.hpp
  90. 280
      example/lesson407-矩阵变换/Raster.cpp
  91. 378
      example/lesson407-矩阵变换/Raster.h
  92. 222
      example/lesson407-矩阵变换/lesson407-矩阵变换.vcproj
  93. 195
      example/lesson407-矩阵变换/lesson407.cpp
  94. 5978
      example/lesson407-绘制第一个3D三角形/CELLMath.hpp
  95. 53
      example/lesson407-绘制第一个3D三角形/CELLTimestamp.hpp
  96. 80
      example/lesson407-绘制第一个3D三角形/Image.hpp
  97. 278
      example/lesson407-绘制第一个3D三角形/Raster.cpp
  98. 361
      example/lesson407-绘制第一个3D三角形/Raster.h
  99. 223
      example/lesson407-绘制第一个3D三角形/lesson407-固定渲染管线实现-裁减.vcproj
  100. 183
      example/lesson407-绘制第一个3D三角形/lesson407.cpp

7
CMakeLists.txt

@ -16,7 +16,8 @@ link_directories(${GTK2_LIBRARY_DIRS})
list(APPEND FC_DEP_LIBS ${GTK2_LIBRARIES})
list(APPEND FC_DEP_LIBS freeimage)
#add_subdirectory(src/raster)
#add_subdirectory(src/texture)
add_subdirectory(src/statemachine)
#add_subdirectory(src/1raster)
#add_subdirectory(src/2texture)
#add_subdirectory(src/3statemachine)
add_subdirectory(src/4matrix)

BIN
example/lesson308-二维操作矩阵/1.ppt

5978
example/lesson308-二维操作矩阵/CELLMath.hpp
File diff suppressed because it is too large
View File

53
example/lesson308-二维操作矩阵/CELLTimestamp.hpp

@ -0,0 +1,53 @@
#pragma once
#include <windows.h>
namespace CELL
{
class CELLTimestamp
{
public:
CELLTimestamp()
{
QueryPerformanceFrequency(&_frequency);
QueryPerformanceCounter(&_startCount);
}
~CELLTimestamp()
{}
void update()
{
QueryPerformanceCounter(&_startCount);
}
/**
* »ñÈ¡µ±Ç°Ãë
*/
double getElapsedSecond()
{
return getElapsedTimeInMicroSec() * 0.000001;
}
/**
* »ñÈ¡ºÁÃë
*/
double getElapsedTimeInMilliSec()
{
return this->getElapsedTimeInMicroSec() * 0.001;
}
/**
* »ñȡ΢Ãî
*/
double getElapsedTimeInMicroSec()
{
LARGE_INTEGER endCount;
QueryPerformanceCounter(&endCount);
double startTimeInMicroSec = _startCount.QuadPart * (1000000.0 / _frequency.QuadPart);
double endTimeInMicroSec = endCount.QuadPart * (1000000.0 / _frequency.QuadPart);
return endTimeInMicroSec - startTimeInMicroSec;
}
protected:
LARGE_INTEGER _frequency;
LARGE_INTEGER _startCount;
};
}

80
example/lesson308-二维操作矩阵/Image.hpp

@ -0,0 +1,80 @@
#pragma once
namespace CELL
{
class Image
{
protected:
int _width;
int _height;
uint* _pixel;
int _wrapType;
public:
Image(int w,int h,void* data)
{
_wrapType = 0;
if (w == 0 || h == 0 || data== 0)
{
_width = 0;
_height = 0;
_pixel = 0;
}
else
{
_width = w;
_height = h;
_pixel = new uint[w * h];
memcpy(_pixel,data,w * h * sizeof(uint));
}
}
~Image()
{
delete []_pixel;
}
void setWrapType(int type)
{
_wrapType = type;
}
int width() const
{
return _width;
}
int height() const
{
return _height;
}
Rgba pixelAt(int x,int y) const
{
return Rgba(_pixel[y * _width + x]);
}
Rgba pixelUV(float u,float v)
{
float x = u * _width;
float y = v * _height;
if (_wrapType == 0)
{
return pixelAt((unsigned)(x)%_width,(unsigned)(y)%_height);
}
else
{
if (x >= _width)
{
x = _width - 1;
}
if (y >= _height)
{
y = _height - 1;
}
return pixelAt(x,y);
}
}
public:
static Image* loadFromFile(const char*);
};
}

77
example/lesson308-二维操作矩阵/Raster.cpp

@ -0,0 +1,77 @@
#include "Raster.h"
#include "FreeImage.h"
namespace CELL
{
Image* Image::loadFromFile(const char* fileName)
{
//1 获取图片格式
FREE_IMAGE_FORMAT fifmt = FreeImage_GetFileType(fileName, 0);
if (fifmt == FIF_UNKNOWN)
{
return 0;
}
//2 加载图片
FIBITMAP *dib = FreeImage_Load(fifmt, fileName,0);
FREE_IMAGE_COLOR_TYPE type = FreeImage_GetColorType(dib);
//! 获取数据指针
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);
int pitch = width*4;
BYTE* row = new BYTE[width*4];
for(int j = 0; j < height / 2; j++)
{
memcpy(row,pixels + j * pitch,pitch );
memcpy(pixels + j * pitch,pixels + (height - j - 1) * pitch,pitch );
memcpy(pixels + (height - j - 1) * pitch,row,pitch );
}
delete []row;
Image* image = new Image(width,height,pixels);
FreeImage_Unload(dib);
return image;
}
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;
}
Raster::~Raster( void )
{
}
void Raster::clear()
{
memset(_buffer,0,_width * _height * sizeof(Rgba));
}
}

418
example/lesson308-二维操作矩阵/Raster.h

@ -0,0 +1,418 @@
#pragma once
#include "CELLMath.hpp"
#include "Image.hpp"
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;
}
}
};
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;
}
}
};
class Raster
{
public:
uint* _buffer;
int _width;
int _height;
Rgba _color;
Image* _texture;
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)
{
int left = tmax<int>(startX,0);
int top = tmax<int>(startY,0);
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);
}
}
}
public:
void vertexPointer(int size,DATETYPE type,int stride,const void* data)
{
_poitionPointer._size = size;
_poitionPointer._type = type;
_poitionPointer._stride = stride;
_poitionPointer._data = data;
}
void colorPointer(int size,DATETYPE type,int stride,const void* data)
{
_colorPointer._size = size;
_colorPointer._type = type;
_colorPointer._stride = stride;
_colorPointer._data = data;
}
void textureCoordPointer(int size,DATETYPE type,int stride,const void* data)
{
_uvPointer._size = size;
_uvPointer._type = type;
_uvPointer._stride = stride;
_uvPointer._data = data;
}
void bindTexture(Image* image)
{
_texture = image;
}
void drawArrays(DRAWMODE pri,int start,int count)
{
if (_poitionPointer._data == 0)
{
return;
}
DateElementDes colorPointerdesc = _colorPointer;
DateElementDes uvPointerdesc = _uvPointer;
if (colorPointerdesc._data == 0)
{
colorPointerdesc = _defaultColorPointer;
}
if (uvPointerdesc._data == 0)
{
uvPointerdesc = _defaultUVPointer;
}
char* posData = (char*)_poitionPointer._data;
char* cData = (char*)colorPointerdesc._data;
char* uvData = (char*)uvPointerdesc._data;
for(int i = start ;i < start + count; i += 3)
{
float* fData = (float*)posData;
int2 p0 (fData[0],fData[1]);
posData += _poitionPointer._stride;
fData = (float*)(posData);
int2 p1 (fData[0],fData[1]);
posData += _poitionPointer._stride;
fData = (float*)(posData);
int2 p2 (fData[0],fData[1]);
posData += _poitionPointer._stride;
Rgba* pColor = (Rgba*)cData;
Rgba c0 (*pColor);
cData += _colorPointer._stride;
Rgba c1 (*pColor);
cData += _colorPointer._stride;
Rgba c2 (*pColor);
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;
}
}
}
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,pixel);
}
}
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;
}
};
}

223
example/lesson308-二维操作矩阵/lesson308-二维操作矩阵.vcproj

@ -0,0 +1,223 @@
<?xml version="1.0" encoding="gb2312"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="lesson308-二维操作矩阵"
ProjectGUID="{4880A4A6-8888-4A22-910F-F65223B5C308}"
RootNamespace="lesson308-二维操作矩阵"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
IntermediateDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../dependencies"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="FreeImage.lib"
OutputFile="../../bin/$(ConfigurationName)/$(ProjectName).exe"
LinkIncremental="2"
AdditionalLibraryDirectories="../../dependencies"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
IntermediateDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="../../dependencies"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
EnableEnhancedInstructionSet="0"
FloatingPointModel="0"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="FreeImage.lib"
OutputFile="../../bin/$(ConfigurationName)/$(ProjectName).exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../dependencies"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="源文件"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\lesson308.cpp"
>
</File>
</Filter>
<Filter
Name="头文件"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\CELLMath.hpp"
>
</File>
<File
RelativePath=".\Image.hpp"
>
</File>
<File
RelativePath=".\Raster.cpp"
>
</File>
<File
RelativePath=".\Raster.h"
>
</File>
</Filter>
<Filter
Name="资源文件"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
<File
RelativePath=".\1.ppt"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

201
example/lesson308-二维操作矩阵/lesson308.cpp

@ -0,0 +1,201 @@
#include <windows.h>
#include <tchar.h>
#include "Raster.h"
#include "CELLTimestamp.hpp"
LRESULT CALLBACK windowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_SIZE:
break;
case WM_CLOSE:
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
break;
}
return DefWindowProc( hWnd, msg, wParam, lParam );
}
void getResourcePath(HINSTANCE hInstance,char pPath[1024])
{
char szPathName[1024];
char szDriver[64];
char szPath[1024];
GetModuleFileNameA(hInstance,szPathName,sizeof(szPathName));
_splitpath( szPathName, szDriver, szPath, 0, 0 );
sprintf(pPath,"%s%s",szDriver,szPath);
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
// 1 ×¢²á´°¿ÚÀà
::WNDCLASSEXA winClass;
winClass.lpszClassName = "Raster";
winClass.cbSize = sizeof(::WNDCLASSEX);
winClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;
winClass.lpfnWndProc = windowProc;
winClass.hInstance = hInstance;
winClass.hIcon = 0;
winClass.hIconSm = 0;
winClass.hCursor = LoadCursor(NULL, IDC_ARROW);
winClass.hbrBackground = (HBRUSH)(BLACK_BRUSH);
winClass.lpszMenuName = NULL;
winClass.cbClsExtra = 0;
winClass.cbWndExtra = 0;
RegisterClassExA(&winClass);
// 2 ´´½¨´°¿Ú
HWND hWnd = CreateWindowExA(
NULL,
"Raster",
"Raster",
WS_OVERLAPPEDWINDOW,
0,
0,
800,
600,
0,
0,
hInstance,
0
);
UpdateWindow( hWnd );
ShowWindow(hWnd,SW_SHOW);
RECT rt = {0};
GetClientRect(hWnd,&rt);
int width = rt.right - rt.left;
int height = rt.bottom - rt.top;
void* buffer = 0;
HDC hDC = GetDC(hWnd);
HDC hMem = ::CreateCompatibleDC(hDC);
BITMAPINFO bmpInfor;
bmpInfor.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfor.bmiHeader.biWidth = width;
bmpInfor.bmiHeader.biHeight = -height;
bmpInfor.bmiHeader.biPlanes = 1;
bmpInfor.bmiHeader.biBitCount = 32;
bmpInfor.bmiHeader.biCompression = BI_RGB;
bmpInfor.bmiHeader.biSizeImage = 0;
bmpInfor.bmiHeader.biXPelsPerMeter = 0;
bmpInfor.bmiHeader.biYPelsPerMeter = 0;
bmpInfor.bmiHeader.biClrUsed = 0;
bmpInfor.bmiHeader.biClrImportant = 0;
HBITMAP hBmp = CreateDIBSection(hDC,&bmpInfor,DIB_RGB_COLORS,(void**)&buffer,0,0);
SelectObject(hMem,hBmp);
char szPath[1024];
getResourcePath(0,szPath);
char szImage[1024];
sprintf(szImage,"%s/image/bg.png",szPath);
CELL::Image* image = CELL::Image::loadFromFile(szImage);
sprintf(szImage,"%s/image/scale.jpg",szPath);
CELL::Image* image1 = CELL::Image::loadFromFile(szImage);
CELL::Raster raster(width,height,buffer);
struct Vertex
{
float x,y;
float u,v;
CELL::Rgba color;
};
MSG msg = {0};
while(true)
{
if (msg.message == WM_DESTROY
||msg.message == WM_CLOSE
||msg.message == WM_QUIT)
{
break;
}
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
raster.clear();
CELL::int2 pt[3] =
{
CELL::int2(100,10),
CELL::int2(10,100),
CELL::int2(200,100),
};
CELL::Rgba color1(255,0,0);
CELL::Rgba color2(0,255,0);
CELL::Rgba color3(0,0,255);
CELL::CELLTimestamp tms;
tms.update();
double mis = tms.getElapsedTimeInMicroSec();
char szBuf[128];
sprintf(szBuf,"%f ",mis);
int i = 00;
memcpy(buffer,raster._buffer,raster._width * raster._height * sizeof(CELL::Rgba));
raster.drawImage(0,0,image);
Vertex vertexs[] =
{
{-10, -10, 0.0f, 0.0f, CELL::Rgba(255,255,255,255)},
{210, 210, 2.0f, 2.0f, CELL::Rgba(255,255,255,255)},
{210, -10, 2.0f, 0.0f, CELL::Rgba(255,255,255,255)},
{-10, -10, 0.0f, 0.0f, CELL::Rgba(255,255,255,255)},
{210, 210, 2.0f, 2.0f, CELL::Rgba(255,255,255,255)},
{-10, 210, 0.0f, 2.0f, CELL::Rgba(255,255,255,255)},
};
image1->setWrapType(1);
raster.bindTexture(image1);
raster.vertexPointer(2,CELL::DT_FLOAT, sizeof(Vertex),&vertexs[0].x);
raster.textureCoordPointer(2,CELL::DT_FLOAT,sizeof(Vertex),&vertexs[0].u);
//raster.colorPointer(4,CELL::DT_BYTE, sizeof(Vertex),&vertexs[0].color);
raster.drawArrays(CELL::DM_TRIANGES,0,6);
//raster.drawTriangle(vertex,image1);
//raster.drawTriangle(vertex1,image1);
//TextOut(hMem,10,10,szBuf,strlen(szBuf));
BitBlt(hDC,0,0,width,height,hMem,0,0,SRCCOPY);
}
delete image;
delete image1;
return 0;
}

5978
example/lesson309-矩阵平移/CELLMath.hpp
File diff suppressed because it is too large
View File

53
example/lesson309-矩阵平移/CELLTimestamp.hpp

@ -0,0 +1,53 @@
#pragma once
#include <windows.h>
namespace CELL
{
class CELLTimestamp
{
public:
CELLTimestamp()
{
QueryPerformanceFrequency(&_frequency);
QueryPerformanceCounter(&_startCount);
}
~CELLTimestamp()
{}
void update()
{
QueryPerformanceCounter(&_startCount);
}
/**
* »ñÈ¡µ±Ç°Ãë
*/
double getElapsedSecond()
{
return getElapsedTimeInMicroSec() * 0.000001;
}
/**
* »ñÈ¡ºÁÃë
*/
double getElapsedTimeInMilliSec()
{
return this->getElapsedTimeInMicroSec() * 0.001;
}
/**
* »ñȡ΢Ãî
*/
double getElapsedTimeInMicroSec()
{
LARGE_INTEGER endCount;
QueryPerformanceCounter(&endCount);
double startTimeInMicroSec = _startCount.QuadPart * (1000000.0 / _frequency.QuadPart);
double endTimeInMicroSec = endCount.QuadPart * (1000000.0 / _frequency.QuadPart);
return endTimeInMicroSec - startTimeInMicroSec;
}
protected:
LARGE_INTEGER _frequency;
LARGE_INTEGER _startCount;
};
}

80
example/lesson309-矩阵平移/Image.hpp

@ -0,0 +1,80 @@
#pragma once
namespace CELL
{
class Image
{
protected:
int _width;
int _height;
uint* _pixel;
int _wrapType;
public:
Image(int w,int h,void* data)
{
_wrapType = 0;
if (w == 0 || h == 0 || data== 0)
{
_width = 0;
_height = 0;
_pixel = 0;
}
else
{
_width = w;
_height = h;
_pixel = new uint[w * h];
memcpy(_pixel,data,w * h * sizeof(uint));
}
}
~Image()
{
delete []_pixel;
}
void setWrapType(int type)
{
_wrapType = type;
}
int width() const
{
return _width;
}
int height() const
{
return _height;
}
Rgba pixelAt(int x,int y) const
{
return Rgba(_pixel[y * _width + x]);
}
Rgba pixelUV(float u,float v)
{
float x = u * _width;
float y = v * _height;
if (_wrapType == 0)
{
return pixelAt((unsigned)(x)%_width,(unsigned)(y)%_height);
}
else
{
if (x >= _width)
{
x = _width - 1;
}
if (y >= _height)
{
y = _height - 1;
}
return pixelAt(x,y);
}
}
public:
static Image* loadFromFile(const char*);
};
}

77
example/lesson309-矩阵平移/Raster.cpp

@ -0,0 +1,77 @@
#include "Raster.h"
#include "FreeImage.h"
namespace CELL
{
Image* Image::loadFromFile(const char* fileName)
{
//1 获取图片格式
FREE_IMAGE_FORMAT fifmt = FreeImage_GetFileType(fileName, 0);
if (fifmt == FIF_UNKNOWN)
{
return 0;
}
//2 加载图片
FIBITMAP *dib = FreeImage_Load(fifmt, fileName,0);
FREE_IMAGE_COLOR_TYPE type = FreeImage_GetColorType(dib);
//! 获取数据指针
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);
int pitch = width*4;
BYTE* row = new BYTE[width*4];
for(int j = 0; j < height / 2; j++)
{
memcpy(row,pixels + j * pitch,pitch );
memcpy(pixels + j * pitch,pixels + (height - j - 1) * pitch,pitch );
memcpy(pixels + (height - j - 1) * pitch,row,pitch );
}
delete []row;
Image* image = new Image(width,height,pixels);
FreeImage_Unload(dib);
return image;
}
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;
}
Raster::~Raster( void )
{
}
void Raster::clear()
{
memset(_buffer,0,_width * _height * sizeof(Rgba));
}
}

418
example/lesson309-矩阵平移/Raster.h

@ -0,0 +1,418 @@
#pragma once
#include "CELLMath.hpp"
#include "Image.hpp"
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;
}
}
};
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;
}
}
};
class Raster
{
public:
uint* _buffer;
int _width;
int _height;
Rgba _color;
Image* _texture;
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)
{
int left = tmax<int>(startX,0);
int top = tmax<int>(startY,0);
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);
}
}
}
public:
void vertexPointer(int size,DATETYPE type,int stride,const void* data)
{
_poitionPointer._size = size;
_poitionPointer._type = type;
_poitionPointer._stride = stride;
_poitionPointer._data = data;
}
void colorPointer(int size,DATETYPE type,int stride,const void* data)
{
_colorPointer._size = size;
_colorPointer._type = type;
_colorPointer._stride = stride;
_colorPointer._data = data;
}
void textureCoordPointer(int size,DATETYPE type,int stride,const void* data)
{
_uvPointer._size = size;
_uvPointer._type = type;
_uvPointer._stride = stride;
_uvPointer._data = data;
}
void bindTexture(Image* image)
{
_texture = image;
}
void drawArrays(DRAWMODE pri,int start,int count)
{
if (_poitionPointer._data == 0)
{
return;
}
DateElementDes colorPointerdesc = _colorPointer;
DateElementDes uvPointerdesc = _uvPointer;
if (colorPointerdesc._data == 0)
{
colorPointerdesc = _defaultColorPointer;
}
if (uvPointerdesc._data == 0)
{
uvPointerdesc = _defaultUVPointer;
}
char* posData = (char*)_poitionPointer._data;
char* cData = (char*)colorPointerdesc._data;
char* uvData = (char*)uvPointerdesc._data;
for(int i = start ;i < start + count; i += 3)
{
float* fData = (float*)posData;
int2 p0 (fData[0],fData[1]);
posData += _poitionPointer._stride;
fData = (float*)(posData);
int2 p1 (fData[0],fData[1]);
posData += _poitionPointer._stride;
fData = (float*)(posData);
int2 p2 (fData[0],fData[1]);
posData += _poitionPointer._stride;
Rgba* pColor = (Rgba*)cData;
Rgba c0 (*pColor);
cData += _colorPointer._stride;
Rgba c1 (*pColor);
cData += _colorPointer._stride;
Rgba c2 (*pColor);
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;
}
}
}
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,pixel);
}
}
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;
}
};
}

219
example/lesson309-矩阵平移/lesson309-矩阵平移.vcproj

@ -0,0 +1,219 @@
<?xml version="1.0" encoding="gb2312"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="lesson309-矩阵应用-平移"
ProjectGUID="{4880A4A6-8888-4A22-910F-F65223B5C309}"
RootNamespace="lesson309-矩阵平移"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
IntermediateDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../dependencies"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="FreeImage.lib"
OutputFile="../../bin/$(ConfigurationName)/$(ProjectName).exe"
LinkIncremental="2"
AdditionalLibraryDirectories="../../dependencies"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
IntermediateDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="../../dependencies"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
EnableEnhancedInstructionSet="0"
FloatingPointModel="0"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="FreeImage.lib"
OutputFile="../../bin/$(ConfigurationName)/$(ProjectName).exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../dependencies"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="源文件"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\lesson309.cpp"
>
</File>
</Filter>
<Filter
Name="头文件"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\CELLMath.hpp"
>
</File>
<File
RelativePath=".\Image.hpp"
>
</File>
<File
RelativePath=".\Raster.cpp"
>
</File>
<File
RelativePath=".\Raster.h"
>
</File>
</Filter>
<Filter
Name="资源文件"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

213
example/lesson309-矩阵平移/lesson309.cpp

@ -0,0 +1,213 @@
#include <windows.h>
#include <tchar.h>
#include "Raster.h"
#include "CELLTimestamp.hpp"
LRESULT CALLBACK windowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_SIZE:
break;
case WM_CLOSE:
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
break;
}
return DefWindowProc( hWnd, msg, wParam, lParam );
}
void getResourcePath(HINSTANCE hInstance,char pPath[1024])
{
char szPathName[1024];
char szDriver[64];
char szPath[1024];
GetModuleFileNameA(hInstance,szPathName,sizeof(szPathName));
_splitpath( szPathName, szDriver, szPath, 0, 0 );
sprintf(pPath,"%s%s",szDriver,szPath);
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
// 1 ×¢²á´°¿ÚÀà
::WNDCLASSEXA winClass;
winClass.lpszClassName = "Raster";
winClass.cbSize = sizeof(::WNDCLASSEX);
winClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;
winClass.lpfnWndProc = windowProc;
winClass.hInstance = hInstance;
winClass.hIcon = 0;
winClass.hIconSm = 0;
winClass.hCursor = LoadCursor(NULL, IDC_ARROW);
winClass.hbrBackground = (HBRUSH)(BLACK_BRUSH);
winClass.lpszMenuName = NULL;
winClass.cbClsExtra = 0;
winClass.cbWndExtra = 0;
RegisterClassExA(&winClass);
// 2 ´´½¨´°¿Ú
HWND hWnd = CreateWindowExA(
NULL,
"Raster",
"Raster",
WS_OVERLAPPEDWINDOW,
0,
0,
800,
600,
0,
0,
hInstance,
0
);
UpdateWindow( hWnd );
ShowWindow(hWnd,SW_SHOW);
RECT rt = {0};
GetClientRect(hWnd,&rt);
int width = rt.right - rt.left;
int height = rt.bottom - rt.top;
void* buffer = 0;
HDC hDC = GetDC(hWnd);
HDC hMem = ::CreateCompatibleDC(hDC);
BITMAPINFO bmpInfor;
bmpInfor.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfor.bmiHeader.biWidth = width;
bmpInfor.bmiHeader.biHeight = -height;
bmpInfor.bmiHeader.biPlanes = 1;
bmpInfor.bmiHeader.biBitCount = 32;
bmpInfor.bmiHeader.biCompression = BI_RGB;
bmpInfor.bmiHeader.biSizeImage = 0;
bmpInfor.bmiHeader.biXPelsPerMeter = 0;
bmpInfor.bmiHeader.biYPelsPerMeter = 0;
bmpInfor.bmiHeader.biClrUsed = 0;
bmpInfor.bmiHeader.biClrImportant = 0;
HBITMAP hBmp = CreateDIBSection(hDC,&bmpInfor,DIB_RGB_COLORS,(void**)&buffer,0,0);
SelectObject(hMem,hBmp);
char szPath[1024];
getResourcePath(0,szPath);
char szImage[1024];
sprintf(szImage,"%s/image/bg.png",szPath);
CELL::Image* image = CELL::Image::loadFromFile(szImage);
sprintf(szImage,"%s/image/scale.jpg",szPath);
CELL::Image* image1 = CELL::Image::loadFromFile(szImage);
CELL::Raster raster(width,height,buffer);
struct Vertex
{
float x,y;
float u,v;
CELL::Rgba color;
};
MSG msg = {0};
while(true)
{
if (msg.message == WM_DESTROY
||msg.message == WM_CLOSE
||msg.message == WM_QUIT)
{
break;
}
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
raster.clear();
CELL::int2 pt[3] =
{
CELL::int2(100,10),
CELL::int2(10,100),
CELL::int2(200,100),
};
CELL::Rgba color1(255,0,0);
CELL::Rgba color2(0,255,0);
CELL::Rgba color3(0,0,255);
CELL::CELLTimestamp tms;
tms.update();
double mis = tms.getElapsedTimeInMicroSec();
char szBuf[128];
sprintf(szBuf,"%f ",mis);
int i = 00;
memcpy(buffer,raster._buffer,raster._width * raster._height * sizeof(CELL::Rgba));
raster.drawImage(0,0,image);
Vertex vertexs[] =
{
{-10, -10, 0.0f, 0.0f, CELL::Rgba(255,255,255,255)},
{210, 210, 2.0f, 2.0f, CELL::Rgba(255,255,255,255)},
{210, -10, 2.0f, 0.0f, CELL::Rgba(255,255,255,255)},
{-10, -10, 0.0f, 0.0f, CELL::Rgba(255,255,255,255)},
{210, 210, 2.0f, 2.0f, CELL::Rgba(255,255,255,255)},
{-10, 210, 0.0f, 2.0f, CELL::Rgba(255,255,255,255)},
};
static float trans = 0;
CELL::matrix3 mat;
mat.translate(trans,0);
trans += 1;
for (int i = 0 ;i < 6 ; ++ i)
{
CELL::float3 pos(vertexs[i].x,vertexs[i].y,1);
pos = mat * pos;
vertexs[i].x = pos.x;
vertexs[i].y = pos.y;
}
image1->setWrapType(1);
raster.bindTexture(image1);
raster.vertexPointer(2,CELL::DT_FLOAT, sizeof(Vertex),&vertexs[0].x);
raster.textureCoordPointer(2,CELL::DT_FLOAT,sizeof(Vertex),&vertexs[0].u);
//raster.colorPointer(4,CELL::DT_BYTE, sizeof(Vertex),&vertexs[0].color);
raster.drawArrays(CELL::DM_TRIANGES,0,6);
//raster.drawTriangle(vertex,image1);
//raster.drawTriangle(vertex1,image1);
//TextOut(hMem,10,10,szBuf,strlen(szBuf));
BitBlt(hDC,0,0,width,height,hMem,0,0,SRCCOPY);
}
delete image;
delete image1;
return 0;
}

5978
example/lesson310-矩阵缩放/CELLMath.hpp
File diff suppressed because it is too large
View File

53
example/lesson310-矩阵缩放/CELLTimestamp.hpp

@ -0,0 +1,53 @@
#pragma once
#include <windows.h>
namespace CELL
{
class CELLTimestamp
{
public:
CELLTimestamp()
{
QueryPerformanceFrequency(&_frequency);
QueryPerformanceCounter(&_startCount);
}
~CELLTimestamp()
{}
void update()
{
QueryPerformanceCounter(&_startCount);
}
/**
* »ñÈ¡µ±Ç°Ãë
*/
double getElapsedSecond()
{
return getElapsedTimeInMicroSec() * 0.000001;
}
/**
* »ñÈ¡ºÁÃë
*/
double getElapsedTimeInMilliSec()
{
return this->getElapsedTimeInMicroSec() * 0.001;
}
/**
* »ñȡ΢Ãî
*/
double getElapsedTimeInMicroSec()
{
LARGE_INTEGER endCount;
QueryPerformanceCounter(&endCount);
double startTimeInMicroSec = _startCount.QuadPart * (1000000.0 / _frequency.QuadPart);
double endTimeInMicroSec = endCount.QuadPart * (1000000.0 / _frequency.QuadPart);
return endTimeInMicroSec - startTimeInMicroSec;
}
protected:
LARGE_INTEGER _frequency;
LARGE_INTEGER _startCount;
};
}

80
example/lesson310-矩阵缩放/Image.hpp

@ -0,0 +1,80 @@
#pragma once
namespace CELL
{
class Image
{
protected:
int _width;
int _height;
uint* _pixel;
int _wrapType;
public:
Image(int w,int h,void* data)
{
_wrapType = 0;
if (w == 0 || h == 0 || data== 0)
{
_width = 0;
_height = 0;
_pixel = 0;
}
else
{
_width = w;
_height = h;
_pixel = new uint[w * h];
memcpy(_pixel,data,w * h * sizeof(uint));
}
}
~Image()
{
delete []_pixel;
}
void setWrapType(int type)
{
_wrapType = type;
}
int width() const
{
return _width;
}
int height() const
{
return _height;
}
Rgba pixelAt(int x,int y) const
{
return Rgba(_pixel[y * _width + x]);
}
Rgba pixelUV(float u,float v)
{
float x = u * _width;
float y = v * _height;
if (_wrapType == 0)
{
return pixelAt((unsigned)(x)%_width,(unsigned)(y)%_height);
}
else
{
if (x >= _width)
{
x = _width - 1;
}
if (y >= _height)
{
y = _height - 1;
}
return pixelAt(x,y);
}
}
public:
static Image* loadFromFile(const char*);
};
}

77
example/lesson310-矩阵缩放/Raster.cpp

@ -0,0 +1,77 @@
#include "Raster.h"
#include "FreeImage.h"
namespace CELL
{
Image* Image::loadFromFile(const char* fileName)
{
//1 获取图片格式
FREE_IMAGE_FORMAT fifmt = FreeImage_GetFileType(fileName, 0);
if (fifmt == FIF_UNKNOWN)
{
return 0;
}
//2 加载图片
FIBITMAP *dib = FreeImage_Load(fifmt, fileName,0);
FREE_IMAGE_COLOR_TYPE type = FreeImage_GetColorType(dib);
//! 获取数据指针
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);
int pitch = width*4;
BYTE* row = new BYTE[width*4];
for(int j = 0; j < height / 2; j++)
{
memcpy(row,pixels + j * pitch,pitch );
memcpy(pixels + j * pitch,pixels + (height - j - 1) * pitch,pitch );
memcpy(pixels + (height - j - 1) * pitch,row,pitch );
}
delete []row;
Image* image = new Image(width,height,pixels);
FreeImage_Unload(dib);
return image;
}
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;
}
Raster::~Raster( void )
{
}
void Raster::clear()
{
memset(_buffer,0,_width * _height * sizeof(Rgba));
}
}

418
example/lesson310-矩阵缩放/Raster.h

@ -0,0 +1,418 @@
#pragma once
#include "CELLMath.hpp"
#include "Image.hpp"
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;
}
}
};
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;
}
}
};
class Raster
{
public:
uint* _buffer;
int _width;
int _height;
Rgba _color;
Image* _texture;
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)
{
int left = tmax<int>(startX,0);
int top = tmax<int>(startY,0);
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);
}
}
}
public:
void vertexPointer(int size,DATETYPE type,int stride,const void* data)
{
_poitionPointer._size = size;
_poitionPointer._type = type;
_poitionPointer._stride = stride;
_poitionPointer._data = data;
}
void colorPointer(int size,DATETYPE type,int stride,const void* data)
{
_colorPointer._size = size;
_colorPointer._type = type;
_colorPointer._stride = stride;
_colorPointer._data = data;
}
void textureCoordPointer(int size,DATETYPE type,int stride,const void* data)
{
_uvPointer._size = size;
_uvPointer._type = type;
_uvPointer._stride = stride;
_uvPointer._data = data;
}
void bindTexture(Image* image)
{
_texture = image;
}
void drawArrays(DRAWMODE pri,int start,int count)
{
if (_poitionPointer._data == 0)
{
return;
}
DateElementDes colorPointerdesc = _colorPointer;
DateElementDes uvPointerdesc = _uvPointer;
if (colorPointerdesc._data == 0)
{
colorPointerdesc = _defaultColorPointer;
}
if (uvPointerdesc._data == 0)
{
uvPointerdesc = _defaultUVPointer;
}
char* posData = (char*)_poitionPointer._data;
char* cData = (char*)colorPointerdesc._data;
char* uvData = (char*)uvPointerdesc._data;
for(int i = start ;i < start + count; i += 3)
{
float* fData = (float*)posData;
int2 p0 (fData[0],fData[1]);
posData += _poitionPointer._stride;
fData = (float*)(posData);
int2 p1 (fData[0],fData[1]);
posData += _poitionPointer._stride;
fData = (float*)(posData);
int2 p2 (fData[0],fData[1]);
posData += _poitionPointer._stride;
Rgba* pColor = (Rgba*)cData;
Rgba c0 (*pColor);
cData += _colorPointer._stride;
Rgba c1 (*pColor);
cData += _colorPointer._stride;
Rgba c2 (*pColor);
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;
}
}
}
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,pixel);
}
}
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;
}
};
}

223
example/lesson310-矩阵缩放/lesson310-矩阵缩放.vcproj

@ -0,0 +1,223 @@
<?xml version="1.0" encoding="gb2312"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="lesson310-矩阵缩放"
ProjectGUID="{4880A4A6-8888-4A22-910F-F65223B5C310}"
RootNamespace="lesson310-矩阵缩放"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
IntermediateDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../dependencies"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="FreeImage.lib"
OutputFile="../../bin/$(ConfigurationName)/$(ProjectName).exe"
LinkIncremental="2"
AdditionalLibraryDirectories="../../dependencies"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
IntermediateDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="../../dependencies"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
EnableEnhancedInstructionSet="0"
FloatingPointModel="0"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="FreeImage.lib"
OutputFile="../../bin/$(ConfigurationName)/$(ProjectName).exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../dependencies"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="源文件"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\lesson310.cpp"
>
</File>
</Filter>
<Filter
Name="头文件"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\CELLMath.hpp"
>
</File>
<File
RelativePath=".\Image.hpp"
>
</File>
<File
RelativePath=".\Raster.cpp"
>
</File>
<File
RelativePath=".\Raster.h"
>
</File>
</Filter>
<Filter
Name="资源文件"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
<File
RelativePath=".\1.ppt"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

224
example/lesson310-矩阵缩放/lesson310.cpp

@ -0,0 +1,224 @@
#include <windows.h>
#include <tchar.h>
#include "Raster.h"
#include "CELLTimestamp.hpp"
LRESULT CALLBACK windowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_SIZE:
break;
case WM_CLOSE:
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
break;
}
return DefWindowProc( hWnd, msg, wParam, lParam );
}
void getResourcePath(HINSTANCE hInstance,char pPath[1024])
{
char szPathName[1024];
char szDriver[64];
char szPath[1024];
GetModuleFileNameA(hInstance,szPathName,sizeof(szPathName));
_splitpath( szPathName, szDriver, szPath, 0, 0 );
sprintf(pPath,"%s%s",szDriver,szPath);
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
// 1 ×¢²á´°¿ÚÀà
::WNDCLASSEXA winClass;
winClass.lpszClassName = "Raster";
winClass.cbSize = sizeof(::WNDCLASSEX);
winClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;
winClass.lpfnWndProc = windowProc;
winClass.hInstance = hInstance;
winClass.hIcon = 0;
winClass.hIconSm = 0;
winClass.hCursor = LoadCursor(NULL, IDC_ARROW);
winClass.hbrBackground = (HBRUSH)(BLACK_BRUSH);
winClass.lpszMenuName = NULL;
winClass.cbClsExtra = 0;
winClass.cbWndExtra = 0;
RegisterClassExA(&winClass);
// 2 ´´½¨´°¿Ú
HWND hWnd = CreateWindowExA(
NULL,
"Raster",
"Raster",
WS_OVERLAPPEDWINDOW,
0,
0,
800,
600,
0,
0,
hInstance,
0
);
UpdateWindow( hWnd );
ShowWindow(hWnd,SW_SHOW);
RECT rt = {0};
GetClientRect(hWnd,&rt);
int width = rt.right - rt.left;
int height = rt.bottom - rt.top;
void* buffer = 0;
HDC hDC = GetDC(hWnd);
HDC hMem = ::CreateCompatibleDC(hDC);
BITMAPINFO bmpInfor;
bmpInfor.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfor.bmiHeader.biWidth = width;
bmpInfor.bmiHeader.biHeight = -height;
bmpInfor.bmiHeader.biPlanes = 1;
bmpInfor.bmiHeader.biBitCount = 32;
bmpInfor.bmiHeader.biCompression = BI_RGB;
bmpInfor.bmiHeader.biSizeImage = 0;
bmpInfor.bmiHeader.biXPelsPerMeter = 0;
bmpInfor.bmiHeader.biYPelsPerMeter = 0;
bmpInfor.bmiHeader.biClrUsed = 0;
bmpInfor.bmiHeader.biClrImportant = 0;
HBITMAP hBmp = CreateDIBSection(hDC,&bmpInfor,DIB_RGB_COLORS,(void**)&buffer,0,0);
SelectObject(hMem,hBmp);
char szPath[1024];
getResourcePath(0,szPath);
char szImage[1024];
sprintf(szImage,"%s/image/bg.png",szPath);
CELL::Image* image = CELL::Image::loadFromFile(szImage);
sprintf(szImage,"%s/image/scale.jpg",szPath);
CELL::Image* image1 = CELL::Image::loadFromFile(szImage);
CELL::Raster raster(width,height,buffer);
struct Vertex
{
float x,y;
float u,v;
CELL::Rgba color;
};
MSG msg = {0};
while(true)
{
if (msg.message == WM_DESTROY
||msg.message == WM_CLOSE
||msg.message == WM_QUIT)
{
break;
}
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
raster.clear();
CELL::int2 pt[3] =
{
CELL::int2(100,10),
CELL::int2(10,100),
CELL::int2(200,100),
};
CELL::Rgba color1(255,0,0);
CELL::Rgba color2(0,255,0);
CELL::Rgba color3(0,0,255);
CELL::CELLTimestamp tms;
tms.update();
double mis = tms.getElapsedTimeInMicroSec();
char szBuf[128];
sprintf(szBuf,"%f ",mis);
int i = 00;
memcpy(buffer,raster._buffer,raster._width * raster._height * sizeof(CELL::Rgba));
raster.drawImage(0,0,image);
Vertex vertexs[] =
{
{-10, -10, 0.0f, 0.0f, CELL::Rgba(255,255,255,255)},
{210, 210, 2.0f, 2.0f, CELL::Rgba(255,255,255,255)},
{210, -10, 2.0f, 0.0f, CELL::Rgba(255,255,255,255)},
{-10, -10, 0.0f, 0.0f, CELL::Rgba(255,255,255,255)},
{210, 210, 2.0f, 2.0f, CELL::Rgba(255,255,255,255)},
{-10, 210, 0.0f, 2.0f, CELL::Rgba(255,255,255,255)},
};
static float scales = -1;
CELL::matrix3 mat;
mat.scale(1,scales);
//scales += 0.01f;
for (int i = 0 ;i < 6 ; ++ i)
{
CELL::float3 pos(vertexs[i].x,vertexs[i].y,1);
pos = mat * pos;
vertexs[i].x = pos.x;
vertexs[i].y = pos.y;
}
CELL::matrix3 matT;
matT.translate(200,200);
for (int i = 0 ;i < 6 ; ++ i)
{
CELL::float3 pos(vertexs[i].x,vertexs[i].y,1);
pos = matT * pos;
vertexs[i].x = pos.x;
vertexs[i].y = pos.y;
}
image1->setWrapType(1);
raster.bindTexture(image1);
raster.vertexPointer(2,CELL::DT_FLOAT, sizeof(Vertex),&vertexs[0].x);
raster.textureCoordPointer(2,CELL::DT_FLOAT,sizeof(Vertex),&vertexs[0].u);
//raster.colorPointer(4,CELL::DT_BYTE, sizeof(Vertex),&vertexs[0].color);
raster.drawArrays(CELL::DM_TRIANGES,0,6);
//raster.drawTriangle(vertex,image1);
//raster.drawTriangle(vertex1,image1);
//TextOut(hMem,10,10,szBuf,strlen(szBuf));
BitBlt(hDC,0,0,width,height,hMem,0,0,SRCCOPY);
}
delete image;
delete image1;
return 0;
}

5978
example/lesson311-矩阵旋转/CELLMath.hpp
File diff suppressed because it is too large
View File

53
example/lesson311-矩阵旋转/CELLTimestamp.hpp

@ -0,0 +1,53 @@
#pragma once
#include <windows.h>
namespace CELL
{
class CELLTimestamp
{
public:
CELLTimestamp()
{
QueryPerformanceFrequency(&_frequency);
QueryPerformanceCounter(&_startCount);
}
~CELLTimestamp()
{}
void update()
{
QueryPerformanceCounter(&_startCount);
}
/**
* »ñÈ¡µ±Ç°Ãë
*/
double getElapsedSecond()
{
return getElapsedTimeInMicroSec() * 0.000001;
}
/**
* »ñÈ¡ºÁÃë
*/
double getElapsedTimeInMilliSec()
{
return this->getElapsedTimeInMicroSec() * 0.001;
}
/**
* »ñȡ΢Ãî
*/
double getElapsedTimeInMicroSec()
{
LARGE_INTEGER endCount;
QueryPerformanceCounter(&endCount);
double startTimeInMicroSec = _startCount.QuadPart * (1000000.0 / _frequency.QuadPart);
double endTimeInMicroSec = endCount.QuadPart * (1000000.0 / _frequency.QuadPart);
return endTimeInMicroSec - startTimeInMicroSec;
}
protected:
LARGE_INTEGER _frequency;
LARGE_INTEGER _startCount;
};
}

80
example/lesson311-矩阵旋转/Image.hpp

@ -0,0 +1,80 @@
#pragma once
namespace CELL
{
class Image
{
protected:
int _width;
int _height;
uint* _pixel;
int _wrapType;
public:
Image(int w,int h,void* data)
{
_wrapType = 0;
if (w == 0 || h == 0 || data== 0)
{
_width = 0;
_height = 0;
_pixel = 0;
}
else
{
_width = w;
_height = h;
_pixel = new uint[w * h];
memcpy(_pixel,data,w * h * sizeof(uint));
}
}
~Image()
{
delete []_pixel;
}
void setWrapType(int type)
{
_wrapType = type;
}
int width() const
{
return _width;
}
int height() const
{
return _height;
}
Rgba pixelAt(int x,int y) const
{
return Rgba(_pixel[y * _width + x]);
}
Rgba pixelUV(float u,float v)
{
float x = u * _width;
float y = v * _height;
if (_wrapType == 0)
{
return pixelAt((unsigned)(x)%_width,(unsigned)(y)%_height);
}
else
{
if (x >= _width)
{
x = _width - 1;
}
if (y >= _height)
{
y = _height - 1;
}
return pixelAt(x,y);
}
}
public:
static Image* loadFromFile(const char*);
};
}

77
example/lesson311-矩阵旋转/Raster.cpp

@ -0,0 +1,77 @@
#include "Raster.h"
#include "FreeImage.h"
namespace CELL
{
Image* Image::loadFromFile(const char* fileName)
{
//1 获取图片格式
FREE_IMAGE_FORMAT fifmt = FreeImage_GetFileType(fileName, 0);
if (fifmt == FIF_UNKNOWN)
{
return 0;
}
//2 加载图片
FIBITMAP *dib = FreeImage_Load(fifmt, fileName,0);
FREE_IMAGE_COLOR_TYPE type = FreeImage_GetColorType(dib);
//! 获取数据指针
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);
int pitch = width*4;
BYTE* row = new BYTE[width*4];
for(int j = 0; j < height / 2; j++)
{
memcpy(row,pixels + j * pitch,pitch );
memcpy(pixels + j * pitch,pixels + (height - j - 1) * pitch,pitch );
memcpy(pixels + (height - j - 1) * pitch,row,pitch );
}
delete []row;
Image* image = new Image(width,height,pixels);
FreeImage_Unload(dib);
return image;
}
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;
}
Raster::~Raster( void )
{
}
void Raster::clear()
{
memset(_buffer,0,_width * _height * sizeof(Rgba));
}
}

418
example/lesson311-矩阵旋转/Raster.h

@ -0,0 +1,418 @@
#pragma once
#include "CELLMath.hpp"
#include "Image.hpp"
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;
}
}
};
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;
}
}
};
class Raster
{
public:
uint* _buffer;
int _width;
int _height;
Rgba _color;
Image* _texture;
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)
{
int left = tmax<int>(startX,0);
int top = tmax<int>(startY,0);
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);
}
}
}
public:
void vertexPointer(int size,DATETYPE type,int stride,const void* data)
{
_poitionPointer._size = size;
_poitionPointer._type = type;
_poitionPointer._stride = stride;
_poitionPointer._data = data;
}
void colorPointer(int size,DATETYPE type,int stride,const void* data)
{
_colorPointer._size = size;
_colorPointer._type = type;
_colorPointer._stride = stride;
_colorPointer._data = data;
}
void textureCoordPointer(int size,DATETYPE type,int stride,const void* data)
{
_uvPointer._size = size;
_uvPointer._type = type;
_uvPointer._stride = stride;
_uvPointer._data = data;
}
void bindTexture(Image* image)
{
_texture = image;
}
void drawArrays(DRAWMODE pri,int start,int count)
{
if (_poitionPointer._data == 0)
{
return;
}
DateElementDes colorPointerdesc = _colorPointer;
DateElementDes uvPointerdesc = _uvPointer;
if (colorPointerdesc._data == 0)
{
colorPointerdesc = _defaultColorPointer;
}
if (uvPointerdesc._data == 0)
{
uvPointerdesc = _defaultUVPointer;
}
char* posData = (char*)_poitionPointer._data;
char* cData = (char*)colorPointerdesc._data;
char* uvData = (char*)uvPointerdesc._data;
for(int i = start ;i < start + count; i += 3)
{
float* fData = (float*)posData;
int2 p0 (fData[0],fData[1]);
posData += _poitionPointer._stride;
fData = (float*)(posData);
int2 p1 (fData[0],fData[1]);
posData += _poitionPointer._stride;
fData = (float*)(posData);
int2 p2 (fData[0],fData[1]);
posData += _poitionPointer._stride;
Rgba* pColor = (Rgba*)cData;
Rgba c0 (*pColor);
cData += _colorPointer._stride;
Rgba c1 (*pColor);
cData += _colorPointer._stride;
Rgba c2 (*pColor);
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;
}
}
}
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,pixel);
}
}
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;
}
};
}

223
example/lesson311-矩阵旋转/lesson311-矩阵旋转.vcproj

@ -0,0 +1,223 @@
<?xml version="1.0" encoding="gb2312"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="lesson311-矩阵旋转"
ProjectGUID="{4880A4A6-8888-4A22-910F-F65223B5C311}"
RootNamespace="lesson311-矩阵旋转"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
IntermediateDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../dependencies"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="FreeImage.lib"
OutputFile="../../bin/$(ConfigurationName)/$(ProjectName).exe"
LinkIncremental="2"
AdditionalLibraryDirectories="../../dependencies"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
IntermediateDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="../../dependencies"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
EnableEnhancedInstructionSet="0"
FloatingPointModel="0"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="FreeImage.lib"
OutputFile="../../bin/$(ConfigurationName)/$(ProjectName).exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../dependencies"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="源文件"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\lesson311.cpp"
>
</File>
</Filter>
<Filter
Name="头文件"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\CELLMath.hpp"
>
</File>
<File
RelativePath=".\Image.hpp"
>
</File>
<File
RelativePath=".\Raster.cpp"
>
</File>
<File
RelativePath=".\Raster.h"
>
</File>
</Filter>
<Filter
Name="资源文件"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
<File
RelativePath=".\1.ppt"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

227
example/lesson311-矩阵旋转/lesson311.cpp

@ -0,0 +1,227 @@
#include <windows.h>
#include <tchar.h>
#include "Raster.h"
#include "CELLTimestamp.hpp"
LRESULT CALLBACK windowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_SIZE:
break;
case WM_CLOSE:
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
break;
}
return DefWindowProc( hWnd, msg, wParam, lParam );
}
void getResourcePath(HINSTANCE hInstance,char pPath[1024])
{
char szPathName[1024];
char szDriver[64];
char szPath[1024];
GetModuleFileNameA(hInstance,szPathName,sizeof(szPathName));
_splitpath( szPathName, szDriver, szPath, 0, 0 );
sprintf(pPath,"%s%s",szDriver,szPath);
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
// 1 ×¢²á´°¿ÚÀà
::WNDCLASSEXA winClass;
winClass.lpszClassName = "Raster";
winClass.cbSize = sizeof(::WNDCLASSEX);
winClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;
winClass.lpfnWndProc = windowProc;
winClass.hInstance = hInstance;
winClass.hIcon = 0;
winClass.hIconSm = 0;
winClass.hCursor = LoadCursor(NULL, IDC_ARROW);
winClass.hbrBackground = (HBRUSH)(BLACK_BRUSH);
winClass.lpszMenuName = NULL;
winClass.cbClsExtra = 0;
winClass.cbWndExtra = 0;
RegisterClassExA(&winClass);
// 2 ´´½¨´°¿Ú
HWND hWnd = CreateWindowExA(
NULL,
"Raster",
"Raster",
WS_OVERLAPPEDWINDOW,
0,
0,
800,
600,
0,
0,
hInstance,
0
);
UpdateWindow( hWnd );
ShowWindow(hWnd,SW_SHOW);
RECT rt = {0};
GetClientRect(hWnd,&rt);
int width = rt.right - rt.left;
int height = rt.bottom - rt.top;
void* buffer = 0;
HDC hDC = GetDC(hWnd);
HDC hMem = ::CreateCompatibleDC(hDC);
BITMAPINFO bmpInfor;
bmpInfor.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfor.bmiHeader.biWidth = width;
bmpInfor.bmiHeader.biHeight = -height;
bmpInfor.bmiHeader.biPlanes = 1;
bmpInfor.bmiHeader.biBitCount = 32;
bmpInfor.bmiHeader.biCompression = BI_RGB;
bmpInfor.bmiHeader.biSizeImage = 0;
bmpInfor.bmiHeader.biXPelsPerMeter = 0;
bmpInfor.bmiHeader.biYPelsPerMeter = 0;
bmpInfor.bmiHeader.biClrUsed = 0;
bmpInfor.bmiHeader.biClrImportant = 0;
HBITMAP hBmp = CreateDIBSection(hDC,&bmpInfor,DIB_RGB_COLORS,(void**)&buffer,0,0);
SelectObject(hMem,hBmp);
char szPath[1024];
getResourcePath(0,szPath);
char szImage[1024];
sprintf(szImage,"%s/image/bg.png",szPath);
CELL::Image* image = CELL::Image::loadFromFile(szImage);
sprintf(szImage,"%s/image/scale.jpg",szPath);
CELL::Image* image1 = CELL::Image::loadFromFile(szImage);
CELL::Raster raster(width,height,buffer);
struct Vertex
{
float x,y;
float u,v;
CELL::Rgba color;
};
MSG msg = {0};
while(true)
{
if (msg.message == WM_DESTROY
||msg.message == WM_CLOSE
||msg.message == WM_QUIT)
{
break;
}
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
raster.clear();
CELL::int2 pt[3] =
{
CELL::int2(100,10),
CELL::int2(10,100),
CELL::int2(200,100),
};
CELL::Rgba color1(255,0,0);
CELL::Rgba color2(0,255,0);
CELL::Rgba color3(0,0,255);
CELL::CELLTimestamp tms;
tms.update();
double mis = tms.getElapsedTimeInMicroSec();
char szBuf[128];
sprintf(szBuf,"%f ",mis);
int i = 00;
memcpy(buffer,raster._buffer,raster._width * raster._height * sizeof(CELL::Rgba));
raster.drawImage(0,0,image);
Vertex vertexs[] =
{
{-10, -10, 0.0f, 0.0f, CELL::Rgba(255,255,255,255)},
{210, 210, 2.0f, 2.0f, CELL::Rgba(255,255,255,255)},
{210, -10, 2.0f, 0.0f, CELL::Rgba(255,255,255,255)},
{-10, -10, 0.0f, 0.0f, CELL::Rgba(255,255,255,255)},
{210, 210, 2.0f, 2.0f, CELL::Rgba(255,255,255,255)},
{-10, 210, 0.0f, 2.0f, CELL::Rgba(255,255,255,255)},
};
static float angles = 0;
CELL::matrix3 matTrans;
matTrans.translate(-110,-110);
CELL::matrix3 rot;
rot.rotate(angles);
CELL::matrix3 matTrans1;
matTrans1.translate(110,110);
CELL::matrix3 all = matTrans1 * (rot * matTrans);
angles += 1.0f;
for (int i = 0 ;i < 6 ; ++ i)
{
CELL::float3 pos(vertexs[i].x,vertexs[i].y,1);
pos = all * pos;
vertexs[i].x = pos.x;
vertexs[i].y = pos.y;
}
image1->setWrapType(1);
raster.bindTexture(image1);
raster.vertexPointer(2,CELL::DT_FLOAT, sizeof(Vertex),&vertexs[0].x);
raster.textureCoordPointer(2,CELL::DT_FLOAT,sizeof(Vertex),&vertexs[0].u);
//raster.colorPointer(4,CELL::DT_BYTE, sizeof(Vertex),&vertexs[0].color);
raster.drawArrays(CELL::DM_TRIANGES,0,6);
//raster.drawTriangle(vertex,image1);
//raster.drawTriangle(vertex1,image1);
//TextOut(hMem,10,10,szBuf,strlen(szBuf));
BitBlt(hDC,0,0,width,height,hMem,0,0,SRCCOPY);
}
delete image;
delete image1;
return 0;
}

5978
example/lesson312-矩阵复合操作/CELLMath.hpp
File diff suppressed because it is too large
View File

53
example/lesson312-矩阵复合操作/CELLTimestamp.hpp

@ -0,0 +1,53 @@
#pragma once
#include <windows.h>
namespace CELL
{
class CELLTimestamp
{
public:
CELLTimestamp()
{
QueryPerformanceFrequency(&_frequency);
QueryPerformanceCounter(&_startCount);
}
~CELLTimestamp()
{}
void update()
{
QueryPerformanceCounter(&_startCount);
}
/**
* »ñÈ¡µ±Ç°Ãë
*/
double getElapsedSecond()
{
return getElapsedTimeInMicroSec() * 0.000001;
}
/**
* »ñÈ¡ºÁÃë
*/
double getElapsedTimeInMilliSec()
{
return this->getElapsedTimeInMicroSec() * 0.001;
}
/**
* »ñȡ΢Ãî
*/
double getElapsedTimeInMicroSec()
{
LARGE_INTEGER endCount;
QueryPerformanceCounter(&endCount);
double startTimeInMicroSec = _startCount.QuadPart * (1000000.0 / _frequency.QuadPart);
double endTimeInMicroSec = endCount.QuadPart * (1000000.0 / _frequency.QuadPart);
return endTimeInMicroSec - startTimeInMicroSec;
}
protected:
LARGE_INTEGER _frequency;
LARGE_INTEGER _startCount;
};
}

80
example/lesson312-矩阵复合操作/Image.hpp

@ -0,0 +1,80 @@
#pragma once
namespace CELL
{
class Image
{
protected:
int _width;
int _height;
uint* _pixel;
int _wrapType;
public:
Image(int w,int h,void* data)
{
_wrapType = 0;
if (w == 0 || h == 0 || data== 0)
{
_width = 0;
_height = 0;
_pixel = 0;
}
else
{
_width = w;
_height = h;
_pixel = new uint[w * h];
memcpy(_pixel,data,w * h * sizeof(uint));
}
}
~Image()
{
delete []_pixel;
}
void setWrapType(int type)
{
_wrapType = type;
}
int width() const
{
return _width;
}
int height() const
{
return _height;
}
Rgba pixelAt(int x,int y) const
{
return Rgba(_pixel[y * _width + x]);
}
Rgba pixelUV(float u,float v)
{
float x = u * _width;
float y = v * _height;
if (_wrapType == 0)
{
return pixelAt((unsigned)(x)%_width,(unsigned)(y)%_height);
}
else
{
if (x >= _width)
{
x = _width - 1;
}
if (y >= _height)
{
y = _height - 1;
}
return pixelAt(x,y);
}
}
public:
static Image* loadFromFile(const char*);
};
}

79
example/lesson312-矩阵复合操作/Raster.cpp

@ -0,0 +1,79 @@
#include "Raster.h"
#include "FreeImage.h"
namespace CELL
{
Image* Image::loadFromFile(const char* fileName)
{
//1 获取图片格式
FREE_IMAGE_FORMAT fifmt = FreeImage_GetFileType(fileName, 0);
if (fifmt == FIF_UNKNOWN)
{
return 0;
}
//2 加载图片
FIBITMAP *dib = FreeImage_Load(fifmt, fileName,0);
FREE_IMAGE_COLOR_TYPE type = FreeImage_GetColorType(dib);
//! 获取数据指针
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);
int pitch = width*4;
BYTE* row = new BYTE[width*4];
for(int j = 0; j < height / 2; j++)
{
memcpy(row,pixels + j * pitch,pitch );
memcpy(pixels + j * pitch,pixels + (height - j - 1) * pitch,pitch );
memcpy(pixels + (height - j - 1) * pitch,row,pitch );
}
delete []row;
Image* image = new Image(width,height,pixels);
FreeImage_Unload(dib);
return image;
}
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;
_matModel = CELL::matrix3(1);
}
Raster::~Raster( void )
{
}
void Raster::clear()
{
memset(_buffer,0,_width * _height * sizeof(Rgba));
}
}

440
example/lesson312-矩阵复合操作/Raster.h

@ -0,0 +1,440 @@
#pragma once
#include "CELLMath.hpp"
#include "Image.hpp"
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;
}
}
};
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;
}
}
};
class Raster
{
public:
uint* _buffer;
int _width;
int _height;
Rgba _color;
Image* _texture;
matrix3 _matModel;
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)
{
int left = tmax<int>(startX,0);
int top = tmax<int>(startY,0);
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);
}
}
}
public:
/**
* ¾ØÕó²Ù×÷º¯Êý
*/
void loadMatrix(const CELL::matrix3& mat)
{
_matModel = mat;
}
void loadIdentity()
{
_matModel = CELL::matrix3(1);
}
void vertexPointer(int size,DATETYPE type,int stride,const void* data)
{
_poitionPointer._size = size;
_poitionPointer._type = type;
_poitionPointer._stride = stride;
_poitionPointer._data = data;
}
void colorPointer(int size,DATETYPE type,int stride,const void* data)
{
_colorPointer._size = size;
_colorPointer._type = type;
_colorPointer._stride = stride;
_colorPointer._data = data;
}
void textureCoordPointer(int size,DATETYPE type,int stride,const void* data)
{
_uvPointer._size = size;
_uvPointer._type = type;
_uvPointer._stride = stride;
_uvPointer._data = data;
}
void bindTexture(Image* image)
{
_texture = image;
}
void drawArrays(DRAWMODE pri,int start,int count)
{
if (_poitionPointer._data == 0)
{
return;
}
DateElementDes colorPointerdesc = _colorPointer;
DateElementDes uvPointerdesc = _uvPointer;
if (colorPointerdesc._data == 0)
{
colorPointerdesc = _defaultColorPointer;
}
if (uvPointerdesc._data == 0)
{
uvPointerdesc = _defaultUVPointer;
}
char* posData = (char*)_poitionPointer._data;
char* cData = (char*)colorPointerdesc._data;
char* uvData = (char*)uvPointerdesc._data;
for(int i = start ;i < start + count; i += 3)
{
float* fData = (float*)posData;
float3 p01 (fData[0],fData[1],1);
posData += _poitionPointer._stride;
fData = (float*)(posData);
p01 = _matModel * p01;
float3 p11 (fData[0],fData[1],1);
posData += _poitionPointer._stride;
fData = (float*)(posData);
p11 = _matModel * p11;
float3 p21 (fData[0],fData[1],1);
posData += _poitionPointer._stride;
p21 = _matModel * p21;
int2 p0(p01.x,p01.y);
int2 p1(p11.x,p11.y);
int2 p2(p21.x,p21.y);
Rgba* pColor = (Rgba*)cData;
Rgba c0 (*pColor);
cData += _colorPointer._stride;
Rgba c1 (*pColor);
cData += _colorPointer._stride;
Rgba c2 (*pColor);
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;
}
}
}
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,pixel);
}
}
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;
}
};
}

223
example/lesson312-矩阵复合操作/lesson312-矩阵复合操作.vcproj

@ -0,0 +1,223 @@
<?xml version="1.0" encoding="gb2312"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="lesson312-矩阵复合操作"
ProjectGUID="{4880A4A6-8888-4A22-910F-F65223B5C312}"
RootNamespace="lesson312-矩阵复合操作"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
IntermediateDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../dependencies"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="FreeImage.lib"
OutputFile="../../bin/$(ConfigurationName)/$(ProjectName).exe"
LinkIncremental="2"
AdditionalLibraryDirectories="../../dependencies"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
IntermediateDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="../../dependencies"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
EnableEnhancedInstructionSet="0"
FloatingPointModel="0"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="FreeImage.lib"
OutputFile="../../bin/$(ConfigurationName)/$(ProjectName).exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../dependencies"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="源文件"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\lesson312.cpp"
>
</File>
</Filter>
<Filter
Name="头文件"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\CELLMath.hpp"
>
</File>
<File
RelativePath=".\Image.hpp"
>
</File>
<File
RelativePath=".\Raster.cpp"
>
</File>
<File
RelativePath=".\Raster.h"
>
</File>
</Filter>
<Filter
Name="资源文件"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
<File
RelativePath=".\1.ppt"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

224
example/lesson312-矩阵复合操作/lesson312.cpp

@ -0,0 +1,224 @@
#include <windows.h>
#include <tchar.h>
#include "Raster.h"
#include "CELLTimestamp.hpp"
LRESULT CALLBACK windowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_SIZE:
break;
case WM_CLOSE:
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
break;
}
return DefWindowProc( hWnd, msg, wParam, lParam );
}
void getResourcePath(HINSTANCE hInstance,char pPath[1024])
{
char szPathName[1024];
char szDriver[64];
char szPath[1024];
GetModuleFileNameA(hInstance,szPathName,sizeof(szPathName));
_splitpath( szPathName, szDriver, szPath, 0, 0 );
sprintf(pPath,"%s%s",szDriver,szPath);
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
// 1 ×¢²á´°¿ÚÀà
::WNDCLASSEXA winClass;
winClass.lpszClassName = "Raster";
winClass.cbSize = sizeof(::WNDCLASSEX);
winClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;
winClass.lpfnWndProc = windowProc;
winClass.hInstance = hInstance;
winClass.hIcon = 0;
winClass.hIconSm = 0;
winClass.hCursor = LoadCursor(NULL, IDC_ARROW);
winClass.hbrBackground = (HBRUSH)(BLACK_BRUSH);
winClass.lpszMenuName = NULL;
winClass.cbClsExtra = 0;
winClass.cbWndExtra = 0;
RegisterClassExA(&winClass);
// 2 ´´½¨´°¿Ú
HWND hWnd = CreateWindowExA(
NULL,
"Raster",
"Raster",
WS_OVERLAPPEDWINDOW,
0,
0,
800,
600,
0,
0,
hInstance,
0
);
UpdateWindow( hWnd );
ShowWindow(hWnd,SW_SHOW);
RECT rt = {0};
GetClientRect(hWnd,&rt);
int width = rt.right - rt.left;
int height = rt.bottom - rt.top;
void* buffer = 0;
HDC hDC = GetDC(hWnd);
HDC hMem = ::CreateCompatibleDC(hDC);
BITMAPINFO bmpInfor;
bmpInfor.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfor.bmiHeader.biWidth = width;
bmpInfor.bmiHeader.biHeight = -height;
bmpInfor.bmiHeader.biPlanes = 1;
bmpInfor.bmiHeader.biBitCount = 32;
bmpInfor.bmiHeader.biCompression = BI_RGB;
bmpInfor.bmiHeader.biSizeImage = 0;
bmpInfor.bmiHeader.biXPelsPerMeter = 0;
bmpInfor.bmiHeader.biYPelsPerMeter = 0;
bmpInfor.bmiHeader.biClrUsed = 0;
bmpInfor.bmiHeader.biClrImportant = 0;
HBITMAP hBmp = CreateDIBSection(hDC,&bmpInfor,DIB_RGB_COLORS,(void**)&buffer,0,0);
SelectObject(hMem,hBmp);
char szPath[1024];
getResourcePath(0,szPath);
char szImage[1024];
sprintf(szImage,"%s/image/bg.png",szPath);
CELL::Image* image = CELL::Image::loadFromFile(szImage);
sprintf(szImage,"%s/image/scale.jpg",szPath);
CELL::Image* image1 = CELL::Image::loadFromFile(szImage);
CELL::Raster raster(width,height,buffer);
struct Vertex
{
float x,y;
float u,v;
CELL::Rgba color;
};
MSG msg = {0};
while(true)
{
if (msg.message == WM_DESTROY
||msg.message == WM_CLOSE
||msg.message == WM_QUIT)
{
break;
}
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
raster.clear();
CELL::int2 pt[3] =
{
CELL::int2(100,10),
CELL::int2(10,100),
CELL::int2(200,100),
};
CELL::Rgba color1(255,0,0);
CELL::Rgba color2(0,255,0);
CELL::Rgba color3(0,0,255);
CELL::CELLTimestamp tms;
tms.update();
double mis = tms.getElapsedTimeInMicroSec();
char szBuf[128];
sprintf(szBuf,"%f ",mis);
int i = 00;
memcpy(buffer,raster._buffer,raster._width * raster._height * sizeof(CELL::Rgba));
raster.drawImage(0,0,image);
Vertex vertexs[] =
{
{-10, -10, 0.0f, 0.0f, CELL::Rgba(255,255,255,255)},
{210, 210, 2.0f, 2.0f, CELL::Rgba(255,255,255,255)},
{210, -10, 2.0f, 0.0f, CELL::Rgba(255,255,255,255)},
{-10, -10, 0.0f, 0.0f, CELL::Rgba(255,255,255,255)},
{210, 210, 2.0f, 2.0f, CELL::Rgba(255,255,255,255)},
{-10, 210, 0.0f, 2.0f, CELL::Rgba(255,255,255,255)},
};
static float angles = 0;
CELL::matrix3 matTrans;
matTrans.translate(-110,-110);
CELL::matrix3 rot;
rot.rotate(angles);
CELL::matrix3 matScale;
matScale.scale(0.5f,0.5f);
CELL::matrix3 matTrans1;
matTrans1.translate(110,110);
CELL::matrix3 all = matTrans1 * (rot * matScale * matTrans);
angles += 1.0f;
raster.loadMatrix(all);
//raster.loadIdentity();
image1->setWrapType(1);
raster.bindTexture(image1);
raster.vertexPointer(2,CELL::DT_FLOAT, sizeof(Vertex),&vertexs[0].x);
raster.textureCoordPointer(2,CELL::DT_FLOAT,sizeof(Vertex),&vertexs[0].u);
//raster.colorPointer(4,CELL::DT_BYTE, sizeof(Vertex),&vertexs[0].color);
raster.drawArrays(CELL::DM_TRIANGES,0,6);
//raster.drawTriangle(vertex,image1);
//raster.drawTriangle(vertex1,image1);
//TextOut(hMem,10,10,szBuf,strlen(szBuf));
BitBlt(hDC,0,0,width,height,hMem,0,0,SRCCOPY);
}
delete image;
delete image1;
return 0;
}

BIN
example/lesson400-三维理论/01.ppt

203
example/lesson400-三维理论/lesson400-3D理论.vcproj

@ -0,0 +1,203 @@
<?xml version="1.0" encoding="gb2312"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="lesson400-3D理论基础"
ProjectGUID="{4880A4A6-8888-4A22-910F-F65223B5C400}"
RootNamespace="lesson400-3D理论"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
IntermediateDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../dependencies"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="FreeImage.lib"
OutputFile="../../bin/$(ConfigurationName)/$(ProjectName).exe"
LinkIncremental="2"
AdditionalLibraryDirectories="../../dependencies"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
IntermediateDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="../../dependencies"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
EnableEnhancedInstructionSet="0"
FloatingPointModel="0"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="FreeImage.lib"
OutputFile="../../bin/$(ConfigurationName)/$(ProjectName).exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../dependencies"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="源文件"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
</Filter>
<Filter
Name="头文件"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
</Filter>
<Filter
Name="资源文件"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
<File
RelativePath=".\01.ppt"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

BIN
example/lesson401-向量-矩阵/02.ppt

203
example/lesson401-向量-矩阵/lesson401-向量-矩阵.vcproj

@ -0,0 +1,203 @@
<?xml version="1.0" encoding="gb2312"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="lesson401-向量-矩阵"
ProjectGUID="{4880A4A6-8888-4A22-910F-F65223B5C401}"
RootNamespace="lesson401-矩阵操作"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
IntermediateDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../dependencies"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="FreeImage.lib"
OutputFile="../../bin/$(ConfigurationName)/$(ProjectName).exe"
LinkIncremental="2"
AdditionalLibraryDirectories="../../dependencies"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
IntermediateDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="../../dependencies"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
EnableEnhancedInstructionSet="0"
FloatingPointModel="0"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="FreeImage.lib"
OutputFile="../../bin/$(ConfigurationName)/$(ProjectName).exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../dependencies"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="源文件"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
</Filter>
<Filter
Name="头文件"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
</Filter>
<Filter
Name="资源文件"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
<File
RelativePath=".\02.ppt"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

BIN
example/lesson402-向量-矩阵/02.ppt

203
example/lesson402-向量-矩阵/lesson402-向量-矩阵.vcproj

@ -0,0 +1,203 @@
<?xml version="1.0" encoding="gb2312"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="lesson402-向量-矩阵"
ProjectGUID="{E570B8A2-23D9-4A3B-A39B-4D052201C402}"
RootNamespace="lesson402-向量-矩阵"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
IntermediateDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../dependencies"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="FreeImage.lib"
OutputFile="../../bin/$(ConfigurationName)/$(ProjectName).exe"
LinkIncremental="2"
AdditionalLibraryDirectories="../../dependencies"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
IntermediateDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="../../dependencies"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
EnableEnhancedInstructionSet="0"
FloatingPointModel="0"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="FreeImage.lib"
OutputFile="../../bin/$(ConfigurationName)/$(ProjectName).exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../dependencies"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="源文件"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
</Filter>
<Filter
Name="头文件"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
</Filter>
<Filter
Name="资源文件"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
<File
RelativePath=".\02.ppt"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

5978
example/lesson403-实现3D的框架/CELLMath.hpp
File diff suppressed because it is too large
View File

53
example/lesson403-实现3D的框架/CELLTimestamp.hpp

@ -0,0 +1,53 @@
#pragma once
#include <windows.h>
namespace CELL
{
class CELLTimestamp
{
public:
CELLTimestamp()
{
QueryPerformanceFrequency(&_frequency);
QueryPerformanceCounter(&_startCount);
}
~CELLTimestamp()
{}
void update()
{
QueryPerformanceCounter(&_startCount);
}
/**
* »ñÈ¡µ±Ç°Ãë
*/
double getElapsedSecond()
{
return getElapsedTimeInMicroSec() * 0.000001;
}
/**
* »ñÈ¡ºÁÃë
*/
double getElapsedTimeInMilliSec()
{
return this->getElapsedTimeInMicroSec() * 0.001;
}
/**
* »ñȡ΢Ãî
*/
double getElapsedTimeInMicroSec()
{
LARGE_INTEGER endCount;
QueryPerformanceCounter(&endCount);
double startTimeInMicroSec = _startCount.QuadPart * (1000000.0 / _frequency.QuadPart);
double endTimeInMicroSec = endCount.QuadPart * (1000000.0 / _frequency.QuadPart);
return endTimeInMicroSec - startTimeInMicroSec;
}
protected:
LARGE_INTEGER _frequency;
LARGE_INTEGER _startCount;
};
}

80
example/lesson403-实现3D的框架/Image.hpp

@ -0,0 +1,80 @@
#pragma once
namespace CELL
{
class Image
{
protected:
int _width;
int _height;
uint* _pixel;
int _wrapType;
public:
Image(int w,int h,void* data)
{
_wrapType = 0;
if (w == 0 || h == 0 || data== 0)
{
_width = 0;
_height = 0;
_pixel = 0;
}
else
{
_width = w;
_height = h;
_pixel = new uint[w * h];
memcpy(_pixel,data,w * h * sizeof(uint));
}
}
~Image()
{
delete []_pixel;
}
void setWrapType(int type)
{
_wrapType = type;
}
int width() const
{
return _width;
}
int height() const
{
return _height;
}
Rgba pixelAt(int x,int y) const
{
return Rgba(_pixel[y * _width + x]);
}
Rgba pixelUV(float u,float v)
{
float x = u * _width;
float y = v * _height;
if (_wrapType == 0)
{
return pixelAt((unsigned)(x)%_width,(unsigned)(y)%_height);
}
else
{
if (x >= _width)
{
x = _width - 1;
}
if (y >= _height)
{
y = _height - 1;
}
return pixelAt(x,y);
}
}
public:
static Image* loadFromFile(const char*);
};
}

79
example/lesson403-实现3D的框架/Raster.cpp

@ -0,0 +1,79 @@
#include "Raster.h"
#include "FreeImage.h"
namespace CELL
{
Image* Image::loadFromFile(const char* fileName)
{
//1 获取图片格式
FREE_IMAGE_FORMAT fifmt = FreeImage_GetFileType(fileName, 0);
if (fifmt == FIF_UNKNOWN)
{
return 0;
}
//2 加载图片
FIBITMAP *dib = FreeImage_Load(fifmt, fileName,0);
FREE_IMAGE_COLOR_TYPE type = FreeImage_GetColorType(dib);
//! 获取数据指针
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);
int pitch = width*4;
BYTE* row = new BYTE[width*4];
for(int j = 0; j < height / 2; j++)
{
memcpy(row,pixels + j * pitch,pitch );
memcpy(pixels + j * pitch,pixels + (height - j - 1) * pitch,pitch );
memcpy(pixels + (height - j - 1) * pitch,row,pitch );
}
delete []row;
Image* image = new Image(width,height,pixels);
FreeImage_Unload(dib);
return image;
}
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;
_matModel = CELL::matrix4(1);
}
Raster::~Raster( void )
{
}
void Raster::clear()
{
memset(_buffer,0,_width * _height * sizeof(Rgba));
}
}

441
example/lesson403-实现3D的框架/Raster.h

@ -0,0 +1,441 @@
#pragma once
#include "CELLMath.hpp"
#include "Image.hpp"
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;
}
}
};
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;
}
}
};
class Raster
{
public:
uint* _buffer;
int _width;
int _height;
Rgba _color;
Image* _texture;
matrix4 _matModel;
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)
{
int left = tmax<int>(startX,0);
int top = tmax<int>(startY,0);
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);
}
}
}
public:
/**
*
*/
void loadMatrix(const CELL::matrix4& mat)
{
_matModel = mat;
}
void loadIdentity()
{
_matModel = CELL::matrix4(1);
}
void vertexPointer(int size,DATETYPE type,int stride,const void* data)
{
_poitionPointer._size = size;
_poitionPointer._type = type;
_poitionPointer._stride = stride;
_poitionPointer._data = data;
}
void colorPointer(int size,DATETYPE type,int stride,const void* data)
{
_colorPointer._size = size;
_colorPointer._type = type;
_colorPointer._stride = stride;
_colorPointer._data = data;
}
void textureCoordPointer(int size,DATETYPE type,int stride,const void* data)
{
_uvPointer._size = size;
_uvPointer._type = type;
_uvPointer._stride = stride;
_uvPointer._data = data;
}
void bindTexture(Image* image)
{
_texture = image;
}
void drawArrays(DRAWMODE pri,int start,int count)
{
if (_poitionPointer._data == 0)
{
return;
}
DateElementDes colorPointerdesc = _colorPointer;
DateElementDes uvPointerdesc = _uvPointer;
if (colorPointerdesc._data == 0)
{
colorPointerdesc = _defaultColorPointer;
}
if (uvPointerdesc._data == 0)
{
uvPointerdesc = _defaultUVPointer;
}
char* posData = (char*)_poitionPointer._data;
char* cData = (char*)colorPointerdesc._data;
char* uvData = (char*)uvPointerdesc._data;
for(int i = start ;i < start + count; i += 3)
{
float* fData = (float*)posData;
float4 p01 (fData[0],fData[1],fData[2],1);
posData += _poitionPointer._stride;
fData = (float*)(posData);
p01 = _matModel * p01;
float4 p11 (fData[0],fData[1],fData[2],1);
posData += _poitionPointer._stride;
fData = (float*)(posData);
p11 = _matModel * p11;
float4 p21 (fData[0],fData[1],fData[2],1);
posData += _poitionPointer._stride;
p21 = _matModel * p21;
//!
int2 p0(p01.x,p01.y);
int2 p1(p11.x,p11.y);
int2 p2(p21.x,p21.y);
Rgba* pColor = (Rgba*)cData;
Rgba c0 (*pColor);
cData += _colorPointer._stride;
Rgba c1 (*pColor);
cData += _colorPointer._stride;
Rgba c2 (*pColor);
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;
}
}
}
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,pixel);
}
}
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;
}
};
}

223
example/lesson403-实现3D的框架/lesson403-实现3D的框架.vcproj

@ -0,0 +1,223 @@
<?xml version="1.0" encoding="gb2312"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="lesson403-实现3D的框架"
ProjectGUID="{4880A4A6-8888-4A22-910F-F65223B5C403}"
RootNamespace="lesson403-实现3D的框架"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
IntermediateDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../dependencies"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="FreeImage.lib"
OutputFile="../../bin/$(ConfigurationName)/$(ProjectName).exe"
LinkIncremental="2"
AdditionalLibraryDirectories="../../dependencies"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
IntermediateDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="../../dependencies"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
EnableEnhancedInstructionSet="0"
FloatingPointModel="0"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="FreeImage.lib"
OutputFile="../../bin/$(ConfigurationName)/$(ProjectName).exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../dependencies"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="源文件"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\lesson403.cpp"
>
</File>
</Filter>
<Filter
Name="头文件"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\CELLMath.hpp"
>
</File>
<File
RelativePath=".\Image.hpp"
>
</File>
<File
RelativePath=".\Raster.cpp"
>
</File>
<File
RelativePath=".\Raster.h"
>
</File>
</Filter>
<Filter
Name="资源文件"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
<File
RelativePath=".\1.ppt"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

186
example/lesson403-实现3D的框架/lesson403.cpp

@ -0,0 +1,186 @@
#include <windows.h>
#include <tchar.h>
#include "Raster.h"
#include "CELLTimestamp.hpp"
LRESULT CALLBACK windowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_SIZE:
break;
case WM_CLOSE:
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
break;
}
return DefWindowProc( hWnd, msg, wParam, lParam );
}
void getResourcePath(HINSTANCE hInstance,char pPath[1024])
{
char szPathName[1024];
char szDriver[64];
char szPath[1024];
GetModuleFileNameA(hInstance,szPathName,sizeof(szPathName));
_splitpath( szPathName, szDriver, szPath, 0, 0 );
sprintf(pPath,"%s%s",szDriver,szPath);
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
// 1 ×¢²á´°¿ÚÀà
::WNDCLASSEXA winClass;
winClass.lpszClassName = "Raster";
winClass.cbSize = sizeof(::WNDCLASSEX);
winClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;
winClass.lpfnWndProc = windowProc;
winClass.hInstance = hInstance;
winClass.hIcon = 0;
winClass.hIconSm = 0;
winClass.hCursor = LoadCursor(NULL, IDC_ARROW);
winClass.hbrBackground = (HBRUSH)(BLACK_BRUSH);
winClass.lpszMenuName = NULL;
winClass.cbClsExtra = 0;
winClass.cbWndExtra = 0;
RegisterClassExA(&winClass);
// 2 ´´½¨´°¿Ú
HWND hWnd = CreateWindowExA(
NULL,
"Raster",
"Raster",
WS_OVERLAPPEDWINDOW,
0,
0,
800,
600,
0,
0,
hInstance,
0
);
UpdateWindow( hWnd );
ShowWindow(hWnd,SW_SHOW);
RECT rt = {0};
GetClientRect(hWnd,&rt);
int width = rt.right - rt.left;
int height = rt.bottom - rt.top;
void* buffer = 0;
HDC hDC = GetDC(hWnd);
HDC hMem = ::CreateCompatibleDC(hDC);
BITMAPINFO bmpInfor;
bmpInfor.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfor.bmiHeader.biWidth = width;
bmpInfor.bmiHeader.biHeight = -height;
bmpInfor.bmiHeader.biPlanes = 1;
bmpInfor.bmiHeader.biBitCount = 32;
bmpInfor.bmiHeader.biCompression = BI_RGB;
bmpInfor.bmiHeader.biSizeImage = 0;
bmpInfor.bmiHeader.biXPelsPerMeter = 0;
bmpInfor.bmiHeader.biYPelsPerMeter = 0;
bmpInfor.bmiHeader.biClrUsed = 0;
bmpInfor.bmiHeader.biClrImportant = 0;
HBITMAP hBmp = CreateDIBSection(hDC,&bmpInfor,DIB_RGB_COLORS,(void**)&buffer,0,0);
SelectObject(hMem,hBmp);
char szPath[1024];
getResourcePath(0,szPath);
char szImage[1024];
sprintf(szImage,"%s/image/bg.png",szPath);
CELL::Image* image = CELL::Image::loadFromFile(szImage);
sprintf(szImage,"%s/image/scale.jpg",szPath);
CELL::Image* image1 = CELL::Image::loadFromFile(szImage);
CELL::Raster raster(width,height,buffer);
struct Vertex
{
float x,y,z;
float u,v;
CELL::Rgba color;
};
MSG msg = {0};
while(true)
{
if (msg.message == WM_DESTROY
||msg.message == WM_CLOSE
||msg.message == WM_QUIT)
{
break;
}
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
raster.clear();
CELL::CELLTimestamp tms;
tms.update();
double mis = tms.getElapsedTimeInMicroSec();
char szBuf[128];
sprintf(szBuf,"%f ",mis);
int i = 00;
memcpy(buffer,raster._buffer,raster._width * raster._height * sizeof(CELL::Rgba));
raster.drawImage(0,0,image);
Vertex vertexs[] =
{
{10, 10, 0, 0.0f, 0.0f, CELL::Rgba(255,255,255,255)},
{110, 110, 0, 1.0f, 1.0f, CELL::Rgba(255,255,255,255)},
{110, 10, 0, 1.0f, 0.0f, CELL::Rgba(255,255,255,255)},
{10, 10, 0, 0.0f, 0.0f, CELL::Rgba(255,255,255,255)},
{110, 110, 0, 1.0f, 1.0f, CELL::Rgba(255,255,255,255)},
{10, 110, 0, 0.0f, 1.0f, CELL::Rgba(255,255,255,255)},
};
raster.loadIdentity();
image1->setWrapType(1);
raster.bindTexture(image1);
raster.vertexPointer(2,CELL::DT_FLOAT, sizeof(Vertex),&vertexs[0].x);
raster.textureCoordPointer(2,CELL::DT_FLOAT,sizeof(Vertex),&vertexs[0].u);
//raster.colorPointer(4,CELL::DT_BYTE, sizeof(Vertex),&vertexs[0].color);
raster.drawArrays(CELL::DM_TRIANGES,0,6);
//TextOut(hMem,10,10,szBuf,strlen(szBuf));
BitBlt(hDC,0,0,width,height,hMem,0,0,SRCCOPY);
}
delete image;
delete image1;
return 0;
}

5978
example/lesson404-固定渲染管线实现/CELLMath.hpp
File diff suppressed because it is too large
View File

53
example/lesson404-固定渲染管线实现/CELLTimestamp.hpp

@ -0,0 +1,53 @@
#pragma once
#include <windows.h>
namespace CELL
{
class CELLTimestamp
{
public:
CELLTimestamp()
{
QueryPerformanceFrequency(&_frequency);
QueryPerformanceCounter(&_startCount);
}
~CELLTimestamp()
{}
void update()
{
QueryPerformanceCounter(&_startCount);
}
/**
* »ñÈ¡µ±Ç°Ãë
*/
double getElapsedSecond()
{
return getElapsedTimeInMicroSec() * 0.000001;
}
/**
* »ñÈ¡ºÁÃë
*/
double getElapsedTimeInMilliSec()
{
return this->getElapsedTimeInMicroSec() * 0.001;
}
/**
* »ñȡ΢Ãî
*/
double getElapsedTimeInMicroSec()
{
LARGE_INTEGER endCount;
QueryPerformanceCounter(&endCount);
double startTimeInMicroSec = _startCount.QuadPart * (1000000.0 / _frequency.QuadPart);
double endTimeInMicroSec = endCount.QuadPart * (1000000.0 / _frequency.QuadPart);
return endTimeInMicroSec - startTimeInMicroSec;
}
protected:
LARGE_INTEGER _frequency;
LARGE_INTEGER _startCount;
};
}

80
example/lesson404-固定渲染管线实现/Image.hpp

@ -0,0 +1,80 @@
#pragma once
namespace CELL
{
class Image
{
protected:
int _width;
int _height;
uint* _pixel;
int _wrapType;
public:
Image(int w,int h,void* data)
{
_wrapType = 0;
if (w == 0 || h == 0 || data== 0)
{
_width = 0;
_height = 0;
_pixel = 0;
}
else
{
_width = w;
_height = h;
_pixel = new uint[w * h];
memcpy(_pixel,data,w * h * sizeof(uint));
}
}
~Image()
{
delete []_pixel;
}
void setWrapType(int type)
{
_wrapType = type;
}
int width() const
{
return _width;
}
int height() const
{
return _height;
}
Rgba pixelAt(int x,int y) const
{
return Rgba(_pixel[y * _width + x]);
}
Rgba pixelUV(float u,float v)
{
float x = u * _width;
float y = v * _height;
if (_wrapType == 0)
{
return pixelAt((unsigned)(x)%_width,(unsigned)(y)%_height);
}
else
{
if (x >= _width)
{
x = _width - 1;
}
if (y >= _height)
{
y = _height - 1;
}
return pixelAt(x,y);
}
}
public:
static Image* loadFromFile(const char*);
};
}

257
example/lesson404-固定渲染管线实现/Raster.cpp

@ -0,0 +1,257 @@
#include "Raster.h"
#include "FreeImage.h"
namespace CELL
{
Image* Image::loadFromFile(const char* fileName)
{
//1 获取图片格式
FREE_IMAGE_FORMAT fifmt = FreeImage_GetFileType(fileName, 0);
if (fifmt == FIF_UNKNOWN)
{
return 0;
}
//2 加载图片
FIBITMAP *dib = FreeImage_Load(fifmt, fileName,0);
FREE_IMAGE_COLOR_TYPE type = FreeImage_GetColorType(dib);
//! 获取数据指针
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);
int pitch = width*4;
BYTE* row = new BYTE[width*4];
for(int j = 0; j < height / 2; j++)
{
memcpy(row,pixels + j * pitch,pitch );
memcpy(pixels + j * pitch,pixels + (height - j - 1) * pitch,pitch );
memcpy(pixels + (height - j - 1) * pitch,row,pitch );
}
delete []row;
Image* image = new Image(width,height,pixels);
FreeImage_Unload(dib);
return image;
}
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;
_matModel = CELL::matrix4(1);
}
Raster::~Raster( void )
{
}
void Raster::clear()
{
memset(_buffer,0,_width * _height * sizeof(Rgba));
}
void Raster::drawImage( int startX,int startY,const Image* image )
{
int left = tmax<int>(startX,0);
int top = tmax<int>(startY,0);
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);
}
}
}
void Raster::drawArrays( DRAWMODE pri,int start,int count )
{
if (_poitionPointer._data == 0)
{
return;
}
DateElementDes colorPointerdesc = _colorPointer;
DateElementDes uvPointerdesc = _uvPointer;
if (colorPointerdesc._data == 0)
{
colorPointerdesc = _defaultColorPointer;
}
if (uvPointerdesc._data == 0)
{
uvPointerdesc = _defaultUVPointer;
}
char* posData = (char*)_poitionPointer._data;
char* cData = (char*)colorPointerdesc._data;
char* uvData = (char*)uvPointerdesc._data;
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);
p01 = piplineTransform(p01);
float3 p11 (fData[0],fData[1],fData[2]);
posData += _poitionPointer._stride;
fData = (float*)(posData);
p11 = piplineTransform(p11);
float3 p21 (fData[0],fData[1],fData[2]);
posData += _poitionPointer._stride;
p21 = piplineTransform(p21);
//! 转化为屏幕坐标
int2 p0(p01.x,p01.y);
int2 p1(p11.x,p11.y);
int2 p2(p21.x,p21.y);
Rgba* pColor = (Rgba*)cData;
Rgba c0 (*pColor);
cData += _colorPointer._stride;
Rgba c1 (*pColor);
cData += _colorPointer._stride;
Rgba c2 (*pColor);
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;
}
}
}
void Raster::bindTexture( Image* image )
{
_texture = 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::colorPointer( int size,DATETYPE type,int stride,const void* data )
{
_colorPointer._size = size;
_colorPointer._type = type;
_colorPointer._stride = stride;
_colorPointer._data = data;
}
void Raster::vertexPointer( int size,DATETYPE type,int stride,const void* data )
{
_poitionPointer._size = size;
_poitionPointer._type = type;
_poitionPointer._stride = stride;
_poitionPointer._data = data;
}
void Raster::loadMatrix( const CELL::matrix4& mat )
{
_matModel = mat;
}
void Raster::loadIdentity()
{
_matModel = CELL::matrix4(1);
}
void Raster::loadProjMatrix( const CELL::matrix4& mat )
{
_matProj = mat;
}
void Raster::loadProjIdentity( const CELL::matrix4& mat )
{
_matProj = CELL::matrix4(1);
}
void Raster::loadViewMatrix( const CELL::matrix4& mat )
{
_matView = mat;
}
void Raster::loadViewIdentity( const CELL::matrix4& mat )
{
_matView = CELL::matrix4(1);
}
void Raster::setPerspective( float fovy, float aspect, float zNear, float zFar )
{
_matProj = CELL::perspective<float>(fovy,aspect,zNear,zFar);
}
void Raster::lookat( float3 const & eye,float3 const & center,float3 const & up )
{
_matView = CELL::lookAt(eye,center,up);
}
void Raster::setViewPort( int x,int y,int w,int h )
{
_viewPort.x = w;
_viewPort.y = h;
}
}

359
example/lesson404-固定渲染管线实现/Raster.h

@ -0,0 +1,359 @@
#pragma once
#include "CELLMath.hpp"
#include "Image.hpp"
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;
}
}
};
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;
}
}
};
class Raster
{
public:
uint* _buffer;
int _width;
int _height;
Rgba _color;
Image* _texture;
matrix4 _matModel;
matrix4 _matView;
matrix4 _matProj;
float2 _viewPort;
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);
void bindTexture(Image* image);
void drawArrays(DRAWMODE pri,int start,int count);
protected:
float3 piplineTransform(float3 pos)
{
float4 world(pos.x,pos.y,pos.z,1);
float4 screen = (_matProj * _matView * _matModel) * 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;
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,pixel);
}
}
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;
}
};
}

186
example/lesson404-固定渲染管线实现/lesson403.cpp

@ -0,0 +1,186 @@
#include <windows.h>
#include <tchar.h>
#include "Raster.h"
#include "CELLTimestamp.hpp"
LRESULT CALLBACK windowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_SIZE:
break;
case WM_CLOSE:
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
break;
}
return DefWindowProc( hWnd, msg, wParam, lParam );
}
void getResourcePath(HINSTANCE hInstance,char pPath[1024])
{
char szPathName[1024];
char szDriver[64];
char szPath[1024];
GetModuleFileNameA(hInstance,szPathName,sizeof(szPathName));
_splitpath( szPathName, szDriver, szPath, 0, 0 );
sprintf(pPath,"%s%s",szDriver,szPath);
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
// 1 ×¢²á´°¿ÚÀà
::WNDCLASSEXA winClass;
winClass.lpszClassName = "Raster";
winClass.cbSize = sizeof(::WNDCLASSEX);
winClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;
winClass.lpfnWndProc = windowProc;
winClass.hInstance = hInstance;
winClass.hIcon = 0;
winClass.hIconSm = 0;
winClass.hCursor = LoadCursor(NULL, IDC_ARROW);
winClass.hbrBackground = (HBRUSH)(BLACK_BRUSH);
winClass.lpszMenuName = NULL;
winClass.cbClsExtra = 0;
winClass.cbWndExtra = 0;
RegisterClassExA(&winClass);
// 2 ´´½¨´°¿Ú
HWND hWnd = CreateWindowExA(
NULL,
"Raster",
"Raster",
WS_OVERLAPPEDWINDOW,
0,
0,
800,
600,
0,
0,
hInstance,
0
);
UpdateWindow( hWnd );
ShowWindow(hWnd,SW_SHOW);
RECT rt = {0};
GetClientRect(hWnd,&rt);
int width = rt.right - rt.left;
int height = rt.bottom - rt.top;
void* buffer = 0;
HDC hDC = GetDC(hWnd);
HDC hMem = ::CreateCompatibleDC(hDC);
BITMAPINFO bmpInfor;
bmpInfor.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfor.bmiHeader.biWidth = width;
bmpInfor.bmiHeader.biHeight = -height;
bmpInfor.bmiHeader.biPlanes = 1;
bmpInfor.bmiHeader.biBitCount = 32;
bmpInfor.bmiHeader.biCompression = BI_RGB;
bmpInfor.bmiHeader.biSizeImage = 0;
bmpInfor.bmiHeader.biXPelsPerMeter = 0;
bmpInfor.bmiHeader.biYPelsPerMeter = 0;
bmpInfor.bmiHeader.biClrUsed = 0;
bmpInfor.bmiHeader.biClrImportant = 0;
HBITMAP hBmp = CreateDIBSection(hDC,&bmpInfor,DIB_RGB_COLORS,(void**)&buffer,0,0);
SelectObject(hMem,hBmp);
char szPath[1024];
getResourcePath(0,szPath);
char szImage[1024];
sprintf(szImage,"%s/image/bg.png",szPath);
CELL::Image* image = CELL::Image::loadFromFile(szImage);
sprintf(szImage,"%s/image/scale.jpg",szPath);
CELL::Image* image1 = CELL::Image::loadFromFile(szImage);
CELL::Raster raster(width,height,buffer);
struct Vertex
{
float x,y,z;
float u,v;
CELL::Rgba color;
};
MSG msg = {0};
while(true)
{
if (msg.message == WM_DESTROY
||msg.message == WM_CLOSE
||msg.message == WM_QUIT)
{
break;
}
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
raster.clear();
CELL::CELLTimestamp tms;
tms.update();
double mis = tms.getElapsedTimeInMicroSec();
char szBuf[128];
sprintf(szBuf,"%f ",mis);
int i = 00;
memcpy(buffer,raster._buffer,raster._width * raster._height * sizeof(CELL::Rgba));
raster.drawImage(0,0,image);
Vertex vertexs[] =
{
{10, 10, 0, 0.0f, 0.0f, CELL::Rgba(255,255,255,255)},
{110, 110, 0, 1.0f, 1.0f, CELL::Rgba(255,255,255,255)},
{110, 10, 0, 1.0f, 0.0f, CELL::Rgba(255,255,255,255)},
{10, 10, 0, 0.0f, 0.0f, CELL::Rgba(255,255,255,255)},
{110, 110, 0, 1.0f, 1.0f, CELL::Rgba(255,255,255,255)},
{10, 110, 0, 0.0f, 1.0f, CELL::Rgba(255,255,255,255)},
};
raster.loadIdentity();
image1->setWrapType(1);
raster.bindTexture(image1);
raster.vertexPointer(2,CELL::DT_FLOAT, sizeof(Vertex),&vertexs[0].x);
raster.textureCoordPointer(2,CELL::DT_FLOAT,sizeof(Vertex),&vertexs[0].u);
//raster.colorPointer(4,CELL::DT_BYTE, sizeof(Vertex),&vertexs[0].color);
raster.drawArrays(CELL::DM_TRIANGES,0,6);
//TextOut(hMem,10,10,szBuf,strlen(szBuf));
BitBlt(hDC,0,0,width,height,hMem,0,0,SRCCOPY);
}
delete image;
delete image1;
return 0;
}

223
example/lesson404-固定渲染管线实现/lesson404-固定渲染管线实现.vcproj

@ -0,0 +1,223 @@
<?xml version="1.0" encoding="gb2312"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="lesson404-固定渲染管线实现"
ProjectGUID="{4880A4A6-8888-4A22-910F-F65223B5C404}"
RootNamespace="lesson404-固定渲染管线实现"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
IntermediateDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../dependencies"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="FreeImage.lib"
OutputFile="../../bin/$(ConfigurationName)/$(ProjectName).exe"
LinkIncremental="2"
AdditionalLibraryDirectories="../../dependencies"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
IntermediateDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="../../dependencies"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
EnableEnhancedInstructionSet="0"
FloatingPointModel="0"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="FreeImage.lib"
OutputFile="../../bin/$(ConfigurationName)/$(ProjectName).exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../dependencies"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="源文件"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\lesson403.cpp"
>
</File>
</Filter>
<Filter
Name="头文件"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\CELLMath.hpp"
>
</File>
<File
RelativePath=".\Image.hpp"
>
</File>
<File
RelativePath=".\Raster.cpp"
>
</File>
<File
RelativePath=".\Raster.h"
>
</File>
</Filter>
<Filter
Name="资源文件"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
<File
RelativePath=".\1.ppt"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

5978
example/lesson405-投影和观察矩阵/CELLMath.hpp
File diff suppressed because it is too large
View File

53
example/lesson405-投影和观察矩阵/CELLTimestamp.hpp

@ -0,0 +1,53 @@
#pragma once
#include <windows.h>
namespace CELL
{
class CELLTimestamp
{
public:
CELLTimestamp()
{
QueryPerformanceFrequency(&_frequency);
QueryPerformanceCounter(&_startCount);
}
~CELLTimestamp()
{}
void update()
{
QueryPerformanceCounter(&_startCount);
}
/**
* »ñÈ¡µ±Ç°Ãë
*/
double getElapsedSecond()
{
return getElapsedTimeInMicroSec() * 0.000001;
}
/**
* »ñÈ¡ºÁÃë
*/
double getElapsedTimeInMilliSec()
{
return this->getElapsedTimeInMicroSec() * 0.001;
}
/**
* »ñȡ΢Ãî
*/
double getElapsedTimeInMicroSec()
{
LARGE_INTEGER endCount;
QueryPerformanceCounter(&endCount);
double startTimeInMicroSec = _startCount.QuadPart * (1000000.0 / _frequency.QuadPart);
double endTimeInMicroSec = endCount.QuadPart * (1000000.0 / _frequency.QuadPart);
return endTimeInMicroSec - startTimeInMicroSec;
}
protected:
LARGE_INTEGER _frequency;
LARGE_INTEGER _startCount;
};
}

80
example/lesson405-投影和观察矩阵/Image.hpp

@ -0,0 +1,80 @@
#pragma once
namespace CELL
{
class Image
{
protected:
int _width;
int _height;
uint* _pixel;
int _wrapType;
public:
Image(int w,int h,void* data)
{
_wrapType = 0;
if (w == 0 || h == 0 || data== 0)
{
_width = 0;
_height = 0;
_pixel = 0;
}
else
{
_width = w;
_height = h;
_pixel = new uint[w * h];
memcpy(_pixel,data,w * h * sizeof(uint));
}
}
~Image()
{
delete []_pixel;
}
void setWrapType(int type)
{
_wrapType = type;
}
int width() const
{
return _width;
}
int height() const
{
return _height;
}
Rgba pixelAt(int x,int y) const
{
return Rgba(_pixel[y * _width + x]);
}
Rgba pixelUV(float u,float v)
{
float x = u * _width;
float y = v * _height;
if (_wrapType == 0)
{
return pixelAt((unsigned)(x)%_width,(unsigned)(y)%_height);
}
else
{
if (x >= _width)
{
x = _width - 1;
}
if (y >= _height)
{
y = _height - 1;
}
return pixelAt(x,y);
}
}
public:
static Image* loadFromFile(const char*);
};
}

257
example/lesson405-投影和观察矩阵/Raster.cpp

@ -0,0 +1,257 @@
#include "Raster.h"
#include "FreeImage.h"
namespace CELL
{
Image* Image::loadFromFile(const char* fileName)
{
//1 获取图片格式
FREE_IMAGE_FORMAT fifmt = FreeImage_GetFileType(fileName, 0);
if (fifmt == FIF_UNKNOWN)
{
return 0;
}
//2 加载图片
FIBITMAP *dib = FreeImage_Load(fifmt, fileName,0);
FREE_IMAGE_COLOR_TYPE type = FreeImage_GetColorType(dib);
//! 获取数据指针
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);
int pitch = width*4;
BYTE* row = new BYTE[width*4];
for(int j = 0; j < height / 2; j++)
{
memcpy(row,pixels + j * pitch,pitch );
memcpy(pixels + j * pitch,pixels + (height - j - 1) * pitch,pitch );
memcpy(pixels + (height - j - 1) * pitch,row,pitch );
}
delete []row;
Image* image = new Image(width,height,pixels);
FreeImage_Unload(dib);
return image;
}
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;
_matModel = CELL::matrix4(1);
}
Raster::~Raster( void )
{
}
void Raster::clear()
{
memset(_buffer,0,_width * _height * sizeof(Rgba));
}
void Raster::drawImage( int startX,int startY,const Image* image )
{
int left = tmax<int>(startX,0);
int top = tmax<int>(startY,0);
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);
}
}
}
void Raster::drawArrays( DRAWMODE pri,int start,int count )
{
if (_poitionPointer._data == 0)
{
return;
}
DateElementDes colorPointerdesc = _colorPointer;
DateElementDes uvPointerdesc = _uvPointer;
if (colorPointerdesc._data == 0)
{
colorPointerdesc = _defaultColorPointer;
}
if (uvPointerdesc._data == 0)
{
uvPointerdesc = _defaultUVPointer;
}
char* posData = (char*)_poitionPointer._data;
char* cData = (char*)colorPointerdesc._data;
char* uvData = (char*)uvPointerdesc._data;
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);
p01 = piplineTransform(p01);
float3 p11 (fData[0],fData[1],fData[2]);
posData += _poitionPointer._stride;
fData = (float*)(posData);
p11 = piplineTransform(p11);
float3 p21 (fData[0],fData[1],fData[2]);
posData += _poitionPointer._stride;
p21 = piplineTransform(p21);
//! 转化为屏幕坐标
int2 p0(p01.x,p01.y);
int2 p1(p11.x,p11.y);
int2 p2(p21.x,p21.y);
Rgba* pColor = (Rgba*)cData;
Rgba c0 (*pColor);
cData += _colorPointer._stride;
Rgba c1 (*pColor);
cData += _colorPointer._stride;
Rgba c2 (*pColor);
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;
}
}
}
void Raster::bindTexture( Image* image )
{
_texture = 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::colorPointer( int size,DATETYPE type,int stride,const void* data )
{
_colorPointer._size = size;
_colorPointer._type = type;
_colorPointer._stride = stride;
_colorPointer._data = data;
}
void Raster::vertexPointer( int size,DATETYPE type,int stride,const void* data )
{
_poitionPointer._size = size;
_poitionPointer._type = type;
_poitionPointer._stride = stride;
_poitionPointer._data = data;
}
void Raster::loadMatrix( const CELL::matrix4& mat )
{
_matModel = mat;
}
void Raster::loadIdentity()
{
_matModel = CELL::matrix4(1);
}
void Raster::loadProjMatrix( const CELL::matrix4& mat )
{
_matProj = mat;
}
void Raster::loadProjIdentity( const CELL::matrix4& mat )
{
_matProj = CELL::matrix4(1);
}
void Raster::loadViewMatrix( const CELL::matrix4& mat )
{
_matView = mat;
}
void Raster::loadViewIdentity( const CELL::matrix4& mat )
{
_matView = CELL::matrix4(1);
}
void Raster::setPerspective( float fovy, float aspect, float zNear, float zFar )
{
_matProj = CELL::perspective<float>(fovy,aspect,zNear,zFar);
}
void Raster::lookat( float3 const & eye,float3 const & center,float3 const & up )
{
_matView = CELL::lookAt(eye,center,up);
}
void Raster::setViewPort( int x,int y,int w,int h )
{
_viewPort.x = w;
_viewPort.y = h;
}
}

363
example/lesson405-投影和观察矩阵/Raster.h

@ -0,0 +1,363 @@
#pragma once
#include "CELLMath.hpp"
#include "Image.hpp"
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;
}
}
};
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;
}
}
};
class Raster
{
public:
uint* _buffer;
int _width;
int _height;
Rgba _color;
Image* _texture;
matrix4 _matModel;
matrix4 _matView;
matrix4 _matProj;
float2 _viewPort;
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)
{
_viewPort.x = w;
_viewPort.y = 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);
void bindTexture(Image* image);
void drawArrays(DRAWMODE pri,int start,int count);
protected:
float3 piplineTransform(float3 pos)
{
float4 world(pos.x,pos.y,pos.z,1);
float4 screen = (_matProj * _matView * _matModel) * 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;
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,pixel);
}
}
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;
}
};
}

223
example/lesson405-投影和观察矩阵/lesson405-投影和观察矩阵.vcproj

@ -0,0 +1,223 @@
<?xml version="1.0" encoding="gb2312"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="lesson405-投影和观察矩阵"
ProjectGUID="{4880A4A6-8888-4A22-910F-F65223B5C405}"
RootNamespace="lesson405-投影和观察矩阵"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
IntermediateDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../dependencies"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="FreeImage.lib"
OutputFile="../../bin/$(ConfigurationName)/$(ProjectName).exe"
LinkIncremental="2"
AdditionalLibraryDirectories="../../dependencies"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
IntermediateDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="../../dependencies"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
EnableEnhancedInstructionSet="0"
FloatingPointModel="0"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="FreeImage.lib"
OutputFile="../../bin/$(ConfigurationName)/$(ProjectName).exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../dependencies"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="源文件"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\lesson405.cpp"
>
</File>
</Filter>
<Filter
Name="头文件"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\CELLMath.hpp"
>
</File>
<File
RelativePath=".\Image.hpp"
>
</File>
<File
RelativePath=".\Raster.cpp"
>
</File>
<File
RelativePath=".\Raster.h"
>
</File>
</Filter>
<Filter
Name="资源文件"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
<File
RelativePath=".\1.ppt"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

186
example/lesson405-投影和观察矩阵/lesson405.cpp

@ -0,0 +1,186 @@
#include <windows.h>
#include <tchar.h>
#include "Raster.h"
#include "CELLTimestamp.hpp"
LRESULT CALLBACK windowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_SIZE:
break;
case WM_CLOSE:
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
break;
}
return DefWindowProc( hWnd, msg, wParam, lParam );
}
void getResourcePath(HINSTANCE hInstance,char pPath[1024])
{
char szPathName[1024];
char szDriver[64];
char szPath[1024];
GetModuleFileNameA(hInstance,szPathName,sizeof(szPathName));
_splitpath( szPathName, szDriver, szPath, 0, 0 );
sprintf(pPath,"%s%s",szDriver,szPath);
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
// 1 ×¢²á´°¿ÚÀà
::WNDCLASSEXA winClass;
winClass.lpszClassName = "Raster";
winClass.cbSize = sizeof(::WNDCLASSEX);
winClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;
winClass.lpfnWndProc = windowProc;
winClass.hInstance = hInstance;
winClass.hIcon = 0;
winClass.hIconSm = 0;
winClass.hCursor = LoadCursor(NULL, IDC_ARROW);
winClass.hbrBackground = (HBRUSH)(BLACK_BRUSH);
winClass.lpszMenuName = NULL;
winClass.cbClsExtra = 0;
winClass.cbWndExtra = 0;
RegisterClassExA(&winClass);
// 2 ´´½¨´°¿Ú
HWND hWnd = CreateWindowExA(
NULL,
"Raster",
"Raster",
WS_OVERLAPPEDWINDOW,
0,
0,
800,
600,
0,
0,
hInstance,
0
);
UpdateWindow( hWnd );
ShowWindow(hWnd,SW_SHOW);
RECT rt = {0};
GetClientRect(hWnd,&rt);
int width = rt.right - rt.left;
int height = rt.bottom - rt.top;
void* buffer = 0;
HDC hDC = GetDC(hWnd);
HDC hMem = ::CreateCompatibleDC(hDC);
BITMAPINFO bmpInfor;
bmpInfor.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfor.bmiHeader.biWidth = width;
bmpInfor.bmiHeader.biHeight = -height;
bmpInfor.bmiHeader.biPlanes = 1;
bmpInfor.bmiHeader.biBitCount = 32;
bmpInfor.bmiHeader.biCompression = BI_RGB;
bmpInfor.bmiHeader.biSizeImage = 0;
bmpInfor.bmiHeader.biXPelsPerMeter = 0;
bmpInfor.bmiHeader.biYPelsPerMeter = 0;
bmpInfor.bmiHeader.biClrUsed = 0;
bmpInfor.bmiHeader.biClrImportant = 0;
HBITMAP hBmp = CreateDIBSection(hDC,&bmpInfor,DIB_RGB_COLORS,(void**)&buffer,0,0);
SelectObject(hMem,hBmp);
char szPath[1024];
getResourcePath(0,szPath);
char szImage[1024];
sprintf(szImage,"%s/image/bg.png",szPath);
CELL::Image* image = CELL::Image::loadFromFile(szImage);
sprintf(szImage,"%s/image/scale.jpg",szPath);
CELL::Image* image1 = CELL::Image::loadFromFile(szImage);
CELL::Raster raster(width,height,buffer);
struct Vertex
{
float x,y,z;
float u,v;
CELL::Rgba color;
};
MSG msg = {0};
while(true)
{
if (msg.message == WM_DESTROY
||msg.message == WM_CLOSE
||msg.message == WM_QUIT)
{
break;
}
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
raster.clear();
CELL::CELLTimestamp tms;
tms.update();
double mis = tms.getElapsedTimeInMicroSec();
char szBuf[128];
sprintf(szBuf,"%f ",mis);
int i = 00;
memcpy(buffer,raster._buffer,raster._width * raster._height * sizeof(CELL::Rgba));
raster.drawImage(0,0,image);
Vertex vertexs[] =
{
{10, 10, 0, 0.0f, 0.0f, CELL::Rgba(255,255,255,255)},
{110, 110, 0, 1.0f, 1.0f, CELL::Rgba(255,255,255,255)},
{110, 10, 0, 1.0f, 0.0f, CELL::Rgba(255,255,255,255)},
{10, 10, 0, 0.0f, 0.0f, CELL::Rgba(255,255,255,255)},
{110, 110, 0, 1.0f, 1.0f, CELL::Rgba(255,255,255,255)},
{10, 110, 0, 0.0f, 1.0f, CELL::Rgba(255,255,255,255)},
};
raster.loadIdentity();
image1->setWrapType(1);
raster.bindTexture(image1);
raster.vertexPointer(2,CELL::DT_FLOAT, sizeof(Vertex),&vertexs[0].x);
raster.textureCoordPointer(2,CELL::DT_FLOAT,sizeof(Vertex),&vertexs[0].u);
//raster.colorPointer(4,CELL::DT_BYTE, sizeof(Vertex),&vertexs[0].color);
raster.drawArrays(CELL::DM_TRIANGES,0,6);
//TextOut(hMem,10,10,szBuf,strlen(szBuf));
BitBlt(hDC,0,0,width,height,hMem,0,0,SRCCOPY);
}
delete image;
delete image1;
return 0;
}

BIN
example/lesson406-固定渲染管线实现-裁减/04.ppt

5978
example/lesson406-固定渲染管线实现-裁减/CELLMath.hpp
File diff suppressed because it is too large
View File

53
example/lesson406-固定渲染管线实现-裁减/CELLTimestamp.hpp

@ -0,0 +1,53 @@
#pragma once
#include <windows.h>
namespace CELL
{
class CELLTimestamp
{
public:
CELLTimestamp()
{
QueryPerformanceFrequency(&_frequency);
QueryPerformanceCounter(&_startCount);
}
~CELLTimestamp()
{}
void update()
{
QueryPerformanceCounter(&_startCount);
}
/**
* »ñÈ¡µ±Ç°Ãë
*/
double getElapsedSecond()
{
return getElapsedTimeInMicroSec() * 0.000001;
}
/**
* »ñÈ¡ºÁÃë
*/
double getElapsedTimeInMilliSec()
{
return this->getElapsedTimeInMicroSec() * 0.001;
}
/**
* »ñȡ΢Ãî
*/
double getElapsedTimeInMicroSec()
{
LARGE_INTEGER endCount;
QueryPerformanceCounter(&endCount);
double startTimeInMicroSec = _startCount.QuadPart * (1000000.0 / _frequency.QuadPart);
double endTimeInMicroSec = endCount.QuadPart * (1000000.0 / _frequency.QuadPart);
return endTimeInMicroSec - startTimeInMicroSec;
}
protected:
LARGE_INTEGER _frequency;
LARGE_INTEGER _startCount;
};
}

80
example/lesson406-固定渲染管线实现-裁减/Image.hpp

@ -0,0 +1,80 @@
#pragma once
namespace CELL
{
class Image
{
protected:
int _width;
int _height;
uint* _pixel;
int _wrapType;
public:
Image(int w,int h,void* data)
{
_wrapType = 0;
if (w == 0 || h == 0 || data== 0)
{
_width = 0;
_height = 0;
_pixel = 0;
}
else
{
_width = w;
_height = h;
_pixel = new uint[w * h];
memcpy(_pixel,data,w * h * sizeof(uint));
}
}
~Image()
{
delete []_pixel;
}
void setWrapType(int type)
{
_wrapType = type;
}
int width() const
{
return _width;
}
int height() const
{
return _height;
}
Rgba pixelAt(int x,int y) const
{
return Rgba(_pixel[y * _width + x]);
}
Rgba pixelUV(float u,float v)
{
float x = u * _width;
float y = v * _height;
if (_wrapType == 0)
{
return pixelAt((unsigned)(x)%_width,(unsigned)(y)%_height);
}
else
{
if (x >= _width)
{
x = _width - 1;
}
if (y >= _height)
{
y = _height - 1;
}
return pixelAt(x,y);
}
}
public:
static Image* loadFromFile(const char*);
};
}

276
example/lesson406-固定渲染管线实现-裁减/Raster.cpp

@ -0,0 +1,276 @@
#include "Raster.h"
#include "FreeImage.h"
namespace CELL
{
Image* Image::loadFromFile(const char* fileName)
{
//1 获取图片格式
FREE_IMAGE_FORMAT fifmt = FreeImage_GetFileType(fileName, 0);
if (fifmt == FIF_UNKNOWN)
{
return 0;
}
//2 加载图片
FIBITMAP *dib = FreeImage_Load(fifmt, fileName,0);
FREE_IMAGE_COLOR_TYPE type = FreeImage_GetColorType(dib);
//! 获取数据指针
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);
int pitch = width*4;
BYTE* row = new BYTE[width*4];
for(int j = 0; j < height / 2; j++)
{
memcpy(row,pixels + j * pitch,pitch );
memcpy(pixels + j * pitch,pixels + (height - j - 1) * pitch,pitch );
memcpy(pixels + (height - j - 1) * pitch,row,pitch );
}
delete []row;
Image* image = new Image(width,height,pixels);
FreeImage_Unload(dib);
return image;
}
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;
_matModel = CELL::matrix4(1);
}
Raster::~Raster( void )
{
}
void Raster::clear()
{
memset(_buffer,0,_width * _height * sizeof(Rgba));
}
void Raster::drawImage( int startX,int startY,const Image* image )
{
int left = tmax<int>(startX,0);
int top = tmax<int>(startY,0);
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);
}
}
}
void Raster::drawArrays( DRAWMODE pri,int start,int count )
{
if (_poitionPointer._data == 0)
{
return;
}
DateElementDes colorPointerdesc = _colorPointer;
DateElementDes uvPointerdesc = _uvPointer;
if (colorPointerdesc._data == 0)
{
colorPointerdesc = _defaultColorPointer;
}
if (uvPointerdesc._data == 0)
{
uvPointerdesc = _defaultUVPointer;
}
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;
if ( _frust.pointInFrustum(p01)
|| _frust.pointInFrustum(p11)
|| _frust.pointInFrustum(p21)
)
{
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;
}
}
}
}
void Raster::bindTexture( Image* image )
{
_texture = 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::colorPointer( int size,DATETYPE type,int stride,const void* data )
{
_colorPointer._size = size;
_colorPointer._type = type;
_colorPointer._stride = stride;
_colorPointer._data = data;
}
void Raster::vertexPointer( int size,DATETYPE type,int stride,const void* data )
{
_poitionPointer._size = size;
_poitionPointer._type = type;
_poitionPointer._stride = stride;
_poitionPointer._data = data;
}
void Raster::loadMatrix( const CELL::matrix4& mat )
{
_matModel = mat;
}
void Raster::loadIdentity()
{
_matModel = CELL::matrix4(1);
}
void Raster::loadProjMatrix( const CELL::matrix4& mat )
{
_matProj = mat;
}
void Raster::loadProjIdentity( const CELL::matrix4& mat )
{
_matProj = CELL::matrix4(1);
}
void Raster::loadViewMatrix( const CELL::matrix4& mat )
{
_matView = mat;
}
void Raster::loadViewIdentity( const CELL::matrix4& mat )
{
_matView = CELL::matrix4(1);
}
void Raster::setPerspective( float fovy, float aspect, float zNear, float zFar )
{
_matProj = CELL::perspective<float>(fovy,aspect,zNear,zFar);
}
void Raster::lookat( float3 const & eye,float3 const & center,float3 const & up )
{
_matView = CELL::lookAt(eye,center,up);
}
void Raster::setViewPort( int x,int y,int w,int h )
{
_viewPort.x = w;
_viewPort.y = h;
}
}

361
example/lesson406-固定渲染管线实现-裁减/Raster.h

@ -0,0 +1,361 @@
#pragma once
#include "CELLMath.hpp"
#include "Image.hpp"
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;
}
}
};
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;
}
}
};
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);
void bindTexture(Image* image);
void drawArrays(DRAWMODE pri,int start,int count);
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,pixel);
}
}
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;
}
};
}

223
example/lesson406-固定渲染管线实现-裁减/lesson406-固定渲染管线实现-裁减.vcproj

@ -0,0 +1,223 @@
<?xml version="1.0" encoding="gb2312"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="lesson406-固定渲染管线实现-裁减"
ProjectGUID="{4880A4A6-8888-8A22-910F-F65223B5C406}"
RootNamespace="lesson405-固定渲染管线实现-裁减"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
IntermediateDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../dependencies"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="FreeImage.lib"
OutputFile="../../bin/$(ConfigurationName)/$(ProjectName).exe"
LinkIncremental="2"
AdditionalLibraryDirectories="../../dependencies"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
IntermediateDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="../../dependencies"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
EnableEnhancedInstructionSet="0"
FloatingPointModel="0"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="FreeImage.lib"
OutputFile="../../bin/$(ConfigurationName)/$(ProjectName).exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../dependencies"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="源文件"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\lesson406.cpp"
>
</File>
</Filter>
<Filter
Name="头文件"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\CELLMath.hpp"
>
</File>
<File
RelativePath=".\Image.hpp"
>
</File>
<File
RelativePath=".\Raster.cpp"
>
</File>
<File
RelativePath=".\Raster.h"
>
</File>
</Filter>
<Filter
Name="资源文件"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
<File
RelativePath=".\1.ppt"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

186
example/lesson406-固定渲染管线实现-裁减/lesson406.cpp

@ -0,0 +1,186 @@
#include <windows.h>
#include <tchar.h>
#include "Raster.h"
#include "CELLTimestamp.hpp"
LRESULT CALLBACK windowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_SIZE:
break;
case WM_CLOSE:
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
break;
}
return DefWindowProc( hWnd, msg, wParam, lParam );
}
void getResourcePath(HINSTANCE hInstance,char pPath[1024])
{
char szPathName[1024];
char szDriver[64];
char szPath[1024];
GetModuleFileNameA(hInstance,szPathName,sizeof(szPathName));
_splitpath( szPathName, szDriver, szPath, 0, 0 );
sprintf(pPath,"%s%s",szDriver,szPath);
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
// 1 ×¢²á´°¿ÚÀà
::WNDCLASSEXA winClass;
winClass.lpszClassName = "Raster";
winClass.cbSize = sizeof(::WNDCLASSEX);
winClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;
winClass.lpfnWndProc = windowProc;
winClass.hInstance = hInstance;
winClass.hIcon = 0;
winClass.hIconSm = 0;
winClass.hCursor = LoadCursor(NULL, IDC_ARROW);
winClass.hbrBackground = (HBRUSH)(BLACK_BRUSH);
winClass.lpszMenuName = NULL;
winClass.cbClsExtra = 0;
winClass.cbWndExtra = 0;
RegisterClassExA(&winClass);
// 2 ´´½¨´°¿Ú
HWND hWnd = CreateWindowExA(
NULL,
"Raster",
"Raster",
WS_OVERLAPPEDWINDOW,
0,
0,
800,
600,
0,
0,
hInstance,
0
);
UpdateWindow( hWnd );
ShowWindow(hWnd,SW_SHOW);
RECT rt = {0};
GetClientRect(hWnd,&rt);
int width = rt.right - rt.left;
int height = rt.bottom - rt.top;
void* buffer = 0;
HDC hDC = GetDC(hWnd);
HDC hMem = ::CreateCompatibleDC(hDC);
BITMAPINFO bmpInfor;
bmpInfor.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfor.bmiHeader.biWidth = width;
bmpInfor.bmiHeader.biHeight = -height;
bmpInfor.bmiHeader.biPlanes = 1;
bmpInfor.bmiHeader.biBitCount = 32;
bmpInfor.bmiHeader.biCompression = BI_RGB;
bmpInfor.bmiHeader.biSizeImage = 0;
bmpInfor.bmiHeader.biXPelsPerMeter = 0;
bmpInfor.bmiHeader.biYPelsPerMeter = 0;
bmpInfor.bmiHeader.biClrUsed = 0;
bmpInfor.bmiHeader.biClrImportant = 0;
HBITMAP hBmp = CreateDIBSection(hDC,&bmpInfor,DIB_RGB_COLORS,(void**)&buffer,0,0);
SelectObject(hMem,hBmp);
char szPath[1024];
getResourcePath(0,szPath);
char szImage[1024];
sprintf(szImage,"%s/image/bg.png",szPath);
CELL::Image* image = CELL::Image::loadFromFile(szImage);
sprintf(szImage,"%s/image/scale.jpg",szPath);
CELL::Image* image1 = CELL::Image::loadFromFile(szImage);
CELL::Raster raster(width,height,buffer);
struct Vertex
{
float x,y,z;
float u,v;
CELL::Rgba color;
};
MSG msg = {0};
while(true)
{
if (msg.message == WM_DESTROY
||msg.message == WM_CLOSE
||msg.message == WM_QUIT)
{
break;
}
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
raster.clear();
CELL::CELLTimestamp tms;
tms.update();
double mis = tms.getElapsedTimeInMicroSec();
char szBuf[128];
sprintf(szBuf,"%f ",mis);
int i = 00;
memcpy(buffer,raster._buffer,raster._width * raster._height * sizeof(CELL::Rgba));
raster.drawImage(0,0,image);
Vertex vertexs[] =
{
{10, 10, 0, 0.0f, 0.0f, CELL::Rgba(255,255,255,255)},
{110, 110, 0, 1.0f, 1.0f, CELL::Rgba(255,255,255,255)},
{110, 10, 0, 1.0f, 0.0f, CELL::Rgba(255,255,255,255)},
{10, 10, 0, 0.0f, 0.0f, CELL::Rgba(255,255,255,255)},
{110, 110, 0, 1.0f, 1.0f, CELL::Rgba(255,255,255,255)},
{10, 110, 0, 0.0f, 1.0f, CELL::Rgba(255,255,255,255)},
};
raster.loadIdentity();
image1->setWrapType(1);
raster.bindTexture(image1);
raster.vertexPointer(2,CELL::DT_FLOAT, sizeof(Vertex),&vertexs[0].x);
raster.textureCoordPointer(2,CELL::DT_FLOAT,sizeof(Vertex),&vertexs[0].u);
//raster.colorPointer(4,CELL::DT_BYTE, sizeof(Vertex),&vertexs[0].color);
raster.drawArrays(CELL::DM_TRIANGES,0,6);
//TextOut(hMem,10,10,szBuf,strlen(szBuf));
BitBlt(hDC,0,0,width,height,hMem,0,0,SRCCOPY);
}
delete image;
delete image1;
return 0;
}

5988
example/lesson407-矩阵变换 - 副本/CELLMath.hpp
File diff suppressed because it is too large
View File

53
example/lesson407-矩阵变换 - 副本/CELLTimestamp.hpp

@ -0,0 +1,53 @@
#pragma once
#include <windows.h>
namespace CELL
{
class CELLTimestamp
{
public:
CELLTimestamp()
{
QueryPerformanceFrequency(&_frequency);
QueryPerformanceCounter(&_startCount);
}
~CELLTimestamp()
{}
void update()
{
QueryPerformanceCounter(&_startCount);
}
/**
* »ñÈ¡µ±Ç°Ãë
*/
double getElapsedSecond()
{
return getElapsedTimeInMicroSec() * 0.000001;
}
/**
* »ñÈ¡ºÁÃë
*/
double getElapsedTimeInMilliSec()
{
return this->getElapsedTimeInMicroSec() * 0.001;
}
/**
* »ñȡ΢Ãî
*/
double getElapsedTimeInMicroSec()
{
LARGE_INTEGER endCount;
QueryPerformanceCounter(&endCount);
double startTimeInMicroSec = _startCount.QuadPart * (1000000.0 / _frequency.QuadPart);
double endTimeInMicroSec = endCount.QuadPart * (1000000.0 / _frequency.QuadPart);
return endTimeInMicroSec - startTimeInMicroSec;
}
protected:
LARGE_INTEGER _frequency;
LARGE_INTEGER _startCount;
};
}

80
example/lesson407-矩阵变换 - 副本/Image.hpp

@ -0,0 +1,80 @@
#pragma once
namespace CELL
{
class Image
{
protected:
int _width;
int _height;
uint* _pixel;
int _wrapType;
public:
Image(int w,int h,void* data)
{
_wrapType = 0;
if (w == 0 || h == 0 || data== 0)
{
_width = 0;
_height = 0;
_pixel = 0;
}
else
{
_width = w;
_height = h;
_pixel = new uint[w * h];
memcpy(_pixel,data,w * h * sizeof(uint));
}
}
~Image()
{
delete []_pixel;
}
void setWrapType(int type)
{
_wrapType = type;
}
int width() const
{
return _width;
}
int height() const
{
return _height;
}
Rgba pixelAt(int x,int y) const
{
return Rgba(_pixel[y * _width + x]);
}
Rgba pixelUV(float u,float v)
{
float x = u * _width;
float y = v * _height;
if (_wrapType == 0)
{
return pixelAt((unsigned)(x)%_width,(unsigned)(y)%_height);
}
else
{
if (x >= _width)
{
x = _width - 1;
}
if (y >= _height)
{
y = _height - 1;
}
return pixelAt(x,y);
}
}
public:
static Image* loadFromFile(const char*);
};
}

280
example/lesson407-矩阵变换 - 副本/Raster.cpp

@ -0,0 +1,280 @@
#include "Raster.h"
#include "FreeImage.h"
namespace CELL
{
Image* Image::loadFromFile(const char* fileName)
{
//1 获取图片格式
FREE_IMAGE_FORMAT fifmt = FreeImage_GetFileType(fileName, 0);
if (fifmt == FIF_UNKNOWN)
{
return 0;
}
//2 加载图片
FIBITMAP *dib = FreeImage_Load(fifmt, fileName,0);
FREE_IMAGE_COLOR_TYPE type = FreeImage_GetColorType(dib);
//! 获取数据指针
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);
int pitch = width*4;
BYTE* row = new BYTE[width*4];
for(int j = 0; j < height / 2; j++)
{
memcpy(row,pixels + j * pitch,pitch );
memcpy(pixels + j * pitch,pixels + (height - j - 1) * pitch,pitch );
memcpy(pixels + (height - j - 1) * pitch,row,pitch );
}
delete []row;
Image* image = new Image(width,height,pixels);
FreeImage_Unload(dib);
return image;
}
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;
_matModel = CELL::matrix4(1);
_matProj = CELL::matrix4(1);
_matView = CELL::matrix4(1);
}
Raster::~Raster( void )
{
}
void Raster::clear()
{
memset(_buffer,0,_width * _height * sizeof(Rgba));
}
void Raster::drawImage( int startX,int startY,const Image* image )
{
int left = tmax<int>(startX,0);
int top = tmax<int>(startY,0);
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);
}
}
}
void Raster::drawArrays( DRAWMODE pri,int start,int count )
{
if (_poitionPointer._data == 0)
{
return;
}
DateElementDes colorPointerdesc = _colorPointer;
DateElementDes uvPointerdesc = _uvPointer;
if (colorPointerdesc._data == 0)
{
colorPointerdesc = _defaultColorPointer;
}
if (uvPointerdesc._data == 0)
{
uvPointerdesc = _defaultUVPointer;
}
char* posData = (char*)_poitionPointer._data;
char* cData = (char*)colorPointerdesc._data;
char* uvData = (char*)uvPointerdesc._data;
_mvp = _matProj * _matView;
matrix4 matMV = _matProj * _matView;
matrix4 matRMVP = matMV.transpose();
_frust.loadFrustum(matRMVP);
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;
if(!(_frust.pointInFrustum(p01) || _frust.pointInFrustum(p11) || _frust.pointInFrustum(p21)))
{
continue;
}
p11 = piplineTransform(p11);
p01 = piplineTransform(p01);
p21 = piplineTransform(p21);
//! 转化为屏幕坐标
int2 p0(p01.x,p01.y);
int2 p1(p11.x,p11.y);
int2 p2(p21.x,p21.y);
Rgba* pColor = (Rgba*)cData;
Rgba c0 (*pColor);
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;
}
}
}
void Raster::bindTexture( Image* image )
{
_texture = 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::colorPointer( int size,DATETYPE type,int stride,const void* data )
{
_colorPointer._size = size;
_colorPointer._type = type;
_colorPointer._stride = stride;
_colorPointer._data = data;
}
void Raster::vertexPointer( int size,DATETYPE type,int stride,const void* data )
{
_poitionPointer._size = size;
_poitionPointer._type = type;
_poitionPointer._stride = stride;
_poitionPointer._data = data;
}
void Raster::loadMatrix( const CELL::matrix4& mat )
{
_matModel = mat;
}
void Raster::loadIdentity()
{
_matModel = CELL::matrix4(1);
}
void Raster::loadProjMatrix( const CELL::matrix4& mat )
{
_matProj = mat;
}
void Raster::loadProjIdentity( const CELL::matrix4& mat )
{
_matProj = CELL::matrix4(1);
}
void Raster::loadViewMatrix( const CELL::matrix4& mat )
{
_matView = mat;
}
void Raster::loadViewIdentity( const CELL::matrix4& mat )
{
_matView = CELL::matrix4(1);
}
void Raster::setPerspective( float fovy, float aspect, float zNear, float zFar )
{
_matProj = CELL::perspective<float>(fovy,aspect,zNear,zFar);
}
void Raster::lookat( float3 const & eye,float3 const & center,float3 const & up )
{
_matView = CELL::lookAt(eye,center,up);
}
void Raster::setViewPort( int x,int y,int w,int h )
{
_viewPort.x = w;
_viewPort.y = h;
}
}

373
example/lesson407-矩阵变换 - 副本/Raster.h

@ -0,0 +1,373 @@
#pragma once
#include "CELLMath.hpp"
#include "Image.hpp"
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;
}
}
};
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;
}
}
};
class Raster
{
public:
uint* _buffer;
int _width;
int _height;
Rgba _color;
Image* _texture;
matrix4 _matModel;
matrix4 _matView;
matrix4 _matProj;
matrix4 _mvp;
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);
void bindTexture(Image* image);
void drawArrays(DRAWMODE pri,int start,int count);
protected:
float3 piplineTransform(float3 pos)
{
float4 world(pos.x,pos.y,pos.z,0);
float4 screen = (_mvp) * world;
if (screen.w == 0.0f)
{
return float3(0,0,0);
}
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 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;
int startY = tmax<int>(0,e2._y1);
int endY = tmin<int>(_height,e2._y2);
float pp = 1 - (endY - startY)/yOffset;
scale += pp;
float xOffset1 = e1._x2 - e1._x1;
float scale1 = (float)(e2._y1 - e1._y1)/yOffset1;
float step1 = 1.0f/yOffset1;
int startY1 = tmax<int>(0,e2._y1);
int endY1 = tmin<int>(_height,e2._y2);
float pp1 = 1 - (endY1 - startY1)/yOffset1;
scale1 += pp1;
for (int y = startY ; y < endY ; ++ 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;
}
};
}

222
example/lesson407-矩阵变换 - 副本/lesson407-矩阵变换.vcproj

@ -0,0 +1,222 @@
<?xml version="1.0" encoding="gb2312"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="lesson407-矩阵变换"
ProjectGUID="{4880A4A6-8888-4A22-910F-F65223B5C407}"
RootNamespace="lesson407-矩阵变换"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
IntermediateDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../dependencies"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="FreeImage.lib"
OutputFile="../../bin/$(ConfigurationName)/$(ProjectName).exe"
LinkIncremental="2"
AdditionalLibraryDirectories="../../dependencies"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
IntermediateDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="../../dependencies"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
EnableEnhancedInstructionSet="0"
FloatingPointModel="0"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile="../../bin/$(ConfigurationName)/$(ProjectName).exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../dependencies"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="源文件"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\lesson407.cpp"
>
</File>
</Filter>
<Filter
Name="头文件"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\CELLMath.hpp"
>
</File>
<File
RelativePath=".\Image.hpp"
>
</File>
<File
RelativePath=".\Raster.cpp"
>
</File>
<File
RelativePath=".\Raster.h"
>
</File>
</Filter>
<Filter
Name="资源文件"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
<File
RelativePath=".\1.ppt"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

195
example/lesson407-矩阵变换 - 副本/lesson407.cpp

@ -0,0 +1,195 @@
#include <windows.h>
#include <tchar.h>
#include "Raster.h"
#include "CELLTimestamp.hpp"
LRESULT CALLBACK windowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_SIZE:
break;
case WM_CLOSE:
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
break;
}
return DefWindowProc( hWnd, msg, wParam, lParam );
}
void getResourcePath(HINSTANCE hInstance,char pPath[1024])
{
char szPathName[1024];
char szDriver[64];
char szPath[1024];
GetModuleFileNameA(hInstance,szPathName,sizeof(szPathName));
_splitpath( szPathName, szDriver, szPath, 0, 0 );
sprintf(pPath,"%s%s",szDriver,szPath);
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
// 1 ×¢²á´°¿ÚÀà
::WNDCLASSEXA winClass;
winClass.lpszClassName = "Raster";
winClass.cbSize = sizeof(::WNDCLASSEX);
winClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;
winClass.lpfnWndProc = windowProc;
winClass.hInstance = hInstance;
winClass.hIcon = 0;
winClass.hIconSm = 0;
winClass.hCursor = LoadCursor(NULL, IDC_ARROW);
winClass.hbrBackground = (HBRUSH)(BLACK_BRUSH);
winClass.lpszMenuName = NULL;
winClass.cbClsExtra = 0;
winClass.cbWndExtra = 0;
RegisterClassExA(&winClass);
// 2 ´´½¨´°¿Ú
HWND hWnd = CreateWindowExA(
NULL,
"Raster",
"Raster",
WS_OVERLAPPEDWINDOW,
0,
0,
800,
600,
0,
0,
hInstance,
0
);
UpdateWindow( hWnd );
ShowWindow(hWnd,SW_SHOW);
RECT rt = {0};
GetClientRect(hWnd,&rt);
int width = rt.right - rt.left;
int height = rt.bottom - rt.top;
void* buffer = 0;
HDC hDC = GetDC(hWnd);
HDC hMem = ::CreateCompatibleDC(hDC);
BITMAPINFO bmpInfor;
bmpInfor.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfor.bmiHeader.biWidth = width;
bmpInfor.bmiHeader.biHeight = -height;
bmpInfor.bmiHeader.biPlanes = 1;
bmpInfor.bmiHeader.biBitCount = 32;
bmpInfor.bmiHeader.biCompression = BI_RGB;
bmpInfor.bmiHeader.biSizeImage = 0;
bmpInfor.bmiHeader.biXPelsPerMeter = 0;
bmpInfor.bmiHeader.biYPelsPerMeter = 0;
bmpInfor.bmiHeader.biClrUsed = 0;
bmpInfor.bmiHeader.biClrImportant = 0;
HBITMAP hBmp = CreateDIBSection(hDC,&bmpInfor,DIB_RGB_COLORS,(void**)&buffer,0,0);
SelectObject(hMem,hBmp);
char szPath[1024];
getResourcePath(0,szPath);
char szImage[1024];
sprintf(szImage,"%s/image/bg.png",szPath);
CELL::Image* image = CELL::Image::loadFromFile(szImage);
sprintf(szImage,"%s/image/scale.jpg",szPath);
CELL::Image* image1 = CELL::Image::loadFromFile(szImage);
CELL::Raster raster(width,height,buffer);
raster.setViewPort(0,0,width,height);
raster.setPerspective(60,(float)(width)/(float)(height),0.1,1000);
struct Vertex
{
float x,y,z;
float u,v;
CELL::Rgba color;
};
MSG msg = {0};
while(true)
{
if (msg.message == WM_DESTROY
||msg.message == WM_CLOSE
||msg.message == WM_QUIT)
{
break;
}
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
raster.clear();
CELL::CELLTimestamp tms;
tms.update();
double mis = tms.getElapsedTimeInMicroSec();
char szBuf[128];
sprintf(szBuf,"%f ",mis);
int i = 00;
memcpy(buffer,raster._buffer,raster._width * raster._height * sizeof(CELL::Rgba));
raster.drawImage(0,0,image);
static float angles = 322;
CELL::matrix4 matRot;
matRot.rotateX(angles);
//angles += 1;
Vertex vertexs[] =
{
{-1.0f, 0.0f, -5.0f, 0.0f, 0.0f, CELL::Rgba(255,0,0,255)},
{0.0f, 1.0f, -5.0f, 1.0f, 1.0f, CELL::Rgba(0,255,0,255)},
{1.0f, 0.0f, -5.0f, 1.0f, 0.0f, CELL::Rgba(0,0,255,255)},
{10, 10, 0, 0.0f, 0.0f, CELL::Rgba(255,255,255,255)},
{110, 110, 0, 1.0f, 1.0f, CELL::Rgba(255,255,255,255)},
{10, 110, 0, 0.0f, 1.0f, CELL::Rgba(255,255,255,255)},
};
raster.loadMatrix(matRot);
image1->setWrapType(1);
raster.bindTexture(image1);
raster.vertexPointer(2,CELL::DT_FLOAT, sizeof(Vertex),&vertexs[0].x);
raster.textureCoordPointer(2,CELL::DT_FLOAT,sizeof(Vertex),&vertexs[0].u);
raster.colorPointer(4,CELL::DT_BYTE, sizeof(Vertex),&vertexs[0].color);
raster.drawArrays(CELL::DM_TRIANGES,0,3);
//TextOut(hMem,10,10,szBuf,strlen(szBuf));
BitBlt(hDC,0,0,width,height,hMem,0,0,SRCCOPY);
}
delete image;
delete image1;
return 0;
}

5988
example/lesson407-矩阵变换-y控制完成/CELLMath.hpp
File diff suppressed because it is too large
View File

53
example/lesson407-矩阵变换-y控制完成/CELLTimestamp.hpp

@ -0,0 +1,53 @@
#pragma once
#include <windows.h>
namespace CELL
{
class CELLTimestamp
{
public:
CELLTimestamp()
{
QueryPerformanceFrequency(&_frequency);
QueryPerformanceCounter(&_startCount);
}
~CELLTimestamp()
{}
void update()
{
QueryPerformanceCounter(&_startCount);
}
/**
* »ñÈ¡µ±Ç°Ãë
*/
double getElapsedSecond()
{
return getElapsedTimeInMicroSec() * 0.000001;
}
/**
* »ñÈ¡ºÁÃë
*/
double getElapsedTimeInMilliSec()
{
return this->getElapsedTimeInMicroSec() * 0.001;
}
/**
* »ñȡ΢Ãî
*/
double getElapsedTimeInMicroSec()
{
LARGE_INTEGER endCount;
QueryPerformanceCounter(&endCount);
double startTimeInMicroSec = _startCount.QuadPart * (1000000.0 / _frequency.QuadPart);
double endTimeInMicroSec = endCount.QuadPart * (1000000.0 / _frequency.QuadPart);
return endTimeInMicroSec - startTimeInMicroSec;
}
protected:
LARGE_INTEGER _frequency;
LARGE_INTEGER _startCount;
};
}

80
example/lesson407-矩阵变换-y控制完成/Image.hpp

@ -0,0 +1,80 @@
#pragma once
namespace CELL
{
class Image
{
protected:
int _width;
int _height;
uint* _pixel;
int _wrapType;
public:
Image(int w,int h,void* data)
{
_wrapType = 0;
if (w == 0 || h == 0 || data== 0)
{
_width = 0;
_height = 0;
_pixel = 0;
}
else
{
_width = w;
_height = h;
_pixel = new uint[w * h];
memcpy(_pixel,data,w * h * sizeof(uint));
}
}
~Image()
{
delete []_pixel;
}
void setWrapType(int type)
{
_wrapType = type;
}
int width() const
{
return _width;
}
int height() const
{
return _height;
}
Rgba pixelAt(int x,int y) const
{
return Rgba(_pixel[y * _width + x]);
}
Rgba pixelUV(float u,float v)
{
float x = u * _width;
float y = v * _height;
if (_wrapType == 0)
{
return pixelAt((unsigned)(x)%_width,(unsigned)(y)%_height);
}
else
{
if (x >= _width)
{
x = _width - 1;
}
if (y >= _height)
{
y = _height - 1;
}
return pixelAt(x,y);
}
}
public:
static Image* loadFromFile(const char*);
};
}

280
example/lesson407-矩阵变换-y控制完成/Raster.cpp

@ -0,0 +1,280 @@
#include "Raster.h"
#include "FreeImage.h"
namespace CELL
{
Image* Image::loadFromFile(const char* fileName)
{
//1 获取图片格式
FREE_IMAGE_FORMAT fifmt = FreeImage_GetFileType(fileName, 0);
if (fifmt == FIF_UNKNOWN)
{
return 0;
}
//2 加载图片
FIBITMAP *dib = FreeImage_Load(fifmt, fileName,0);
FREE_IMAGE_COLOR_TYPE type = FreeImage_GetColorType(dib);
//! 获取数据指针
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);
int pitch = width*4;
BYTE* row = new BYTE[width*4];
for(int j = 0; j < height / 2; j++)
{
memcpy(row,pixels + j * pitch,pitch );
memcpy(pixels + j * pitch,pixels + (height - j - 1) * pitch,pitch );
memcpy(pixels + (height - j - 1) * pitch,row,pitch );
}
delete []row;
Image* image = new Image(width,height,pixels);
FreeImage_Unload(dib);
return image;
}
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;
_matModel = CELL::matrix4(1);
_matProj = CELL::matrix4(1);
_matView = CELL::matrix4(1);
}
Raster::~Raster( void )
{
}
void Raster::clear()
{
memset(_buffer,0,_width * _height * sizeof(Rgba));
}
void Raster::drawImage( int startX,int startY,const Image* image )
{
int left = tmax<int>(startX,0);
int top = tmax<int>(startY,0);
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);
}
}
}
void Raster::drawArrays( DRAWMODE pri,int start,int count )
{
if (_poitionPointer._data == 0)
{
return;
}
DateElementDes colorPointerdesc = _colorPointer;
DateElementDes uvPointerdesc = _uvPointer;
if (colorPointerdesc._data == 0)
{
colorPointerdesc = _defaultColorPointer;
}
if (uvPointerdesc._data == 0)
{
uvPointerdesc = _defaultUVPointer;
}
char* posData = (char*)_poitionPointer._data;
char* cData = (char*)colorPointerdesc._data;
char* uvData = (char*)uvPointerdesc._data;
_mvp = _matProj * _matView;
matrix4 matMV = _matProj * _matView;
matrix4 matRMVP = matMV.transpose();
_frust.loadFrustum(matRMVP);
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;
if(!(_frust.pointInFrustum(p01) || _frust.pointInFrustum(p11) || _frust.pointInFrustum(p21)))
{
continue;
}
p11 = piplineTransform(p11);
p01 = piplineTransform(p01);
p21 = piplineTransform(p21);
//! 转化为屏幕坐标
int2 p0(p01.x,p01.y);
int2 p1(p11.x,p11.y);
int2 p2(p21.x,p21.y);
Rgba* pColor = (Rgba*)cData;
Rgba c0 (*pColor);
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;
}
}
}
void Raster::bindTexture( Image* image )
{
_texture = 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::colorPointer( int size,DATETYPE type,int stride,const void* data )
{
_colorPointer._size = size;
_colorPointer._type = type;
_colorPointer._stride = stride;
_colorPointer._data = data;
}
void Raster::vertexPointer( int size,DATETYPE type,int stride,const void* data )
{
_poitionPointer._size = size;
_poitionPointer._type = type;
_poitionPointer._stride = stride;
_poitionPointer._data = data;
}
void Raster::loadMatrix( const CELL::matrix4& mat )
{
_matModel = mat;
}
void Raster::loadIdentity()
{
_matModel = CELL::matrix4(1);
}
void Raster::loadProjMatrix( const CELL::matrix4& mat )
{
_matProj = mat;
}
void Raster::loadProjIdentity( const CELL::matrix4& mat )
{
_matProj = CELL::matrix4(1);
}
void Raster::loadViewMatrix( const CELL::matrix4& mat )
{
_matView = mat;
}
void Raster::loadViewIdentity( const CELL::matrix4& mat )
{
_matView = CELL::matrix4(1);
}
void Raster::setPerspective( float fovy, float aspect, float zNear, float zFar )
{
_matProj = CELL::perspective<float>(fovy,aspect,zNear,zFar);
}
void Raster::lookat( float3 const & eye,float3 const & center,float3 const & up )
{
_matView = CELL::lookAt(eye,center,up);
}
void Raster::setViewPort( int x,int y,int w,int h )
{
_viewPort.x = w;
_viewPort.y = h;
}
}

373
example/lesson407-矩阵变换-y控制完成/Raster.h

@ -0,0 +1,373 @@
#pragma once
#include "CELLMath.hpp"
#include "Image.hpp"
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;
}
}
};
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;
}
}
};
class Raster
{
public:
uint* _buffer;
int _width;
int _height;
Rgba _color;
Image* _texture;
matrix4 _matModel;
matrix4 _matView;
matrix4 _matProj;
matrix4 _mvp;
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);
void bindTexture(Image* image);
void drawArrays(DRAWMODE pri,int start,int count);
protected:
float3 piplineTransform(float3 pos)
{
float4 world(pos.x,pos.y,pos.z,0);
float4 screen = (_mvp) * world;
if (screen.w == 0.0f)
{
return float3(0,0,0);
}
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 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;
int startY = tmax<int>(0,e2._y1);
int endY = tmin<int>(_height,e2._y2);
float pp = (startY -e2._y1)/yOffset;
scale += pp;
float xOffset1 = e1._x2 - e1._x1;
float scale1 = (float)(e2._y1 - e1._y1)/yOffset1;
float step1 = 1.0f/yOffset1;
int startY1 = tmax<int>(0,e1._y1);
int endY1 = tmin<int>(_height,e1._y2);
float pp1 = (startY1 - e1._y1)/yOffset1;
scale1 += pp1;
for (int y = startY ; y < endY ; ++ 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;
}
};
}

222
example/lesson407-矩阵变换-y控制完成/lesson407-矩阵变换.vcproj

@ -0,0 +1,222 @@
<?xml version="1.0" encoding="gb2312"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="lesson407-矩阵变换"
ProjectGUID="{4880A4A6-8888-4A22-910F-F65223B5C407}"
RootNamespace="lesson407-矩阵变换"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
IntermediateDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../dependencies"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="FreeImage.lib"
OutputFile="../../bin/$(ConfigurationName)/$(ProjectName).exe"
LinkIncremental="2"
AdditionalLibraryDirectories="../../dependencies"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
IntermediateDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="../../dependencies"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
EnableEnhancedInstructionSet="0"
FloatingPointModel="0"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile="../../bin/$(ConfigurationName)/$(ProjectName).exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../dependencies"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="源文件"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\lesson407.cpp"
>
</File>
</Filter>
<Filter
Name="头文件"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\CELLMath.hpp"
>
</File>
<File
RelativePath=".\Image.hpp"
>
</File>
<File
RelativePath=".\Raster.cpp"
>
</File>
<File
RelativePath=".\Raster.h"
>
</File>
</Filter>
<Filter
Name="资源文件"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
<File
RelativePath=".\1.ppt"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

195
example/lesson407-矩阵变换-y控制完成/lesson407.cpp

@ -0,0 +1,195 @@
#include <windows.h>
#include <tchar.h>
#include "Raster.h"
#include "CELLTimestamp.hpp"
LRESULT CALLBACK windowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_SIZE:
break;
case WM_CLOSE:
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
break;
}
return DefWindowProc( hWnd, msg, wParam, lParam );
}
void getResourcePath(HINSTANCE hInstance,char pPath[1024])
{
char szPathName[1024];
char szDriver[64];
char szPath[1024];
GetModuleFileNameA(hInstance,szPathName,sizeof(szPathName));
_splitpath( szPathName, szDriver, szPath, 0, 0 );
sprintf(pPath,"%s%s",szDriver,szPath);
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
// 1 ×¢²á´°¿ÚÀà
::WNDCLASSEXA winClass;
winClass.lpszClassName = "Raster";
winClass.cbSize = sizeof(::WNDCLASSEX);
winClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;
winClass.lpfnWndProc = windowProc;
winClass.hInstance = hInstance;
winClass.hIcon = 0;
winClass.hIconSm = 0;
winClass.hCursor = LoadCursor(NULL, IDC_ARROW);
winClass.hbrBackground = (HBRUSH)(BLACK_BRUSH);
winClass.lpszMenuName = NULL;
winClass.cbClsExtra = 0;
winClass.cbWndExtra = 0;
RegisterClassExA(&winClass);
// 2 ´´½¨´°¿Ú
HWND hWnd = CreateWindowExA(
NULL,
"Raster",
"Raster",
WS_OVERLAPPEDWINDOW,
0,
0,
800,
600,
0,
0,
hInstance,
0
);
UpdateWindow( hWnd );
ShowWindow(hWnd,SW_SHOW);
RECT rt = {0};
GetClientRect(hWnd,&rt);
int width = rt.right - rt.left;
int height = rt.bottom - rt.top;
void* buffer = 0;
HDC hDC = GetDC(hWnd);
HDC hMem = ::CreateCompatibleDC(hDC);
BITMAPINFO bmpInfor;
bmpInfor.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfor.bmiHeader.biWidth = width;
bmpInfor.bmiHeader.biHeight = -height;
bmpInfor.bmiHeader.biPlanes = 1;
bmpInfor.bmiHeader.biBitCount = 32;
bmpInfor.bmiHeader.biCompression = BI_RGB;
bmpInfor.bmiHeader.biSizeImage = 0;
bmpInfor.bmiHeader.biXPelsPerMeter = 0;
bmpInfor.bmiHeader.biYPelsPerMeter = 0;
bmpInfor.bmiHeader.biClrUsed = 0;
bmpInfor.bmiHeader.biClrImportant = 0;
HBITMAP hBmp = CreateDIBSection(hDC,&bmpInfor,DIB_RGB_COLORS,(void**)&buffer,0,0);
SelectObject(hMem,hBmp);
char szPath[1024];
getResourcePath(0,szPath);
char szImage[1024];
sprintf(szImage,"%s/image/bg.png",szPath);
CELL::Image* image = CELL::Image::loadFromFile(szImage);
sprintf(szImage,"%s/image/scale.jpg",szPath);
CELL::Image* image1 = CELL::Image::loadFromFile(szImage);
CELL::Raster raster(width,height,buffer);
raster.setViewPort(0,0,width,height);
raster.setPerspective(60,(float)(width)/(float)(height),0.1,1000);
struct Vertex
{
float x,y,z;
float u,v;
CELL::Rgba color;
};
MSG msg = {0};
while(true)
{
if (msg.message == WM_DESTROY
||msg.message == WM_CLOSE
||msg.message == WM_QUIT)
{
break;
}
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
raster.clear();
CELL::CELLTimestamp tms;
tms.update();
double mis = tms.getElapsedTimeInMicroSec();
char szBuf[128];
sprintf(szBuf,"%f ",mis);
int i = 00;
memcpy(buffer,raster._buffer,raster._width * raster._height * sizeof(CELL::Rgba));
raster.drawImage(0,0,image);
static float angles = 22;
CELL::matrix4 matRot;
matRot.rotateX(angles);
angles += 1;
Vertex vertexs[] =
{
{-1.0f, 0.0f, -5.0f, 0.0f, 0.0f, CELL::Rgba(255,0,0,255)},
{0.0f, 1.0f, -5.0f, 1.0f, 1.0f, CELL::Rgba(0,255,0,255)},
{1.0f, 0.0f, -5.0f, 1.0f, 0.0f, CELL::Rgba(0,0,255,255)},
{10, 10, 0, 0.0f, 0.0f, CELL::Rgba(255,255,255,255)},
{110, 110, 0, 1.0f, 1.0f, CELL::Rgba(255,255,255,255)},
{10, 110, 0, 0.0f, 1.0f, CELL::Rgba(255,255,255,255)},
};
raster.loadMatrix(matRot);
image1->setWrapType(1);
raster.bindTexture(image1);
raster.vertexPointer(2,CELL::DT_FLOAT, sizeof(Vertex),&vertexs[0].x);
raster.textureCoordPointer(2,CELL::DT_FLOAT,sizeof(Vertex),&vertexs[0].u);
raster.colorPointer(4,CELL::DT_BYTE, sizeof(Vertex),&vertexs[0].color);
raster.drawArrays(CELL::DM_TRIANGES,0,3);
//TextOut(hMem,10,10,szBuf,strlen(szBuf));
BitBlt(hDC,0,0,width,height,hMem,0,0,SRCCOPY);
}
delete image;
delete image1;
return 0;
}

5988
example/lesson407-矩阵变换/CELLMath.hpp
File diff suppressed because it is too large
View File

53
example/lesson407-矩阵变换/CELLTimestamp.hpp

@ -0,0 +1,53 @@
#pragma once
#include <windows.h>
namespace CELL
{
class CELLTimestamp
{
public:
CELLTimestamp()
{
QueryPerformanceFrequency(&_frequency);
QueryPerformanceCounter(&_startCount);
}
~CELLTimestamp()
{}
void update()
{
QueryPerformanceCounter(&_startCount);
}
/**
* »ñÈ¡µ±Ç°Ãë
*/
double getElapsedSecond()
{
return getElapsedTimeInMicroSec() * 0.000001;
}
/**
* »ñÈ¡ºÁÃë
*/
double getElapsedTimeInMilliSec()
{
return this->getElapsedTimeInMicroSec() * 0.001;
}
/**
* »ñȡ΢Ãî
*/
double getElapsedTimeInMicroSec()
{
LARGE_INTEGER endCount;
QueryPerformanceCounter(&endCount);
double startTimeInMicroSec = _startCount.QuadPart * (1000000.0 / _frequency.QuadPart);
double endTimeInMicroSec = endCount.QuadPart * (1000000.0 / _frequency.QuadPart);
return endTimeInMicroSec - startTimeInMicroSec;
}
protected:
LARGE_INTEGER _frequency;
LARGE_INTEGER _startCount;
};
}

80
example/lesson407-矩阵变换/Image.hpp

@ -0,0 +1,80 @@
#pragma once
namespace CELL
{
class Image
{
protected:
int _width;
int _height;
uint* _pixel;
int _wrapType;
public:
Image(int w,int h,void* data)
{
_wrapType = 0;
if (w == 0 || h == 0 || data== 0)
{
_width = 0;
_height = 0;
_pixel = 0;
}
else
{
_width = w;
_height = h;
_pixel = new uint[w * h];
memcpy(_pixel,data,w * h * sizeof(uint));
}
}
~Image()
{
delete []_pixel;
}
void setWrapType(int type)
{
_wrapType = type;
}
int width() const
{
return _width;
}
int height() const
{
return _height;
}
Rgba pixelAt(int x,int y) const
{
return Rgba(_pixel[y * _width + x]);
}
Rgba pixelUV(float u,float v)
{
float x = u * _width;
float y = v * _height;
if (_wrapType == 0)
{
return pixelAt((unsigned)(x)%_width,(unsigned)(y)%_height);
}
else
{
if (x >= _width)
{
x = _width - 1;
}
if (y >= _height)
{
y = _height - 1;
}
return pixelAt(x,y);
}
}
public:
static Image* loadFromFile(const char*);
};
}

280
example/lesson407-矩阵变换/Raster.cpp

@ -0,0 +1,280 @@
#include "Raster.h"
#include "FreeImage.h"
namespace CELL
{
Image* Image::loadFromFile(const char* fileName)
{
//1 获取图片格式
FREE_IMAGE_FORMAT fifmt = FreeImage_GetFileType(fileName, 0);
if (fifmt == FIF_UNKNOWN)
{
return 0;
}
//2 加载图片
FIBITMAP *dib = FreeImage_Load(fifmt, fileName,0);
FREE_IMAGE_COLOR_TYPE type = FreeImage_GetColorType(dib);
//! 获取数据指针
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);
int pitch = width*4;
BYTE* row = new BYTE[width*4];
for(int j = 0; j < height / 2; j++)
{
memcpy(row,pixels + j * pitch,pitch );
memcpy(pixels + j * pitch,pixels + (height - j - 1) * pitch,pitch );
memcpy(pixels + (height - j - 1) * pitch,row,pitch );
}
delete []row;
Image* image = new Image(width,height,pixels);
FreeImage_Unload(dib);
return image;
}
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;
_matModel = CELL::matrix4(1);
_matProj = CELL::matrix4(1);
_matView = CELL::matrix4(1);
}
Raster::~Raster( void )
{
}
void Raster::clear()
{
memset(_buffer,0,_width * _height * sizeof(Rgba));
}
void Raster::drawImage( int startX,int startY,const Image* image )
{
int left = tmax<int>(startX,0);
int top = tmax<int>(startY,0);
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);
}
}
}
void Raster::drawArrays( DRAWMODE pri,int start,int count )
{
if (_poitionPointer._data == 0)
{
return;
}
DateElementDes colorPointerdesc = _colorPointer;
DateElementDes uvPointerdesc = _uvPointer;
if (colorPointerdesc._data == 0)
{
colorPointerdesc = _defaultColorPointer;
}
if (uvPointerdesc._data == 0)
{
uvPointerdesc = _defaultUVPointer;
}
char* posData = (char*)_poitionPointer._data;
char* cData = (char*)colorPointerdesc._data;
char* uvData = (char*)uvPointerdesc._data;
_mvp = _matProj * _matView;
matrix4 matMV = _matProj * _matView;
matrix4 matRMVP = matMV.transpose();
_frust.loadFrustum(matRMVP);
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;
if(!(_frust.pointInFrustum(p01) || _frust.pointInFrustum(p11) || _frust.pointInFrustum(p21)))
{
continue;
}
p11 = piplineTransform(p11);
p01 = piplineTransform(p01);
p21 = piplineTransform(p21);
//! 转化为屏幕坐标
int2 p0(p01.x,p01.y);
int2 p1(p11.x,p11.y);
int2 p2(p21.x,p21.y);
Rgba* pColor = (Rgba*)cData;
Rgba c0 (*pColor);
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;
}
}
}
void Raster::bindTexture( Image* image )
{
_texture = 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::colorPointer( int size,DATETYPE type,int stride,const void* data )
{
_colorPointer._size = size;
_colorPointer._type = type;
_colorPointer._stride = stride;
_colorPointer._data = data;
}
void Raster::vertexPointer( int size,DATETYPE type,int stride,const void* data )
{
_poitionPointer._size = size;
_poitionPointer._type = type;
_poitionPointer._stride = stride;
_poitionPointer._data = data;
}
void Raster::loadMatrix( const CELL::matrix4& mat )
{
_matModel = mat;
}
void Raster::loadIdentity()
{
_matModel = CELL::matrix4(1);
}
void Raster::loadProjMatrix( const CELL::matrix4& mat )
{
_matProj = mat;
}
void Raster::loadProjIdentity( const CELL::matrix4& mat )
{
_matProj = CELL::matrix4(1);
}
void Raster::loadViewMatrix( const CELL::matrix4& mat )
{
_matView = mat;
}
void Raster::loadViewIdentity( const CELL::matrix4& mat )
{
_matView = CELL::matrix4(1);
}
void Raster::setPerspective( float fovy, float aspect, float zNear, float zFar )
{
_matProj = CELL::perspective<float>(fovy,aspect,zNear,zFar);
}
void Raster::lookat( float3 const & eye,float3 const & center,float3 const & up )
{
_matView = CELL::lookAt(eye,center,up);
}
void Raster::setViewPort( int x,int y,int w,int h )
{
_viewPort.x = w;
_viewPort.y = h;
}
}

378
example/lesson407-矩阵变换/Raster.h

@ -0,0 +1,378 @@
#pragma once
#include "CELLMath.hpp"
#include "Image.hpp"
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;
}
}
};
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;
}
}
};
class Raster
{
public:
uint* _buffer;
int _width;
int _height;
Rgba _color;
Image* _texture;
matrix4 _matModel;
matrix4 _matView;
matrix4 _matProj;
matrix4 _mvp;
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);
void bindTexture(Image* image);
void drawArrays(DRAWMODE pri,int start,int count);
protected:
float3 piplineTransform(float3 pos)
{
float4 world(pos.x,pos.y,pos.z,0);
float4 screen = (_mvp) * world;
if (screen.w == 0.0f)
{
return float3(0,0,0);
}
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 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;
int startY = tmax<int>(0,e2._y1);
int endY = tmin<int>(_height,e2._y2);
float pp = (startY -e2._y1)/yOffset;
scale += pp;
float xOffset1 = e1._x2 - e1._x1;
float scale1 = (float)(e2._y1 - e1._y1)/yOffset1;
float step1 = 1.0f/yOffset1;
int startY1 = tmax<int>(0,e1._y1);
int endY1 = tmin<int>(_height,e1._y2);
float pp1 = (startY1 - e1._y1)/yOffset1;
scale1 += pp1;
for (int y = startY ; y < endY ; ++ 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;
int startX = tmax<int>(0,span._xStart);
int endX = tmin<int>(_width,span._xEnd);
float scale = (startX - span._xStart)/length ;
float step = 1.0f/length;
for (int x = startX ; x < endX; ++ 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;
}
};
}

222
example/lesson407-矩阵变换/lesson407-矩阵变换.vcproj

@ -0,0 +1,222 @@
<?xml version="1.0" encoding="gb2312"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="lesson407-矩阵变换"
ProjectGUID="{4880A4A6-8888-4A22-910F-F65223B5C407}"
RootNamespace="lesson407-矩阵变换"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
IntermediateDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../dependencies"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="FreeImage.lib"
OutputFile="../../bin/$(ConfigurationName)/$(ProjectName).exe"
LinkIncremental="2"
AdditionalLibraryDirectories="../../dependencies"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
IntermediateDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="../../dependencies"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
EnableEnhancedInstructionSet="0"
FloatingPointModel="0"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile="../../bin/$(ConfigurationName)/$(ProjectName).exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../dependencies"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="源文件"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\lesson407.cpp"
>
</File>
</Filter>
<Filter
Name="头文件"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\CELLMath.hpp"
>
</File>
<File
RelativePath=".\Image.hpp"
>
</File>
<File
RelativePath=".\Raster.cpp"
>
</File>
<File
RelativePath=".\Raster.h"
>
</File>
</Filter>
<Filter
Name="资源文件"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
<File
RelativePath=".\1.ppt"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

195
example/lesson407-矩阵变换/lesson407.cpp

@ -0,0 +1,195 @@
#include <windows.h>
#include <tchar.h>
#include "Raster.h"
#include "CELLTimestamp.hpp"
LRESULT CALLBACK windowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_SIZE:
break;
case WM_CLOSE:
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
break;
}
return DefWindowProc( hWnd, msg, wParam, lParam );
}
void getResourcePath(HINSTANCE hInstance,char pPath[1024])
{
char szPathName[1024];
char szDriver[64];
char szPath[1024];
GetModuleFileNameA(hInstance,szPathName,sizeof(szPathName));
_splitpath( szPathName, szDriver, szPath, 0, 0 );
sprintf(pPath,"%s%s",szDriver,szPath);
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
// 1 ×¢²á´°¿ÚÀà
::WNDCLASSEXA winClass;
winClass.lpszClassName = "Raster";
winClass.cbSize = sizeof(::WNDCLASSEX);
winClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;
winClass.lpfnWndProc = windowProc;
winClass.hInstance = hInstance;
winClass.hIcon = 0;
winClass.hIconSm = 0;
winClass.hCursor = LoadCursor(NULL, IDC_ARROW);
winClass.hbrBackground = (HBRUSH)(BLACK_BRUSH);
winClass.lpszMenuName = NULL;
winClass.cbClsExtra = 0;
winClass.cbWndExtra = 0;
RegisterClassExA(&winClass);
// 2 ´´½¨´°¿Ú
HWND hWnd = CreateWindowExA(
NULL,
"Raster",
"Raster",
WS_OVERLAPPEDWINDOW,
0,
0,
800,
600,
0,
0,
hInstance,
0
);
UpdateWindow( hWnd );
ShowWindow(hWnd,SW_SHOW);
RECT rt = {0};
GetClientRect(hWnd,&rt);
int width = rt.right - rt.left;
int height = rt.bottom - rt.top;
void* buffer = 0;
HDC hDC = GetDC(hWnd);
HDC hMem = ::CreateCompatibleDC(hDC);
BITMAPINFO bmpInfor;
bmpInfor.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfor.bmiHeader.biWidth = width;
bmpInfor.bmiHeader.biHeight = -height;
bmpInfor.bmiHeader.biPlanes = 1;
bmpInfor.bmiHeader.biBitCount = 32;
bmpInfor.bmiHeader.biCompression = BI_RGB;
bmpInfor.bmiHeader.biSizeImage = 0;
bmpInfor.bmiHeader.biXPelsPerMeter = 0;
bmpInfor.bmiHeader.biYPelsPerMeter = 0;
bmpInfor.bmiHeader.biClrUsed = 0;
bmpInfor.bmiHeader.biClrImportant = 0;
HBITMAP hBmp = CreateDIBSection(hDC,&bmpInfor,DIB_RGB_COLORS,(void**)&buffer,0,0);
SelectObject(hMem,hBmp);
char szPath[1024];
getResourcePath(0,szPath);
char szImage[1024];
sprintf(szImage,"%s/image/bg.png",szPath);
CELL::Image* image = CELL::Image::loadFromFile(szImage);
sprintf(szImage,"%s/image/scale.jpg",szPath);
CELL::Image* image1 = CELL::Image::loadFromFile(szImage);
CELL::Raster raster(width,height,buffer);
raster.setViewPort(0,0,width,height);
raster.setPerspective(60,(float)(width)/(float)(height),0.1,1000);
struct Vertex
{
float x,y,z;
float u,v;
CELL::Rgba color;
};
MSG msg = {0};
while(true)
{
if (msg.message == WM_DESTROY
||msg.message == WM_CLOSE
||msg.message == WM_QUIT)
{
break;
}
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
raster.clear();
CELL::CELLTimestamp tms;
tms.update();
double mis = tms.getElapsedTimeInMicroSec();
char szBuf[128];
sprintf(szBuf,"%f ",mis);
int i = 00;
memcpy(buffer,raster._buffer,raster._width * raster._height * sizeof(CELL::Rgba));
raster.drawImage(0,0,image);
static float angles = 22;
CELL::matrix4 matRot;
matRot.rotateX(angles);
angles += 1;
Vertex vertexs[] =
{
{-3.0f, 0.0f, -2.0f, 0.0f, 0.0f, CELL::Rgba(255,0,0,255)},
{0.0f, 1.0f, -2.0f, 1.0f, 1.0f, CELL::Rgba(0,255,0,255)},
{1.0f, 0.0f, -2.0f, 1.0f, 0.0f, CELL::Rgba(0,0,255,255)},
{10, 10, 0, 0.0f, 0.0f, CELL::Rgba(255,255,255,255)},
{110, 110, 0, 1.0f, 1.0f, CELL::Rgba(255,255,255,255)},
{10, 110, 0, 0.0f, 1.0f, CELL::Rgba(255,255,255,255)},
};
raster.loadMatrix(matRot);
image1->setWrapType(1);
raster.bindTexture(image1);
raster.vertexPointer(2,CELL::DT_FLOAT, sizeof(Vertex),&vertexs[0].x);
raster.textureCoordPointer(2,CELL::DT_FLOAT,sizeof(Vertex),&vertexs[0].u);
raster.colorPointer(4,CELL::DT_BYTE, sizeof(Vertex),&vertexs[0].color);
raster.drawArrays(CELL::DM_TRIANGES,0,3);
//TextOut(hMem,10,10,szBuf,strlen(szBuf));
BitBlt(hDC,0,0,width,height,hMem,0,0,SRCCOPY);
}
delete image;
delete image1;
return 0;
}

5978
example/lesson407-绘制第一个3D三角形/CELLMath.hpp
File diff suppressed because it is too large
View File

53
example/lesson407-绘制第一个3D三角形/CELLTimestamp.hpp

@ -0,0 +1,53 @@
#pragma once
#include <windows.h>
namespace CELL
{
class CELLTimestamp
{
public:
CELLTimestamp()
{
QueryPerformanceFrequency(&_frequency);
QueryPerformanceCounter(&_startCount);
}
~CELLTimestamp()
{}
void update()
{
QueryPerformanceCounter(&_startCount);
}
/**
* »ñÈ¡µ±Ç°Ãë
*/
double getElapsedSecond()
{
return getElapsedTimeInMicroSec() * 0.000001;
}
/**
* »ñÈ¡ºÁÃë
*/
double getElapsedTimeInMilliSec()
{
return this->getElapsedTimeInMicroSec() * 0.001;
}
/**
* »ñȡ΢Ãî
*/
double getElapsedTimeInMicroSec()
{
LARGE_INTEGER endCount;
QueryPerformanceCounter(&endCount);
double startTimeInMicroSec = _startCount.QuadPart * (1000000.0 / _frequency.QuadPart);
double endTimeInMicroSec = endCount.QuadPart * (1000000.0 / _frequency.QuadPart);
return endTimeInMicroSec - startTimeInMicroSec;
}
protected:
LARGE_INTEGER _frequency;
LARGE_INTEGER _startCount;
};
}

80
example/lesson407-绘制第一个3D三角形/Image.hpp

@ -0,0 +1,80 @@
#pragma once
namespace CELL
{
class Image
{
protected:
int _width;
int _height;
uint* _pixel;
int _wrapType;
public:
Image(int w,int h,void* data)
{
_wrapType = 0;
if (w == 0 || h == 0 || data== 0)
{
_width = 0;
_height = 0;
_pixel = 0;
}
else
{
_width = w;
_height = h;
_pixel = new uint[w * h];
memcpy(_pixel,data,w * h * sizeof(uint));
}
}
~Image()
{
delete []_pixel;
}
void setWrapType(int type)
{
_wrapType = type;
}
int width() const
{
return _width;
}
int height() const
{
return _height;
}
Rgba pixelAt(int x,int y) const
{
return Rgba(_pixel[y * _width + x]);
}
Rgba pixelUV(float u,float v)
{
float x = u * _width;
float y = v * _height;
if (_wrapType == 0)
{
return pixelAt((unsigned)(x)%_width,(unsigned)(y)%_height);
}
else
{
if (x >= _width)
{
x = _width - 1;
}
if (y >= _height)
{
y = _height - 1;
}
return pixelAt(x,y);
}
}
public:
static Image* loadFromFile(const char*);
};
}

278
example/lesson407-绘制第一个3D三角形/Raster.cpp

@ -0,0 +1,278 @@
#include "Raster.h"
#include "FreeImage.h"
namespace CELL
{
Image* Image::loadFromFile(const char* fileName)
{
//1 获取图片格式
FREE_IMAGE_FORMAT fifmt = FreeImage_GetFileType(fileName, 0);
if (fifmt == FIF_UNKNOWN)
{
return 0;
}
//2 加载图片
FIBITMAP *dib = FreeImage_Load(fifmt, fileName,0);
FREE_IMAGE_COLOR_TYPE type = FreeImage_GetColorType(dib);
//! 获取数据指针
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);
int pitch = width*4;
BYTE* row = new BYTE[width*4];
for(int j = 0; j < height / 2; j++)
{
memcpy(row,pixels + j * pitch,pitch );
memcpy(pixels + j * pitch,pixels + (height - j - 1) * pitch,pitch );
memcpy(pixels + (height - j - 1) * pitch,row,pitch );
}
delete []row;
Image* image = new Image(width,height,pixels);
FreeImage_Unload(dib);
return image;
}
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;
_matModel = CELL::matrix4(1);
_matView = CELL::matrix4(1);
_matProj = CELL::matrix4(1);
}
Raster::~Raster( void )
{
}
void Raster::clear()
{
memset(_buffer,0,_width * _height * sizeof(Rgba));
}
void Raster::drawImage( int startX,int startY,const Image* image )
{
int left = tmax<int>(startX,0);
int top = tmax<int>(startY,0);
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);
}
}
}
void Raster::drawArrays( DRAWMODE pri,int start,int count )
{
if (_poitionPointer._data == 0)
{
return;
}
DateElementDes colorPointerdesc = _colorPointer;
DateElementDes uvPointerdesc = _uvPointer;
if (colorPointerdesc._data == 0)
{
colorPointerdesc = _defaultColorPointer;
}
if (uvPointerdesc._data == 0)
{
uvPointerdesc = _defaultUVPointer;
}
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;
if ( _frust.pointInFrustum(p01)
|| _frust.pointInFrustum(p11)
|| _frust.pointInFrustum(p21)
)
{
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;
}
}
}
}
void Raster::bindTexture( Image* image )
{
_texture = 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::colorPointer( int size,DATETYPE type,int stride,const void* data )
{
_colorPointer._size = size;
_colorPointer._type = type;
_colorPointer._stride = stride;
_colorPointer._data = data;
}
void Raster::vertexPointer( int size,DATETYPE type,int stride,const void* data )
{
_poitionPointer._size = size;
_poitionPointer._type = type;
_poitionPointer._stride = stride;
_poitionPointer._data = data;
}
void Raster::loadMatrix( const CELL::matrix4& mat )
{
_matModel = mat;
}
void Raster::loadIdentity()
{
_matModel = CELL::matrix4(1);
}
void Raster::loadProjMatrix( const CELL::matrix4& mat )
{
_matProj = mat;
}
void Raster::loadProjIdentity( const CELL::matrix4& mat )
{
_matProj = CELL::matrix4(1);
}
void Raster::loadViewMatrix( const CELL::matrix4& mat )
{
_matView = mat;
}
void Raster::loadViewIdentity( const CELL::matrix4& mat )
{
_matView = CELL::matrix4(1);
}
void Raster::setPerspective( float fovy, float aspect, float zNear, float zFar )
{
_matProj = CELL::perspective<float>(fovy,aspect,zNear,zFar);
}
void Raster::lookat( float3 const & eye,float3 const & center,float3 const & up )
{
_matView = CELL::lookAt(eye,center,up);
}
void Raster::setViewPort( int x,int y,int w,int h )
{
_viewPort.x = w;
_viewPort.y = h;
}
}

361
example/lesson407-绘制第一个3D三角形/Raster.h

@ -0,0 +1,361 @@
#pragma once
#include "CELLMath.hpp"
#include "Image.hpp"
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;
}
}
};
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;
}
}
};
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);
void bindTexture(Image* image);
void drawArrays(DRAWMODE pri,int start,int count);
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;
}
};
}

223
example/lesson407-绘制第一个3D三角形/lesson407-固定渲染管线实现-裁减.vcproj

@ -0,0 +1,223 @@
<?xml version="1.0" encoding="gb2312"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="lesson407-绘制第一个3D三角形"
ProjectGUID="{4880A4A6-8888-8A22-910F-F65223B5C407}"
RootNamespace="lesson407-绘制第一个3D三角形"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
IntermediateDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../dependencies"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="FreeImage.lib"
OutputFile="../../bin/$(ConfigurationName)/$(ProjectName).exe"
LinkIncremental="2"
AdditionalLibraryDirectories="../../dependencies"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
IntermediateDirectory="../../temp/$(ConfigurationName)/$(ProjectName)"
ConfigurationType="1"
CharacterSet="2"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="../../dependencies"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
EnableEnhancedInstructionSet="0"
FloatingPointModel="0"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="FreeImage.lib"
OutputFile="../../bin/$(ConfigurationName)/$(ProjectName).exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../dependencies"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="源文件"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\lesson407.cpp"
>
</File>
</Filter>
<Filter
Name="头文件"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\CELLMath.hpp"
>
</File>
<File
RelativePath=".\Image.hpp"
>
</File>
<File
RelativePath=".\Raster.cpp"
>
</File>
<File
RelativePath=".\Raster.h"
>
</File>
</Filter>
<Filter
Name="资源文件"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
<File
RelativePath=".\1.ppt"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

183
example/lesson407-绘制第一个3D三角形/lesson407.cpp

@ -0,0 +1,183 @@
#include <windows.h>
#include <tchar.h>
#include "Raster.h"
#include "CELLTimestamp.hpp"
LRESULT CALLBACK windowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_SIZE:
break;
case WM_CLOSE:
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
break;
}
return DefWindowProc( hWnd, msg, wParam, lParam );
}
void getResourcePath(HINSTANCE hInstance,char pPath[1024])
{
char szPathName[1024];
char szDriver[64];
char szPath[1024];
GetModuleFileNameA(hInstance,szPathName,sizeof(szPathName));
_splitpath( szPathName, szDriver, szPath, 0, 0 );
sprintf(pPath,"%s%s",szDriver,szPath);
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
// 1 ×¢²á´°¿ÚÀà
::WNDCLASSEXA winClass;
winClass.lpszClassName = "Raster";
winClass.cbSize = sizeof(::WNDCLASSEX);
winClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;
winClass.lpfnWndProc = windowProc;
winClass.hInstance = hInstance;
winClass.hIcon = 0;
winClass.hIconSm = 0;
winClass.hCursor = LoadCursor(NULL, IDC_ARROW);
winClass.hbrBackground = (HBRUSH)(BLACK_BRUSH);
winClass.lpszMenuName = NULL;
winClass.cbClsExtra = 0;
winClass.cbWndExtra = 0;
RegisterClassExA(&winClass);
// 2 ´´½¨´°¿Ú
HWND hWnd = CreateWindowExA(
NULL,
"Raster",
"Raster",
WS_OVERLAPPEDWINDOW,
0,
0,
800,
600,
0,
0,
hInstance,
0
);
UpdateWindow( hWnd );
ShowWindow(hWnd,SW_SHOW);
RECT rt = {0};
GetClientRect(hWnd,&rt);
int width = rt.right - rt.left;
int height = rt.bottom - rt.top;
void* buffer = 0;
HDC hDC = GetDC(hWnd);
HDC hMem = ::CreateCompatibleDC(hDC);
BITMAPINFO bmpInfor;
bmpInfor.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfor.bmiHeader.biWidth = width;
bmpInfor.bmiHeader.biHeight = -height;
bmpInfor.bmiHeader.biPlanes = 1;
bmpInfor.bmiHeader.biBitCount = 32;
bmpInfor.bmiHeader.biCompression = BI_RGB;
bmpInfor.bmiHeader.biSizeImage = 0;
bmpInfor.bmiHeader.biXPelsPerMeter = 0;
bmpInfor.bmiHeader.biYPelsPerMeter = 0;
bmpInfor.bmiHeader.biClrUsed = 0;
bmpInfor.bmiHeader.biClrImportant = 0;
HBITMAP hBmp = CreateDIBSection(hDC,&bmpInfor,DIB_RGB_COLORS,(void**)&buffer,0,0);
SelectObject(hMem,hBmp);
char szPath[1024];
getResourcePath(0,szPath);
char szImage[1024];
sprintf(szImage,"%s/image/bg.png",szPath);
CELL::Image* image = CELL::Image::loadFromFile(szImage);
sprintf(szImage,"%s/image/scale.jpg",szPath);
CELL::Image* image1 = CELL::Image::loadFromFile(szImage);
CELL::Raster raster(width,height,buffer);
raster.setViewPort(0,0,width,height);
raster.setPerspective(60,(float)(width)/(float)(height),0.1,1000);
struct Vertex
{
float x,y,z;
float u,v;
CELL::Rgba color;
};
MSG msg = {0};
while(true)
{
if (msg.message == WM_DESTROY
||msg.message == WM_CLOSE
||msg.message == WM_QUIT)
{
break;
}
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
raster.clear();
CELL::CELLTimestamp tms;
tms.update();
double mis = tms.getElapsedTimeInMicroSec();
char szBuf[128];
sprintf(szBuf,"%f ",mis);
int i = 00;
memcpy(buffer,raster._buffer,raster._width * raster._height * sizeof(CELL::Rgba));
raster.drawImage(0,0,image);
Vertex vertexs[] =
{
{-1.0f, 0.0f, -2.0f, 0.0f, 0.0f, CELL::Rgba(255,0,0,255)},
{0.0f, 1.0f, -9.0f, 1.0f, 1.0f, CELL::Rgba(0,255,0,255)},
{1.0f, 0.0f, -2.0f, 1.0f, 0.0f, CELL::Rgba(0,0,255,255)},
};
image1->setWrapType(1);
raster.bindTexture(image1);
raster.vertexPointer(2,CELL::DT_FLOAT, sizeof(Vertex),&vertexs[0].x);
raster.textureCoordPointer(2,CELL::DT_FLOAT,sizeof(Vertex),&vertexs[0].u);
raster.colorPointer(4,CELL::DT_BYTE, sizeof(Vertex),&vertexs[0].color);
raster.drawArrays(CELL::DM_TRIANGES,0,3);
//TextOut(hMem,10,10,szBuf,strlen(szBuf));
BitBlt(hDC,0,0,width,height,hMem,0,0,SRCCOPY);
}
delete image;
delete image1;
return 0;
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save