fix Draw2DImage

This commit is contained in:
olebeck 2025-06-27 00:38:05 +02:00
parent 5a6d05c38f
commit 5f9b9675eb
14 changed files with 132 additions and 182 deletions

View File

@ -1 +1,2 @@
*.exe *.exe
cache/

View File

@ -29,14 +29,12 @@ bool with_razor = false;
INCBIN(main_vert_gxp, "shaders/main.vert.gxp"); INCBIN(main_vert_gxp, "shaders/main.vert.gxp");
INCBIN(main_frag_gxp, "shaders/main.frag.gxp"); INCBIN(main_frag_gxp, "shaders/main.frag.gxp");
//INCBIN(clear_vert_gxp, "shaders/clear.vert.gxp"); INCBIN(color_frag_gxp, "shaders/color.frag.gxp");
INCBIN(clear_frag_gxp, "shaders/clear.frag.gxp");
INCBIN(image_frag_gxp, "shaders/image.frag.gxp"); INCBIN(image_frag_gxp, "shaders/image.frag.gxp");
const SceGxmProgram* mainVertexProgramGxp = (const SceGxmProgram*)_inc_main_vert_gxpData; const SceGxmProgram* mainVertexProgramGxp = (const SceGxmProgram*)_inc_main_vert_gxpData;
const SceGxmProgram* mainFragmentProgramGxp = (const SceGxmProgram*)_inc_main_frag_gxpData; const SceGxmProgram* mainFragmentProgramGxp = (const SceGxmProgram*)_inc_main_frag_gxpData;
//const SceGxmProgram* clearVertexProgramGxp = (const SceGxmProgram*)_inc_clear_vert_gxpData; const SceGxmProgram* colorFragmentProgramGxp = (const SceGxmProgram*)_inc_color_frag_gxpData;
const SceGxmProgram* clearFragmentProgramGxp = (const SceGxmProgram*)_inc_clear_frag_gxpData;
const SceGxmProgram* imageFragmentProgramGxp = (const SceGxmProgram*)_inc_image_frag_gxpData; const SceGxmProgram* imageFragmentProgramGxp = (const SceGxmProgram*)_inc_image_frag_gxpData;
extern "C" int sceRazorGpuCaptureSetTrigger(int frames, const char* path); extern "C" int sceRazorGpuCaptureSetTrigger(int frames, const char* path);
@ -67,7 +65,7 @@ static void load_razor() {
} }
if(with_razor) { if(with_razor) {
//sceRazorGpuCaptureEnableSalvage("ux0:data/gpu_crash.sgx"); sceRazorGpuCaptureEnableSalvage("ux0:data/gpu_crash.sgx");
} }
} }
@ -244,9 +242,8 @@ bool get_gxm_context(SceGxmContext** context, SceGxmShaderPatcher** shaderPatche
static bool create_gxm_renderer(int width, int height, GXMRendererData* data) { static bool create_gxm_renderer(int width, int height, GXMRendererData* data) {
const unsigned int alignedWidth = ALIGN(VITA_GXM_SCREEN_WIDTH, SCE_GXM_TILE_SIZEX); const unsigned int alignedWidth = ALIGN(VITA_GXM_SCREEN_WIDTH, SCE_GXM_TILE_SIZEX);
const unsigned int alignedHeight = ALIGN(VITA_GXM_SCREEN_HEIGHT, SCE_GXM_TILE_SIZEY); const unsigned int alignedHeight = ALIGN(VITA_GXM_SCREEN_HEIGHT, SCE_GXM_TILE_SIZEY);
const unsigned int sampleCount = alignedWidth * alignedHeight;
unsigned int sampleCount = alignedWidth * alignedHeight; const unsigned int depthStrideInSamples = alignedWidth;
unsigned int depthStrideInSamples = alignedWidth;
if(!get_gxm_context(&data->context, &data->shaderPatcher, &data->cdramPool)) { if(!get_gxm_context(&data->context, &data->shaderPatcher, &data->cdramPool)) {
return false; return false;
@ -347,7 +344,7 @@ static bool create_gxm_renderer(int width, int height, GXMRendererData* data) {
} }
// register shader programs // register shader programs
if(SCE_ERR(sceGxmShaderPatcherRegisterProgram, data->shaderPatcher, clearFragmentProgramGxp, &data->clearFragmentProgramId)) { if(SCE_ERR(sceGxmShaderPatcherRegisterProgram, data->shaderPatcher, colorFragmentProgramGxp, &data->colorFragmentProgramId)) {
return false; return false;
} }
if(SCE_ERR(sceGxmShaderPatcherRegisterProgram, data->shaderPatcher, mainVertexProgramGxp, &data->mainVertexProgramId)) { if(SCE_ERR(sceGxmShaderPatcherRegisterProgram, data->shaderPatcher, mainVertexProgramGxp, &data->mainVertexProgramId)) {
@ -360,34 +357,6 @@ static bool create_gxm_renderer(int width, int height, GXMRendererData* data) {
return false; return false;
} }
// clear shader
/*
{
GET_SHADER_PARAM(positionAttribute, clearVertexProgramGxp, "aPosition", false);
SceGxmVertexAttribute vertexAttributes[1];
SceGxmVertexStream vertexStreams[1];
vertexAttributes[0].streamIndex = 0;
vertexAttributes[0].offset = 0;
vertexAttributes[0].format = SCE_GXM_ATTRIBUTE_FORMAT_F32;
vertexAttributes[0].componentCount = 2;
vertexAttributes[0].regIndex = sceGxmProgramParameterGetResourceIndex(positionAttribute);
vertexStreams[0].stride = sizeof(float)*2;
vertexStreams[0].indexSource = SCE_GXM_INDEX_SOURCE_INDEX_16BIT;
if(SCE_ERR(sceGxmShaderPatcherCreateVertexProgram,
data->shaderPatcher,
data->clearVertexProgramId,
vertexAttributes, 1,
vertexStreams, 1,
&data->clearVertexProgram
)) {
return false;
}
}
*/
// main shader // main shader
{ {
GET_SHADER_PARAM(positionAttribute, mainVertexProgramGxp, "aPosition", false); GET_SHADER_PARAM(positionAttribute, mainVertexProgramGxp, "aPosition", false);
@ -465,12 +434,12 @@ static bool create_gxm_renderer(int width, int height, GXMRendererData* data) {
// color // color
if(SCE_ERR(sceGxmShaderPatcherCreateFragmentProgram, if(SCE_ERR(sceGxmShaderPatcherCreateFragmentProgram,
data->shaderPatcher, data->shaderPatcher,
data->clearFragmentProgramId, data->colorFragmentProgramId,
SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4, SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4,
SCE_GXM_MULTISAMPLE_NONE, SCE_GXM_MULTISAMPLE_NONE,
NULL, NULL,
mainVertexProgramGxp, mainVertexProgramGxp,
&data->clearFragmentProgram &data->colorFragmentProgram
)) { )) {
return false; return false;
} }
@ -488,7 +457,7 @@ static bool create_gxm_renderer(int width, int height, GXMRendererData* data) {
data->uUseTexture = sceGxmProgramFindParameterByName(mainFragmentProgramGxp, "uUseTexture"); // int data->uUseTexture = sceGxmProgramFindParameterByName(mainFragmentProgramGxp, "uUseTexture"); // int
// clear uniforms // clear uniforms
data->clearShader_uColor = sceGxmProgramFindParameterByName(clearFragmentProgramGxp, "uColor"); // vec4 data->colorShader_uColor = sceGxmProgramFindParameterByName(colorFragmentProgramGxp, "uColor"); // vec4
// light uniforms buffer // light uniforms buffer
data->lightDataBuffer = sceClibMspaceMalloc(data->cdramPool, data->lightDataBuffer = sceClibMspaceMalloc(data->cdramPool,
@ -513,28 +482,28 @@ static void CreateOrthoMatrix(float left, float right, float bottom, float top,
{ {
float near = -1.0f; float near = -1.0f;
float far = 1.0f; float far = 1.0f;
float rl = right - left; float width = right - left;
float tb = top - bottom; float height = top - bottom;
float fn = far - near; float depth = far - near;
outMatrix[0][0] = 2.0f / rl; outMatrix[0][0] = 2.0f / width;
outMatrix[0][1] = 0.0f; outMatrix[0][1] = 0.0f;
outMatrix[0][2] = 0.0f; outMatrix[0][2] = 0.0f;
outMatrix[0][3] = 0.0f; outMatrix[0][3] = -(right + left) / width; // translation x
outMatrix[1][0] = 0.0f; outMatrix[1][0] = 0.0f;
outMatrix[1][1] = -2.0f / tb; outMatrix[1][1] = 2.0f / height;
outMatrix[1][2] = 0.0f; outMatrix[1][2] = 0.0f;
outMatrix[1][3] = 0.0f; outMatrix[1][3] = -(top + bottom) / height; // translation y
outMatrix[2][0] = 0.0f; outMatrix[2][0] = 0.0f;
outMatrix[2][1] = 0.0f; outMatrix[2][1] = 0.0f;
outMatrix[2][2] = -2.0f / fn; outMatrix[2][2] = -2.0f / depth;
outMatrix[2][3] = 0.0f; outMatrix[2][3] = -(far + near) / depth; // translation z
outMatrix[3][0] = -(right + left) / rl; outMatrix[3][0] = 0.0f;
outMatrix[3][1] = -(top + bottom) / tb; outMatrix[3][1] = 0.0f;
outMatrix[3][2] = -(far + near) / fn; outMatrix[3][2] = 0.0f;
outMatrix[3][3] = 1.0f; outMatrix[3][3] = 1.0f;
} }
@ -598,7 +567,7 @@ void GXMRenderer::SetFrustumPlanes(const Plane* frustumPlanes)
void GXMRenderer::SetProjection(const D3DRMMATRIX4D& projection, D3DVALUE front, D3DVALUE back) void GXMRenderer::SetProjection(const D3DRMMATRIX4D& projection, D3DVALUE front, D3DVALUE back)
{ {
memcpy(&m_projection, projection, sizeof(D3DRMMATRIX4D)); memcpy(&m_projection, projection, sizeof(D3DRMMATRIX4D));
m_projection[1][1] *= -1.0f; // OpenGL is upside down m_projection[1][1] *= -1.0f; // GXM is upside down
} }
struct TextureDestroyContextGXM { struct TextureDestroyContextGXM {
@ -621,7 +590,7 @@ void GXMRenderer::AddTextureDestroyCallback(Uint32 id, IDirect3DRMTexture* textu
); );
} }
void convertTextureMetadata(SDL_Surface* surface, bool* supportedFormat, SceGxmTextureFormat* textureFormat, size_t* textureSize, size_t* textureAlignment) { static void convertTextureMetadata(SDL_Surface* surface, bool* supportedFormat, SceGxmTextureFormat* textureFormat, size_t* textureSize, size_t* textureAlignment) {
*supportedFormat = true; *supportedFormat = true;
*textureAlignment = SCE_GXM_TEXTURE_ALIGNMENT; *textureAlignment = SCE_GXM_TEXTURE_ALIGNMENT;
switch(surface->format) { switch(surface->format) {
@ -630,6 +599,7 @@ void convertTextureMetadata(SDL_Surface* surface, bool* supportedFormat, SceGxmT
*textureSize = surface->h * surface->pitch; *textureSize = surface->h * surface->pitch;
break; break;
} }
/* crashes when opening the guestbook for some reason
case SDL_PIXELFORMAT_INDEX8: { case SDL_PIXELFORMAT_INDEX8: {
*textureFormat = SCE_GXM_TEXTURE_FORMAT_P8_ABGR; *textureFormat = SCE_GXM_TEXTURE_FORMAT_P8_ABGR;
int pixelsSize = surface->h * surface->pitch; int pixelsSize = surface->h * surface->pitch;
@ -638,22 +608,13 @@ void convertTextureMetadata(SDL_Surface* surface, bool* supportedFormat, SceGxmT
*textureAlignment = SCE_GXM_PALETTE_ALIGNMENT; *textureAlignment = SCE_GXM_PALETTE_ALIGNMENT;
break; break;
} }
*/
default: { default: {
*supportedFormat = false; *supportedFormat = false;
} }
} }
} }
bool createRgbaCopySurface(SDL_Surface* surface, size_t *textureSize, SceGxmTextureFormat* textureFormat, SDL_Surface** copy_surf) {
*copy_surf = SDL_ConvertSurface(surface, SDL_PIXELFORMAT_ABGR8888);
if (!*copy_surf) {
return false;
}
*textureFormat = SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ABGR;
*textureSize = (*copy_surf)->w * (*copy_surf)->h * 4;
return true;
}
Uint32 GXMRenderer::GetTextureId(IDirect3DRMTexture* iTexture) Uint32 GXMRenderer::GetTextureId(IDirect3DRMTexture* iTexture)
{ {
auto texture = static_cast<Direct3DRMTextureImpl*>(iTexture); auto texture = static_cast<Direct3DRMTextureImpl*>(iTexture);
@ -666,9 +627,6 @@ Uint32 GXMRenderer::GetTextureId(IDirect3DRMTexture* iTexture)
SceGxmTextureFormat textureFormat; SceGxmTextureFormat textureFormat;
convertTextureMetadata(surface->m_surface, &supportedFormat, &textureFormat, &textureSize, &textureAlignment); convertTextureMetadata(surface->m_surface, &supportedFormat, &textureFormat, &textureSize, &textureAlignment);
if(!supportedFormat) {
SDL_Log("unsupported SDL texture format %s, falling back on SDL_PIXELFORMAT_ABGR8888", SDL_GetPixelFormatName(surface->m_surface->format));
}
for (Uint32 i = 0; i < m_textures.size(); ++i) { for (Uint32 i = 0; i < m_textures.size(); ++i) {
auto& tex = m_textures[i]; auto& tex = m_textures[i];
@ -676,12 +634,13 @@ Uint32 GXMRenderer::GetTextureId(IDirect3DRMTexture* iTexture)
if (tex.version != texture->m_version) { if (tex.version != texture->m_version) {
void* textureData = sceGxmTextureGetData(&tex.gxmTexture); void* textureData = sceGxmTextureGetData(&tex.gxmTexture);
if(!supportedFormat) { if(!supportedFormat) {
SDL_Surface* copy_surf; SDL_ConvertPixels(
if(!createRgbaCopySurface(surface->m_surface, &textureSize, &textureFormat, &copy_surf)) { surface->m_surface->w, surface->m_surface->h,
return NO_TEXTURE_ID; surface->m_surface->format,
} surface->m_surface->pixels,
memcpy(textureData, copy_surf->pixels, textureSize); surface->m_surface->pitch,
SDL_DestroySurface(copy_surf); SDL_PIXELFORMAT_ABGR8888, textureData, surface->m_surface->pitch
);
} else { } else {
memcpy(textureData, surface->m_surface->pixels, textureSize); memcpy(textureData, surface->m_surface->pixels, textureSize);
} }
@ -698,21 +657,25 @@ Uint32 GXMRenderer::GetTextureId(IDirect3DRMTexture* iTexture)
SDL_Log("Create Texture %s w=%d h=%d s=%d", SDL_Log("Create Texture %s w=%d h=%d s=%d",
SDL_GetPixelFormatName(surface->m_surface->format), textureWidth, textureHeight, textureStride); SDL_GetPixelFormatName(surface->m_surface->format), textureWidth, textureHeight, textureStride);
SDL_Surface* copy_surf = nullptr;
if(!supportedFormat) { if(!supportedFormat) {
if(!createRgbaCopySurface(surface->m_surface, &textureSize, &textureFormat, &copy_surf)) { textureAlignment = SCE_GXM_TEXTURE_ALIGNMENT;
return NO_TEXTURE_ID; textureSize = textureHeight * textureStride * 4;
} textureFormat = SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ABGR;
} }
// allocate gpu memory // allocate gpu memory
void* textureData = sceClibMspaceMemalign(this->m_data.cdramPool, textureAlignment, textureSize); void* textureData = sceClibMspaceMemalign(this->m_data.cdramPool, textureAlignment, textureSize);
uint8_t* paletteData = nullptr; uint8_t* paletteData = nullptr;
if(copy_surf) if(!supportedFormat) {
{ SDL_Log("unsupported SDL texture format %s, falling back on SDL_PIXELFORMAT_ABGR8888", SDL_GetPixelFormatName(surface->m_surface->format));
memcpy(textureData, copy_surf->pixels, textureSize); SDL_ConvertPixels(
SDL_DestroySurface(copy_surf); surface->m_surface->w, surface->m_surface->h,
surface->m_surface->format,
surface->m_surface->pixels,
surface->m_surface->pitch,
SDL_PIXELFORMAT_ABGR8888, textureData, surface->m_surface->pitch
);
} }
else if(surface->m_surface->format == SDL_PIXELFORMAT_INDEX8) else if(surface->m_surface->format == SDL_PIXELFORMAT_INDEX8)
{ {
@ -733,9 +696,8 @@ Uint32 GXMRenderer::GetTextureId(IDirect3DRMTexture* iTexture)
} }
SceGxmTexture gxmTexture; SceGxmTexture gxmTexture;
SDL_Log("textureData: %p", textureData);
SCE_ERR(sceGxmTextureInitLinearStrided, &gxmTexture, textureData, textureFormat, textureWidth, textureHeight, textureStride); SCE_ERR(sceGxmTextureInitLinearStrided, &gxmTexture, textureData, textureFormat, textureWidth, textureHeight, textureStride);
sceGxmTextureSetMinFilter(&gxmTexture, SCE_GXM_TEXTURE_FILTER_LINEAR); //sceGxmTextureSetMinFilter(&gxmTexture, SCE_GXM_TEXTURE_FILTER_LINEAR);
sceGxmTextureSetMagFilter(&gxmTexture, SCE_GXM_TEXTURE_FILTER_LINEAR); sceGxmTextureSetMagFilter(&gxmTexture, SCE_GXM_TEXTURE_FILTER_LINEAR);
if(paletteData) { if(paletteData) {
sceGxmTextureSetPalette(&gxmTexture, paletteData); sceGxmTextureSetPalette(&gxmTexture, paletteData);
@ -902,8 +864,8 @@ void GXMRenderer::StartScene() {
&this->m_data.displayBuffersSurface[this->backBufferIndex], &this->m_data.displayBuffersSurface[this->backBufferIndex],
&this->m_data.depthSurface &this->m_data.depthSurface
); );
sceGxmSetViewport(this->m_data.context, 0, m_width, 0, m_height, 0, 0);
this->sceneStarted = true; this->sceneStarted = true;
// reset quad vertices buffer
this->m_data.quadVertices = (Vertex*)(this->m_data.quadIndices + 4); this->m_data.quadVertices = (Vertex*)(this->m_data.quadIndices + 4);
} }
@ -991,9 +953,9 @@ void GXMRenderer::SubmitDraw(
transpose4x4(modelViewMatrix, modelViewMatrixTrans); transpose4x4(modelViewMatrix, modelViewMatrixTrans);
transpose4x4(m_projection, projectionTrans); transpose4x4(m_projection, projectionTrans);
SET_UNIFORM(vertUniforms, this->m_data.uModelViewMatrix, modelViewMatrixTrans, mainVertexProgramGxp); SET_UNIFORM(vertUniforms, this->m_data.uModelViewMatrix, modelViewMatrixTrans);
SET_UNIFORM(vertUniforms, this->m_data.uNormalMatrix, normalMatrix, mainVertexProgramGxp); SET_UNIFORM(vertUniforms, this->m_data.uProjectionMatrix, projectionTrans);
SET_UNIFORM(vertUniforms, this->m_data.uProjectionMatrix, projectionTrans, mainVertexProgramGxp); SET_UNIFORM(vertUniforms, this->m_data.uNormalMatrix, normalMatrix);
float color[4] = { float color[4] = {
appearance.color.r / 255.0f, appearance.color.r / 255.0f,
@ -1001,11 +963,11 @@ void GXMRenderer::SubmitDraw(
appearance.color.b / 255.0f, appearance.color.b / 255.0f,
appearance.color.a / 255.0f appearance.color.a / 255.0f
}; };
SET_UNIFORM(fragUniforms, this->m_data.uColor, color, mainFragmentProgramGxp); SET_UNIFORM(fragUniforms, this->m_data.uColor, color);
SET_UNIFORM(fragUniforms, this->m_data.uShininess, appearance.shininess, mainFragmentProgramGxp); SET_UNIFORM(fragUniforms, this->m_data.uShininess, appearance.shininess);
int useTexture = appearance.textureId != NO_TEXTURE_ID ? 1 : 0; int useTexture = appearance.textureId != NO_TEXTURE_ID ? 1 : 0;
SET_UNIFORM(fragUniforms, this->m_data.uUseTexture, useTexture, mainFragmentProgramGxp); SET_UNIFORM(fragUniforms, this->m_data.uUseTexture, useTexture);
if(useTexture) { if(useTexture) {
auto& texture = m_textures[appearance.textureId]; auto& texture = m_textures[appearance.textureId];
sceGxmSetFragmentTexture(this->m_data.context, 0, &texture.gxmTexture); sceGxmSetFragmentTexture(this->m_data.context, 0, &texture.gxmTexture);
@ -1027,26 +989,6 @@ HRESULT GXMRenderer::FinalizeFrame() {
return DD_OK; return DD_OK;
} }
void orthoMatrixRowMajor(float mat[4][4], float left, float right, float bottom, float top, float nearZ, float farZ) {
memset(mat, 0, sizeof(float) * 16);
mat[0][0] = 2.0f / (right - left);
mat[1][1] = 2.0f / (top - bottom);
mat[2][2] = -2.0f / (farZ - nearZ);
mat[3][0] = -(right + left) / (right - left);
mat[3][1] = -(top + bottom) / (top - bottom);
mat[3][2] = -(farZ + nearZ) / (farZ - nearZ);
mat[3][3] = 1.0f;
}
void identityMatrix(float mat[4][4]) {
memset(mat, 0, sizeof(float) * 16);
mat[0][0] = 1.0f;
mat[1][1] = 1.0f;
mat[2][2] = 1.0f;
mat[3][3] = 1.0f;
}
Vertex* GXMRenderer::GetQuadVertices() { Vertex* GXMRenderer::GetQuadVertices() {
Vertex* verts = this->m_data.quadVertices; Vertex* verts = this->m_data.quadVertices;
this->m_data.quadVertices += 4; this->m_data.quadVertices += 4;
@ -1067,32 +1009,31 @@ void GXMRenderer::Clear(float r, float g, float b) {
sceGxmPushUserMarker(this->m_data.context, marker); sceGxmPushUserMarker(this->m_data.context, marker);
sceGxmSetVertexProgram(this->m_data.context, this->m_data.mainVertexProgram); sceGxmSetVertexProgram(this->m_data.context, this->m_data.mainVertexProgram);
sceGxmSetFragmentProgram(this->m_data.context, this->m_data.clearFragmentProgram); sceGxmSetFragmentProgram(this->m_data.context, this->m_data.colorFragmentProgram);
void* vertUniforms; void* vertUniforms;
void* fragUniforms; void* fragUniforms;
sceGxmReserveVertexDefaultUniformBuffer(this->m_data.context, &vertUniforms); sceGxmReserveVertexDefaultUniformBuffer(this->m_data.context, &vertUniforms);
sceGxmReserveFragmentDefaultUniformBuffer(this->m_data.context, &fragUniforms); sceGxmReserveFragmentDefaultUniformBuffer(this->m_data.context, &fragUniforms);
float left = -m_viewportTransform.offsetX / m_viewportTransform.scale;
float right = (m_width - m_viewportTransform.offsetX) / m_viewportTransform.scale;
float top = -m_viewportTransform.offsetY / m_viewportTransform.scale;
float bottom = (m_height - m_viewportTransform.offsetY) / m_viewportTransform.scale;
D3DRMMATRIX4D projection; D3DRMMATRIX4D projection;
orthoMatrixRowMajor(projection, left, right, bottom, top, -1.0, 1.0); CreateOrthoMatrix(0.0, 1.0, 1.0, 0.0, projection);
D3DRMMATRIX4D identity; D3DRMMATRIX4D identity;
identityMatrix(identity); memset(identity, 0, sizeof(identity));
identity[0][0] = 1.0f;
identity[1][1] = 1.0f;
identity[2][2] = 1.0f;
identity[3][3] = 1.0f;
Matrix3x3 normal = {{1.f, 0.f, 0.f}, {0.f, 1.f, 0.f}, {0.f, 0.f, 1.f}}; Matrix3x3 normal = {{1.f, 0.f, 0.f}, {0.f, 1.f, 0.f}, {0.f, 0.f, 1.f}};
SET_UNIFORM(vertUniforms, this->m_data.uModelViewMatrix, identity, mainVertexProgramGxp); // float4x4 SET_UNIFORM(vertUniforms, this->m_data.uModelViewMatrix, identity); // float4x4
SET_UNIFORM(vertUniforms, this->m_data.uNormalMatrix, normal, mainVertexProgramGxp); // float3x3 SET_UNIFORM(vertUniforms, this->m_data.uNormalMatrix, normal); // float3x3
SET_UNIFORM(vertUniforms, this->m_data.uProjectionMatrix, projection, mainVertexProgramGxp); // float4x4 SET_UNIFORM(vertUniforms, this->m_data.uProjectionMatrix, projection); // float4x4
float color[] = {r,g,b,1}; float color[] = {r,g,b,1};
SET_UNIFORM(fragUniforms, this->m_data.clearShader_uColor, color, clearFragmentProgramGxp); SET_UNIFORM(fragUniforms, this->m_data.colorShader_uColor, color);
float x1 = 0; float x1 = 0;
float y1 = 0; float y1 = 0;
@ -1117,19 +1058,22 @@ void GXMRenderer::Clear(float r, float g, float b) {
} }
void GXMRenderer::Flip() { void GXMRenderer::Flip() {
if(this->sceneStarted) { if(!this->sceneStarted) {
sceGxmEndScene( this->Clear(0,0,0);
this->m_data.context,
nullptr, nullptr
);
sceGxmPadHeartbeat(
&this->m_data.displayBuffersSurface[this->backBufferIndex],
this->m_data.displayBuffersSync[this->backBufferIndex]
);
this->sceneStarted = false;
} }
// end scene
sceGxmEndScene(
this->m_data.context,
nullptr, nullptr
);
sceGxmPadHeartbeat(
&this->m_data.displayBuffersSurface[this->backBufferIndex],
this->m_data.displayBuffersSync[this->backBufferIndex]
);
this->sceneStarted = false;
// display
GXMDisplayData displayData; GXMDisplayData displayData;
displayData.address = this->m_data.displayBuffers[this->backBufferIndex]; displayData.address = this->m_data.displayBuffers[this->backBufferIndex];
@ -1158,25 +1102,38 @@ void GXMRenderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const S
sceGxmReserveVertexDefaultUniformBuffer(this->m_data.context, &vertUniforms); sceGxmReserveVertexDefaultUniformBuffer(this->m_data.context, &vertUniforms);
sceGxmReserveFragmentDefaultUniformBuffer(this->m_data.context, &fragUniforms); sceGxmReserveFragmentDefaultUniformBuffer(this->m_data.context, &fragUniforms);
float left = -m_viewportTransform.offsetX / m_viewportTransform.scale; float left = -this->m_viewportTransform.offsetX / this->m_viewportTransform.scale;
float right = (m_width - m_viewportTransform.offsetX) / m_viewportTransform.scale; float right = (this->m_width - this->m_viewportTransform.offsetX) / this->m_viewportTransform.scale;
float top = -m_viewportTransform.offsetY / m_viewportTransform.scale; float top = -this->m_viewportTransform.offsetY / this->m_viewportTransform.scale;
float bottom = (m_height - m_viewportTransform.offsetY) / m_viewportTransform.scale; float bottom = (this->m_height - this->m_viewportTransform.offsetY) / this->m_viewportTransform.scale;
#define virtualToNDCX(x) (((x - left) / (right - left)));
#define virtualToNDCY(y) (((y - top) / (bottom - top)));
float x1_virtual = static_cast<float>(dstRect.x);
float y1_virtual = static_cast<float>(dstRect.y);
float x2_virtual = x1_virtual + dstRect.w;
float y2_virtual = y1_virtual + dstRect.h;
float x1 = virtualToNDCX(x1_virtual);
float y1 = virtualToNDCY(y1_virtual);
float x2 = virtualToNDCX(x2_virtual);
float y2 = virtualToNDCY(y2_virtual);
D3DRMMATRIX4D projection; D3DRMMATRIX4D projection;
CreateOrthoMatrix(left, right, bottom, top, projection); CreateOrthoMatrix(0.0, 1.0, 1.0, 0.0, projection);
D3DRMMATRIX4D projectionTrans; static const Matrix3x3 normal = {{1.f, 0.f, 0.f}, {0.f, 1.f, 0.f}, {0.f, 0.f, 1.f}};
transpose4x4(projection, projectionTrans);
D3DRMMATRIX4D identity = {{1.f, 0.f, 0.f, 0.f}, {0.f, 1.f, 0.f, 0.f}, {0.f, 0.f, 1.f, 0.f}, {0.f, 0.f, 0.f, 1.f}}; D3DRMMATRIX4D identity;
Matrix3x3 normal = {{1.f, 0.f, 0.f}, {0.f, 1.f, 0.f}, {0.f, 0.f, 1.f}}; memset(identity, 0, sizeof(identity));
identity[0][0] = 1.0f;
identity[1][1] = 1.0f;
identity[2][2] = 1.0f;
identity[3][3] = 1.0f;
D3DRMMATRIX4D identityTrans; SET_UNIFORM(vertUniforms, this->m_data.uModelViewMatrix, identity); // float4x4
transpose4x4(identity, identityTrans); SET_UNIFORM(vertUniforms, this->m_data.uNormalMatrix, normal); // float3x3
SET_UNIFORM(vertUniforms, this->m_data.uProjectionMatrix, projection); // float4x4
SET_UNIFORM(vertUniforms, this->m_data.uModelViewMatrix, identityTrans, mainVertexProgramGxp); // float4x4
SET_UNIFORM(vertUniforms, this->m_data.uNormalMatrix, normal, mainVertexProgramGxp); // float3x3
SET_UNIFORM(vertUniforms, this->m_data.uProjectionMatrix, projectionTrans, mainVertexProgramGxp); // float4x4
const GXMTextureCacheEntry& texture = m_textures[textureId]; const GXMTextureCacheEntry& texture = m_textures[textureId];
sceGxmSetFragmentTexture(this->m_data.context, 0, &texture.gxmTexture); sceGxmSetFragmentTexture(this->m_data.context, 0, &texture.gxmTexture);
@ -1184,16 +1141,11 @@ void GXMRenderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const S
float texW = sceGxmTextureGetWidth(&texture.gxmTexture); float texW = sceGxmTextureGetWidth(&texture.gxmTexture);
float texH = sceGxmTextureGetHeight(&texture.gxmTexture); float texH = sceGxmTextureGetHeight(&texture.gxmTexture);
float u1 = srcRect.x / texW; float u1 = static_cast<float>(srcRect.x) / texW;
float v1 = srcRect.y / texH; float v1 = static_cast<float>(srcRect.y) / texH;
float u2 = (srcRect.x + srcRect.w) / texW; float u2 = static_cast<float>(srcRect.x + srcRect.w) / texW;
float v2 = (srcRect.y + srcRect.h) / texH; float v2 = static_cast<float>(srcRect.y + srcRect.h) / texH;
float x1 = static_cast<float>(dstRect.x);
float y1 = static_cast<float>(dstRect.y);
float x2 = x1 + dstRect.w;
float y2 = y1 + dstRect.h;
Vertex* quadVertices = this->GetQuadVertices(); Vertex* quadVertices = this->GetQuadVertices();
quadVertices[0] = Vertex{ .position = {x1, y1, 0}, .normal = {0,0,0}, .texCoord = {u1, v1}}; quadVertices[0] = Vertex{ .position = {x1, y1, 0}, .normal = {0,0,0}, .texCoord = {u1, v1}};
quadVertices[1] = Vertex{ .position = {x2, y1, 0}, .normal = {0,0,0}, .texCoord = {u2, v1}}; quadVertices[1] = Vertex{ .position = {x2, y1, 0}, .normal = {0,0,0}, .texCoord = {u2, v1}};
@ -1212,18 +1164,17 @@ void GXMRenderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const S
} }
void GXMRenderer::Download(SDL_Surface* target) { void GXMRenderer::Download(SDL_Surface* target) {
SDL_Surface* src = SDL_CreateSurfaceFrom(
this->m_width, this->m_height,
SDL_PIXELFORMAT_RGBA32,
this->m_data.displayBuffers[this->backBufferIndex], VITA_GXM_SCREEN_STRIDE
);
SDL_Rect srcRect = { SDL_Rect srcRect = {
static_cast<int>(m_viewportTransform.offsetX), static_cast<int>(m_viewportTransform.offsetX),
static_cast<int>(m_viewportTransform.offsetY), static_cast<int>(m_viewportTransform.offsetY),
static_cast<int>(target->w * m_viewportTransform.scale), static_cast<int>(target->w * m_viewportTransform.scale),
static_cast<int>(target->h * m_viewportTransform.scale), static_cast<int>(target->h * m_viewportTransform.scale),
}; };
SDL_Surface* src = SDL_CreateSurfaceFrom(
this->m_width, this->m_height,
SDL_PIXELFORMAT_RGBA32,
this->m_data.displayBuffers[this->backBufferIndex], VITA_GXM_SCREEN_STRIDE
);
SDL_BlitSurfaceScaled(src, &srcRect, target, nullptr, SDL_SCALEMODE_NEAREST); SDL_BlitSurfaceScaled(src, &srcRect, target, nullptr, SDL_SCALEMODE_NEAREST);
SDL_DestroySurface(src);
} }

View File

@ -1,5 +1,5 @@
shaders += main.frag.gxp main.vert.gxp image.frag.gxp shaders += main.frag.gxp main.vert.gxp
shaders += clear.frag.gxp clear.vert.gxp shaders += color.frag.gxp image.frag.gxp
all: $(shaders) all: $(shaders)

View File

@ -1,7 +0,0 @@
void main(
float2 aPosition : POSITION,
out float4 vPosition : POSITION
) {
vPosition = float4(aPosition, 0.0, 1.0);
}

View File

@ -18,13 +18,11 @@
#define ALIGNMENT(n, a) (((a) - ((n) % (a))) % (a)) #define ALIGNMENT(n, a) (((a) - ((n) % (a))) % (a))
#define SET_UNIFORM(buffer, param, value, program) \ #define SET_UNIFORM(buffer, param, value) \
do { \ do { \
size_t __offset = sceGxmProgramParameterGetResourceIndex(param); \ size_t __offset = sceGxmProgramParameterGetResourceIndex(param); \
void* __dst = (uint8_t*)(buffer) + (__offset * sizeof(uint32_t)); \ void* __dst = (uint8_t*)(buffer) + (__offset * sizeof(uint32_t)); \
memcpy(__dst, reinterpret_cast<const void*>(&(value)), sizeof(value)); \ memcpy(__dst, reinterpret_cast<const void*>(&(value)), sizeof(value)); \
/*SDL_Log("set uniform param=%s offset=%d size=%d buffer_size=%d", \
sceGxmProgramParameterGetName(param), __offset*4, sizeof(value), sceGxmProgramGetDefaultUniformBufferSize(program));*/ \
} while (0) } while (0)
#define GET_SHADER_PARAM(var, gxp, name, ret) \ #define GET_SHADER_PARAM(var, gxp, name, ret) \
@ -33,3 +31,11 @@
SDL_Log("Failed to find param %s", name); \ SDL_Log("Failed to find param %s", name); \
return ret; \ return ret; \
} }
static void printMatrix4x4(float mat[4][4]) {
sceClibPrintf("mat4{\n");
for(int i = 0; i < 4; i++) {
sceClibPrintf("%f %f %f %f\n", mat[i][0], mat[i][1], mat[i][2], mat[i][3]);
}
sceClibPrintf("}\n");
}

View File

@ -101,18 +101,17 @@ typedef struct GXMRendererData {
void* stencilBufferData; void* stencilBufferData;
SceGxmDepthStencilSurface depthSurface; SceGxmDepthStencilSurface depthSurface;
// clear shader
SceGxmShaderPatcherId clearFragmentProgramId;
SceGxmFragmentProgram* clearFragmentProgram;
// main shader // main shader
SceGxmShaderPatcherId mainVertexProgramId; SceGxmShaderPatcherId mainVertexProgramId;
SceGxmShaderPatcherId mainFragmentProgramId; SceGxmShaderPatcherId mainFragmentProgramId;
SceGxmShaderPatcherId imageFragmentProgramId; SceGxmShaderPatcherId imageFragmentProgramId;
SceGxmShaderPatcherId colorFragmentProgramId;
SceGxmVertexProgram* mainVertexProgram; SceGxmVertexProgram* mainVertexProgram;
SceGxmFragmentProgram* opaqueFragmentProgram; // 3d with no transparency SceGxmFragmentProgram* opaqueFragmentProgram; // 3d with no transparency
SceGxmFragmentProgram* transparentFragmentProgram; // 3d with transparency SceGxmFragmentProgram* transparentFragmentProgram; // 3d with transparency
SceGxmFragmentProgram* imageFragmentProgram; // 2d images, no lighting SceGxmFragmentProgram* imageFragmentProgram; // 2d images, no lighting
SceGxmFragmentProgram* colorFragmentProgram; // 2d color, no lighting
// main shader vertex uniforms // main shader vertex uniforms
const SceGxmProgramParameter* uModelViewMatrix; const SceGxmProgramParameter* uModelViewMatrix;
@ -126,7 +125,7 @@ typedef struct GXMRendererData {
const SceGxmProgramParameter* uColor; const SceGxmProgramParameter* uColor;
const SceGxmProgramParameter* uUseTexture; const SceGxmProgramParameter* uUseTexture;
const SceGxmProgramParameter* clearShader_uColor; const SceGxmProgramParameter* colorShader_uColor;
// scene light data // scene light data
void* lightDataBuffer; void* lightDataBuffer;