theproadam / renderXF

High performance software rendering in c#
MIT License
11 stars 4 forks source link

Question: How to pass texture to fragment shader? #2

Closed kf6kjg closed 3 years ago

kf6kjg commented 3 years ago

In OpenGL I'd set up a uniform, but I'm not seeing how to do this here. The obvious way is to simply make my textures members of the object that contains my shaders, then access the texture bytes from within the shader method. But if that's the case, what's the point of the GLTexture class when I've already got the image in a bitmap...

I've reviewed the codebase, and read through the wiki. Not seeing an example stand out, did I miss it?

theproadam commented 3 years ago

The GLTexture class only exists to hold textures in raw data form. Because it holds its stuff in unmanaged memory, it has great interoperability with the software renderer. Reading from bitmaps is very slow. Obviously you can pin their memory and read it, however it is much faster just to copy and keep their data in an unmanaged array.

As for how to display textures, there is no need for uniform items for renderXF since the shader code can easily access all of your global variables since the shader delegates can be declared anywhere. So uniform objects can be simply accessed in the same assembly.

It may not seem convenient to have to manually sample stuff, however when software rendering, performance is critical and sometimes you have to trade speed for ease-of-use.

void InitShader()
{
        DisplayTexture = new Shader(CubeShader, TextureShader, GLRenderMode.Triangle);

        texture2d = new GLTexture("container2.png", MemoryLocation.Heap, DuringLoad.Flip);
        TEXTURE_ADDR = (int*)texture2d.GetAddress();

        textureHeight = texture2d.Height;
        textureWidthMinusOne = texture2d.Width - 1;
        textureHeightMinusOne = texture2d.Height - 1;
}

int* TEXTURE_ADDR;
int textureWidthMinusOne;
int textureHeightMinusOne;
int textureHeight;

unsafe void TextureShader(byte* BGR, float* Attributes, int FaceIndex)
{
        //Clamp to ensure we wont read outside of the array for TextAddr:
        int U = (int)(Clamp01(Attributes[0]) * textureWidthMinusOne);
        int V = (int)(Clamp01(Attributes[1]) * textureHeightMinusOne);

        int* iptr = (int*)BGR;

        *iptr = TEXTURE_ADDR[U + V * textureHeight];     
}

Unfortunately, I have seem to have inadvertently broken the attribute interpolation so a fix should occur within the next few hours.

theproadam commented 3 years ago

@kf6kjg I have fixed the interpolation issue, and I have created a demo texture example in Examples/TextureTest. There is also a newly added wiki part for how to display a texture, and I also ported over the new bitmap blitting tool.

kf6kjg commented 3 years ago

Excellent, thank you.