internal void ProcessQuadRenderCommand(CCQuadCommand quadCommand) { var worldTransform = quadCommand.WorldTransform; var identity = worldTransform == CCAffineTransform.Identity; quadCommands.Add(quadCommand); var quads = quadCommand.Quads; for (int i = 0, N = quadCommand.QuadCount; i < N; ++i) { if (identity) { currentBatchedQuads.Add(quads[i]); } else { currentBatchedQuads.Add(worldTransform.Transform(quads[i])); } } // We're changing command types so render any pending sequence of commandss // e.g. Batched quad commands if ((currentCommandType & CCCommandType.Quad) == CCCommandType.None) { Flush(); } currentCommandType = CCCommandType.Quad; }
// See http://slabode.exofire.net/circle_draw.shtml // An Efficient Way to Draw Approximate Circles in OpenGL // Try to keep from calculating Cos and Sin of values everytime and just use // add and subtract where possible to calculate the values. public void DrawCircle(CCPoint pos, float radius, CCColor4B color) { var cl = color.ToColor(); int segments = (int)(10 * (float)Math.Sqrt(radius)); //<- Let's try to guess at # segments for a reasonable smoothness float theta = MathHelper.Pi * 2.0f / segments; float tangetial_factor = (float)Math.Tan(theta); //calculate the tangential factor float radial_factor = (float)Math.Cos(theta); //calculate the radial factor float x = radius; //we start at angle = 0 float y = 0; var verticeCenter = new VertexPositionColor(new Vector3(pos.X, pos.Y, 0), cl); var vert1 = new VertexPositionColor(Vector3.Zero, cl); float tx = 0; float ty = 0; for (int i = 0; i < segments; i++) { vert1.Position.X = x + pos.X; vert1.Position.Y = y + pos.Y; lineVertices.Add(vert1); // output vertex //calculate the tangential vector //remember, the radial vector is (x, y) //to get the tangential vector we flip those coordinates and negate one of them tx = -y; ty = x; //add the tangential vector x += tx * tangetial_factor; y += ty * tangetial_factor; //correct using the radial factor x *= radial_factor; y *= radial_factor; vert1.Position.X = x + pos.X; vert1.Position.Y = y + pos.Y; lineVertices.Add(vert1); // output vertex } dirty = true; }
public void AddTargetWithActionForControlEvent(object target, Action <object, CCControlEvent> action, CCControlEvent controlEvent) { // Create the invocation object var invocation = new CCInvocation(target, action, controlEvent); // Add the invocation into the dispatch list for the given control event CCRawList <CCInvocation> eventInvocationList = DispatchListforControlEvent(controlEvent); eventInvocationList.Add(invocation); }
void ExecuteRenderCommand(CCRenderCommand command) { if (command is CCQuadCommand) { Flush3D(); FlushTriangles(); //Console.WriteLine(((CCQuadCommand)command).QuadCount); var quadCommand = (CCQuadCommand)command; var drawManager = DrawManager; //Draw batched quads if necessary // TODO: Check for buffer size if (command.IsSkipBatching) // || (numberQuads + cmd->getQuadCount()) * 4 > VBO_SIZE ) { // TODO: Check for buffer size //CCASSERT(cmd->getQuadCount()>= 0 && cmd->getQuadCount() * 4 < VBO_SIZE, "VBO for vertex is not big enough, please break the data down or use customized render command"); //Draw batched quads if VBO is full DrawBatchedQuads(); } var mv = command.ModelViewTransform; batchQuadCommands.Add(quadCommand); for (int b = 0; b < quadCommand.QuadCount; b++) { quads.Add(mv.Transform(quadCommand.Quads[b])); } numberQuads += quadCommand.QuadCount; if (quadCommand.IsSkipBatching) { DrawBatchedQuads(); } } else { Flush(); command.Execute(DrawManager); } }
void FlushLines() { if (!hasBegun) { throw new InvalidOperationException("Begin must be called before Flush can be called."); } if (lineVertsCount >= 2) { int primitiveCount = lineVertsCount / 2; var lines = new CCV3F_C4B[lineVertsCount]; Array.Copy(lineVertices, lines, triangleVertsCount); // add the Line Lists to our line list vertices for later rendering from the Renderer lineVerts.Add(lines); lineVertsCount -= primitiveCount * 2; } }
void FlushTriangles() { if (!hasBegun) { throw new InvalidOperationException("Begin must be called before Flush can be called."); } if (triangleVertsCount >= 3) { int primitiveCount = triangleVertsCount / 3; var triangles = new CCV3F_C4B[triangleVertsCount]; Array.Copy(triangleVertices, triangles, triangleVertsCount); // add the Triangle List to our triangles list vertices for later rendering from the Renderer triangleVerts.Add(triangles); triangleVertsCount -= primitiveCount * 3; } }
public CCGeometryInstance CreateGeometryInstance(int numberOfVertices, int numberOfIndicies) { var item = new CCGeometryInstance(); if (item.GeometryPacket.Vertices.Length < numberOfVertices) { item.GeometryPacket.Vertices = new CCV3F_C4B_T2F[numberOfVertices]; } if (item.GeometryPacket.Indicies.Length < numberOfIndicies) { item.GeometryPacket.Indicies = new int[numberOfIndicies]; } item.GeometryPacket.NumberOfVertices = numberOfVertices; item.GeometryPacket.NumberOfIndicies = numberOfIndicies; batchItemList.Add(item); return(item); }
public CCGeometryInstance CreateGeometryInstance(int numberOfVertices, int numberOfIndicies, PrimitiveType primitiveType = PrimitiveType.TriangleList) { var item = new CCGeometryInstance(); item.InstanceAttributes.PrimitiveType = primitiveType; if (item.GeometryPacket.Vertices.Length < numberOfVertices) { item.GeometryPacket.Vertices = new CCV3F_C4B_T2F[numberOfVertices]; } if (item.GeometryPacket.Indicies.Length < numberOfIndicies) { item.GeometryPacket.Indicies = new int[numberOfIndicies]; } item.GeometryPacket.NumberOfVertices = numberOfVertices; item.GeometryPacket.NumberOfIndicies = numberOfIndicies; batchItemList.Add(item); return(item); }
public void AddLineVertex(CCV3F_C4B lineVertex) { lineVertices.Add(lineVertex); }
public void AddTriangleVertex(CCV3F_C4B triangleVertex) { triangleVertices.Add(triangleVertex); }
protected void UpdateLabel() { SetString(labelInitialText, false); if (string.IsNullOrEmpty(labelText)) { return; } if (labelDimensions.Width > 0) { // Step 1: Make multiline string str_whole = labelText; int stringLength = str_whole.Length; var multiline_string = new StringBuilder(stringLength); var last_word = new StringBuilder(stringLength); int line = 1, i = 0; bool start_line = false, start_word = false; float startOfLine = -1, startOfWord = -1; int skip = 0; CCRawList <CCNode> children = Children; for (int j = 0; j < children.Count; j++) { CCSprite characterSprite; int justSkipped = 0; while ((characterSprite = (CCSprite)this[(j + skip + justSkipped)]) == null) { justSkipped++; } skip += justSkipped; if (!characterSprite.Visible) { continue; } if (i >= stringLength) { break; } char character = str_whole[i]; if (!start_word) { startOfWord = GetLetterPosXLeft(characterSprite); start_word = true; } if (!start_line) { startOfLine = startOfWord; start_line = true; } // Newline. if (character == '\n') { int len = last_word.Length; while (len > 0 && Char.IsWhiteSpace(last_word[len - 1])) { len--; last_word.Remove(len, 1); } multiline_string.Append(last_word); multiline_string.Append('\n'); last_word.Clear(); start_word = false; start_line = false; startOfWord = -1; startOfLine = -1; i += justSkipped; line++; if (i >= stringLength) { break; } character = str_whole[i]; if (startOfWord == 0) { startOfWord = GetLetterPosXLeft(characterSprite); start_word = true; } if (startOfLine == 0) { startOfLine = startOfWord; start_line = true; } } // Whitespace. if (Char.IsWhiteSpace(character)) { last_word.Append(character); multiline_string.Append(last_word); last_word.Clear(); start_word = false; startOfWord = -1; i++; continue; } // Out of bounds. if (GetLetterPosXRight(characterSprite) - startOfLine > labelDimensions.Width) { if (!lineBreakWithoutSpaces) { last_word.Append(character); int len = multiline_string.Length; while (len > 0 && Char.IsWhiteSpace(multiline_string[len - 1])) { len--; multiline_string.Remove(len, 1); } if (multiline_string.Length > 0) { multiline_string.Append('\n'); } line++; start_line = false; startOfLine = -1; i++; } else { int len = last_word.Length; while (len > 0 && Char.IsWhiteSpace(last_word[len - 1])) { len--; last_word.Remove(len, 1); } multiline_string.Append(last_word); multiline_string.Append('\n'); last_word.Clear(); start_word = false; start_line = false; startOfWord = -1; startOfLine = -1; line++; if (i >= stringLength) { break; } if (startOfWord == 0) { startOfWord = GetLetterPosXLeft(characterSprite); start_word = true; } if (startOfLine == 0) { startOfLine = startOfWord; start_line = true; } j--; } continue; } else { // Character is normal. last_word.Append(character); i++; continue; } } multiline_string.Append(last_word); SetString(multiline_string.ToString(), false); } // Step 2: Make alignment if (horzAlignment != CCTextAlignment.Left) { int i = 0; int lineNumber = 0; int str_len = labelText.Length; var last_line = new CCRawList <char>(); // If label dim is 0, then we need to use the content size width instead float maxLabelWidth = labelDimensions.Width > 0 ? labelDimensions.Width : ContentSize.Width; for (int ctr = 0; ctr <= str_len; ++ctr) { if (ctr == str_len || labelText[ctr] == '\n') { float lineWidth = 0.0f; int line_length = last_line.Count; // if last line is empty we must just increase lineNumber and work with next line if (line_length == 0) { lineNumber++; continue; } int index = i + line_length - 1 + lineNumber; if (index < 0) { continue; } var lastChar = (CCSprite)this[index]; if (lastChar == null) { continue; } lineWidth = lastChar.Position.X + lastChar.ContentSize.Width; var shift = maxLabelWidth - lineWidth; if (horzAlignment == CCTextAlignment.Center) { shift /= 2; } for (int j = 0; j < line_length; j++) { index = i + j + lineNumber; if (index < 0) { continue; } var characterSprite = this[index]; characterSprite.PositionX += shift; } i += line_length; lineNumber++; last_line.Clear(); continue; } last_line.Add(labelText[ctr]); } } if (vertAlignment != CCVerticalTextAlignment.Bottom && labelDimensions.Height > 0) { int lineNumber = 1; int str_len = labelText.Length; for (int ctr = 0; ctr < str_len; ++ctr) { if (labelText[ctr] == '\n') { lineNumber++; } } float yOffset = labelDimensions.Height - FontConfiguration.CommonHeight * lineNumber; if (vertAlignment == CCVerticalTextAlignment.Center) { yOffset /= 2f; } for (int i = 0; i < str_len; i++) { var characterSprite = this[i] as CCSprite; if (characterSprite != null && characterSprite.Visible) { characterSprite.PositionY += yOffset; } } } }
public void AddLineVertex(CCV3F_C4B lineVertex) { lineVertices.Add(lineVertex); dirty = true; }
private CCBMFontConfiguration InitializeFont(string fontName, float fontSize, string charset) { if (m_pData == null) { InitializeTTFAtlas(1024, 1024); } if (String.IsNullOrEmpty(charset)) { charset = " "; } var chars = new CCRawList <char>(); var fontKey = GetFontKey(fontName, fontSize); CCBMFontConfiguration fontConfig; if (!fontConfigurations.TryGetValue(fontKey, out fontConfig)) { fontConfig = new CCBMFontConfiguration(); fontConfigurations.Add(fontKey, fontConfig); } for (int i = 0; i < charset.Length; i++) { var ch = charset[i]; if (!fontConfig.Glyphs.ContainsKey(ch) && chars.IndexOf(ch) == -1) { chars.Add(ch); } } if (chars.Count == 0) { return(fontConfig); } CreateFont(fontName, fontSize, chars); fontConfig.CommonHeight = (int)Math.Ceiling(GetFontHeight()); int[] data = null; for (int i = 0; i < chars.Count; i++) { var s = chars[i].ToString(); var charSize = GetMeasureString(s); int w = (int)Math.Ceiling(charSize.Width + 2); int h = (int)Math.Ceiling(charSize.Height + 2); if (data == null || data.Length < (w * h)) { data = new int[w * h]; } unsafe { int stride; byte *pBase = GetBitmapData(s, out stride); int minX = w; int maxX = 0; int minY = h; int maxY = 0; for (int y = 0; y < h; y++) { var row = (int *)(pBase + y * stride); for (int x = 0; x < w; x++) { if (row[x] != 0) { minX = Math.Min(minX, x); maxX = Math.Max(maxX, x); minY = Math.Min(minY, y); maxY = Math.Max(maxY, y); } } } w = Math.Max(maxX - minX + 1, 1); h = Math.Max(maxY - minY + 1, 1); //maxX = minX + w; //maxY = minY + h; int index = 0; for (int y = minY; y <= maxY; y++) { var row = (int *)(pBase + y * stride); for (int x = minX; x <= maxX; x++) { data[index] = row[x]; index++; } } var region = AllocateRegion(w, h); if (region.x >= 0) { SetRegionData(region, data, w); var info = GetKerningInfo(chars[i]); var fontDef = new CCBMFontConfiguration.CCBMGlyphDef() { Character = chars[i], Subrect = new CCRect(region.x, region.y, region.width, region.height), XOffset = minX, // + (int)Math.Ceiling(info.A), YOffset = minY, XAdvance = (int)Math.Ceiling(info.A + info.B + info.C) }; fontConfig.CharacterSet.Add(chars[i]); fontConfig.Glyphs.Add(chars[i], fontDef); } else { CCLog.Log("Texture atlas is full"); } } } isTextureDirty = true; return(fontConfig); }