We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Hello dear, FIXED NOW! I have tried to port to C# Is it correct or wrongly? My code is completely with Clear and ClearColor in class Rasterizer
Clear
ClearColor
namespace SurfaceRasterizer; using static DeafMan1983.ConvFunctions; using DeafMan1983.Interop.SDL2; using static DeafMan1983.Interop.SDL2.SDL; using System.Runtime.InteropServices; unsafe class Program { const int WIDTH = 1024; const int HEIGHT = 728; const int POS = (int)SDL_WINDOWPOS_CENTERED; static sbyte* TITLE = SBytePointerFromString("Draw Filled Triangle!"); const uint FLAGS = (uint)SDL_WindowFlags.SDL_WINDOW_SHOWN; // Structure Color struct Color { public float R, G, B; public Color(float r, float g, float b) { R = r; G = g; B = b; } public uint ToPixel() { byte red = (byte)(R * 255.0f); byte green = (byte)(G * 255.0f); byte blue = (byte)(B * 255.0f); return (uint)((red << 16) | (green << 8) | blue); } public static Color operator +(Color left, Color right) { return new Color(left.R + right.R, left.G + right.G, left.B + right.B); } public static Color operator -(Color left, Color right) { return new Color(left.R - right.R, left.G - right.G, left.B - right.B); } public static Color operator *(Color color, float f) { return new Color(color.R * f, color.G * f, color.B * f); } } // Structure Vertex public struct Vertex { public float x, y; public float r, g, b; public Vertex(float x, float y, float r, float g, float b) { this.x = x; this.y = y; this.r = r; this.g = g; this.b = b; } public static Vertex operator -(Vertex left, Vertex right) { return new Vertex(left.x - right.x, left.y - right.y, left.r - right.r, left.g - right.g, left.b - right.b); } public static Vertex operator +(Vertex left, Vertex right) { return new Vertex(left.x + right.x, left.y + right.y, left.r + right.r, left.g + right.g, left.b + right.b); } } // Structure EdgeEquation struct EdgeEquation { public float a, b, c; public bool tie; public EdgeEquation(Vertex v0, Vertex v1) { a = v0.y - v1.y; b = v1.x - v0.x; c = - (a * (v0.x + v1.x) + b * (v0.y + v1.y)) / 2; tie = a != 0 ? a > 0 : b > 0; } public float evaluate(float x, float y) { return a * x + b * y + c; } public bool test(float x, float y) { return test(evaluate(x, y)); } public bool test(float v) { return (v > 0 || v == 0 && tie); } } // Structure ParameterEquation struct ParameterEquation { public float a, b, c; public ParameterEquation(float p0, float p1, float p2, EdgeEquation e0, EdgeEquation e1, EdgeEquation e2, float area) { float factor = 1.0f / (2.0f * area); a = factor * (p0 * e0.a + p1 * e1.a + p2 * e2.a); b = factor * (p0 * e0.b + p1 * e1.b + p2 * e2.b); c = factor * (p0 * e0.c + p1 * e1.c + p2 * e2.c); } public float evaluate(float x, float y) { return a * x + b * y + c; } } // Raszerizer class Raszerizer { [DllImport("c")] public static extern void* memset(void* str, int c, nuint n); private SDL_Surface* m_surf; private uint* m_pixels; private int m_width; private int m_height; private int m_minX, m_minY, m_maxX, m_maxY; public Raszerizer() { Viewport(0, 0, 0, 0); } public void SetFrameBuffer(SDL_Surface* surf, int width, int height) { m_surf = surf; m_pixels = (uint*)surf->pixels; m_width = width; m_height = height; } private void SetPixel(int x, int y, Color color) { if (x >= m_width || y >= m_height) return; m_pixels[y * m_width + x] = color.ToPixel(); } private void SetPixel(int x, int y, uint color_pixel) { if (x >= m_width || y >= m_height) return; m_pixels[y * m_width + x] = color_pixel; } public void Clear() { memset(m_pixels, 0, (nuint)(sizeof(uint) * m_width * m_height)); } public void ClearColor(Color color) { for (int x = 0; x < m_width; x++) { for (int y = 0; y < m_height; y++) { SetPixel(x, y, color); } } } public void Viewport(int x, int y, int width, int height) { m_minX = x; m_minY = y; m_maxX = x + width; m_maxY = y + m_height; } public void DrawTriangle(Vertex v0, Vertex v1, Vertex v2) { // Compute triangle bounding box. int minX = (int)Math.Min(Math.Min(v0.x, v1.x), v2.x); int maxX = (int)Math.Max(Math.Max(v0.x, v1.x), v2.x); int minY = (int)Math.Min(Math.Min(v0.y, v1.y), v2.y); int maxY = (int)Math.Max(Math.Max(v0.y, v1.y), v2.y); // Clip to scissor rect. minX = Math.Max(minX, m_minX); maxX = Math.Min(maxX, m_maxX); minY = Math.Max(minY, m_minY); maxY = Math.Min(maxY, m_maxY); // Compute edge equations. EdgeEquation e0 = new(v1, v2); EdgeEquation e1 = new(v2, v0); EdgeEquation e2 = new(v0, v1); float area = (float)(0.5 * (e0.c + e1.c + e2.c)); // Check if triangle is backfacing. if (area < 0) return; ParameterEquation r = new(v0.r, v1.r, v2.r, e0, e1, e2, area); ParameterEquation g = new(v0.g, v1.g, v2.g, e0, e1, e2, area); ParameterEquation b = new(v0.b, v1.b, v2.b, e0, e1, e2, area); // Add 0.5 to sample at pixel centers. for (float x = minX + 0.5f, xm = maxX + 0.5f; x <= xm; x += 1.0f) for (float y = minY + 0.5f, ym = maxY + 0.5f; y <= ym; y += 1.0f) { if (e0.test(x, y) && e1.test(x, y) && e2.test(x, y)) { byte rint = (byte)(r.evaluate(x, y) * 255); byte gint = (byte)(g.evaluate(x, y) * 255); byte bint = (byte)(b.evaluate(x, y) * 255); uint color = SDL_MapRGB(m_surf->format, rint, gint, bint); SetPixel((int)x, (int)y, color); } } } } // Static Main function static int Main(string[] args) { SDL_Init(SDL_INIT_VIDEO); SDL_Window* window = SDL_CreateWindow(TITLE, POS, POS, WIDTH, HEIGHT, FLAGS); SDL_Surface* surface = SDL_GetWindowSurface(window); Raszerizer rast = new(); while (true) { SDL_Event evt; SDL_PollEvent(&evt); if (evt.type == (uint)SDL_EventType.SDL_QUIT) { break; } if (evt.type == (uint)SDL_EventType.SDL_KEYDOWN) { if (evt.key.keysym.sym == SDL_KeyCode.SDLK_ESCAPE) { break; } } if (evt.type == (uint)SDL_EventType.SDL_WINDOWEVENT) { if (evt.window.eventID == (byte)SDL_WindowEventID.SDL_WINDOWEVENT_EXPOSED) { SDL_SetWindowSize(SDL_GetWindowFromID(evt.window.windowID), evt.window.data1, evt.window.data2); } if (evt.window.eventID == (byte)SDL_WindowEventID.SDL_WINDOWEVENT_MAXIMIZED) { SDL_SetWindowSize(SDL_GetWindowFromID(evt.window.windowID), evt.window.data1, evt.window.data2); SDL_SetWindowMaximumSize(SDL_GetWindowFromID(evt.window.windowID), evt.window.data1, evt.window.data2); } if (evt.window.eventID == (byte)SDL_WindowEventID.SDL_WINDOWEVENT_MAXIMIZED) { SDL_SetWindowSize(SDL_GetWindowFromID(evt.window.windowID), evt.window.data1, evt.window.data2); } } // Lock Surface if (SDL_LockSurface(surface) != 0) return -1; // Set Rasterizing FrameBuffer rast.SetFrameBuffer(surface, WIDTH, HEIGHT); rast.Clear(); rast.Viewport(0, 0, WIDTH, HEIGHT); // Clear color Color backcolor = new Color { R = 1.0f, G = 1.0f / 4, B = 0f }; rast.ClearColor(backcolor); // Draw Filled Traingle Vertex v1 = new Vertex { x = 256, y = 540, r = 1f, g = 0f, b = 0f }; Vertex v2 = new Vertex { x = WIDTH / 2, y = 180, r = 0f, g = 1f, b = 0f }; Vertex v3 = new Vertex { x = 768, y = 540, r = 0f, g = 0f, b = 1f }; rast.DrawTriangle(v1, v2, v3); // Unlock and Update Surface SDL_UnlockSurface(surface); SDL_UpdateWindowSurface(window); } SDL_FreeSurface(surface); SDL_DestroyWindow(window); SDL_Quit(); return 0; } }
Update: I don't expect that float means 1.0f = WIDTH like in OpenGL or Vulkan. float 1 : int 1 .... Now it works fine :D
Thanks
The text was updated successfully, but these errors were encountered:
No branches or pull requests
Hello dear,
FIXED NOW!
I have tried to port to C#
Is it correct or wrongly?
My code is completely with
Clear
andClearColor
in class RasterizerUpdate: I don't expect that float means 1.0f = WIDTH like in OpenGL or Vulkan.
float 1 : int 1 ....
Now it works fine :D
Thanks
The text was updated successfully, but these errors were encountered: