Created
September 14, 2011 15:29
-
-
Save anonymous/1216872 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "ssr.h" | |
| #define SSR_FTORGB(r, g, b) ((DWORD)(255 << 24 | ((BYTE)(r * 255.0f)) << 16 | ((BYTE)(g * 255.0f)) << 8 | ((BYTE)(b * 255.0f)))) | |
| #define SSR_FTOARGB(a, r, g, b) ((DWORD)(((BYTE)(a * 255.0f)) << 24 | ((BYTE)(r * 255.0f)) << 16 | ((BYTE)(g * 255.0f)) << 8 | ((BYTE)(b * 255.0f)))) | |
| #define SSR_ARGB(a, r, g, b) ((DWORD)(((BYTE)a) << 24 | ((BYTE)(r)) << 16 | ((BYTE)(g)) << 8 | ((BYTE)(b)))) | |
| #define SSR_GETA(rgb) ((BYTE)((rgb & 0xFF000000) >> 24)) | |
| #define SSR_GETR(rgb) ((BYTE)((rgb & 0x00FF0000) >> 16)) | |
| #define SSR_GETG(rgb) ((BYTE)((rgb & 0x0000FF00) >> 8)) | |
| #define SSR_GETB(rgb) ((BYTE)((rgb & 0x000000FF))) | |
| #define SSR_SQRTFUNC sqrtf | |
| #define SSR_FLERP(l, r, p) (l + (p * (r - l))) | |
| #define SSR_DEG_TO_RAD 0.0174532925f | |
| #define SSR_RAD_TO_DEG 57.2957795f | |
| #define SSR_MATRIX_MULTIPLY(m1, m2, result) \ | |
| result[0] = m1[0]*m2[0] + m1[4]*m2[1] + m1[8]*m2[2] + m1[12]*m2[3]; \ | |
| result[1] = m1[1]*m2[0] + m1[5]*m2[1] + m1[9]*m2[2] + m1[13]*m2[3]; \ | |
| result[2] = m1[2]*m2[0] + m1[6]*m2[1] + m1[10]*m2[2] + m1[14]*m2[3]; \ | |
| result[3] = m1[3]*m2[0] + m1[7]*m2[1] + m1[11]*m2[2] + m1[15]*m2[3]; \ | |
| result[4] = m1[0]*m2[4] + m1[4]*m2[5] + m1[8]*m2[6] + m1[12]*m2[7]; \ | |
| result[5] = m1[1]*m2[4] + m1[5]*m2[5] + m1[9]*m2[6] + m1[13]*m2[7]; \ | |
| result[6] = m1[2]*m2[4] + m1[6]*m2[5] + m1[10]*m2[6] + m1[14]*m2[7]; \ | |
| result[7] = m1[3]*m2[4] + m1[7]*m2[5] + m1[11]*m2[6] + m1[15]*m2[7]; \ | |
| result[8] = m1[0]*m2[8] + m1[4]*m2[9] + m1[8]*m2[10] + m1[12]*m2[11]; \ | |
| result[9] = m1[1]*m2[8] + m1[5]*m2[9] + m1[9]*m2[10] + m1[13]*m2[11]; \ | |
| result[10] = m1[2]*m2[8] + m1[6]*m2[9] + m1[10]*m2[10] + m1[14]*m2[11]; \ | |
| result[11] = m1[3]*m2[8] + m1[7]*m2[9] + m1[11]*m2[10] + m1[15]*m2[11]; \ | |
| result[12] = m1[0]*m2[12] + m1[4]*m2[13] + m1[8]*m2[14] + m1[12]*m2[15]; \ | |
| result[13] = m1[1]*m2[12] + m1[5]*m2[13] + m1[9]*m2[14] + m1[13]*m2[15]; \ | |
| result[14] = m1[2]*m2[12] + m1[6]*m2[13] + m1[10]*m2[14] + m1[14]*m2[15]; \ | |
| result[15] = m1[3]*m2[12] + m1[7]*m2[13] + m1[11]*m2[14] + m1[15]*m2[15]; | |
| #define SSR_DOT_PRODUCT(v1, v2, r) r = ((v1[0] * v2[0]) + (v1[1] * v2[1]) + (v1[2] * v2[2])); | |
| #define SSR_CROSS_PRODUCT(side1, side2, normal);\ | |
| normal[0] = (side1[1] * side2[2]) - (side1[2] - side2[1]);\ | |
| normal[1] = (side1[2] * side2[0]) - (side1[0] - side2[2]);\ | |
| normal[2] = (side1[0] * side2[1]) - (side1[1] - side2[0]); | |
| #define SSR_VECTOR_MATRIX_MULTIPLY(vector, matrix, output) \ | |
| output[0] = vector[0] * matrix[0] + vector[1] * matrix[4] + vector[2] * matrix[8] + matrix[12]; \ | |
| output[1] = vector[0] * matrix[1] + vector[1] * matrix[5] + vector[2] * matrix[9] + matrix[13]; \ | |
| output[2] = vector[0] * matrix[2] + vector[1] * matrix[6] + vector[2] * matrix[10] + matrix[14]; | |
| #define SSR_NORMALIZE(normal, scratch)\ | |
| scratch = sqrtf((normal[0] * normal[0]) + (normal[1] * normal[1]) + (normal[2] * normal[2]));\ | |
| normal[0] /= scratch;\ | |
| normal[1] /= scratch;\ | |
| normal[2] /= scratch; | |
| #define SSR_VIEWPORT_LEFT 0 | |
| #define SSR_VIEWPORT_RIGHT 1 | |
| #define SSR_VIEWPORT_TOP 2 | |
| #define SSR_VIEWPORT_BOTTOM 3 | |
| #define SSR_VERTVEC_INCREMENT 3 | |
| typedef struct SSR_VERT_TYPE { | |
| float x, y, z; | |
| union { | |
| struct { float r; }; | |
| struct { float usingUV; }; | |
| }; | |
| union { | |
| struct { float g; }; | |
| struct { float u; }; | |
| }; | |
| union { | |
| struct { float b; }; | |
| struct { float v; }; | |
| }; | |
| } SSRVERTEX, *PSSRVERTEX; | |
| typedef struct SSR_MATRIX_COMPONENT_TYPE { | |
| float projectionMatrixStack[8][16]; | |
| float modelviewMatrixStack[32][16]; | |
| int currentProjectionMatrix; | |
| int currentModelviewMatrix; | |
| int projectionMode; | |
| int matrixMode; | |
| } SSRMATRIXCOMPONENT, *PSSRMATRIXCOMPONENT; | |
| typedef struct SSR_DISPLAY_COMPONENT_TYPE { | |
| COLORREF* imageBuffer; | |
| float* depthBuffer; | |
| COLORREF clearColor; | |
| SSRIMID boundImage; | |
| } SSRDISPLAYCOMPONENT, *PSSRDISPLAYCOMPONENT; | |
| typedef struct SSR_RENDERINFO_COMPONENT_TYPE { | |
| int cullDirection; | |
| int imageWrapMode; | |
| int viewport[4]; | |
| float offset[4]; | |
| float perspectiveCompensate[2]; | |
| float normalizeValues[2]; | |
| } SSRRENDERINFOCOMPONENT, *PSSRRENDERINFOCOMPONENT; | |
| typedef struct SSR_WINDOWSDISPLAY_COMPONENT_TYPE { | |
| HDC hdcDisplay; | |
| HDC hdcBitmap; | |
| HBITMAP hbmBitmap; | |
| HBITMAP hbmBitmapOld; | |
| BITMAP bmBitmapInfo; | |
| } SSRWINDOWDISPLAYCOMPONENT, *PSSRWINDOWDISPLAYCOMPONENT; | |
| typedef struct SSR_BATCH_COMPONENT_TYPE { | |
| vector<SSRVERTEX> masterVertexList; | |
| int batchType; | |
| } SSRBATCHCOMPONENT, *PSSRBATCHCOMPONENT; | |
| typedef struct SSR_TEXT_TYPE { | |
| string displayString; | |
| int x, y; | |
| COLORREF color; | |
| } SSRTEXT, *PSSRTEXT; | |
| typedef struct SSR_CONTEXT_TYPE { | |
| SSRDISPLAYCOMPONENT displayComponent; | |
| SSRMATRIXCOMPONENT matrixComponent; | |
| SSRRENDERINFOCOMPONENT renderInfoComponent; | |
| SSRWINDOWDISPLAYCOMPONENT windowsDisplayComponent; | |
| SSRBATCHCOMPONENT batchComponent; | |
| vector<SSRTEXT> textOutputComponent; | |
| } SSRCONTEXT, *PSSRCONTEXT; | |
| #pragma pack(1) | |
| typedef struct TGA_H { | |
| signed char identsize; | |
| signed char colorMapType; | |
| signed char imageType; | |
| unsigned short colorMapStart; | |
| unsigned short colorMapLength; | |
| unsigned char colorMapBits; | |
| unsigned short xstart; | |
| unsigned short ystart; | |
| unsigned short width; | |
| unsigned short height; | |
| signed char bits; | |
| signed char descriptor; | |
| } TGAHEADER; | |
| #pragma pack(8) | |
| void ssrMatrixMakeZRotation(float angle, float* matrix); | |
| void ssrMatrixMakeYRotation(float angle, float* matrix); | |
| void ssrMatrixMakeXRotation(float angle, float* matrix); | |
| void ssrEndOnTriangle(); | |
| void ssrEndOnQuad(); | |
| void ssrEndOnTriangleStrip(); | |
| float* ssrClampToZeroOne(float* f); | |
| float ssrClampToZeroOne(float f); | |
| int ssrGet32(FILE *f); | |
| int ssrGet16(FILE *f); | |
| int ssrNextPowerOf2(int n); | |
| void ssrDrawBlackLine(float x1, float x2, float z1, float z2, float y); | |
| void ssrRenderBlackTriangle(float* verts); | |
| void ssrDrawColoredLine(float x1, float x2, float y, float z1, float z2, float* color_left, float* color_right); | |
| void ssrRenderColoredTriangle(float* verts, float (*colors)[3]); | |
| void ssrSortSplitSubmitTexturedTriangle(float (*triangle)[3], float (*uvs)[2]); | |
| void ssrRenderTexturedTriangle(float* verts, float * uvs); | |
| bool ssrIsBackFacing(float* verts); | |
| void ssrSortTriangle(float (*verts)[3], int* order); | |
| void ssrSortSplitAndSumbitTriangle(float (*triangle)[3]); | |
| void ssrSortSplitSubmitColoredTriangle(float (*triangle)[3], float (*colors)[3]); | |
| void ssrTransformToScreenSpace(); | |
| void ssrDoProjectedClipping(); | |
| void ssrProjectedTriangleClip(); | |
| void ssrProjectedQuadClip(); | |
| void ssrProjectedStripClip(); | |
| void ssrDrawText(); | |
| void ssrBitmapHelper(char* imagePath, unsigned char (*videoArea[])[4]); | |
| void ssrTargaHelper(char* imagePath, unsigned char (*videoArea[])[4]); | |
| PSSRCONTEXT ssr_pCurrentRenderContext = NULL; | |
| int ssr_nLastError = SSR_ERR_NONE; | |
| int ssr_debugNumTriangles; | |
| const char* ssrErrors[] = { | |
| "No error", | |
| "Render context is invalid", | |
| "HDC is not attached to a HWND", | |
| "Could not find window size", | |
| "Global RC handle is null", | |
| "Invalid argument", | |
| "Projection matrix was not set up", | |
| "Master vertex list is not initialized", | |
| "Unknown primitive", | |
| "Triangle strip needs at least 3 verts", | |
| "Could not read in image file", | |
| "Bitmap must be a 24 bit image", | |
| "There is no image to delete!", | |
| "Trying to bind to a null texture", | |
| "No projection has ben set", | |
| "Targa must be a 32 bit image!" | |
| }; | |
| void ssrVertex(float x, float y, float z) { | |
| if (ssr_pCurrentRenderContext == NULL) { | |
| ssr_nLastError = SSR_ERR_GLRC; | |
| return; | |
| } | |
| SSRVERTEX v; v.x = x; v.y = y; v.z = z; v.r = -1.0f; v.g = -1.0f; v.b = -1.0f; | |
| ssr_pCurrentRenderContext->batchComponent.masterVertexList.push_back(v); | |
| } | |
| void ssrColor(float r, float g, float b) { | |
| if (ssr_pCurrentRenderContext == NULL) { | |
| ssr_nLastError = SSR_ERR_GLRC; | |
| return; | |
| } | |
| int vertexIndex = ssr_pCurrentRenderContext->batchComponent.masterVertexList.size() - 1; | |
| if (r < 0.0f) r = 0.0f; | |
| if (g < 0.0f) g = 0.0f; | |
| if (b < 0.0f) b = 0.0f; | |
| if (r > 1.0f) r = 1.0f; | |
| if (g > 1.0f) g = 1.0f; | |
| if (b > 1.0f) b = 1.0f; | |
| ssr_pCurrentRenderContext->batchComponent.masterVertexList[vertexIndex].r = r; | |
| ssr_pCurrentRenderContext->batchComponent.masterVertexList[vertexIndex].g = g; | |
| ssr_pCurrentRenderContext->batchComponent.masterVertexList[vertexIndex].b = b; | |
| } | |
| void ssrTexCoord(float u, float v) { | |
| if (ssr_pCurrentRenderContext == NULL) { | |
| ssr_nLastError = SSR_ERR_GLRC; | |
| return; | |
| } | |
| int vertexIndex = ssr_pCurrentRenderContext->batchComponent.masterVertexList.size() - 1; | |
| if (ssr_pCurrentRenderContext->renderInfoComponent.imageWrapMode == SSR_REPEAT) { | |
| while (u < 0.0f) u += 1.0f; while (u > 1.0f) u -= 1.0f; | |
| while (v < 0.0f) v += 1.0f; while (v > 1.0f) v -= 1.0f; | |
| } else { | |
| if (u > 1.0f) u = 1.0f; | |
| if (u < 0.0f) u = 0.0f; | |
| if (v > 1.0f) v = 1.0f; | |
| if (v < 0.0f) v = 0.0f; | |
| } | |
| ssr_pCurrentRenderContext->batchComponent.masterVertexList[vertexIndex].u = u; | |
| ssr_pCurrentRenderContext->batchComponent.masterVertexList[vertexIndex].v = v; | |
| } | |
| void ssrBegin(int batchType) { | |
| if (ssr_pCurrentRenderContext == NULL) { | |
| ssr_nLastError = SSR_ERR_GLRC; | |
| return; | |
| } | |
| if (batchType != SSR_TRIANGLE && batchType != SSR_TRIANGLESTRIP && batchType != SSR_QUAD) { | |
| ssr_nLastError = SSR_ERR_INVARG; | |
| return; | |
| } | |
| ssr_pCurrentRenderContext->batchComponent.masterVertexList.clear(); | |
| ssr_pCurrentRenderContext->batchComponent.batchType = batchType; | |
| } | |
| void ssrEnd() { | |
| if (ssr_pCurrentRenderContext == NULL) { | |
| ssr_nLastError = SSR_ERR_GLRC; | |
| return; | |
| } | |
| ssrTransformToScreenSpace(); | |
| if (ssr_pCurrentRenderContext->batchComponent.batchType == SSR_TRIANGLE) { | |
| ssrEndOnTriangle(); | |
| } else if (ssr_pCurrentRenderContext->batchComponent.batchType == SSR_TRIANGLESTRIP) { | |
| ssrEndOnTriangleStrip(); | |
| } else if (ssr_pCurrentRenderContext->batchComponent.batchType == SSR_QUAD) { | |
| ssrEndOnQuad(); | |
| } | |
| ssr_pCurrentRenderContext->batchComponent.masterVertexList.clear(); | |
| } | |
| void ssrBitmapHelper(char* imagePath, unsigned char (*videoArea[])[4]) { | |
| FILE* bmp; | |
| int fileSize, offsetToImage, headerSize, d; | |
| unsigned int w, h; | |
| int bpp, imageSize, xpels, ypels, lookupTableSize; | |
| int impColors, compression; | |
| if ((bmp = fopen(imagePath, "rb")) == NULL) { | |
| ssr_nLastError = SSR_ERR_NOREADIMAGE; | |
| return; | |
| } | |
| char buf[8]; | |
| if (fread(buf, 1, 2, bmp) != 2 || strncmp("BM", buf, 2) != 0) { | |
| ssr_nLastError = SSR_ERR_NOREADIMAGE; | |
| fclose(bmp); | |
| return; | |
| } | |
| fileSize = ssrGet32(bmp); | |
| ssrGet16(bmp); ssrGet16(bmp); | |
| offsetToImage = ssrGet32(bmp); | |
| headerSize = ssrGet32(bmp); | |
| w = ssrGet32(bmp); h = ssrGet32(bmp); d = ssrGet16(bmp); | |
| *videoArea = new unsigned char[w * h + 2][4]; // R G will contain width & height | |
| (*videoArea)[0][0] = (w ) & 0xff; | |
| (*videoArea)[0][1] = (w >> 8) & 0xff; | |
| (*videoArea)[0][2] = (w >> 16) & 0xff; | |
| (*videoArea)[0][3] = (w >> 24) & 0xff; | |
| (*videoArea)[1][0] = (h ) & 0xff; | |
| (*videoArea)[1][1] = (h >> 8) & 0xff; | |
| (*videoArea)[1][2] = (h >> 16) & 0xff; | |
| (*videoArea)[1][3] = (h >> 24) & 0xff; | |
| if ((bpp = ssrGet16(bmp)) != 24) { | |
| ssr_nLastError = SSR_ERR_BITMAPBITSOFF; | |
| fclose(bmp); | |
| return; | |
| } | |
| if ((compression = ssrGet32(bmp)) != 0) { | |
| ssr_nLastError = SSR_ERR_NOREADIMAGE; | |
| fclose(bmp); | |
| return; | |
| } | |
| imageSize = ssrGet32(bmp); | |
| xpels = ssrGet32(bmp); | |
| ypels = ssrGet32(bmp); | |
| if ((lookupTableSize = ssrGet32(bmp)) != 0) { | |
| ssr_nLastError = SSR_ERR_NOREADIMAGE; | |
| fclose(bmp); | |
| return; | |
| } | |
| impColors = ssrGet32(bmp); | |
| for (int j = (int)h - 1; j >= 0; --j) { // Read in reverse row order | |
| for (int i = 0; i < (int)w; ++i) { | |
| unsigned char bgr[3]; | |
| if (fread(bgr, 1, 3, bmp) != 3) { | |
| ssr_nLastError = SSR_ERR_NOREADIMAGE; | |
| fclose(bmp); | |
| return; | |
| } | |
| int index = (j * w + i) + 2; | |
| (*videoArea)[index][0] = bgr[2]; | |
| (*videoArea)[index][1] = bgr[1]; | |
| (*videoArea)[index][2] = bgr[0]; | |
| (*videoArea)[index][3] = 255; | |
| } | |
| } | |
| fclose(bmp); | |
| } | |
| void ssrDrawBlackLine(float x1, float x2, float z1, float z2, float y) { | |
| if (x1 > x2) { | |
| float temp = x1; | |
| x1 = x2; | |
| x2 = temp; | |
| temp = z1; | |
| z1 = z2; | |
| z2 = temp; | |
| } | |
| int earlyOutOnIndex = (int)ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmWidth * (int)ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmHeight; | |
| for (int x = (int)x1, xmax = (int)x2, width = (int)ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmWidth; x < xmax; ++x) { | |
| if (x > (float)ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmWidth - 1) continue; | |
| if (x < 0) continue; | |
| if (y < 0) continue; | |
| if (y > (float)ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmHeight - 1) continue; | |
| int index = (int)y * width + x; | |
| if (index < 0) continue; | |
| if (index > earlyOutOnIndex) continue; | |
| float p = ((float)((int)x - (int)x1) / (float)((int)x2 - (int)x1)); | |
| float z = SSR_FLERP(z1, z2, p); | |
| if (z > ssr_pCurrentRenderContext->displayComponent.depthBuffer[index]) continue; | |
| ssr_pCurrentRenderContext->displayComponent.imageBuffer[index] = SSR_FTORGB(0, 0, 0); | |
| ssr_pCurrentRenderContext->displayComponent.depthBuffer[index] = z; | |
| } | |
| } | |
| void ssrRenderBlackTriangle(float* verts) { | |
| #define x1 ((int)verts[0]) | |
| #define y1 ((int)verts[1]) | |
| #define z1 verts[2] | |
| #define x2 ((int)verts[3]) | |
| #define y2 ((int)verts[4]) | |
| #define z2 verts[5] | |
| #define x3 ((int)verts[6]) | |
| #define y3 ((int)verts[7]) | |
| #define z3 verts[8] | |
| float slope_left, slope_right; | |
| float left, right; | |
| float height = (float)(y3 - y1); | |
| if (height == 0) | |
| return; | |
| slope_left = (x2 - x1) / height; | |
| slope_right = (x3 - x1) / height; | |
| left = right = (float)x1; | |
| float z_left; | |
| float z_right; | |
| z_left = z_right = z1; | |
| float z_slope_left = (z2 - z1) / height; | |
| float z_slope_right = (z3 - z1) / height; | |
| if (y1 < y3) { | |
| for (int y = (int)y1; y < (int)y3; ++y) { | |
| ssrDrawBlackLine(left, right, z_left, z_right, (float)y); | |
| left += slope_left; | |
| right += slope_right; | |
| z_left += z_slope_left; | |
| z_right += z_slope_right; | |
| } | |
| } else { | |
| for (int y = (int)y1; y >= (int)y3; --y) { | |
| ssrDrawBlackLine(left, right, z_left, z_right, (float)y); | |
| left -= slope_left; | |
| right -= slope_right; | |
| z_left -= z_slope_left; | |
| z_right -= z_slope_right; | |
| } | |
| } | |
| #undef x1 | |
| #undef x2 | |
| #undef x3 | |
| #undef y1 | |
| #undef y2 | |
| #undef y3 | |
| #undef z1 | |
| #undef z2 | |
| #undef z3 | |
| } | |
| void ssrDrawColoredLine(float x1, float x2, float y, float z1, float z2, float* color_left, float* color_right) { | |
| float c_l[3], c_r[3]; | |
| if (x1 > x2) { | |
| float temp = x1; | |
| x1 = x2; | |
| x2 = temp; | |
| temp = z1; | |
| z1 = z2; | |
| z2 = temp; | |
| c_l[0] = color_right[0]; | |
| c_l[1] = color_right[1]; | |
| c_l[2] = color_right[2]; | |
| c_r[0] = color_left[0]; | |
| c_r[1] = color_left[1]; | |
| c_r[2] = color_left[2]; | |
| } else { | |
| c_l[0] = color_left[0]; | |
| c_l[1] = color_left[1]; | |
| c_l[2] = color_left[2]; | |
| c_r[0] = color_right[0]; | |
| c_r[1] = color_right[1]; | |
| c_r[2] = color_right[2]; | |
| } | |
| int earlyOutOnIndex = (int)ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmWidth * (int)ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmHeight; | |
| for (int x = (int)x1, xmax = (int)x2, width = (int)ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmWidth; x < xmax; ++x) { | |
| if (x > (float)ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmWidth - 1) continue; | |
| if (x < 0) continue; | |
| if (y < 0) continue; | |
| if (y > (float)ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmHeight - 1) continue; | |
| int index = (int)y * width + x; | |
| if (index < 0) continue; | |
| if (index > earlyOutOnIndex) continue; | |
| float p = ((float)((int)x - (int)x1) / (float)((int)x2 - (int)x1)); | |
| float z = SSR_FLERP(z1, z2, p); | |
| if (z > ssr_pCurrentRenderContext->displayComponent.depthBuffer[index]) continue; | |
| if (z <= 0.0f) continue; | |
| float color[3]; | |
| color[0] = ssrClampToZeroOne(SSR_FLERP(c_l[0], c_r[0], p)); | |
| color[1] = ssrClampToZeroOne(SSR_FLERP(c_l[1], c_r[1], p)); | |
| color[2] = ssrClampToZeroOne(SSR_FLERP(c_l[2], c_r[2], p)); | |
| ssr_pCurrentRenderContext->displayComponent.imageBuffer[index] = SSR_FTORGB(color[0], color[1], color[2]); | |
| ssr_pCurrentRenderContext->displayComponent.depthBuffer[index] = z; | |
| } | |
| } | |
| void ssrRenderColoredTriangle(float* verts, float (*colors)[3]) { | |
| #define x1 ((int)verts[0]) | |
| #define y1 ((int)verts[1]) | |
| #define z1 verts[2] | |
| #define x2 ((int)verts[3]) | |
| #define y2 ((int)verts[4]) | |
| #define z2 verts[5] | |
| #define x3 ((int)verts[6]) | |
| #define y3 ((int)verts[7]) | |
| #define z3 verts[8] | |
| float slope_left, slope_right; | |
| float left, right; | |
| float height = y3 - y1; | |
| if (height == 0) | |
| return; | |
| slope_left = (x2 - x1) / height; | |
| slope_right = (x3 - x1) / height; | |
| left = right = x1; | |
| float color_left[3] = {ssrClampToZeroOne(colors[0][0]), ssrClampToZeroOne(colors[0][1]), ssrClampToZeroOne(colors[0][2])}; | |
| float color_right[3] = {color_left[0], color_left[1], color_left[2]}; | |
| float color_left_slope[3] = {(colors[1][0] - colors[0][0]) / height, (colors[1][1] - colors[0][1]) / height, (colors[1][2] - colors[0][2]) / height}; | |
| float color_right_slope[3] = {(colors[2][0] - colors[0][0]) / height, (colors[2][1] - colors[0][1]) / height, (colors[2][2] - colors[0][2]) / height}; | |
| float z_left; | |
| float z_right; | |
| z_left = z_right = z1; | |
| float z_slope_left = (z2 - z1) / height; | |
| float z_slope_right = (z3 - z1) / height; | |
| if (y1 < y3) { | |
| for (int y = (int)y1; y < (int)y3; ++y) { | |
| ssrDrawColoredLine(left, right, (float)y, z_left, z_right, ssrClampToZeroOne(color_left), ssrClampToZeroOne(color_right)); | |
| color_left[0] += color_left_slope[0]; | |
| color_left[1] += color_left_slope[1]; | |
| color_left[2] += color_left_slope[2]; | |
| color_right[0] += color_right_slope[0]; | |
| color_right[1] += color_right_slope[1]; | |
| color_right[2] += color_right_slope[2]; | |
| left += slope_left; | |
| right += slope_right; | |
| z_left += z_slope_left; | |
| z_right += z_slope_right; | |
| } | |
| } else { | |
| for (int y = (int)y1; y >= (int)y3; --y) { | |
| ssrDrawColoredLine(left, right, (float)y, z_left, z_right, ssrClampToZeroOne(color_left), ssrClampToZeroOne(color_right)); | |
| color_left[0] -= color_left_slope[0]; | |
| color_left[1] -= color_left_slope[1]; | |
| color_left[2] -= color_left_slope[2]; | |
| color_right[0] -= color_right_slope[0]; | |
| color_right[1] -= color_right_slope[1]; | |
| color_right[2] -= color_right_slope[2]; | |
| left -= slope_left; | |
| right -= slope_right; | |
| z_left -= z_slope_left; | |
| z_right -= z_slope_right; | |
| } | |
| } | |
| #undef x1 | |
| #undef x2 | |
| #undef x3 | |
| #undef y1 | |
| #undef y2 | |
| #undef y3 | |
| #undef z1 | |
| #undef z2 | |
| #undef z3 | |
| } | |
| void ssrEndOnTriangle() { | |
| for (int i = 0, size = ssr_pCurrentRenderContext->batchComponent.masterVertexList.size(); i < size; i += 3) { | |
| float triangle[3][3]; float color[3][3]; float uvs[3][2]; | |
| triangle[0][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].x; | |
| triangle[0][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].y; | |
| triangle[0][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].z; | |
| triangle[1][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 1].x; | |
| triangle[1][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 1].y; | |
| triangle[1][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 1].z; | |
| triangle[2][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].x; | |
| triangle[2][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].y; | |
| triangle[2][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].z; | |
| if (ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].r == -1.0f) { | |
| if (ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].u == -1.0f) { | |
| ssrSortSplitAndSumbitTriangle(triangle); | |
| } else { | |
| uvs[0][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].u; | |
| uvs[0][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].v; | |
| uvs[1][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 1].u; | |
| uvs[1][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 1].v; | |
| uvs[2][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].u; | |
| uvs[2][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].v; | |
| ssrSortSplitSubmitTexturedTriangle(triangle, uvs); | |
| } | |
| } else { | |
| color[0][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].r; | |
| color[0][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].g; | |
| color[0][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].b; | |
| color[1][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 1].r; | |
| color[1][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 1].g; | |
| color[1][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 1].b; | |
| color[2][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].r; | |
| color[2][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].g; | |
| color[2][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].b; | |
| ssrSortSplitSubmitColoredTriangle(triangle, color); | |
| } | |
| } | |
| } | |
| void ssrEndOnQuad() { | |
| for (int i = 0, size = ssr_pCurrentRenderContext->batchComponent.masterVertexList.size(); i < size; i += 4) { | |
| float triangle[3][3]; float color[3][3]; float uvs[3][2]; | |
| triangle[0][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].x; | |
| triangle[0][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].y; | |
| triangle[0][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].z; | |
| triangle[1][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 1].x; | |
| triangle[1][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 1].y; | |
| triangle[1][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 1].z; | |
| triangle[2][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].x; | |
| triangle[2][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].y; | |
| triangle[2][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].z; | |
| if (ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].r == -1.0f) { | |
| if (ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].u == -1.0f) { | |
| ssrSortSplitAndSumbitTriangle(triangle); | |
| } else { | |
| uvs[0][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].u; | |
| uvs[0][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].v; | |
| uvs[1][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 1].u; | |
| uvs[1][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 1].v; | |
| uvs[2][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].u; | |
| uvs[2][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].v; | |
| ssrSortSplitSubmitTexturedTriangle(triangle, uvs); | |
| } | |
| } else { | |
| color[0][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].r; | |
| color[0][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].g; | |
| color[0][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].b; | |
| color[1][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 1].r; | |
| color[1][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 1].g; | |
| color[1][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 1].b; | |
| color[2][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].r; | |
| color[2][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].g; | |
| color[2][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].b; | |
| ssrSortSplitSubmitColoredTriangle(triangle, color); | |
| } | |
| triangle[2][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].x; | |
| triangle[2][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].y; | |
| triangle[2][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].z; | |
| triangle[0][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].x; | |
| triangle[0][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].y; | |
| triangle[0][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].z; | |
| triangle[1][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 3].x; | |
| triangle[1][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 3].y; | |
| triangle[1][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 3].z; | |
| if (ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].r == -1.0f) { | |
| if (ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].u == -1.0f) { | |
| ssrSortSplitAndSumbitTriangle(triangle); | |
| } else { | |
| uvs[2][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].u; | |
| uvs[2][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].v; | |
| uvs[0][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].u; | |
| uvs[0][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].v; | |
| uvs[1][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 3].u; | |
| uvs[1][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 3].v; | |
| ssrSortSplitSubmitTexturedTriangle(triangle, uvs); | |
| } | |
| } else { | |
| color[2][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].r; | |
| color[2][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].g; | |
| color[2][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].b; | |
| color[0][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].r; | |
| color[0][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].g; | |
| color[0][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 2].b; | |
| color[1][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 3].r; | |
| color[1][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 3].g; | |
| color[1][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 3].b; | |
| ssrSortSplitSubmitColoredTriangle(triangle, color); | |
| } | |
| } | |
| } | |
| void ssrEndOnTriangleStrip() { | |
| if (ssr_pCurrentRenderContext->batchComponent.masterVertexList.size() < 3) { | |
| ssr_nLastError = SSR_ERR_TRISTRPMV; | |
| return; | |
| } | |
| float init_triangle[3][3]; float init_color[3][3]; float init_uvs[3][2]; | |
| init_triangle[0][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[0].x; | |
| init_triangle[0][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[0].y; | |
| init_triangle[0][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[0].z; | |
| init_triangle[1][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[1].x; | |
| init_triangle[1][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[1].y; | |
| init_triangle[1][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[1].z; | |
| init_triangle[2][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[2].x; | |
| init_triangle[2][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[2].y; | |
| init_triangle[2][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[2].z; | |
| if (ssr_pCurrentRenderContext->batchComponent.masterVertexList[0].r == -1.0f) { | |
| if (ssr_pCurrentRenderContext->batchComponent.masterVertexList[0].u == -1.0f) { | |
| ssrSortSplitAndSumbitTriangle(init_triangle); | |
| } else { | |
| init_uvs[0][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[0].u; | |
| init_uvs[0][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[0].v; | |
| init_uvs[1][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[1].u; | |
| init_uvs[1][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[1].v; | |
| init_uvs[2][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[2].u; | |
| init_uvs[2][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[2].v; | |
| ssrSortSplitSubmitTexturedTriangle(init_triangle, init_uvs); | |
| } | |
| } else { | |
| init_color[0][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[0].r; | |
| init_color[0][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[0].g; | |
| init_color[0][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[0].b; | |
| init_color[1][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[1].r; | |
| init_color[1][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[1].g; | |
| init_color[1][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[1].b; | |
| init_color[2][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[2].r; | |
| init_color[2][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[2].g; | |
| init_color[2][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[2].b; | |
| ssrSortSplitSubmitColoredTriangle(init_triangle, init_color); | |
| } | |
| for (int i = 3, size = ssr_pCurrentRenderContext->batchComponent.masterVertexList.size(); i < size; ++i) { | |
| float triangle[3][3]; float color[3][3]; float uvs[3][2]; | |
| triangle[0][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].x; | |
| triangle[0][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].y; | |
| triangle[0][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].z; | |
| triangle[1][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i - 1].x; | |
| triangle[1][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i - 1].y; | |
| triangle[1][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i - 1].z; | |
| triangle[2][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i - 2].x; | |
| triangle[2][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i - 2].y; | |
| triangle[2][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i - 2].z; | |
| if (ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].r == -1.0f) { | |
| if (ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].u == -1.0f) { | |
| ssrSortSplitAndSumbitTriangle(triangle); | |
| } else { | |
| uvs[0][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].u; | |
| uvs[0][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].v; | |
| uvs[1][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i - 1].u; | |
| uvs[1][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i - 1].v; | |
| uvs[2][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i - 2].u; | |
| uvs[2][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i - 2].v; | |
| ssrSortSplitSubmitTexturedTriangle(triangle, uvs); | |
| } | |
| } else { | |
| color[0][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].r; | |
| color[0][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].g; | |
| color[0][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i + 0].b; | |
| color[1][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i - 1].r; | |
| color[1][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i - 1].g; | |
| color[1][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i - 1].b; | |
| color[2][0] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i - 2].r; | |
| color[2][1] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i - 2].g; | |
| color[2][2] = ssr_pCurrentRenderContext->batchComponent.masterVertexList[i - 2].b; | |
| ssrSortSplitSubmitColoredTriangle(triangle, color); | |
| } | |
| } | |
| } | |
| void ssrWriteText(char* text, int x, int y, COLORREF c) { | |
| SSRTEXT display; | |
| display.displayString = text; | |
| display.x = x; | |
| display.y = y; | |
| display.color = c; | |
| ssr_pCurrentRenderContext->textOutputComponent.push_back(display); | |
| } | |
| void ssrBindTexture(SSRIMID texToBindTo) { | |
| if (ssr_pCurrentRenderContext == NULL) { | |
| ssr_nLastError = SSR_ERR_GLRC; | |
| return; | |
| } | |
| if (texToBindTo == NULL) { | |
| ssr_nLastError = SSR_ERR_BINDNULLTEX; | |
| return; | |
| } | |
| ssr_pCurrentRenderContext->displayComponent.boundImage = texToBindTo; | |
| } | |
| SSRIMID ssrLoadBitmap(char* filePath) { | |
| unsigned char (*imageBuffer)[4] = NULL; | |
| ssrBitmapHelper(filePath, &imageBuffer); | |
| return imageBuffer; | |
| } | |
| SSRIMID ssrLoadTarga(char* filePath) { | |
| unsigned char (*imageBuffer)[4] = NULL; | |
| ssrTargaHelper(filePath, &imageBuffer); | |
| return imageBuffer; | |
| } | |
| void ssrUnloadIamge(SSRIMID imageId) { | |
| unsigned char (*imageBuffer)[4] = (unsigned char(*)[4])imageId; | |
| delete[] imageId; | |
| } | |
| SSRRC ssrCreateContext() { | |
| ssr_nLastError = SSR_ERR_NONE; | |
| PSSRCONTEXT context = new SSRCONTEXT(); | |
| context->displayComponent.imageBuffer = NULL; | |
| context->displayComponent.depthBuffer = NULL; | |
| context->displayComponent.clearColor = SSR_FTORGB(125, 125, 125); | |
| context->displayComponent.boundImage = NULL; | |
| context->windowsDisplayComponent.hdcDisplay = (HDC)NULL; | |
| context->windowsDisplayComponent.hdcBitmap = (HDC)NULL; | |
| context->matrixComponent.currentProjectionMatrix = 0; | |
| context->matrixComponent.currentModelviewMatrix = 0; | |
| context->matrixComponent.matrixMode = SSR_MODELVIEW; | |
| for (int j = 0; j < 8; ++j) { | |
| for (int i = 0; i < 16; ++i) | |
| context->matrixComponent.projectionMatrixStack[j][i] = 0.0f; | |
| context->matrixComponent.projectionMatrixStack[j][0] = context->matrixComponent.projectionMatrixStack[j][5] = 1.0f; | |
| context->matrixComponent.projectionMatrixStack[j][10] = context->matrixComponent.projectionMatrixStack[j][15] = 1.0f; | |
| } | |
| for (int j = 0; j < 32; ++j) { | |
| for (int i = 0; i < 16; ++i) | |
| context->matrixComponent.modelviewMatrixStack[j][i] = 0.0f; | |
| context->matrixComponent.modelviewMatrixStack[j][0] = context->matrixComponent.modelviewMatrixStack[j][5] = 1.0f; | |
| context->matrixComponent.modelviewMatrixStack[j][10] = context->matrixComponent.modelviewMatrixStack[j][15] = 1.0f; | |
| } | |
| context->matrixComponent.projectionMode = 0; | |
| context->renderInfoComponent.viewport[0] = context->renderInfoComponent.viewport[2] = 0; | |
| context->renderInfoComponent.viewport[1] = 640; context->renderInfoComponent.viewport[3] = 320; | |
| context->renderInfoComponent.cullDirection = SSR_BACK; | |
| context->renderInfoComponent.imageWrapMode = SSR_CLAMP; | |
| context->renderInfoComponent.perspectiveCompensate[0] = 0.0f; | |
| context->renderInfoComponent.perspectiveCompensate[1] = 0.0f; | |
| context->renderInfoComponent.normalizeValues[0] = 0.0f; | |
| context->renderInfoComponent.normalizeValues[1] = 0.0f; | |
| context->batchComponent.masterVertexList.clear(); | |
| context->batchComponent.batchType = SSR_TRIANGLE; | |
| return context; | |
| } | |
| bool ssrDeleteContext(SSRRC ssrRc) { | |
| if (ssrRc == NULL) { | |
| ssr_nLastError = SSR_ERR_NORC; | |
| return false; | |
| } | |
| if (((PSSRCONTEXT)ssrRc)->displayComponent.imageBuffer != NULL) { | |
| ssr_nLastError = SSR_ERR_NORC; | |
| return false; | |
| } | |
| ssr_nLastError = SSR_ERR_NONE; | |
| ((PSSRCONTEXT)ssrRc)->textOutputComponent.clear(); | |
| ((PSSRCONTEXT)ssrRc)->batchComponent.masterVertexList.clear(); | |
| delete ssrRc; | |
| return true; | |
| } | |
| bool ssrMakecurrent(HDC hDc, SSRRC ssrRc) { | |
| if (ssrRc == NULL) { | |
| if (ssr_pCurrentRenderContext != NULL) { | |
| if (ssr_pCurrentRenderContext->windowsDisplayComponent.hdcBitmap != (HDC)NULL) { | |
| SelectObject(ssr_pCurrentRenderContext->windowsDisplayComponent.hdcBitmap, ssr_pCurrentRenderContext->windowsDisplayComponent.hbmBitmapOld); | |
| DeleteObject(ssr_pCurrentRenderContext->windowsDisplayComponent.hbmBitmap); | |
| DeleteDC(ssr_pCurrentRenderContext->windowsDisplayComponent.hdcBitmap); | |
| ssr_pCurrentRenderContext->windowsDisplayComponent.hdcBitmap = (HDC)NULL; | |
| if (ssr_pCurrentRenderContext->displayComponent.depthBuffer != NULL) | |
| delete[] ssr_pCurrentRenderContext->displayComponent.depthBuffer; | |
| ssr_pCurrentRenderContext->displayComponent.depthBuffer = NULL; | |
| ssr_pCurrentRenderContext->displayComponent.imageBuffer = NULL; | |
| } | |
| } | |
| return true; | |
| } | |
| if (ssrRc != NULL && ((PSSRCONTEXT)ssrRc)->windowsDisplayComponent.hdcDisplay != (HDC)NULL) { | |
| ssr_nLastError = SSR_ERR_NORC; | |
| return false; | |
| } | |
| if (ssrRc != NULL && ((PSSRCONTEXT)ssrRc)->displayComponent.imageBuffer != NULL) { | |
| ssr_nLastError = SSR_ERR_NORC; | |
| return false; | |
| } | |
| if (ssr_pCurrentRenderContext != NULL) { | |
| if (ssr_pCurrentRenderContext->displayComponent.imageBuffer != NULL) { | |
| if (ssr_pCurrentRenderContext->windowsDisplayComponent.hdcBitmap != (HDC)NULL) { | |
| SelectObject(ssr_pCurrentRenderContext->windowsDisplayComponent.hdcBitmap, ssr_pCurrentRenderContext->windowsDisplayComponent.hbmBitmapOld); | |
| DeleteObject(ssr_pCurrentRenderContext->windowsDisplayComponent.hbmBitmap); | |
| DeleteDC(ssr_pCurrentRenderContext->windowsDisplayComponent.hdcBitmap); | |
| ssr_pCurrentRenderContext->windowsDisplayComponent.hdcBitmap = (HDC)NULL; | |
| delete[] ssr_pCurrentRenderContext->displayComponent.depthBuffer; | |
| ssr_pCurrentRenderContext->displayComponent.depthBuffer = NULL; | |
| ssr_pCurrentRenderContext->displayComponent.imageBuffer = NULL; | |
| } | |
| } | |
| } | |
| ((PSSRCONTEXT)ssrRc)->windowsDisplayComponent.hdcDisplay = hDc; | |
| RECT clientRect; | |
| if (WindowFromDC(hDc) == (HWND)NULL) { | |
| ssr_nLastError = SSR_ERR_NOWND; | |
| return false; | |
| } | |
| if (GetClientRect(WindowFromDC(hDc), &clientRect) == 0) { | |
| ssr_nLastError = SSR_ERR_NOSIZE; | |
| return false; | |
| } | |
| LONG width = (clientRect.right - clientRect.left); | |
| LONG height = (clientRect.bottom - clientRect.top); | |
| ssr_pCurrentRenderContext = (PSSRCONTEXT)ssrRc; | |
| ssr_nLastError = SSR_ERR_NONE; | |
| BITMAPINFO bitmap; | |
| bitmap.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); | |
| bitmap.bmiHeader.biWidth = width; | |
| bitmap.bmiHeader.biHeight = -1 * height; | |
| bitmap.bmiHeader.biPlanes = 1; | |
| bitmap.bmiHeader.biBitCount = 32; | |
| bitmap.bmiHeader.biCompression = BI_RGB; | |
| bitmap.bmiHeader.biSizeImage = 0; | |
| bitmap.bmiHeader.biClrUsed = 0; | |
| bitmap.bmiHeader.biClrImportant = 0; | |
| ssr_pCurrentRenderContext->displayComponent.depthBuffer = new float[width * height]; | |
| ssr_pCurrentRenderContext->windowsDisplayComponent.hbmBitmap = CreateDIBSection(ssr_pCurrentRenderContext->windowsDisplayComponent.hdcDisplay, &bitmap, DIB_RGB_COLORS, (void**)&(ssr_pCurrentRenderContext->displayComponent.imageBuffer), NULL, 0); | |
| if (ssr_pCurrentRenderContext->windowsDisplayComponent.hbmBitmap == 0) | |
| cout << "Could not create device independent section\n"; | |
| ssr_pCurrentRenderContext->windowsDisplayComponent.hdcBitmap = CreateCompatibleDC(ssr_pCurrentRenderContext->windowsDisplayComponent.hdcDisplay); | |
| if (ssr_pCurrentRenderContext->windowsDisplayComponent.hdcBitmap == 0) | |
| cout << "Could not create compatible device context!"; | |
| ssr_pCurrentRenderContext->windowsDisplayComponent.hbmBitmapOld = (HBITMAP)SelectObject(ssr_pCurrentRenderContext->windowsDisplayComponent.hdcBitmap , ssr_pCurrentRenderContext->windowsDisplayComponent.hbmBitmap); | |
| GetObject(ssr_pCurrentRenderContext->windowsDisplayComponent.hbmBitmap , sizeof(BITMAP), &ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo); | |
| if (ssr_pCurrentRenderContext->windowsDisplayComponent.hbmBitmap == 0) | |
| cout << "Could not reselect bitmap"; | |
| return true; | |
| } | |
| SSRRC ssrGetCurrentContext() { | |
| return ssr_pCurrentRenderContext; | |
| } | |
| HDC ssrGetCurrentDc() { | |
| if (ssr_pCurrentRenderContext == NULL) | |
| return (HDC)NULL; | |
| return ssr_pCurrentRenderContext->windowsDisplayComponent.hdcDisplay; | |
| } | |
| void ssrMatrixMode(int matrixType) { | |
| if (ssr_pCurrentRenderContext == NULL) { | |
| ssr_nLastError = SSR_ERR_GLRC; | |
| return; | |
| } | |
| if (matrixType != SSR_MODELVIEW && SSR_MODELVIEW != SSR_PROJECTION) { | |
| ssr_nLastError = SSR_ERR_INVARG; | |
| return; | |
| } | |
| ssr_pCurrentRenderContext->matrixComponent.matrixMode = matrixType; | |
| } | |
| void ssrLoadIdentity() { | |
| if (ssr_pCurrentRenderContext == NULL) { | |
| ssr_nLastError = SSR_ERR_GLRC; | |
| return; | |
| } | |
| if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_MODELVIEW) { | |
| for (int i = 0; i < 16; ++i) | |
| ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix][i] = 0.0f; | |
| ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix][0] = 1.0f; | |
| ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix][5] = 1.0f; | |
| ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix][10] = 1.0f; | |
| ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix][15] = 1.0f; | |
| } else if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_PROJECTION) { | |
| for (int i = 0; i < 16; ++i) | |
| ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][i] = 0.0f; | |
| ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][0] = 1.0f; | |
| ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][5] = 1.0f; | |
| ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][10] = 1.0f; | |
| ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][15] = 1.0f; | |
| } | |
| } | |
| void ssrPushMatrix() { | |
| if (ssr_pCurrentRenderContext == NULL) { | |
| ssr_nLastError = SSR_ERR_GLRC; | |
| return; | |
| } | |
| if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_MODELVIEW) { | |
| ++(ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix); | |
| } else if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_PROJECTION) { | |
| ++(ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix); | |
| } | |
| } | |
| void ssrPopMatrix() { | |
| if (ssr_pCurrentRenderContext == NULL) { | |
| ssr_nLastError = SSR_ERR_GLRC; | |
| return; | |
| } | |
| if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_MODELVIEW) { | |
| --(ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix); | |
| } else if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_PROJECTION) { | |
| --(ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix); | |
| } | |
| } | |
| void ssrLoadMatrix(float* matrix) { | |
| if (ssr_pCurrentRenderContext == NULL) { | |
| ssr_nLastError = SSR_ERR_GLRC; | |
| return; | |
| } | |
| if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_MODELVIEW) { | |
| for (int i = 0; i < 16; ++i) | |
| ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix][i] = matrix[i]; | |
| } else if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_PROJECTION) { | |
| for (int i = 0; i < 16; ++i) | |
| ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][i] = matrix[i]; | |
| } | |
| } | |
| void ssrMultMatrix(float* matrix) { | |
| if (ssr_pCurrentRenderContext == NULL) { | |
| ssr_nLastError = SSR_ERR_GLRC; | |
| return; | |
| } | |
| float scratch[16]; | |
| if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_MODELVIEW) { | |
| SSR_MATRIX_MULTIPLY(ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix], matrix, scratch); | |
| for (int i = 0; i < 16; ++i) | |
| ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix][i] = scratch[i]; | |
| } else if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_PROJECTION) { | |
| SSR_MATRIX_MULTIPLY(ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix], matrix, scratch); | |
| for (int i = 0; i < 16; ++i) | |
| ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][i] = scratch[i]; | |
| } | |
| } | |
| void ssrRotate(float* rotationVector) { | |
| if (ssr_pCurrentRenderContext == NULL) { | |
| ssr_nLastError = SSR_ERR_GLRC; | |
| return; | |
| } | |
| float accumulator[16]; | |
| float rotation[16]; | |
| float scratch[16]; | |
| for (int i = 0; i < 16; ++i) { | |
| accumulator[i] = 0.0f; | |
| scratch[i] = 0.0f; | |
| } | |
| accumulator[0] = accumulator[5] = accumulator[10] = accumulator[15] = 1.0f; | |
| scratch[0] = scratch[5] = scratch[10] = scratch[15] = 1.0f; | |
| if(rotationVector[0] != 0.0f) { | |
| ssrMatrixMakeXRotation(rotationVector[0], rotation); | |
| SSR_MATRIX_MULTIPLY(accumulator, rotation, scratch); | |
| for (int i = 0; i < 16; ++i) | |
| accumulator[i] = scratch[i]; | |
| } | |
| if(rotationVector[1] != 0.0f) { | |
| ssrMatrixMakeYRotation(rotationVector[1], rotation); | |
| SSR_MATRIX_MULTIPLY(accumulator, rotation, scratch); | |
| for (int i = 0; i < 16; ++i) | |
| accumulator[i] = scratch[i]; | |
| } | |
| if(rotationVector[2] != 0.0f) { | |
| ssrMatrixMakeZRotation(rotationVector[2], rotation); | |
| SSR_MATRIX_MULTIPLY(accumulator, rotation, scratch); | |
| for (int i = 0; i < 16; ++i) | |
| accumulator[i] = scratch[i]; | |
| } | |
| if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_MODELVIEW) { | |
| SSR_MATRIX_MULTIPLY(ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix], accumulator, scratch); | |
| for (int i = 0; i < 16; ++i) | |
| ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix][i] = scratch[i]; | |
| } else if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_PROJECTION) { | |
| SSR_MATRIX_MULTIPLY(ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix], accumulator, scratch); | |
| for (int i = 0; i < 16; ++i) | |
| ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][i] = scratch[i]; | |
| } | |
| } | |
| void ssrRotate(float x, float y, float z) { | |
| float rotate[3] = {x, y, z}; | |
| ssrRotate(rotate); | |
| } | |
| void ssrScale(float* scaleVector) { | |
| if (ssr_pCurrentRenderContext == NULL) { | |
| ssr_nLastError = SSR_ERR_GLRC; | |
| return; | |
| } | |
| float scaleMatrix[16]; | |
| float scratch[16]; | |
| for (int i = 0; i < 16; ++i) | |
| scaleMatrix[i] = 0.0f; | |
| scaleMatrix[15] = 1.0f; | |
| scaleMatrix[0] = scaleVector[0]; | |
| scaleMatrix[5] = scaleVector[1]; | |
| scaleMatrix[10] = scaleVector[2]; | |
| if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_MODELVIEW) { | |
| SSR_MATRIX_MULTIPLY(ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix], scaleMatrix, scratch); | |
| for (int i = 0; i < 16; ++i) | |
| ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix][i] = scratch[i]; | |
| } else if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_PROJECTION) { | |
| SSR_MATRIX_MULTIPLY(ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix], scaleMatrix, scratch); | |
| for (int i = 0; i < 16; ++i) | |
| ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][i] = scratch[i]; | |
| } | |
| } | |
| void ssrScale(float x, float y, float z) { | |
| float scale[3] = {z, y, z}; | |
| ssrScale(scale); | |
| } | |
| void ssrTranslate(float x, float y, float z) { | |
| float translate[3] = {x, y, z}; | |
| ssrTranslate(translate); | |
| } | |
| void ssrTranslate(float* translateVector) { | |
| if (ssr_pCurrentRenderContext == NULL) { | |
| ssr_nLastError = SSR_ERR_GLRC; | |
| return; | |
| } | |
| if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_MODELVIEW) { | |
| ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix][12] += translateVector[0]; | |
| ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix][13] += translateVector[1]; | |
| ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix][14] += translateVector[2]; | |
| } else if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_PROJECTION) { | |
| ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][12] += translateVector[0]; | |
| ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][13] += translateVector[1]; | |
| ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][14] += translateVector[2]; | |
| } | |
| } | |
| void ssrMatrixMakeXRotation(float angle, float* matrix) { | |
| while (angle > 360.0f) | |
| angle -= 360.0f; | |
| while (angle < 0) | |
| angle += 360.0f; | |
| angle *= SSR_DEG_TO_RAD; | |
| for (int i = 0; i < 16; ++i) | |
| matrix[i] = 0.0f; | |
| matrix[0] = 1.0f; | |
| matrix[5] = 1.0f; | |
| matrix[10] = 1.0f; | |
| matrix[15] = 1.0f; | |
| matrix[5] = cosf(angle); | |
| matrix[6] = sinf(angle); | |
| matrix[9] = -1.0f * sinf(angle); | |
| matrix[10] = cosf(angle); | |
| } | |
| void ssrMatrixMakeYRotation(float angle, float* matrix) { | |
| while (angle > 360.0f) | |
| angle -= 360.0f; | |
| while (angle < 0) | |
| angle += 360.0f; | |
| angle *= SSR_DEG_TO_RAD; | |
| for (int i = 0; i < 16; ++i) | |
| matrix[i] = 0.0f; | |
| matrix[0] = 1.0f; | |
| matrix[5] = 1.0f; | |
| matrix[10] = 1.0f; | |
| matrix[15] = 1.0f; | |
| matrix[0] = cosf(angle); | |
| matrix[2] = -1.0f * sinf(angle); | |
| matrix[8] = sinf(angle); | |
| matrix[10] = cosf(angle); | |
| } | |
| void ssrMatrixMakeZRotation(float angle, float* matrix) { | |
| while (angle > 360.0f) | |
| angle -= 360.0f; | |
| while (angle < 0) | |
| angle += 360.0f; | |
| angle *= SSR_DEG_TO_RAD; | |
| for (int i = 0; i < 16; ++i) | |
| matrix[i] = 0.0f; | |
| matrix[0] = 1.0f; | |
| matrix[5] = 1.0f; | |
| matrix[10] = 1.0f; | |
| matrix[15] = 1.0f; | |
| matrix[0] = cosf(angle); | |
| matrix[1] = sinf(angle); | |
| matrix[4] = -1.0f * sinf(angle); | |
| matrix[5] = cosf(angle); | |
| } | |
| void ssrTransformToScreenSpace() { | |
| float modelViewProjectionMatrix[16]; | |
| SSR_MATRIX_MULTIPLY(ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix], ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix], modelViewProjectionMatrix); | |
| int screenW = ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmWidth; | |
| int screenH = ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmHeight; | |
| int halfScreenW = (int)(ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmWidth * 0.5f); | |
| int halfScreenH = (int)(ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmHeight * 0.5); | |
| for (int i = 0, imax = ssr_pCurrentRenderContext->batchComponent.masterVertexList.size(); i < imax; ++i) { | |
| float vertex[3] = { ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].x, ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].y, ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].z }; | |
| float result[3]; | |
| SSR_VECTOR_MATRIX_MULTIPLY(vertex, modelViewProjectionMatrix, result); | |
| ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].x = result[0]; | |
| ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].y = result[1]; | |
| ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].z = result[2]; | |
| } | |
| for (int i = 0, imax = ssr_pCurrentRenderContext->batchComponent.masterVertexList.size(); i < imax; ++i) { | |
| float result[3] = { ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].x, ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].y, ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].z }; | |
| if (ssr_pCurrentRenderContext->matrixComponent.projectionMode == SSR_ORTHO) { // Orthographic | |
| result[0] = (result[0] + ssr_pCurrentRenderContext->renderInfoComponent.offset[0]) * ssr_pCurrentRenderContext->renderInfoComponent.normalizeValues[0]; | |
| result[1] = (result[1] + ssr_pCurrentRenderContext->renderInfoComponent.offset[1]) * ssr_pCurrentRenderContext->renderInfoComponent.normalizeValues[1]; | |
| } else if (ssr_pCurrentRenderContext->matrixComponent.projectionMode == SSR_PERSP) { // Perspective | |
| result[0] = (result[0] * ssr_pCurrentRenderContext->renderInfoComponent.perspectiveCompensate[0] / ((result[2] == 0.0f) ? -0.0001f : result[2]) + ssr_pCurrentRenderContext->renderInfoComponent.offset[0]) * ssr_pCurrentRenderContext->renderInfoComponent.normalizeValues[0]; | |
| result[1] = (-1.0f * result[1] * ssr_pCurrentRenderContext->renderInfoComponent.perspectiveCompensate[1] / ((result[2] == 0.0f) ? -0.0001f : result[2]) + ssr_pCurrentRenderContext->renderInfoComponent.offset[1]) * ssr_pCurrentRenderContext->renderInfoComponent.normalizeValues[1]; | |
| } else { | |
| ssr_nLastError = SSR_ERR_NOPROJSETUP; | |
| return; | |
| } | |
| result[0] *= screenW; | |
| result[1] *= screenH; | |
| ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].x = result[0]; | |
| ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].y = result[1]; | |
| ssr_pCurrentRenderContext->batchComponent.masterVertexList[i].z = result[2]; | |
| } | |
| } | |
| void ssrPresentScene() { | |
| if (ssr_pCurrentRenderContext == NULL) { | |
| ssr_nLastError = SSR_ERR_GLRC; | |
| return; | |
| } | |
| ssr_pCurrentRenderContext->batchComponent.masterVertexList.clear(); | |
| int left = ssr_pCurrentRenderContext->renderInfoComponent.viewport[SSR_VIEWPORT_LEFT]; | |
| int top = ssr_pCurrentRenderContext->renderInfoComponent.viewport[SSR_VIEWPORT_TOP]; | |
| int right = ssr_pCurrentRenderContext->renderInfoComponent.viewport[SSR_VIEWPORT_RIGHT]; | |
| int bottom = ssr_pCurrentRenderContext->renderInfoComponent.viewport[SSR_VIEWPORT_BOTTOM]; | |
| int width = right - left; int height = bottom - top; | |
| ssrDrawText(); | |
| BitBlt(ssr_pCurrentRenderContext->windowsDisplayComponent.hdcDisplay, left, top, width, height, ssr_pCurrentRenderContext->windowsDisplayComponent.hdcBitmap, 0, 0, SRCCOPY); | |
| } | |
| void ssrClear() { | |
| if (ssr_pCurrentRenderContext == NULL) { | |
| ssr_nLastError = SSR_ERR_GLRC; | |
| return; | |
| } | |
| for (int j = 0; j < ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmHeight; ++j) { | |
| for (int i = 0; i < ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmWidth; ++i) { | |
| int index = (j * ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmWidth + i); | |
| ssr_pCurrentRenderContext->displayComponent.imageBuffer[index] = ssr_pCurrentRenderContext->displayComponent.clearColor; | |
| ssr_pCurrentRenderContext->displayComponent.depthBuffer[index] = FLT_MAX; | |
| } | |
| } | |
| } | |
| void ssrCullFace(int cullMode) { | |
| if (ssr_pCurrentRenderContext == NULL) { | |
| ssr_nLastError = SSR_ERR_GLRC; | |
| return; | |
| } | |
| if (cullMode != SSR_FRONT && cullMode != SSR_BACK && cullMode != SSR_NOCULL) { | |
| ssr_nLastError = SSR_ERR_INVARG; | |
| return; | |
| } | |
| ssr_pCurrentRenderContext->renderInfoComponent.cullDirection = cullMode; | |
| } | |
| int ssrGetError() { | |
| return ssr_nLastError; | |
| } | |
| void ssrWrapMode(int wrapMode) { | |
| if (ssr_pCurrentRenderContext == NULL) { | |
| ssr_nLastError = SSR_ERR_GLRC; | |
| return; | |
| } | |
| ssr_pCurrentRenderContext->renderInfoComponent.imageWrapMode = wrapMode; | |
| } | |
| void ssrSortTriangle(float (*verts)[3], int* order) { | |
| #define ay verts[0][1] | |
| #define by verts[1][1] | |
| #define cy verts[2][1] | |
| // Find the lowest y | |
| if (ay < by) { | |
| if (ay < cy) { | |
| order[0] = 0; | |
| } else { | |
| order[0] = 2; | |
| } | |
| } else { | |
| if (by < cy) { | |
| order[0] = 1; | |
| } else { | |
| order[0] = 2; | |
| } | |
| } | |
| // Find the highest y | |
| if (ay > by) { | |
| if (ay > cy) { | |
| order[2] = 0; | |
| } else { | |
| order[2] = 2; | |
| } | |
| } else { | |
| if (by > cy) { | |
| order[2] = 1; | |
| } else { | |
| order[2] = 2; | |
| } | |
| } | |
| // Figure out middle y | |
| order[1] = 3 - (order[0] + order[2]); | |
| #undef ay | |
| #undef by | |
| #undef cy | |
| } | |
| bool ssrIsBackFacing(float* verts) { | |
| #define x1 verts[0] | |
| #define y1 verts[1] | |
| #define z1 verts[2] | |
| #define x2 verts[3] | |
| #define y2 verts[4] | |
| #define z2 verts[5] | |
| #define x3 verts[6] | |
| #define y3 verts[7] | |
| #define z3 verts[8] | |
| float d1x, d1y, d2x, d2y, z; | |
| d1x = x3 - x1; | |
| d1y = y3 - y1; | |
| d2x = x3 - x2; | |
| d2y = y3 - y2; | |
| if (ssr_pCurrentRenderContext->renderInfoComponent.cullDirection == SSR_BACK) { | |
| z = (d2x * d1y) - (d2y * d1x); | |
| } else if (ssr_pCurrentRenderContext->renderInfoComponent.cullDirection == SSR_FRONT) { | |
| z = (d1x * d2y) - (d1y * d2x); | |
| } else { | |
| return false; | |
| } | |
| return (z < 0.0f); | |
| #undef x1 | |
| #undef x2 | |
| #undef x3 | |
| #undef y1 | |
| #undef y2 | |
| #undef y3 | |
| #undef z1 | |
| #undef z2 | |
| #undef z3 | |
| } | |
| void ssrSortSplitAndSumbitTriangle(float (*triangle)[3]) { | |
| int order[3]; float renderVerts[9]; | |
| renderVerts[0] = triangle[0][0]; | |
| renderVerts[1] = triangle[0][1]; | |
| renderVerts[2] = triangle[0][2]; | |
| renderVerts[3] = triangle[1][0]; | |
| renderVerts[4] = triangle[1][1]; | |
| renderVerts[5] = triangle[1][2]; | |
| renderVerts[6] = triangle[2][0]; | |
| renderVerts[7] = triangle[2][1]; | |
| renderVerts[8] = triangle[2][2]; | |
| if (ssrIsBackFacing(renderVerts)) | |
| return; | |
| ssr_debugNumTriangles++; | |
| ssrSortTriangle(triangle, order); | |
| if (triangle[order[1]][1] != triangle[order[0]][1] && triangle[order[2]][1] != triangle[order[0]][1] && | |
| triangle[order[2]][1] != triangle[order[1]][1] /* y2 != y1 && y3 != y1 && y3 != y2 */) { // Needs to be split into two | |
| // new x: (x3 - x1) * ((y2 - y1) / (y3 - y1)) + x1; | |
| float newX = (triangle[order[2]][0] - triangle[order[0]][0]) * ((triangle[order[1]][1] - triangle[order[0]][1]) / (triangle[order[2]][1] - triangle[order[0]][1])) + triangle[order[0]][0]; | |
| float newZ = (triangle[order[2]][2] - triangle[order[0]][2]) * ((triangle[order[1]][1] - triangle[order[0]][1]) / (triangle[order[2]][1] - triangle[order[0]][1])) + triangle[order[0]][2]; | |
| if (newX < triangle[order[1]][0]/* newX < x2 */) { | |
| int firstBatch[3] = { order[0], order[1], order[1] }; | |
| int secondBatch[3] = { order[2], order[1], order[1] }; | |
| renderVerts[0] = triangle[firstBatch[0]][0]; | |
| renderVerts[1] = triangle[firstBatch[0]][1]; | |
| renderVerts[2] = triangle[firstBatch[0]][2]; | |
| renderVerts[3] = newX; | |
| renderVerts[4] = triangle[firstBatch[1]][1]; | |
| renderVerts[5] = newZ; | |
| renderVerts[6] = triangle[firstBatch[1]][0]; | |
| renderVerts[7] = triangle[firstBatch[1]][1]; | |
| renderVerts[8] = triangle[firstBatch[1]][2]; | |
| ssrRenderBlackTriangle(renderVerts); | |
| renderVerts[0] = triangle[secondBatch[0]][0]; | |
| renderVerts[1] = triangle[secondBatch[0]][1]; | |
| renderVerts[2] = triangle[secondBatch[0]][2]; | |
| renderVerts[3] = triangle[secondBatch[1]][0]; | |
| renderVerts[4] = triangle[secondBatch[1]][1]; | |
| renderVerts[5] = triangle[secondBatch[1]][2]; | |
| renderVerts[6] = newX; | |
| renderVerts[7] = triangle[secondBatch[1]][1]; | |
| renderVerts[8] = newZ; | |
| ssrRenderBlackTriangle(renderVerts); | |
| } else { | |
| int firstBatch[3] = { order[0], order[1], order[1] }; | |
| int secondBatch[3] = { order[2], order[1], order[1] }; | |
| renderVerts[0] = triangle[firstBatch[0]][0]; | |
| renderVerts[1] = triangle[firstBatch[0]][1]; | |
| renderVerts[2] = triangle[firstBatch[0]][2]; | |
| renderVerts[3] = triangle[firstBatch[1]][0]; | |
| renderVerts[4] = triangle[firstBatch[1]][1]; | |
| renderVerts[5] = triangle[firstBatch[1]][2]; | |
| renderVerts[6] = newX; | |
| renderVerts[7] = triangle[firstBatch[1]][1]; | |
| renderVerts[8] = newZ; | |
| ssrRenderBlackTriangle(renderVerts); | |
| renderVerts[0] = triangle[secondBatch[0]][0]; | |
| renderVerts[1] = triangle[secondBatch[0]][1]; | |
| renderVerts[2] = triangle[secondBatch[0]][2]; | |
| renderVerts[3] = triangle[secondBatch[1]][0]; | |
| renderVerts[4] = triangle[secondBatch[1]][1]; | |
| renderVerts[5] = triangle[secondBatch[1]][2]; | |
| renderVerts[6] = newX; | |
| renderVerts[7] = triangle[secondBatch[1]][1]; | |
| renderVerts[8] = newZ; | |
| ssrRenderBlackTriangle(renderVerts); | |
| } | |
| } else if (triangle[order[0]][1] == triangle[order[1]][1] /* y1 == y2 */) { // Top half is flat | |
| if (triangle[order[0]][0] < triangle[order[1]][0]) { // x1 < x2 | |
| int newOrder[3] = { order[2], order[1], order[0] }; | |
| order[0] = newOrder[0]; | |
| order[1] = newOrder[1]; | |
| order[2] = newOrder[2]; | |
| } else { | |
| int newOrder[3] = { order[2], order[0], order[1] }; | |
| order[0] = newOrder[0]; | |
| order[1] = newOrder[1]; | |
| order[2] = newOrder[2]; | |
| } | |
| renderVerts[0] = triangle[order[0]][0]; | |
| renderVerts[1] = triangle[order[0]][1]; | |
| renderVerts[2] = triangle[order[0]][2]; | |
| renderVerts[3] = triangle[order[1]][0]; | |
| renderVerts[4] = triangle[order[1]][1]; | |
| renderVerts[5] = triangle[order[1]][2]; | |
| renderVerts[6] = triangle[order[2]][0]; | |
| renderVerts[7] = triangle[order[2]][1]; | |
| renderVerts[8] = triangle[order[2]][2]; | |
| ssrRenderBlackTriangle(renderVerts); | |
| } else if (triangle[order[1]][1] == triangle[order[2]][1] /* y2 == y3 */) { // Bottom half is flat | |
| if (triangle[order[1]][0] < triangle[order[2]][0]) { // x2 < x3 | |
| int newOrder[3] = { order[0], order[1], order[2] }; | |
| order[0] = newOrder[0]; | |
| order[1] = newOrder[1]; | |
| order[2] = newOrder[2]; | |
| } else { | |
| int newOrder[3] = { order[0], order[2], order[1] }; | |
| order[0] = newOrder[0]; | |
| order[1] = newOrder[1]; | |
| order[2] = newOrder[2]; | |
| } | |
| renderVerts[0] = triangle[order[0]][0]; | |
| renderVerts[1] = triangle[order[0]][1]; | |
| renderVerts[2] = triangle[order[0]][2]; | |
| renderVerts[3] = triangle[order[1]][0]; | |
| renderVerts[4] = triangle[order[1]][1]; | |
| renderVerts[5] = triangle[order[1]][2]; | |
| renderVerts[6] = triangle[order[2]][0]; | |
| renderVerts[7] = triangle[order[2]][1]; | |
| renderVerts[8] = triangle[order[2]][2]; | |
| ssrRenderBlackTriangle(renderVerts); | |
| } | |
| } | |
| void ssrSortSplitSubmitColoredTriangle(float (*triangle)[3], float (*colors)[3]) { | |
| int order[3]; float renderVerts[9]; | |
| renderVerts[0] = triangle[0][0]; | |
| renderVerts[1] = triangle[0][1]; | |
| renderVerts[2] = triangle[0][2]; | |
| renderVerts[3] = triangle[1][0]; | |
| renderVerts[4] = triangle[1][1]; | |
| renderVerts[5] = triangle[1][2]; | |
| renderVerts[6] = triangle[2][0]; | |
| renderVerts[7] = triangle[2][1]; | |
| renderVerts[8] = triangle[2][2]; | |
| if (ssrIsBackFacing(renderVerts)) | |
| return; | |
| ssrSortTriangle(triangle, order); float color[3][3]; | |
| float nearPlane = ssr_pCurrentRenderContext->renderInfoComponent.offset[2]; | |
| if (triangle[order[1]][1] != triangle[order[0]][1] && triangle[order[2]][1] != triangle[order[0]][1] && | |
| triangle[order[2]][1] != triangle[order[1]][1] /* y2 != y1 && y3 != y1 && y3 != y2 */) { // Needs to be split into two | |
| // new x: (x3 - x1) * ((y2 - y1) / (y3 - y1)) + x1; | |
| float newX = (triangle[order[2]][0] - triangle[order[0]][0]) * ((triangle[order[1]][1] - triangle[order[0]][1]) / (triangle[order[2]][1] - triangle[order[0]][1])) + triangle[order[0]][0]; | |
| float newZ = (triangle[order[2]][2] - triangle[order[0]][2]) * ((triangle[order[1]][1] - triangle[order[0]][1]) / (triangle[order[2]][1] - triangle[order[0]][1])) + triangle[order[0]][2]; | |
| float newColor[3]; float p; | |
| if (newX < triangle[order[1]][0]/* newX < x2 */) { | |
| int firstBatch[3] = { order[0], order[1], order[1] }; | |
| int secondBatch[3] = { order[2], order[1], order[1] }; | |
| renderVerts[0] = triangle[firstBatch[0]][0]; | |
| renderVerts[1] = triangle[firstBatch[0]][1]; | |
| renderVerts[2] = triangle[firstBatch[0]][2]; | |
| renderVerts[3] = newX; | |
| renderVerts[4] = triangle[firstBatch[1]][1]; | |
| renderVerts[5] = newZ; | |
| renderVerts[6] = triangle[firstBatch[1]][0]; | |
| renderVerts[7] = triangle[firstBatch[1]][1]; | |
| renderVerts[8] = triangle[firstBatch[1]][2]; | |
| //////// Just figure out the new color.... | |
| float point1[3] = {triangle[firstBatch[0]][0], triangle[firstBatch[0]][1], triangle[firstBatch[0]][2]}; | |
| float point2[3] = {triangle[secondBatch[0]][0], triangle[secondBatch[0]][1], triangle[secondBatch[0]][2]}; | |
| float line[3] = {point2[0] - point1[0], point2[1] - point1[1], point2[2] - point1[2]}; | |
| float whole = sqrtf( (line[0] * line[0]) + (line[1] * line[1]) + (line[2] * line[2]) ); | |
| point2[0] = newX; point2[1] = triangle[firstBatch[1]][1]; point2[2] = newZ; | |
| line[0] = point2[0] - point1[0]; line[1] = point2[1] - point1[1]; line[2] = point2[2] - point1[2]; | |
| float part = sqrtf( (line[0] * line[0]) + (line[1] * line[1]) + (line[2] * line[2]) ); | |
| p = part / whole; | |
| newColor[0] = ssrClampToZeroOne(SSR_FLERP(colors[firstBatch[0]][0], colors[secondBatch[0]][0], p)); | |
| newColor[1] = ssrClampToZeroOne(SSR_FLERP(colors[firstBatch[0]][1], colors[secondBatch[0]][1], p)); | |
| newColor[2] = ssrClampToZeroOne(SSR_FLERP(colors[firstBatch[0]][2], colors[secondBatch[0]][2], p)); | |
| //////// Found | |
| color[0][0] = colors[firstBatch[0]][0]; | |
| color[0][1] = colors[firstBatch[0]][1]; | |
| color[0][2] = colors[firstBatch[0]][2]; | |
| color[1][0] = newColor[0]; | |
| color[1][1] = newColor[1]; | |
| color[1][2] = newColor[2]; | |
| color[2][0] = colors[firstBatch[1]][0]; | |
| color[2][1] = colors[firstBatch[1]][1]; | |
| color[2][2] = colors[firstBatch[1]][2]; | |
| if (renderVerts[2] > nearPlane && renderVerts[5] > nearPlane && renderVerts[8] > nearPlane) { | |
| ssrRenderColoredTriangle(renderVerts, color); | |
| } | |
| renderVerts[0] = triangle[secondBatch[0]][0]; | |
| renderVerts[1] = triangle[secondBatch[0]][1]; | |
| renderVerts[2] = triangle[secondBatch[0]][2]; | |
| renderVerts[3] = triangle[secondBatch[1]][0]; | |
| renderVerts[4] = triangle[secondBatch[1]][1]; | |
| renderVerts[5] = triangle[secondBatch[1]][2]; | |
| renderVerts[6] = newX; | |
| renderVerts[7] = triangle[secondBatch[1]][1]; | |
| renderVerts[8] = newZ; | |
| color[0][0] = colors[secondBatch[0]][0]; | |
| color[0][1] = colors[secondBatch[0]][1]; | |
| color[0][2] = colors[secondBatch[0]][2]; | |
| color[1][0] = colors[secondBatch[1]][0]; | |
| color[1][1] = colors[secondBatch[1]][1]; | |
| color[1][2] = colors[secondBatch[1]][2]; | |
| color[2][0] = newColor[0]; | |
| color[2][1] = newColor[1]; | |
| color[2][2] = newColor[2]; | |
| if (renderVerts[2] > nearPlane && renderVerts[5] > nearPlane && renderVerts[8] > nearPlane) { | |
| ssrRenderColoredTriangle(renderVerts, color); | |
| } | |
| } else { | |
| int firstBatch[3] = { order[0], order[1], order[1] }; | |
| int secondBatch[3] = { order[2], order[1], order[1] }; | |
| //////// Just figure out the new color.... | |
| float point1[3] = {triangle[firstBatch[0]][0], triangle[firstBatch[0]][1], triangle[firstBatch[0]][2]}; | |
| float point2[3] = {triangle[secondBatch[0]][0], triangle[secondBatch[0]][1], triangle[secondBatch[0]][2]}; | |
| float line[3] = {point2[0] - point1[0], point2[1] - point1[1], point2[2] - point1[2]}; | |
| float whole = sqrtf( (line[0] * line[0]) + (line[1] * line[1]) + (line[2] * line[2]) ); | |
| point2[0] = newX; point2[1] = triangle[firstBatch[1]][1]; point2[2] = newZ; | |
| line[0] = point2[0] - point1[0]; line[1] = point2[1] - point1[1]; line[2] = point2[2] - point1[2]; | |
| float part = sqrtf( (line[0] * line[0]) + (line[1] * line[1]) + (line[2] * line[2]) ); | |
| p = part / whole; | |
| newColor[0] = ssrClampToZeroOne(SSR_FLERP(colors[firstBatch[0]][0], colors[secondBatch[0]][0], p)); | |
| newColor[1] = ssrClampToZeroOne(SSR_FLERP(colors[firstBatch[0]][1], colors[secondBatch[0]][1], p)); | |
| newColor[2] = ssrClampToZeroOne(SSR_FLERP(colors[firstBatch[0]][2], colors[secondBatch[0]][2], p)); | |
| //////// Found | |
| renderVerts[0] = triangle[firstBatch[0]][0]; | |
| renderVerts[1] = triangle[firstBatch[0]][1]; | |
| renderVerts[2] = triangle[firstBatch[0]][2]; | |
| renderVerts[3] = triangle[firstBatch[1]][0]; | |
| renderVerts[4] = triangle[firstBatch[1]][1]; | |
| renderVerts[5] = triangle[firstBatch[1]][2]; | |
| renderVerts[6] = newX; | |
| renderVerts[7] = triangle[firstBatch[1]][1]; | |
| renderVerts[8] = newZ; | |
| color[0][0] = colors[firstBatch[0]][0]; | |
| color[0][1] = colors[firstBatch[0]][1]; | |
| color[0][2] = colors[firstBatch[0]][2]; | |
| color[1][0] = colors[firstBatch[1]][0]; | |
| color[1][1] = colors[firstBatch[1]][1]; | |
| color[1][2] = colors[firstBatch[1]][2]; | |
| color[2][0] = newColor[0]; | |
| color[2][1] = newColor[1]; | |
| color[2][2] = newColor[2]; | |
| if (renderVerts[2] > nearPlane && renderVerts[5] > nearPlane && renderVerts[8] > nearPlane) { | |
| ssrRenderColoredTriangle(renderVerts, color); | |
| } | |
| renderVerts[0] = triangle[secondBatch[0]][0]; | |
| renderVerts[1] = triangle[secondBatch[0]][1]; | |
| renderVerts[2] = triangle[secondBatch[0]][2]; | |
| renderVerts[3] = triangle[secondBatch[1]][0]; | |
| renderVerts[4] = triangle[secondBatch[1]][1]; | |
| renderVerts[5] = triangle[secondBatch[1]][2]; | |
| renderVerts[6] = newX; | |
| renderVerts[7] = triangle[secondBatch[1]][1]; | |
| renderVerts[8] = newZ; | |
| color[0][0] = colors[secondBatch[0]][0]; | |
| color[0][1] = colors[secondBatch[0]][1]; | |
| color[0][2] = colors[secondBatch[0]][2]; | |
| color[1][0] = colors[secondBatch[1]][0]; | |
| color[1][1] = colors[secondBatch[1]][1]; | |
| color[1][2] = colors[secondBatch[1]][2]; | |
| color[2][0] = newColor[0]; | |
| color[2][1] = newColor[1]; | |
| color[2][2] = newColor[2]; | |
| if (renderVerts[2] > nearPlane && renderVerts[5] > nearPlane && renderVerts[8] > nearPlane) { | |
| ssrRenderColoredTriangle(renderVerts, color); | |
| } | |
| } | |
| } else if (triangle[order[0]][1] == triangle[order[1]][1] /* y1 == y2 */) { // Top half is flat | |
| if (triangle[order[0]][0] < triangle[order[1]][0]) { // x1 < x2 | |
| int newOrder[3] = { order[2], order[1], order[0] }; | |
| order[0] = newOrder[0]; | |
| order[1] = newOrder[1]; | |
| order[2] = newOrder[2]; | |
| } else { | |
| int newOrder[3] = { order[2], order[0], order[1] }; | |
| order[0] = newOrder[0]; | |
| order[1] = newOrder[1]; | |
| order[2] = newOrder[2]; | |
| } | |
| renderVerts[0] = triangle[order[0]][0]; | |
| renderVerts[1] = triangle[order[0]][1]; | |
| renderVerts[2] = triangle[order[0]][2]; | |
| renderVerts[3] = triangle[order[1]][0]; | |
| renderVerts[4] = triangle[order[1]][1]; | |
| renderVerts[5] = triangle[order[1]][2]; | |
| renderVerts[6] = triangle[order[2]][0]; | |
| renderVerts[7] = triangle[order[2]][1]; | |
| renderVerts[8] = triangle[order[2]][2]; | |
| color[0][0] = colors[order[0]][0]; | |
| color[0][1] = colors[order[0]][1]; | |
| color[0][2] = colors[order[0]][2]; | |
| color[1][0] = colors[order[1]][0]; | |
| color[1][1] = colors[order[1]][1]; | |
| color[1][2] = colors[order[1]][2]; | |
| color[2][0] = colors[order[2]][0]; | |
| color[2][1] = colors[order[2]][1]; | |
| color[2][2] = colors[order[2]][2]; | |
| if (renderVerts[2] > nearPlane && renderVerts[5] > nearPlane && renderVerts[8] > nearPlane) { | |
| ssrRenderColoredTriangle(renderVerts, color); | |
| } | |
| } else if (triangle[order[1]][1] == triangle[order[2]][1] /* y2 == y3 */) { // Bottom half is flat | |
| if (triangle[order[1]][0] < triangle[order[2]][0]) { // x2 < x3 | |
| int newOrder[3] = { order[0], order[1], order[2] }; | |
| order[0] = newOrder[0]; | |
| order[1] = newOrder[1]; | |
| order[2] = newOrder[2]; | |
| } else { | |
| int newOrder[3] = { order[0], order[2], order[1] }; | |
| order[0] = newOrder[0]; | |
| order[1] = newOrder[1]; | |
| order[2] = newOrder[2]; | |
| } | |
| renderVerts[0] = triangle[order[0]][0]; | |
| renderVerts[1] = triangle[order[0]][1]; | |
| renderVerts[2] = triangle[order[0]][2]; | |
| renderVerts[3] = triangle[order[1]][0]; | |
| renderVerts[4] = triangle[order[1]][1]; | |
| renderVerts[5] = triangle[order[1]][2]; | |
| renderVerts[6] = triangle[order[2]][0]; | |
| renderVerts[7] = triangle[order[2]][1]; | |
| renderVerts[8] = triangle[order[2]][2]; | |
| color[0][0] = colors[order[0]][0]; | |
| color[0][1] = colors[order[0]][1]; | |
| color[0][2] = colors[order[0]][2]; | |
| color[1][0] = colors[order[1]][0]; | |
| color[1][1] = colors[order[1]][1]; | |
| color[1][2] = colors[order[1]][2]; | |
| color[2][0] = colors[order[2]][0]; | |
| color[2][1] = colors[order[2]][1]; | |
| color[2][2] = colors[order[2]][2]; | |
| if (renderVerts[2] > nearPlane && renderVerts[5] > nearPlane && renderVerts[8] > nearPlane) { | |
| ssrRenderColoredTriangle(renderVerts, color); | |
| } | |
| } | |
| } | |
| void ssrSortSplitSubmitTexturedTriangle(float (*triangle)[3], float (*uvs)[2]) { | |
| int order[3]; float renderVerts[9]; float sumbituvs[6]; | |
| renderVerts[0] = triangle[0][0]; | |
| renderVerts[1] = triangle[0][1]; | |
| renderVerts[2] = triangle[0][2]; | |
| renderVerts[3] = triangle[1][0]; | |
| renderVerts[4] = triangle[1][1]; | |
| renderVerts[5] = triangle[1][2]; | |
| renderVerts[6] = triangle[2][0]; | |
| renderVerts[7] = triangle[2][1]; | |
| renderVerts[8] = triangle[2][2]; | |
| if (ssrIsBackFacing(renderVerts)) | |
| return; | |
| ssr_debugNumTriangles++; | |
| ssrSortTriangle(triangle, order); | |
| if (triangle[order[1]][1] != triangle[order[0]][1] && triangle[order[2]][1] != triangle[order[0]][1] && | |
| triangle[order[2]][1] != triangle[order[1]][1] /* y2 != y1 && y3 != y1 && y3 != y2 */) { // Needs to be split into two | |
| // new x: (x3 - x1) * ((y2 - y1) / (y3 - y1)) + x1; | |
| float newX = (triangle[order[2]][0] - triangle[order[0]][0]) * ((triangle[order[1]][1] - triangle[order[0]][1]) / (triangle[order[2]][1] - triangle[order[0]][1])) + triangle[order[0]][0]; | |
| float newZ = (triangle[order[2]][2] - triangle[order[0]][2]) * ((triangle[order[1]][1] - triangle[order[0]][1]) / (triangle[order[2]][1] - triangle[order[0]][1])) + triangle[order[0]][2]; | |
| float newU, newV, p; | |
| if (newX < triangle[order[1]][0]/* newX < x2 */) { | |
| int firstBatch[3] = { order[0], order[1], order[1] }; | |
| int secondBatch[3] = { order[2], order[1], order[1] }; | |
| //////// Just figure out the new texture coords.... | |
| float point1[3] = {triangle[firstBatch[0]][0], triangle[firstBatch[0]][1], triangle[firstBatch[0]][2]}; | |
| float point2[3] = {triangle[secondBatch[0]][0], triangle[secondBatch[0]][1], triangle[secondBatch[0]][2]}; | |
| float line[3] = {point2[0] - point1[0], point2[1] - point1[1], point2[2] - point1[2]}; | |
| float whole = SSR_SQRTFUNC( (line[0] * line[0]) + (line[1] * line[1]) + (line[2] * line[2]) ); | |
| point2[0] = newX; point2[1] = triangle[firstBatch[1]][1]; point2[2] = newZ; | |
| line[0] = point2[0] - point1[0]; line[1] = point2[1] - point1[1]; line[2] = point2[2] - point1[2]; | |
| float part = SSR_SQRTFUNC( (line[0] * line[0]) + (line[1] * line[1]) + (line[2] * line[2]) ); | |
| p = part / whole; | |
| newU = ssrClampToZeroOne(SSR_FLERP(uvs[firstBatch[0]][0], uvs[secondBatch[0]][0], p)); | |
| newV = ssrClampToZeroOne(SSR_FLERP(uvs[firstBatch[0]][1], uvs[secondBatch[0]][1], p)); | |
| //////// Found | |
| renderVerts[0] = triangle[firstBatch[0]][0]; | |
| renderVerts[1] = triangle[firstBatch[0]][1]; | |
| renderVerts[2] = triangle[firstBatch[0]][2]; | |
| renderVerts[3] = newX; | |
| renderVerts[4] = triangle[firstBatch[1]][1]; | |
| renderVerts[5] = newZ; | |
| renderVerts[6] = triangle[firstBatch[1]][0]; | |
| renderVerts[7] = triangle[firstBatch[1]][1]; | |
| renderVerts[8] = triangle[firstBatch[1]][2]; | |
| sumbituvs[0] = uvs[firstBatch[0]][0]; | |
| sumbituvs[1] = uvs[firstBatch[0]][1]; | |
| sumbituvs[2] = newU; | |
| sumbituvs[3] = newV; | |
| sumbituvs[4] = uvs[firstBatch[1]][0]; | |
| sumbituvs[5] = uvs[firstBatch[1]][1]; | |
| ssrRenderTexturedTriangle(renderVerts, sumbituvs); | |
| renderVerts[0] = triangle[secondBatch[0]][0]; | |
| renderVerts[1] = triangle[secondBatch[0]][1]; | |
| renderVerts[2] = triangle[secondBatch[0]][2]; | |
| renderVerts[3] = triangle[secondBatch[1]][0]; | |
| renderVerts[4] = triangle[secondBatch[1]][1]; | |
| renderVerts[5] = triangle[secondBatch[1]][2]; | |
| renderVerts[6] = newX; | |
| renderVerts[7] = triangle[secondBatch[1]][1]; | |
| renderVerts[8] = newZ; | |
| sumbituvs[0] = uvs[secondBatch[0]][0]; | |
| sumbituvs[1] = uvs[secondBatch[0]][1]; | |
| sumbituvs[2] = uvs[secondBatch[1]][0]; | |
| sumbituvs[3] = uvs[secondBatch[1]][1]; | |
| sumbituvs[4] = newU; | |
| sumbituvs[5] = newV; | |
| ssrRenderTexturedTriangle(renderVerts, sumbituvs); | |
| } else { | |
| int firstBatch[3] = { order[0], order[1], order[1] }; | |
| int secondBatch[3] = { order[2], order[1], order[1] }; | |
| //////// Just figure out the new texture coords.... | |
| float point1[3] = {triangle[firstBatch[0]][0], triangle[firstBatch[0]][1], triangle[firstBatch[0]][2]}; | |
| float point2[3] = {triangle[secondBatch[0]][0], triangle[secondBatch[0]][1], triangle[secondBatch[0]][2]}; | |
| float line[3] = {point2[0] - point1[0], point2[1] - point1[1], point2[2] - point1[2]}; | |
| float whole = SSR_SQRTFUNC( (line[0] * line[0]) + (line[1] * line[1]) + (line[2] * line[2]) ); | |
| point2[0] = newX; point2[1] = triangle[firstBatch[1]][1]; point2[2] = newZ; | |
| line[0] = point2[0] - point1[0]; line[1] = point2[1] - point1[1]; line[2] = point2[2] - point1[2]; | |
| float part = SSR_SQRTFUNC( (line[0] * line[0]) + (line[1] * line[1]) + (line[2] * line[2]) ); | |
| p = part / whole; | |
| newU = ssrClampToZeroOne(SSR_FLERP(uvs[firstBatch[0]][0], uvs[secondBatch[0]][0], p)); | |
| newV = ssrClampToZeroOne(SSR_FLERP(uvs[firstBatch[0]][1], uvs[secondBatch[0]][1], p)); | |
| //////// Found | |
| renderVerts[0] = triangle[firstBatch[0]][0]; | |
| renderVerts[1] = triangle[firstBatch[0]][1]; | |
| renderVerts[2] = triangle[firstBatch[0]][2]; | |
| renderVerts[3] = triangle[firstBatch[1]][0]; | |
| renderVerts[4] = triangle[firstBatch[1]][1]; | |
| renderVerts[5] = triangle[firstBatch[1]][2]; | |
| renderVerts[6] = newX; | |
| renderVerts[7] = triangle[firstBatch[1]][1]; | |
| renderVerts[8] = newZ; | |
| sumbituvs[0] = uvs[firstBatch[0]][0]; | |
| sumbituvs[1] = uvs[firstBatch[0]][1]; | |
| sumbituvs[2] = uvs[firstBatch[1]][0]; | |
| sumbituvs[3] = uvs[firstBatch[1]][1]; | |
| sumbituvs[4] = newU; | |
| sumbituvs[5] = newV; | |
| ssrRenderTexturedTriangle(renderVerts, sumbituvs); | |
| renderVerts[0] = triangle[secondBatch[0]][0]; | |
| renderVerts[1] = triangle[secondBatch[0]][1]; | |
| renderVerts[2] = triangle[secondBatch[0]][2]; | |
| renderVerts[3] = triangle[secondBatch[1]][0]; | |
| renderVerts[4] = triangle[secondBatch[1]][1]; | |
| renderVerts[5] = triangle[secondBatch[1]][2]; | |
| renderVerts[6] = newX; | |
| renderVerts[7] = triangle[secondBatch[1]][1]; | |
| renderVerts[8] = newZ; | |
| sumbituvs[0] = uvs[secondBatch[0]][0]; | |
| sumbituvs[1] = uvs[secondBatch[0]][1]; | |
| sumbituvs[2] = uvs[secondBatch[1]][0]; | |
| sumbituvs[3] = uvs[secondBatch[1]][1]; | |
| sumbituvs[4] = newU; | |
| sumbituvs[5] = newV; | |
| ssrRenderTexturedTriangle(renderVerts, sumbituvs); | |
| } | |
| } else if (triangle[order[0]][1] == triangle[order[1]][1] /* y1 == y2 */) { // Top half is flat | |
| if (triangle[order[0]][0] < triangle[order[1]][0]) { // x1 < x2 | |
| int newOrder[3] = { order[2], order[1], order[0] }; | |
| order[0] = newOrder[0]; | |
| order[1] = newOrder[1]; | |
| order[2] = newOrder[2]; | |
| } else { | |
| int newOrder[3] = { order[2], order[0], order[1] }; | |
| order[0] = newOrder[0]; | |
| order[1] = newOrder[1]; | |
| order[2] = newOrder[2]; | |
| } | |
| renderVerts[0] = triangle[order[0]][0]; | |
| renderVerts[1] = triangle[order[0]][1]; | |
| renderVerts[2] = triangle[order[0]][2]; | |
| renderVerts[3] = triangle[order[1]][0]; | |
| renderVerts[4] = triangle[order[1]][1]; | |
| renderVerts[5] = triangle[order[1]][2]; | |
| renderVerts[6] = triangle[order[2]][0]; | |
| renderVerts[7] = triangle[order[2]][1]; | |
| renderVerts[8] = triangle[order[2]][2]; | |
| sumbituvs[0] = uvs[order[0]][0]; | |
| sumbituvs[1] = uvs[order[0]][1]; | |
| sumbituvs[2] = uvs[order[1]][0]; | |
| sumbituvs[3] = uvs[order[1]][1]; | |
| sumbituvs[4] = uvs[order[2]][0]; | |
| sumbituvs[5] = uvs[order[2]][1]; | |
| ssrRenderTexturedTriangle(renderVerts, sumbituvs); | |
| } else if (triangle[order[1]][1] == triangle[order[2]][1] /* y2 == y3 */) { // Bottom half is flat | |
| if (triangle[order[1]][0] < triangle[order[2]][0]) { // x2 < x3 | |
| int newOrder[3] = { order[0], order[1], order[2] }; | |
| order[0] = newOrder[0]; | |
| order[1] = newOrder[1]; | |
| order[2] = newOrder[2]; | |
| } else { | |
| int newOrder[3] = { order[0], order[2], order[1] }; | |
| order[0] = newOrder[0]; | |
| order[1] = newOrder[1]; | |
| order[2] = newOrder[2]; | |
| } | |
| renderVerts[0] = triangle[order[0]][0]; | |
| renderVerts[1] = triangle[order[0]][1]; | |
| renderVerts[2] = triangle[order[0]][2]; | |
| renderVerts[3] = triangle[order[1]][0]; | |
| renderVerts[4] = triangle[order[1]][1]; | |
| renderVerts[5] = triangle[order[1]][2]; | |
| renderVerts[6] = triangle[order[2]][0]; | |
| renderVerts[7] = triangle[order[2]][1]; | |
| renderVerts[8] = triangle[order[2]][2]; | |
| sumbituvs[0] = uvs[order[0]][0]; | |
| sumbituvs[1] = uvs[order[0]][1]; | |
| sumbituvs[2] = uvs[order[1]][0]; | |
| sumbituvs[3] = uvs[order[1]][1]; | |
| sumbituvs[4] = uvs[order[2]][0]; | |
| sumbituvs[5] = uvs[order[2]][1]; | |
| ssrRenderTexturedTriangle(renderVerts, sumbituvs); | |
| } | |
| } | |
| void ssrTargaHelper(char* imagePath, unsigned char (*videoArea[])[4]) { | |
| FILE *pFile; | |
| TGAHEADER tgaHeader; | |
| unsigned long lImageSize; | |
| short sDepth; | |
| pFile = fopen(imagePath, "rb"); | |
| if(pFile == NULL) { | |
| ssr_nLastError = SSR_ERR_NOREADIMAGE; | |
| return; | |
| } | |
| fread(&tgaHeader, 18, 1, pFile); | |
| sDepth = tgaHeader.bits / 8; | |
| if(tgaHeader.bits != 32) { | |
| ssr_nLastError = SSR_ERR_TARGABITSOFF; | |
| fclose(pFile); | |
| return; | |
| } | |
| if (sDepth != 4) { | |
| ssr_nLastError = SSR_ERR_TARGABITSOFF; | |
| fclose(pFile); | |
| return ; | |
| } | |
| lImageSize = tgaHeader.width * tgaHeader.height * sDepth; | |
| int h = tgaHeader.height; | |
| int w = tgaHeader.width; | |
| *videoArea = new unsigned char[w * h + 2][4]; | |
| (*videoArea)[0][0] = (w ) & 0xff; | |
| (*videoArea)[0][1] = (w >> 8) & 0xff; | |
| (*videoArea)[0][2] = (w >> 16) & 0xff; | |
| (*videoArea)[0][3] = (w >> 24) & 0xff; | |
| (*videoArea)[1][0] = (h ) & 0xff; | |
| (*videoArea)[1][1] = (h >> 8) & 0xff; | |
| (*videoArea)[1][2] = (h >> 16) & 0xff; | |
| (*videoArea)[1][3] = (h >> 24) & 0xff; | |
| for (int j = h - 1; j >= 0; --j) { | |
| for (int i = 0; i < w; ++i) { | |
| unsigned char bgra[4]; | |
| if (fread(bgra, 1, 4, pFile) != 4) { | |
| ssr_nLastError = SSR_ERR_NOREADIMAGE; | |
| fclose(pFile); | |
| return; | |
| } | |
| int index = (j * w + i) + 2; | |
| (*videoArea)[index][0] = bgra[2]; | |
| (*videoArea)[index][1] = bgra[1]; | |
| (*videoArea)[index][2] = bgra[0]; | |
| (*videoArea)[index][3] = bgra[3]; | |
| } | |
| } | |
| fclose(pFile); | |
| } | |
| void ssrDrawTexturedLine(float x1, float x2, float y, float z1, float z2, float u_left, float v_left, float u_right, float v_right) { | |
| if (x1 > x2) { | |
| float temp = x1; | |
| x1 = x2; | |
| x2 = temp; | |
| temp = z1; | |
| z1 = z2; | |
| z2 = temp; | |
| temp = u_left; | |
| u_left = u_right; | |
| u_right = temp; | |
| temp = v_left; | |
| v_left = v_right; | |
| v_right = temp; | |
| } | |
| x1 -= 1; | |
| x2 += 1; | |
| unsigned char (*bound)[4] = (unsigned char(*)[4])ssr_pCurrentRenderContext->displayComponent.boundImage; | |
| unsigned int w = (bound[0][0]) | (bound[0][1] << 8) | (bound[0][2] << 16) | (bound[0][3] << 24); | |
| unsigned int h = (bound[1][0]) | (bound[1][1] << 8) | (bound[1][2] << 16) | (bound[1][3] << 24); | |
| int outOne = (int)ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmWidth - 1; | |
| int outTwo = (int)ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmHeight - 1; | |
| int outThree = (int)ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmWidth * (int)ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmHeight; | |
| for (int x = (int)x1, xmax = (int)x2; x < xmax; ++x) { | |
| if (x > outOne) continue; | |
| if (x < 0) continue; | |
| if (y < 0) continue; | |
| if (y > outTwo) continue; | |
| int index = (int)y * (outOne + 1) + x; | |
| if (index < 0) continue; | |
| if (index > outThree) continue; | |
| float p = ((float)((int)x - (int)x1) / (float)((int)x2 - (int)x1)); | |
| float z = SSR_FLERP(z1, z2, p); | |
| if (z > ssr_pCurrentRenderContext->displayComponent.depthBuffer[index]) continue; | |
| int access = 0; | |
| if (ssr_pCurrentRenderContext->renderInfoComponent.imageWrapMode == SSR_CLAMP) { | |
| access = (int)(ssrClampToZeroOne(SSR_FLERP(v_left, v_right, p)) * h) * w + (int)(ssrClampToZeroOne(SSR_FLERP(u_left, u_right, p)) * w) + 2; | |
| } else { | |
| while (v_left < 0.0f) v_left += 1.0f; | |
| while (v_left > 1.0f) v_left -= 1.0f; | |
| while (v_right < 0.0f) v_right += 1.0f; | |
| while (v_right > 1.0f) v_right -= 1.0f; | |
| while (u_left < 0.0f) u_left += 1.0f; | |
| while (u_left > 1.0f) u_left -= 1.0f; | |
| while (u_right < 0.0f) u_right += 1.0f; | |
| while (u_right > 1.0f) u_right -= 1.0f; | |
| access = (int)( | |
| ssrClampToZeroOne(SSR_FLERP(v_left, v_right, p)) * h | |
| ) * w + (int)( | |
| ssrClampToZeroOne(SSR_FLERP(u_left, u_right, p)) * w | |
| ) + 2; | |
| } | |
| COLORREF pixel_color = SSR_ARGB(bound[access][3], bound[access][0], bound[access][1], bound[access][2]); | |
| if (bound[access][3] != 255) { | |
| COLORREF existing_pixel = ssr_pCurrentRenderContext->displayComponent.imageBuffer[index]; | |
| unsigned char dr = SSR_GETR(existing_pixel); | |
| unsigned char dg = SSR_GETG(existing_pixel); | |
| unsigned char db = SSR_GETB(existing_pixel); | |
| db = (bound[access][3] * (bound[access][2] - db))/255 + db; | |
| dg = (bound[access][3] * (bound[access][1] - dg))/255 + dg; | |
| dr = (bound[access][3] * (bound[access][0] - dr))/255 + dr; | |
| ssr_pCurrentRenderContext->displayComponent.imageBuffer[index] = SSR_ARGB(255, dr, dg, db); | |
| } else { | |
| ssr_pCurrentRenderContext->displayComponent.imageBuffer[index] = pixel_color; | |
| } | |
| ssr_pCurrentRenderContext->displayComponent.depthBuffer[index] = z; | |
| } | |
| } | |
| void ssrRenderTexturedTriangle(float* verts, float * uvs) { | |
| #define x1 ((int)verts[0]) | |
| #define y1 ((int)verts[1]) | |
| #define z1 (verts[2]) | |
| #define x2 ((int)verts[3]) | |
| #define y2 ((int)verts[4]) | |
| #define z2 (verts[5]) | |
| #define x3 ((int)verts[6]) | |
| #define y3 ((int)verts[7]) | |
| #define z3 (verts[8]) | |
| #define u1 uvs[0] | |
| #define v1 uvs[1] | |
| #define u2 uvs[2] | |
| #define v2 uvs[3] | |
| #define u3 uvs[4] | |
| #define v3 uvs[5] | |
| float slope_left, slope_right; | |
| float left, right; | |
| float height = (float)(y3 - y1); | |
| if (height == 0.0f) | |
| return; | |
| float reciprical = 1.0f / height; | |
| slope_left = ((float)(x2 - x1)) * reciprical; | |
| slope_right = ((float)(x3 - x1)) * reciprical; | |
| left = right = (float)x1; | |
| float uv_left[2] = { u1, v1}; | |
| float uv_right[2] = { u1, v1}; | |
| float uv_left_slope[2] = { (u2 - u1) * reciprical, (v2 - v1) * reciprical}; | |
| float uv_right_slope[2] = {(u3 - u1) * reciprical, (v3 - v1) * reciprical}; | |
| float z_left; | |
| float z_right; | |
| z_left = z_right = z1; | |
| float z_slope_left = ((float)(z2 - z1)) * reciprical; | |
| float z_slope_right = ((float)(z3 - z1)) * reciprical; | |
| if (y1 < y3) { | |
| for (int y = y1; y < y3; ++y) { | |
| ssrDrawTexturedLine(left, right, (float)y, z_left, z_right, uv_left[0], uv_left[1], uv_right[0], uv_right[1]); | |
| uv_left[0] += uv_left_slope[0]; | |
| uv_left[1] += uv_left_slope[1]; | |
| uv_right[0] += uv_right_slope[0]; | |
| uv_right[1] += uv_right_slope[1]; | |
| left += slope_left; | |
| right += slope_right; | |
| z_left += z_slope_left; | |
| z_right += z_slope_right; | |
| } | |
| } else { | |
| for (int y = (y1); y >= (y3); --y) { | |
| ssrDrawTexturedLine(left, right, (float)y, z_left, z_right, uv_left[0], uv_left[1], uv_right[0], uv_right[1]); | |
| uv_left[0] -= uv_left_slope[0]; | |
| uv_left[1] -= uv_left_slope[1]; | |
| uv_right[0] -= uv_right_slope[0]; | |
| uv_right[1] -= uv_right_slope[1]; | |
| left -= slope_left; | |
| right -= slope_right; | |
| z_left -= z_slope_left; | |
| z_right -= z_slope_right; | |
| } | |
| } | |
| #undef x1 | |
| #undef x2 | |
| #undef x3 | |
| #undef y1 | |
| #undef y2 | |
| #undef y3 | |
| #undef z1 | |
| #undef z2 | |
| #undef z3 | |
| #undef u1 | |
| #undef u2 | |
| #undef u3 | |
| #undef v1 | |
| #undef v2 | |
| #undef v3 | |
| } | |
| float ssrClampToZeroOne(float f) { | |
| if (f < 0.0f) return 0.0f; | |
| if (f > 1.0f) return 1.0f; | |
| return f; | |
| } | |
| float* ssrClampToZeroOne(float* f) { | |
| if (f[0] < 0.0f) f[0] = 0.0f; | |
| if (f[0] > 1.0f) f[0] = 1.0f; | |
| if (f[1] < 0.0f) f[1] = 0.0f; | |
| if (f[1] > 1.0f) f[1] = 1.0f; | |
| if (f[2] < 0.0f) f[2] = 0.0f; | |
| if (f[2] > 1.0f) f[2] = 1.0f; | |
| return f; | |
| } | |
| int ssrGet32(FILE *f) { | |
| unsigned long num; | |
| unsigned char bytes[4]; | |
| fread(bytes, 1, 4, f); | |
| num = (bytes[3] << 24) | (bytes[2] << 16) | (bytes[1] << 8) | bytes[0]; | |
| return (int) num; | |
| } | |
| int ssrGet16(FILE *f) { | |
| unsigned short num; | |
| unsigned char bytes[2]; | |
| fread(bytes, 1, 2, f); | |
| num = (bytes[1] << 8) | bytes[0]; | |
| return (int) num; | |
| } | |
| int ssrNextPowerOf2(int n) { | |
| int pow; | |
| for (pow = 1; pow < n; pow <<= 1); | |
| return pow; | |
| } | |
| void ssrLookAt(float* _position, float* _forward, float* _up) { | |
| if (ssr_pCurrentRenderContext == NULL) { | |
| ssr_nLastError = SSR_ERR_GLRC; | |
| return; | |
| } | |
| float m[16], r[16]; | |
| float x[3], y[3], z[3]; | |
| float mag; | |
| /* Z vector */ | |
| z[0] = _position[0] - _forward[0]; | |
| z[1] = _position[1] - _forward[1]; | |
| z[2] = _position[2] - _forward[2]; | |
| mag = sqrtf(z[0] * z[0] + z[1] * z[1] + z[2] * z[2]); | |
| if (mag) { | |
| z[0] /= mag; | |
| z[1] /= mag; | |
| z[2] /= mag; | |
| } | |
| /* Y vector */ | |
| y[0] = _up[0]; | |
| y[1] = _up[1]; | |
| y[2] = _up[2]; | |
| /* X vector = Y cross Z */ | |
| x[0] = y[1] * z[2] - y[2] * z[1]; | |
| x[1] = -y[0] * z[2] + y[2] * z[0]; | |
| x[2] = y[0] * z[1] - y[1] * z[0]; | |
| /* Recompute Y = Z cross X */ | |
| y[0] = z[1] * x[2] - z[2] * x[1]; | |
| y[1] = -z[0] * x[2] + z[2] * x[0]; | |
| y[2] = z[0] * x[1] - z[1] * x[0]; | |
| /* cross product gives area of parallelogram, which is < 1.0 for | |
| * non-perpendicular unit-length vectors; so normalize x, y here | |
| */ | |
| mag = sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]); | |
| if (mag) { | |
| x[0] /= mag; | |
| x[1] /= mag; | |
| x[2] /= mag; | |
| } | |
| mag = sqrt(y[0] * y[0] + y[1] * y[1] + y[2] * y[2]); | |
| if (mag) { | |
| y[0] /= mag; | |
| y[1] /= mag; | |
| y[2] /= mag; | |
| } | |
| m[0] = x[0]; | |
| m[1] = x[1]; | |
| m[2] = x[2]; | |
| m[3] = 0.0; | |
| m[4] = y[0]; | |
| m[5] = y[1]; | |
| m[6] = y[2]; | |
| m[7] = 0.0; | |
| m[8] = z[0]; | |
| m[9] = z[1]; | |
| m[10] = z[2]; | |
| m[11] = 0.0; | |
| m[12] = 0.0; | |
| m[13] = 0.0; | |
| m[14] = 0.0; | |
| m[15] = 1.0; | |
| if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_MODELVIEW) { | |
| SSR_MATRIX_MULTIPLY(ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix], m, r); | |
| for (int i = 0; i < 16; ++i) | |
| ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix][i] = r[i]; | |
| ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix][12] += -_position[0]; | |
| ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix][13] += -_position[1]; | |
| ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix][14] += -_position[2]; | |
| } else if (ssr_pCurrentRenderContext->matrixComponent.matrixMode == SSR_PROJECTION) { | |
| SSR_MATRIX_MULTIPLY(ssr_pCurrentRenderContext->matrixComponent.modelviewMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentModelviewMatrix], m, r); | |
| for (int i = 0; i < 16; ++i) | |
| ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][i] = r[i]; | |
| ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][12] += -_position[0]; | |
| ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][13] += -_position[1]; | |
| ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][14] += -_position[2]; | |
| } | |
| } | |
| void ssrFrustum(float left, float right, float bottom, float top, float near_, float far_) { | |
| // Via http://msdn.microsoft.com/en-us/library/dd373537(v=vs.85).aspx (Matrix transposed) | |
| if (ssr_pCurrentRenderContext == NULL) { | |
| ssr_nLastError = SSR_ERR_GLRC; | |
| return; | |
| } | |
| float projectionMatrix[16]; | |
| for (int i = 0; i < 16; ++i) | |
| projectionMatrix[i] = 0.0f; | |
| projectionMatrix[0] = projectionMatrix[5] = 1.0f; | |
| projectionMatrix[10] = projectionMatrix[15] = 1.0f; | |
| projectionMatrix[0] = (2.0f * near_) / (right - left); | |
| projectionMatrix[5] = (2.0f * near_) / (top - bottom); | |
| projectionMatrix[8] = (right + left) / (right - left); | |
| projectionMatrix[9] = (top + bottom) / (top - bottom); | |
| projectionMatrix[10] = -1.0f * ((far_ + near_) / (far_ - near_)); | |
| projectionMatrix[11] = -1.0f; | |
| projectionMatrix[14] = -1.0f * ((2.0f * (far_ + near_)) / (far_ - near_)); | |
| projectionMatrix[15] = 0.0f; | |
| ssr_pCurrentRenderContext->renderInfoComponent.offset[0] = (right - left) / 2.0f; | |
| ssr_pCurrentRenderContext->renderInfoComponent.offset[1] = (top - bottom) / 2.0f; | |
| ssr_pCurrentRenderContext->renderInfoComponent.offset[2] = near_; | |
| ssr_pCurrentRenderContext->renderInfoComponent.offset[3] = far_; | |
| ssr_pCurrentRenderContext->renderInfoComponent.normalizeValues[0] = 1.0f / (ssr_pCurrentRenderContext->renderInfoComponent.offset[0] * 2); | |
| ssr_pCurrentRenderContext->renderInfoComponent.normalizeValues[1] = 1.0f / (ssr_pCurrentRenderContext->renderInfoComponent.offset[1] * 2); | |
| ssr_pCurrentRenderContext->matrixComponent.projectionMode = SSR_PERSP; | |
| float FOV = float(atanf(top / near_)) * SSR_RAD_TO_DEG * 2.0f; | |
| ssr_pCurrentRenderContext->renderInfoComponent.perspectiveCompensate[0] = ssr_pCurrentRenderContext->renderInfoComponent.offset[0] / tanf(FOV * 0.5f); | |
| ssr_pCurrentRenderContext->renderInfoComponent.perspectiveCompensate[1] = ssr_pCurrentRenderContext->renderInfoComponent.offset[1] / tanf(FOV * 0.5f); | |
| for (int i = 0; i < 16; ++i) | |
| ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][i] = projectionMatrix[i]; | |
| } | |
| void ssrPerspective(float fov, float aspect, float near_, float far_) { | |
| float top = near_ * float(tanf(fov * 3.14159265f / 360.0f)); | |
| float bottom = -1.0f * top; | |
| float left = bottom * aspect; | |
| float right = -1.0f * left; | |
| ssrFrustum(left, right, bottom, top, near_, far_); | |
| ssr_pCurrentRenderContext->renderInfoComponent.perspectiveCompensate[0] = ssr_pCurrentRenderContext->renderInfoComponent.offset[0] / tanf(fov * 0.5f); | |
| ssr_pCurrentRenderContext->renderInfoComponent.perspectiveCompensate[1] = ssr_pCurrentRenderContext->renderInfoComponent.offset[1] / tanf(fov * 0.5f); | |
| } | |
| void ssrOrtho(float left, float right, float bottom, float top, float _near, float _far) { | |
| float projectionMatrix[16]; | |
| projectionMatrix[0] = 2.0f / (right - left); | |
| projectionMatrix[1] = 0.0f; | |
| projectionMatrix[2] = 0.0f; | |
| projectionMatrix[3] = 0.0f; | |
| projectionMatrix[4] = 0.0f; | |
| projectionMatrix[5] = 2.0f / (top - bottom); | |
| projectionMatrix[6] = 0.0f; | |
| projectionMatrix[7] = 0.0f; | |
| projectionMatrix[8] = 0.0f; | |
| projectionMatrix[9] = 0.0f; | |
| projectionMatrix[10] = -2.0f / (_far - _near); | |
| projectionMatrix[11] = 0.0f; | |
| projectionMatrix[12] = (right + left) / (right - left); | |
| projectionMatrix[13] = (top + bottom) / (top - bottom); | |
| projectionMatrix[14] = (_far + _near) / (_far - _near); | |
| projectionMatrix[15] = 1.0f; | |
| ssr_pCurrentRenderContext->renderInfoComponent.offset[0] = (right - left) / 2.0f; | |
| ssr_pCurrentRenderContext->renderInfoComponent.offset[1] = (top - bottom) / 2.0f; | |
| ssr_pCurrentRenderContext->renderInfoComponent.offset[2] = _near; | |
| ssr_pCurrentRenderContext->renderInfoComponent.offset[3] = _far; | |
| ssr_pCurrentRenderContext->renderInfoComponent.normalizeValues[0] = 1.0f / (ssr_pCurrentRenderContext->renderInfoComponent.offset[0] * 2); | |
| ssr_pCurrentRenderContext->renderInfoComponent.normalizeValues[1] = 1.0f / (ssr_pCurrentRenderContext->renderInfoComponent.offset[1] * 2); | |
| ssr_pCurrentRenderContext->matrixComponent.projectionMode = SSR_ORTHO; | |
| for (int i = 0; i < 16; ++i) | |
| ssr_pCurrentRenderContext->matrixComponent.projectionMatrixStack[ssr_pCurrentRenderContext->matrixComponent.currentProjectionMatrix][i] = projectionMatrix[i]; | |
| } | |
| void ssrViewport(int x, int y, int width, int height) { | |
| if (ssr_pCurrentRenderContext == NULL) { | |
| ssr_nLastError = SSR_ERR_GLRC; | |
| return; | |
| } | |
| if (x < 0) x = 0; | |
| if (y < 0) y = 0; | |
| if (width == 0) width = 1; | |
| if (height == 0) height = 1; | |
| if (x + width > ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmWidth) { | |
| x -= 1; | |
| width = 1; | |
| } | |
| if (y + height > ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmHeight) { | |
| y -= 1; | |
| height = 1; | |
| } | |
| ssr_pCurrentRenderContext->renderInfoComponent.viewport[SSR_VIEWPORT_LEFT] = x; | |
| ssr_pCurrentRenderContext->renderInfoComponent.viewport[SSR_VIEWPORT_TOP] = y; | |
| ssr_pCurrentRenderContext->renderInfoComponent.viewport[SSR_VIEWPORT_RIGHT] = x + width; | |
| ssr_pCurrentRenderContext->renderInfoComponent.viewport[SSR_VIEWPORT_BOTTOM] = y + height; | |
| } | |
| void ssrClearColor(float r, float g, float b) { | |
| if (ssr_pCurrentRenderContext == NULL) { | |
| ssr_nLastError = SSR_ERR_GLRC; | |
| return; | |
| } | |
| if (r > 1.0f) r = 1.0f; | |
| if (g > 1.0f) g = 1.0f; | |
| if (b > 1.0f) b = 1.0f; | |
| if (r < 0.0f) r = 0.0f; | |
| if (g < 0.0f) g = 0.0f; | |
| if (b < 0.0f) b = 0.0f; | |
| ssr_pCurrentRenderContext->displayComponent.clearColor = SSR_FTORGB(r, g, b); | |
| } | |
| static unsigned char ssr_chFont[1533][4] = { | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {0, 0, 0, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255}, | |
| {255, 255, 255, 255} | |
| }; | |
| SSRIMID ssrGetFont() { | |
| return ssr_chFont; | |
| } | |
| void ssrRenderFont(PSSRTEXT toDraw) { | |
| int current_x = toDraw->x; | |
| int current_y = toDraw->y; | |
| int top = 0; | |
| int left = 0; | |
| int width = 0; | |
| int height = 0; | |
| for (int i = 0, max = toDraw->displayString.size(); i < max; ++i) { | |
| if (toDraw->displayString[i] == '\0') | |
| break; | |
| switch (toDraw->displayString[i]) { | |
| case 'a': | |
| case 'A': | |
| top = 1; left = 1; | |
| width = 5; height = 5; | |
| break; | |
| case 'b': | |
| case 'B': | |
| top = 1; left = 7; | |
| width = 5; height = 5; | |
| break; | |
| case 'c': | |
| case 'C': | |
| top = 1; left = 13; | |
| width = 5; height = 5; | |
| break; | |
| case 'd': | |
| case 'D': | |
| top = 1; left = 19; | |
| width = 5; height = 5; | |
| break; | |
| case 'e': | |
| case 'E': | |
| top = 1; left = 25; | |
| width = 5; height = 5; | |
| break; | |
| case 'f': | |
| case 'F': | |
| top = 1; left = 31; | |
| width = 5; height = 5; | |
| break; | |
| case 'g': | |
| case 'G': | |
| top = 1; left = 37; | |
| width = 5; height = 5; | |
| break; | |
| case 'h': | |
| case 'H': | |
| top = 1; left = 43; | |
| width = 5; height = 5; | |
| break; | |
| case 'i': | |
| case 'I': | |
| top = 1; left = 49; | |
| width = 5; height = 5; | |
| break; | |
| case 'j': | |
| case 'J': | |
| top = 1; left = 55; | |
| width = 5; height = 5; | |
| break; | |
| case 'k': | |
| case 'K': | |
| top = 1; left = 61; | |
| width = 5; height = 5; | |
| break; | |
| case 'l': | |
| case 'L': | |
| top = 1; left = 67; | |
| width = 5; height = 5; | |
| break; | |
| case 'm': | |
| case 'M': | |
| top = 1; left = 73; | |
| width = 5; height = 5; | |
| break; | |
| case 'n': | |
| case 'N': | |
| top = 1; left = 80; | |
| width = 5; height = 5; | |
| break; | |
| case 'o': | |
| case 'O': | |
| top = 1; left = 86; | |
| width = 5; height = 5; | |
| break; | |
| case 'p': | |
| case 'P': | |
| top = 1; left = 92; | |
| width = 5; height = 5; | |
| break; | |
| case 'q': | |
| case 'Q': | |
| top = 1; left = 98; | |
| width = 5; height = 6; | |
| break; | |
| case 'r': | |
| case 'R': | |
| top = 1; left = 104; | |
| width = 5; height = 5; | |
| break; | |
| case 's': | |
| case 'S': | |
| top = 1; left = 110; | |
| width = 5; height = 5; | |
| break; | |
| case 't': | |
| case 'T': | |
| top = 1; left = 116; | |
| width = 5; height = 5; | |
| break; | |
| case 'u': | |
| case 'U': | |
| top = 1; left = 122; | |
| width = 5; height = 5; | |
| break; | |
| case 'v': | |
| case 'V': | |
| top = 1; left = 128; | |
| width = 5; height = 5; | |
| break; | |
| case 'w': | |
| case 'W': | |
| top = 1; left = 134; | |
| width = 5; height = 5; | |
| break; | |
| case 'x': | |
| case 'X': | |
| top = 1; left = 140; | |
| width = 5; height = 5; | |
| break; | |
| case 'y': | |
| case 'Y': | |
| top = 1; left = 146; | |
| width = 5; height = 5; | |
| break; | |
| case 'z': | |
| case 'Z': | |
| top = 1; left = 153; | |
| width = 5; height = 5; | |
| break; | |
| case '0': | |
| top = 1; left = 161; | |
| width = 5; height = 5; | |
| break; | |
| case '1': | |
| top = 1; left = 167; | |
| width = 2; height = 5; | |
| break; | |
| case '2': | |
| top = 1; left = 170; | |
| width = 5; height = 5; | |
| break; | |
| case '3': | |
| top = 1; left = 176; | |
| width = 5; height = 5; | |
| break; | |
| case '4': | |
| top = 1; left = 182; | |
| width = 5; height = 5; | |
| break; | |
| case '5': | |
| top = 1; left = 188; | |
| width = 5; height = 5; | |
| break; | |
| case '6': | |
| top = 1; left = 194; | |
| width = 5; height = 5; | |
| break; | |
| case '7': | |
| top = 1; left = 200; | |
| width = 5; height = 5; | |
| break; | |
| case '8': | |
| top = 1; left = 206; | |
| width = 5; height = 5; | |
| break; | |
| case '9': | |
| top = 1; left = 212; | |
| width = 5; height = 5; | |
| break; | |
| } | |
| if (toDraw->displayString[i] == '\n') { | |
| current_y += 7; | |
| current_x = toDraw->x; | |
| continue; | |
| } else if (toDraw->displayString[i] == ' ') { | |
| current_x += 4; | |
| continue; | |
| } | |
| int font_width = 220; | |
| int stage_width = (int)ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmWidth; | |
| int stage_height = (int)ssr_pCurrentRenderContext->windowsDisplayComponent.bmBitmapInfo.bmHeight; | |
| for (int k = 0; k < 7; ++k) { | |
| for (int j = left; j < left + width; ++j) { | |
| int index = ((6 - k) * font_width + j); | |
| if (ssr_chFont[index][0] == 0) { | |
| int stage_y = stage_height - (current_y + k); | |
| int stage_x = current_x + (j - left); | |
| int stage_index = stage_y * stage_width + stage_x; | |
| ssr_pCurrentRenderContext->displayComponent.imageBuffer[stage_index] = toDraw->color; | |
| } | |
| } | |
| } | |
| current_x += width + 1; | |
| } | |
| } | |
| void ssrDrawText() { | |
| for (unsigned int i = 0, max = ssr_pCurrentRenderContext->textOutputComponent.size(); i < max; ++i) | |
| ssrRenderFont(&(ssr_pCurrentRenderContext->textOutputComponent[i])); | |
| ssr_pCurrentRenderContext->textOutputComponent.clear(); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment