Search code examples
c++graphicsshadersdl-2rasterizing

why is this triangle shader that I wrote splitting into four?


I wrote a triangle shader with an edge function and tried to use weight to color it in, but the colors split into 4 separate triangles each with their own smaller version of the shader for some reason. the drawing function is just two lines of code for color and position and should not be causing this error.

triangle

int edgeFunction(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3){
        return (x2-x1)*(y3-y1)-(y2-y1)*(x3-x1);
}

std::vector<fragment> RGBtri(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3){
        std::vector<fragment> tri; //fragment is a struct with xyrgba

        int minX = std::min(x1, std::min(x2,x3));
        int maxX = std::max(x1, std::max(x2,x3));
        int minY = std::min(y1, std::min(y2,y3));
        int maxY = std::max(y1, std::max(y2,y3));

        int p = edgeFunction(x1,y2,x2,y2,x3,y3);

        for(uint16_t y = minY;y<=maxY;y++){
                for(uint16_t x = minX;x<=maxX;x++){
                        int a = edgeFunction(x2,y2,x3,y3,x,y);
                        int b = edgeFunction(x3,y3,x1,y1,x,y);
                        int c = edgeFunction(x1,y1,x2,y2,x,y);

                        if((a|b|c)>=0){
                                float d = ((float)a*255/(float)p);
                                float e = ((float)b*255/(float)p);
                                float f = ((float)c*255/(float)p);

                                uint8_t r = static_cast<uint8_t>(d);
                                uint8_t g = static_cast<uint8_t>(e);
                                uint8_t b = static_cast<uint8_t>(f);

                                 tri.push_back({x,y,r,g,b,255});
                        }
                }
         }
          return tri;
}

I got a lot of my information here

I tried a few variations but at most I got the rgb and cmy sections to swap.

my goal is to have red green and blue in the vertices of the main triangle, and not have the split


Solution

  • Found the answer, point p is x1 y2 for the first point not x1 y1, abc should not be multiplied by 255, the result should be multiplied by 255 and then cast to uint8

    std::vector<fragment> RGBtri(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3){
            std::vector<fragment> tri;
    
            int minX = std::min(x1, std::min(x2,x3));
            int maxX = std::max(x1, std::max(x2,x3));
            int minY = std::min(y1, std::min(y2,y3));
            int maxY = std::max(y1, std::max(y2,y3));
    
            int p = edgeFunction(x1,y1,x2,y2,x3,y3);
    
            for(uint16_t y = minY;y<=maxY;y++){
                    for(uint16_t x = minX;x<=maxX;x++){
                            int a = edgeFunction(x2,y2,x3,y3,x,y);
                            int b = edgeFunction(x3,y3,x1,y1,x,y);
                            int c = edgeFunction(x1,y1,x2,y2,x,y);
    
                            if(a>=0&&b>=0&&c>=0){
                                    float w1 = ((float)a/(float)p);
                                    float w2 = ((float)b/(float)p);
                                    float w3 = ((float)c/(float)p);
    
                                    uint8_t R = red.r*w1+green.r*w2+blue.r*w3;
                                    uint8_t G = red.g*w1+green.g*w2+blue.g*w3;
                                    uint8_t B = red.b*w1+green.b*w2+blue.b*w3;
    
                                    tri.push_back({x,y,R,G,B,255});
                            }
                    }
            }
    
            return tri;
    
    }