diff --git a/src/render/wiiu/SDL_render_wiiu.c b/src/render/wiiu/SDL_render_wiiu.c index 74d0a190d..d45483b88 100644 --- a/src/render/wiiu/SDL_render_wiiu.c +++ b/src/render/wiiu/SDL_render_wiiu.c @@ -101,6 +101,9 @@ typedef struct GX2Sampler sampler; GX2ColorBuffer cbuf; GX2ContextState ctx; + GX2RBuffer texPositionBuffer; + GX2RBuffer texCoordBuffer; + GX2RBuffer texColourBuffer; } WIIU_RenderData; static Uint32 @@ -174,6 +177,36 @@ WIIU_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->driverdata = data; renderer->window = window; + // Setup texture shader attribute buffers + data->texPositionBuffer.flags = + data->texCoordBuffer.flags = + data->texColourBuffer.flags = + GX2R_RESOURCE_BIND_VERTEX_BUFFER | + GX2R_RESOURCE_USAGE_CPU_READ | + GX2R_RESOURCE_USAGE_CPU_WRITE | + GX2R_RESOURCE_USAGE_GPU_READ; + data->texPositionBuffer.elemSize = sizeof(float) * 3; + data->texCoordBuffer.elemSize = sizeof(float) * 2; + data->texColourBuffer.elemSize = sizeof(float) * 4; + data->texPositionBuffer.elemCount = + data->texCoordBuffer.elemCount = + data->texColourBuffer.elemCount = 4; + + GX2RCreateBuffer(&data->texPositionBuffer); + GX2RCreateBuffer(&data->texCoordBuffer); + GX2RCreateBuffer(&data->texColourBuffer); + + // Prepare texture color buffer data (it's costant between textures) + float aColourDefault[] = { + 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, + }; + GX2RLockBufferEx(&data->texColourBuffer, 0); + memcpy(data->texColourBuffer.buffer, aColourDefault, data->texColourBuffer.elemCount * data->texColourBuffer.elemSize); + GX2RUnlockBufferEx(&data->texColourBuffer, 0); + // Setup sampler GX2InitSampler(&data->sampler, GX2_TEX_CLAMP_MODE_CLAMP, GX2_TEX_XY_FILTER_MODE_LINEAR); @@ -239,7 +272,7 @@ PixelFormatToWIIUFMT(Uint32 format) static int WIIU_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) { - GX2Texture *wiiu_tex = (WIIU_TextureData*) SDL_calloc(1, sizeof(*wiiu_tex)); + GX2Texture *wiiu_tex = (GX2Texture*) SDL_calloc(1, sizeof(*wiiu_tex)); if (!wiiu_tex) return -1; @@ -300,6 +333,85 @@ WIIU_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture) return 0; } +static int +WIIU_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * srcrect, const SDL_FRect * dstrect) +{ + WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata; + GX2Texture *wiiu_tex = (GX2Texture*) texture->driverdata; + + //TODO: Move texCoord/pos math to shader + float transform_x, transform_y; + if (renderer->viewport.x || renderer->viewport.y) { + transform_x = (((renderer->viewport.x + dstrect->x) / (float)data->cbuf.surface.width) * 2.0f)-1.0f; + transform_y = (((renderer->viewport.y + dstrect->y) / (float)data->cbuf.surface.height) * 2.0f)-1.0f; + } else { + transform_x = ((dstrect->x / (float)data->cbuf.surface.width) * 2.0f)-1.0f; + transform_y = ((dstrect->y / (float)data->cbuf.surface.height) * 2.0f)-1.0f; + } + float transform_width = (dstrect->w / (float)data->cbuf.surface.width) * 2.0f; + float transform_height = (dstrect->h / (float)data->cbuf.surface.height) * 2.0f; + + float aPosition[] = + { + transform_x, transform_y, 0.0f, + transform_x + transform_width, transform_y, 0.0f, + transform_x + transform_width, transform_y + transform_height, 0.0f, + transform_x, transform_y + transform_height, 0.0f, + }; + + GX2RLockBufferEx(&data->texPositionBuffer, 0); + memcpy(data->texPositionBuffer.buffer, aPosition, data->texPositionBuffer.elemCount * data->texPositionBuffer.elemSize); + GX2RUnlockBufferEx(&data->texPositionBuffer, 0); + + float tex_x_min = (float)srcrect->x / (float)wiiu_tex->surface.width; + float tex_x_max = (float)(srcrect->x + srcrect->w) / (float)wiiu_tex->surface.width; + float tex_y_min = (float)srcrect->y / (float)wiiu_tex->surface.height; + float tex_y_max = (float)(srcrect->y + srcrect->h) / (float)wiiu_tex->surface.height; + + float aTexCoord[] = + { + tex_x_min, tex_y_max, + tex_x_max, tex_y_max, + tex_x_max, tex_y_min, + tex_x_min, tex_y_min, + }; + + GX2RLockBufferEx(&data->texCoordBuffer, 0); + memcpy(data->texCoordBuffer.buffer, aTexCoord, data->texCoordBuffer.elemCount * data->texCoordBuffer.elemSize); + GX2RUnlockBufferEx(&data->texCoordBuffer, 0); + + //RENDER + GX2SetContextState(&data->ctx); + + GX2SetFetchShader(&texShaders.fetchShader); + GX2SetVertexShader(texShaders.vertexShader); + GX2SetPixelShader(texShaders.pixelShader); + + GX2SetPixelTexture(texture, 0); + GX2SetPixelSampler(sampler, 0); + + GX2RSetAttributeBuffer(&data->texPositionBuffer, 0, data->texPositionBuffer.elemSize, 0); + GX2RSetAttributeBuffer(&data->texCoordBuffer, 1, data->texCoordBuffer.elemSize, 0); + GX2RSetAttributeBuffer(&data->texColourBuffer, 2, data->texColourBuffer.elemSize, 0); + + GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1); +} + +static void +WIIU_RenderPresent(SDL_Renderer * renderer) +{ + WIIU_RenderData *data = (WIIU_RenderData *) renderer->driverdata; + SDL_Window *window = renderer->window; + + GX2Invalidate(GX2_INVALIDATE_MODE_CPU | GX2_INVALIDATE_MODE_TEXTURE, data->cbuf.surface.image, data->cbuf.surface.imageSize); + + if (window) { + SDL_UpdateWindowSurface(window); + } +} + + #endif /* SDL_VIDEO_RENDER_WIIU */ /* vi: set ts=4 sw=4 expandtab: */ \ No newline at end of file