private unsafe void ImplDrawSurface(RenderSurface surface, int index) { var vertex_buffer = new TransientVertexBuffer(4, Vertex2DLayout); fixed(void *v = surface.Vertices) { Unsafe.CopyBlock((void *)vertex_buffer.Data, v, (uint)(4 * Vertex2D.Stride)); } var pass = (byte)(max_render_pass + index + 1); gfx.SetViewport(pass, 0, 0, Game.Instance.ScreenSize.W, Game.Instance.ScreenSize.H); var proj = screen_projection; gfx.SetProjection(pass, &proj.M11); //gfx.SetClearColor(pass, Color.Blue); Bgfx.SetTexture(0, current_shader_program.Samplers[0], surface.RenderTarget.NativeTexture, TextureFlags.FilterPoint | TextureFlags.ClampUVW); Bgfx.SetRenderState(render_state); Bgfx.SetIndexBuffer(index_buffer, 0, 6); Bgfx.SetVertexBuffer(0, vertex_buffer, 0, vertex_index); Bgfx.Submit(pass, surface.Shader?.Program ?? current_shader_program.Program); }
public TransientVertexBuffer StreamVertices2D(Vertex2D[] vertices, int count) { var vertex_buffer = new TransientVertexBuffer(count, Vertex2D.Layout); fixed(void *v = vertices) { Unsafe.CopyBlock((void *)vertex_buffer.Data, v, (uint)(count * Vertex2D.Stride)); } return(vertex_buffer); }
public void Submit( byte view, int vertex_count, ShaderProgram shader, IndexBuffer index_buffer, TransientVertexBuffer vertex_buffer, Texture2D texture, RenderState render_state) { Bgfx.SetTexture(0, shader.Samplers[0], texture.Texture, texture.TexFlags); Bgfx.SetRenderState(render_state); Bgfx.SetIndexBuffer(index_buffer, 0, vertex_count / 4 * 6); Bgfx.SetVertexBuffer(0, vertex_buffer, 0, vertex_count); shader.SubmitValues(); Bgfx.Submit(view, shader.Program); }
private unsafe void ImplSubmit() { var vertex_buffer = new TransientVertexBuffer(vertex_index, Vertex2DLayout); fixed(void *v = vertices) { Unsafe.CopyBlock((void *)vertex_buffer.Data, v, (uint)(vertex_index * Vertex2D.Stride)); } Bgfx.SetTexture(0, current_shader_program.Samplers[0], current_texture.Texture, current_texture.TexFlags); Bgfx.SetRenderState(render_state); Bgfx.SetIndexBuffer(index_buffer, 0, vertex_index / 4 * 6); Bgfx.SetVertexBuffer(0, vertex_buffer, 0, vertex_index); current_shader_program.SubmitValues(); Bgfx.SetViewMode(current_render_pass, ViewMode.Sequential); Bgfx.Submit(current_render_pass, current_shader_program.Program); }
public static extern void bgfx_set_transient_vertex_buffer(ref TransientVertexBuffer tvb, int startVertex, int numVertices);
public static extern void bgfx_alloc_transient_vertex_buffer(out TransientVertexBuffer tvb, int num, ref VertexLayout.Data decl);
public static extern bool bgfx_alloc_transient_buffers(out TransientVertexBuffer tvb, ref VertexLayout.Data decl, ushort numVertices, out TransientIndexBuffer tib, ushort numIndices);
public void SetVertexBuffer(TransientVertexBuffer vb, int startIndex = 0, int count = -1) { Bgfx.SetVertexBuffer(vb, startIndex, count); }
public void End() { if (currentProgram == null) { throw new ApplicationException("Unexpected End call, start a new batch with Begin()"); } if (spriteBatch.Count == 0) { currentProgram = null; return; } VertexTextureColor[] vertices = new VertexTextureColor[4]; ushort[] indices = new ushort[6]; Array.Copy(rectangleVertices, vertices, 4); Array.Copy(rectangleIndices, indices, 6); GCHandle handleVertices = GCHandle.Alloc(vertices, GCHandleType.Pinned); TransientVertexBuffer vertexBuffer = new TransientVertexBuffer(); TransientIndexBuffer indexBuffer = new TransientIndexBuffer(); for (int i = 0, batchLeft = 0, batchSize = 0; i < spriteBatch.Count; i++) { Sprite sprite = spriteBatch[i]; Texture2D texture = sprite.texture; if (batchLeft == 0) { for (int j = i; j < spriteBatch.Count; j++) { if (spriteBatch[j].texture != texture) { break; } batchLeft++; } batchLeft = Math.Min(batchLeft, ushort.MaxValue / 4); vertexBuffer = new TransientVertexBuffer(batchLeft * 4, VertexTextureColor.vertexLayout); indexBuffer = new TransientIndexBuffer(batchLeft * 6); } vertices[0].x = vertices[0].u = 0.0f; vertices[0].y = vertices[0].v = 0.0f; vertices[1].u = 1.0f; vertices[1].y = vertices[1].v = 0.0f; vertices[2].u = 1.0f; vertices[2].v = 1.0f; vertices[3].x = vertices[3].u = 0.0f; vertices[3].v = 1.0f; vertices[1].x = vertices[2].x = sprite.size.x; vertices[2].y = vertices[3].y = sprite.size.y; // translation and rotation if (sprite.rotation == 0.0f) { for (int j = 0; j < 4; ++j) { vertices[j].x += sprite.position.x; vertices[j].y += sprite.position.y; vertices[j].color = sprite.color; } } else { for (int j = 0; j < 4; ++j) { double cosRot = Math.Cos(sprite.rotation); double sinRot = Math.Sin(sprite.rotation); double rotX = sprite.originX + (vertices[j].x - sprite.originX) * cosRot - (vertices[j].y - sprite.originY) * sinRot; double rotY = sprite.originY + (vertices[j].x - sprite.originX) * sinRot + (vertices[j].y - sprite.originY) * cosRot; vertices[j].x = (float)(rotX + sprite.position.x - (int)sprite.originX); vertices[j].y = (float)(rotY + sprite.position.y - (int)sprite.originY); vertices[j].color = sprite.color; } } // texture coordinates if (texture != null) { float left = sprite.sourceRect.x; float top = sprite.sourceRect.y; float right = sprite.sourceRect.x + sprite.sourceRect.width; float bottom = sprite.sourceRect.y + sprite.sourceRect.height; if (sprite.size == sprite.sourceRect.size) { vertices[0].u = vertices[3].u = left / texture.width; vertices[0].v = vertices[1].v = top / texture.height; vertices[2].u = vertices[1].u = right / texture.width; vertices[2].v = vertices[3].v = bottom / texture.height; } else { // when stretching textures, texture sampling points needs to be adjusted // by half pixel in order to prevent neighbouring subtextures bleeding // around the edges. vertices[0].u = vertices[3].u = (left + 0.5f) / texture.width; vertices[0].v = vertices[1].v = (top + 0.5f) / texture.height; vertices[2].u = vertices[1].u = (right - 0.5f) / texture.width; vertices[2].v = vertices[3].v = (bottom - 0.5f) / texture.height; } } // copy data to buffers unsafe { int offset = (batchSize * 4); VertexTextureColor *vertexData = (VertexTextureColor *)handleVertices.AddrOfPinnedObject(); VertexTextureColor *vbData = (VertexTextureColor *)(vertexBuffer.Data) + offset; ushort * ibData = (ushort *)(indexBuffer.Data) + (batchSize * 6); for (int j = 0; j < 4; ++j) { *vbData = *vertexData; vbData++; vertexData++; } for (int j = 0; j < 6; ++j) { *ibData = (ushort)(indices[j] + offset); ibData++; } } batchSize++; batchLeft--; if (batchLeft == 0) { // draw current batch renderer.SetRenderState(Renderer.AlphaBlendNoDepth); renderer.SetVertexBuffer(vertexBuffer, 0, batchSize * 4); renderer.SetIndexBuffer(indexBuffer, 0, batchSize * 6); if (texture != null) { renderer.SetTexture(0, texture, textureFlags); } renderer.Submit(currentViewport, currentProgram); batchSize = 0; } } handleVertices.Free(); spriteBatch.Clear(); currentViewport++; currentProgram = null; }
/// <summary> /// Sets the vertex buffer to use for drawing primitives. /// </summary> /// <param name="vertexBuffer">The vertex buffer to set.</param> /// <param name="firstVertex">The index of the first vertex to use.</param> /// <param name="count">The number of vertices to pull from the buffer.</param> public static void SetVertexBuffer(TransientVertexBuffer vertexBuffer, int firstVertex = 0, int count = -1) { NativeMethods.bgfx_set_transient_vertex_buffer(ref vertexBuffer, firstVertex, count); }
/// <summary> /// Attempts to allocate both a transient vertex buffer and index buffer. /// </summary> /// <param name="vertexCount">The number of vertices to allocate.</param> /// <param name="layout">The layout of each vertex.</param> /// <param name="indexCount">The number of indices to allocate.</param> /// <param name="vertexBuffer">Returns the allocated transient vertex buffer.</param> /// <param name="indexBuffer">Returns the allocated transient index buffer.</param> /// <returns><c>true</c> if both space requirements are satisfied and the buffers were allocated.</returns> public static bool AllocateTransientBuffers(int vertexCount, VertexLayout layout, int indexCount, out TransientVertexBuffer vertexBuffer, out TransientIndexBuffer indexBuffer) { return NativeMethods.bgfx_alloc_transient_buffers(out vertexBuffer, ref layout.data, (ushort)vertexCount, out indexBuffer, (ushort)indexCount); }