public static Dictionary <string, System.Func <object[], object> > GetCallbackFunctions() { Dictionary <string, System.Func <object[], object> > lookup = new Dictionary <string, System.Func <object[], object> >(); lookup["force-load-texture"] = new System.Func <object[], object>(args => { return(GlUtil.ForceLoadTexture((UniversalBitmap)args[0])); }); lookup["set-render-data"] = new System.Func <object[], object>(args => { SetRenderData((int[])args[0], (int)args[1], (object[][])args[2], (List <int>)args[3]); return(null); }); return(lookup); }
public static void render(int[] commands, int length, object[][] texturesNativeData, int VW, int VH, int RW, int RH) { bool scaled = VW != RW || VH != RH; bool rotated = false; int i = 0; int image_i = 0; int width = 0; int height = 0; int cropWidth; int cropHeight; int left = 0; int right = 0; int top = 0; int bottom = 0; int lineWidth = 0; int j = 0; int ptCount = 0; int startX = 0; int startY = 0; int endX = 0; int endY = 0; int mask = 0; double textureWidth; double textureHeight; double textureResourceWidth; double textureResourceHeight; double textureLeft; double textureRight; double textureTop; double textureBottom; double croppedLeft; double croppedRight; double croppedTop; double croppedBottom; double slope = 0.0; double slopeScalingCoefficient = 0.0; double offsetXComp = 0.0; double offsetYComp = 0.0; double ax = 0.0; double ay = 0.0; double bx = 0.0; double by = 0.0; double cx = 0.0; double cy = 0.0; double dx = 0.0; double dy = 0.0; double tx = 0.0; double ty = 0.0; double angle = 0.0; double r_cos = 0.0; double r_sin = 0.0; int red = 0; int green = 0; int blue = 0; int alpha = 0; int textureId = (-1); object[] textureNativeData; object[] textureResourceNativeData; GlRenderState state = null; int[] textureArray = new int[1]; while (i < length) { switch (commands[i]) { case 1: left = commands[i | 1]; top = commands[i | 2]; right = commands[i | 3] + left; bottom = commands[i | 4] + top; red = commands[i | 5]; green = commands[i | 6]; blue = commands[i | 7]; alpha = commands[i | 8]; if (right >= 0 && left < VW && bottom > 0 && top < VH) { if (state == null || state.commandType != 1 || state.mode != 1 || state.textureId != 0 || state.r != red || state.g != green || state.b != blue || state.a != alpha) { if (state == null) { state = new GlRenderState(1, 0, 0, 0, 0, 0, 0); } else { GL.End(); } state.mode = 1; state.textureId = 0; state.r = red; state.g = green; state.b = blue; state.a = alpha; GL.Disable(EnableCap.Texture2D); GL.Color4((byte)red, (byte)green, (byte)blue, (byte)alpha); GL.Begin(BeginMode.Quads); } if (scaled) { GL.Vertex2(left * RW / VW, top * RH / VH); GL.Vertex2(right * RW / VW, top * RH / VH); GL.Vertex2(right * RW / VW, bottom * RH / VH); GL.Vertex2(left * RW / VW, bottom * RH / VH); } else { GL.Vertex2(left, top); GL.Vertex2(right, top); GL.Vertex2(right, bottom); GL.Vertex2(left, bottom); } } break; case 2: left = commands[i | 1]; top = commands[i | 2]; right = commands[i | 3] + left; bottom = commands[i | 4] + top; red = commands[i | 5]; green = commands[i | 6]; blue = commands[i | 7]; alpha = commands[i | 8]; width = (right - left); height = (bottom - top); startX = left + width / 2; startY = top + height / 2; width = width / 2; height = height / 2; if (right >= 0 && left < VW && bottom >= 0 && top < VH && width > 0 && height > 0) { if (state != null) { GL.End(); state = null; } GL.Disable(EnableCap.Texture2D); GL.Color4((byte)red, (byte)green, (byte)blue, (byte)alpha); GL.Begin(BeginMode.Polygon); ptCount = (width + height) / 8; if (ptCount < 16) { ptCount = 16; } j = 0; while ((j < ptCount)) { endX = (int)(Math.Cos(-6.28318530717958 * j / ptCount) * width + startX); endY = (int)(Math.Sin(-6.28318530717958 * j / ptCount) * height + startY); if (scaled) { GL.Vertex2(endX * RW / VW, endY * RH / VH); } else { GL.Vertex2(endX, endY); } j += 1; } GL.End(); } break; case 3: startX = commands[i | 1]; startY = commands[i | 2]; endX = commands[i | 3]; endY = commands[i | 4]; lineWidth = commands[i | 5]; red = commands[i | 6]; green = commands[i | 7]; blue = commands[i | 8]; alpha = commands[i | 9]; left = startX; right = startX; if (startX > endX) { left = endX; } else { right = endX; } top = startY; bottom = startY; if (startY > endY) { top = endY; } else { bottom = endY; } if (startX > endX) { j = startX; startX = endX; endX = j; j = startY; startY = endY; endY = j; } slope = -(1.0 * endY - startY) / (endX - startX); textureRight = slope; if ((textureRight < 0)) { textureRight = -textureRight; } slopeScalingCoefficient = System.Math.Pow((1 + 1.0 / (slope * slope)), 0.5); offsetXComp = lineWidth / slopeScalingCoefficient / 2; offsetYComp = lineWidth / (2 * textureRight * slopeScalingCoefficient); ax = startX; ay = startY; bx = endX; by = endY; cx = bx; cy = by; dx = ax; dy = ay; if (slope > 0) { ax -= offsetXComp; ay -= offsetYComp; bx -= offsetXComp; by -= offsetYComp; cx += offsetXComp; cy += offsetYComp; dx += offsetXComp; dy += offsetYComp; } else { ax += offsetXComp; ay -= offsetYComp; bx += offsetXComp; by -= offsetYComp; cx -= offsetXComp; cy += offsetYComp; dx -= offsetXComp; dy += offsetYComp; } if (state == null || state.commandType != 3 || state.mode != 1 || state.textureId != 0 || state.r != red || state.g != green || state.b != blue || state.a != alpha) { if (state == null) { state = new GlRenderState(3, 0, 0, 0, 0, 0, 0); } else { GL.End(); } state.mode = 1; state.textureId = 0; state.r = red; state.g = green; state.b = blue; state.a = alpha; GL.Disable(EnableCap.Texture2D); GL.Color4((byte)red, (byte)green, (byte)blue, (byte)alpha); GL.Begin(BeginMode.Quads); } if (scaled) { GL.Vertex2(ax * RW / VW, ay * RH / VH); GL.Vertex2(bx * RW / VW, by * RH / VH); GL.Vertex2(cx * RW / VW, cy * RH / VH); GL.Vertex2(dx * RW / VW, dy * RH / VH); } else { GL.Vertex2(ax, ay); GL.Vertex2(bx, by); GL.Vertex2(cx, cy); GL.Vertex2(dx, dy); } break; case 4: ax = commands[i | 1]; ay = commands[i | 2]; bx = commands[i | 3]; by = commands[i | 4]; cx = commands[i | 5]; cy = commands[i | 6]; red = commands[i | 7]; green = commands[i | 8]; blue = commands[i | 9]; alpha = commands[i | 10]; if (state != null) { GL.End(); state = null; } GL.Disable(EnableCap.Texture2D); GL.Color4((byte)red, (byte)green, (byte)blue, (byte)alpha); GL.Begin(BeginMode.Polygon); ptCount = (width + height) / 8; if (ptCount < 16) { ptCount = 16; } if (scaled) { GL.Vertex2(ax * RW / VW, ay * RH / VH); GL.Vertex2(bx * RW / VW, by * RH / VH); GL.Vertex2(cx * RW / VW, cy * RH / VH); } else { GL.Vertex2(ax, ay); GL.Vertex2(bx, by); GL.Vertex2(cx, cy); } GL.End(); break; case 5: ax = commands[i | 1]; ay = commands[i | 2]; bx = commands[i | 3]; by = commands[i | 4]; cx = commands[i | 5]; cy = commands[i | 6]; dx = commands[i | 7]; dy = commands[i | 8]; red = commands[i | 9]; green = commands[i | 10]; blue = commands[i | 11]; alpha = commands[i | 12]; if (state != null) { GL.End(); state = null; } GL.Disable(EnableCap.Texture2D); GL.Color4((byte)red, (byte)green, (byte)blue, (byte)alpha); GL.Begin(BeginMode.Polygon); ptCount = (width + height) / 8; if (ptCount < 16) { ptCount = 16; } if (scaled) { GL.Vertex2(ax * RW / VW, ay * RH / VH); GL.Vertex2(bx * RW / VW, by * RH / VH); GL.Vertex2(cx * RW / VW, cy * RH / VH); GL.Vertex2(dx * RW / VW, dy * RH / VH); } else { GL.Vertex2(ax, ay); GL.Vertex2(bx, by); GL.Vertex2(cx, cy); GL.Vertex2(dx, dy); } GL.End(); break; case 6: textureNativeData = texturesNativeData[image_i++]; textureResourceNativeData = (object[])textureNativeData[0]; if (!(bool)textureResourceNativeData[1]) { if (state != null) { state = null; GL.End(); } textureResourceNativeData[2] = GlUtil.ForceLoadTexture((UniversalBitmap)textureResourceNativeData[3]); textureResourceNativeData[1] = true; } mask = commands[i | 1]; rotated = (mask & 4) != 0; textureId = (int)textureResourceNativeData[2]; alpha = 255; startX = commands[i | 8]; // left startY = commands[i | 9]; // top // alpha if ((mask & 8) != 0) { alpha = commands[i | 11]; } textureLeft = (double)textureNativeData[1]; textureTop = (double)textureNativeData[2]; textureRight = (double)textureNativeData[3]; textureBottom = (double)textureNativeData[4]; width = (int)textureNativeData[5]; height = (int)textureNativeData[6]; textureWidth = textureRight - textureLeft; textureHeight = textureBottom - textureTop; textureResourceWidth = (int)textureResourceNativeData[4]; textureResourceHeight = (int)textureResourceNativeData[5]; // slice if ((mask & 1) != 0) { ax = commands[i | 2]; ay = commands[i | 3]; cropWidth = commands[i | 4]; cropHeight = commands[i | 5]; croppedLeft = textureLeft + textureWidth * ax / width; croppedRight = textureLeft + textureWidth * (ax + cropWidth) / width; croppedTop = textureTop + textureHeight * ay / height; croppedBottom = textureTop + textureHeight * (ay + cropHeight) / height; textureLeft = croppedLeft; textureRight = croppedRight; textureTop = croppedTop; textureBottom = croppedBottom; width = cropWidth; height = cropHeight; } // stretch if ((mask & 2) != 0) { width = commands[i | 6]; height = commands[i | 7]; } if (state == null || state.commandType != 6 || state.mode != 1 || state.a != alpha || state.textureId != textureId) { if (state == null) { state = new GlRenderState(6, 0, 0, 0, 0, 0, 0); } else { GL.End(); } state.mode = 1; state.textureId = textureId; state.a = alpha; GL.Enable(EnableCap.Texture2D); GL.Color4((byte)255, (byte)255, (byte)255, (byte)alpha); GL.BindTexture(TextureTarget.Texture2D, textureId); GL.Begin(BeginMode.Quads); } if (rotated) { angle = commands[i | 10] / 1048576.0; r_cos = Math.Cos(angle); r_sin = Math.Sin(angle); tx = width * 0.5; ty = height * 0.5; ax = (r_cos * -tx - r_sin * -ty) + startX; ay = (r_sin * -tx + r_cos * -ty) + startY; bx = (r_cos * tx - r_sin * -ty) + startX; by = (r_sin * tx + r_cos * -ty) + startY; cx = (r_cos * -tx - r_sin * ty) + startX; cy = (r_sin * -tx + r_cos * ty) + startY; dx = (r_cos * tx - r_sin * ty) + startX; dy = (r_sin * tx + r_cos * ty) + startY; GL.TexCoord2(textureLeft, textureTop); GL.Vertex2((int)(ax * RW / VW), (int)(ay * RH / VH)); GL.TexCoord2(textureRight, textureTop); GL.Vertex2((int)(bx * RW / VW), (int)(by * RH / VH)); GL.TexCoord2(textureRight, textureBottom); GL.Vertex2((int)(dx * RW / VW), (int)(dy * RH / VH)); GL.TexCoord2(textureLeft, textureBottom); GL.Vertex2((int)(cx * RW / VW), (int)(cy * RH / VH)); } else { endX = startX + width; endY = startY + height; GL.TexCoord2(textureLeft, textureTop); GL.Vertex2(startX * RW / VW, startY * RH / VH); GL.TexCoord2(textureRight, textureTop); GL.Vertex2(endX * RW / VW, startY * RH / VH); GL.TexCoord2(textureRight, textureBottom); GL.Vertex2(endX * RW / VW, endY * RH / VH); GL.TexCoord2(textureLeft, textureBottom); GL.Vertex2(startX * RW / VW, endY * RH / VH); } break; // Extensible render event for libraries that manage their own GL textures. // For example, this is used by the Graphics2DText renderer. // Draws a colored axis-aligned quad with a texture ID and color tint. case 8: textureId = commands[i | 1]; startX = commands[i | 2]; // screen left coordinate startY = commands[i | 3]; // screen top coordinate endX = commands[i | 4]; // screen right coordinate endY = commands[i | 5]; // screen bottom coordinate left = commands[i | 6]; // texture left top = commands[i | 7]; // texture top right = commands[i | 8]; // texture right bottom = commands[i | 9]; // texture bottom red = commands[i | 10]; green = commands[i | 11]; blue = commands[i | 12]; alpha = commands[i | 13]; width = commands[i | 14]; // texture width height = commands[i | 15]; // texture height if (state == null || state.commandType != 8 || state.textureId != textureId || state.r != red || state.g != green || state.b != blue || state.a != alpha) { if (state != null) { state = null; GL.End(); } } if (state == null) { state = new GlRenderState(8, 0, textureId, red, green, blue, alpha); GL.Enable(EnableCap.Texture2D); GL.Color4((byte)red, (byte)green, (byte)blue, (byte)alpha); GL.BindTexture(TextureTarget.Texture2D, textureId); GL.Begin(BeginMode.Quads); } GL.TexCoord2(left / 1024f, 1f * top / height); GL.Vertex2(startX * RW / VW, startY * RH / VH); GL.TexCoord2(right / 1024f, 1f * top / height); GL.Vertex2(endX * RW / VW, startY * RH / VH); GL.TexCoord2(right / 1024f, 1f * bottom / height); GL.Vertex2(endX * RW / VW, endY * RH / VH); GL.TexCoord2(left / 1024f, 1f * bottom / height); GL.Vertex2(startX * RW / VW, endY * RH / VH); break; default: return; } i += 16; } if (state != null) { GL.End(); } }