mirror of
https://github.com/isledecomp/isle-portable.git
synced 2026-01-12 18:51:15 +00:00
split 2d and 3d shaders completely
This commit is contained in:
parent
35ee36d50e
commit
b3d37a4d74
@ -5,6 +5,11 @@
|
||||
|
||||
#define GXM_DISPLAY_BUFFER_COUNT 3
|
||||
|
||||
typedef struct Vertex2D {
|
||||
float position[2];
|
||||
float texCoord[2];
|
||||
} Vertex2D;
|
||||
|
||||
typedef struct GXMContext {
|
||||
// context
|
||||
SceUID vdmRingBufferUid;
|
||||
@ -36,12 +41,14 @@ typedef struct GXMContext {
|
||||
SceGxmShaderPatcher* shaderPatcher;
|
||||
|
||||
// clear
|
||||
SceGxmShaderPatcherId clearVertexProgramId;
|
||||
SceGxmShaderPatcherId clearFragmentProgramId;
|
||||
SceGxmVertexProgram* clearVertexProgram;
|
||||
SceGxmFragmentProgram* clearFragmentProgram;
|
||||
const SceGxmProgramParameter* clear_uColor;
|
||||
float* clearVertices;
|
||||
SceGxmShaderPatcherId planeVertexProgramId;
|
||||
SceGxmShaderPatcherId colorFragmentProgramId;
|
||||
SceGxmShaderPatcherId imageFragmentProgramId;
|
||||
SceGxmVertexProgram* planeVertexProgram;
|
||||
SceGxmFragmentProgram* colorFragmentProgram;
|
||||
SceGxmFragmentProgram* imageFragmentProgram;
|
||||
const SceGxmProgramParameter* color_uColor;
|
||||
Vertex2D* clearVertices;
|
||||
uint16_t* clearIndices;
|
||||
|
||||
// display
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#define WITH_RAZOR
|
||||
bool with_razor = false;
|
||||
bool with_razor_hud = false;
|
||||
bool gxm_initialized = false;
|
||||
@ -36,19 +37,16 @@ const SceGxmMultisampleMode msaaMode = SCE_GXM_MULTISAMPLE_NONE;
|
||||
|
||||
#define SCE_GXM_PRECOMPUTED_ALIGNMENT 16
|
||||
|
||||
INCBIN(main_vert_gxp, "shaders/main.vert.gxp");
|
||||
INCBIN(main_color_frag_gxp, "shaders/main.color.frag.gxp");
|
||||
INCBIN(main_texture_frag_gxp, "shaders/main.texture.frag.gxp");
|
||||
INCBIN(image_frag_gxp, "shaders/image.frag.gxp");
|
||||
INCBIN(clear_vert_gxp, "shaders/clear.vert.gxp");
|
||||
INCBIN(clear_frag_gxp, "shaders/clear.frag.gxp");
|
||||
#define INCSHADER(filename, name) INCBIN(name, filename); const SceGxmProgram* name = (const SceGxmProgram*) _inc_##name##Data;
|
||||
|
||||
INCSHADER("shaders/main.vert.gxp", mainVertexProgramGxp);
|
||||
INCSHADER("shaders/main.color.frag.gxp", mainColorFragmentProgramGxp);
|
||||
INCSHADER("shaders/main.texture.frag.gxp", mainTextureFragmentProgramGxp);
|
||||
|
||||
INCSHADER("shaders/plane.vert.gxp", planeVertexProgramGxp);
|
||||
INCSHADER("shaders/image.frag.gxp", imageFragmentProgramGxp);
|
||||
INCSHADER("shaders/color.frag.gxp", colorFragmentProgramGxp);
|
||||
|
||||
const SceGxmProgram* mainVertexProgramGxp = (const SceGxmProgram*) _inc_main_vert_gxpData;
|
||||
const SceGxmProgram* mainColorFragmentProgramGxp = (const SceGxmProgram*) _inc_main_color_frag_gxpData;
|
||||
const SceGxmProgram* mainTextureFragmentProgramGxp = (const SceGxmProgram*) _inc_main_texture_frag_gxpData;
|
||||
const SceGxmProgram* imageFragmentProgramGxp = (const SceGxmProgram*) _inc_image_frag_gxpData;
|
||||
const SceGxmProgram* clearVertexProgramGxp = (const SceGxmProgram*) _inc_clear_vert_gxpData;
|
||||
const SceGxmProgram* clearFragmentProgramGxp = (const SceGxmProgram*) _inc_clear_frag_gxpData;
|
||||
|
||||
static const SceGxmBlendInfo blendInfoOpaque = {
|
||||
.colorMask = SCE_GXM_COLOR_MASK_ALL,
|
||||
@ -86,71 +84,72 @@ static void display_callback(const void* callback_data)
|
||||
sceDisplayWaitSetFrameBuf();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
#include <taihen.h>
|
||||
#ifdef WITH_RAZOR
|
||||
#include <taihen.h>
|
||||
|
||||
static int load_skprx(const char* name)
|
||||
{
|
||||
int modid = taiLoadKernelModule(name, 0, nullptr);
|
||||
if (modid < 0) {
|
||||
sceClibPrintf("%s load: 0x%08x\n", name, modid);
|
||||
return modid;
|
||||
}
|
||||
int status;
|
||||
int ret = taiStartKernelModule(modid, 0, nullptr, 0, nullptr, &status);
|
||||
if (ret < 0) {
|
||||
sceClibPrintf("%s start: 0x%08x\n", name, ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int load_suprx(const char* name)
|
||||
{
|
||||
int modid = _sceKernelLoadModule(name, 0, nullptr);
|
||||
if (modid < 0) {
|
||||
sceClibPrintf("%s load: 0x%08x\n", name, modid);
|
||||
return modid;
|
||||
}
|
||||
int status;
|
||||
int ret = sceKernelStartModule(modid, 0, nullptr, 0, nullptr, &status);
|
||||
if (ret < 0) {
|
||||
sceClibPrintf("%s start: 0x%08x\n", name, ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const bool extra_debug = false;
|
||||
|
||||
static void load_razor()
|
||||
{
|
||||
if (load_suprx("app0:librazorcapture_es4.suprx") >= 0) {
|
||||
with_razor = true;
|
||||
static int load_skprx(const char* name)
|
||||
{
|
||||
int modid = taiLoadKernelModule(name, 0, nullptr);
|
||||
if (modid < 0) {
|
||||
sceClibPrintf("%s load: 0x%08x\n", name, modid);
|
||||
return modid;
|
||||
}
|
||||
int status;
|
||||
int ret = taiStartKernelModule(modid, 0, nullptr, 0, nullptr, &status);
|
||||
if (ret < 0) {
|
||||
sceClibPrintf("%s start: 0x%08x\n", name, ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (extra_debug) {
|
||||
load_skprx("ux0:app/LEGO00001/syslibtrace.skprx");
|
||||
load_skprx("ux0:app/LEGO00001/pamgr.skprx");
|
||||
static int load_suprx(const char* name)
|
||||
{
|
||||
sceClibPrintf("loading %s\n", name);
|
||||
int modid = _sceKernelLoadModule(name, 0, nullptr);
|
||||
if (modid < 0) {
|
||||
sceClibPrintf("%s load: 0x%08x\n", name, modid);
|
||||
return modid;
|
||||
}
|
||||
int status;
|
||||
int ret = sceKernelStartModule(modid, 0, nullptr, 0, nullptr, &status);
|
||||
if (ret < 0) {
|
||||
sceClibPrintf("%s start: 0x%08x\n", name, ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (load_suprx("app0:libperf.suprx") >= 0) {
|
||||
static const bool extra_debug = false;
|
||||
|
||||
static void load_razor()
|
||||
{
|
||||
if (load_suprx("app0:librazorcapture_es4.suprx") >= 0) {
|
||||
with_razor = true;
|
||||
}
|
||||
|
||||
if (load_suprx("app0:librazorhud_es4.suprx") >= 0) {
|
||||
with_razor_hud = true;
|
||||
if (extra_debug) {
|
||||
load_skprx("ux0:app/LEGO00001/syslibtrace.skprx");
|
||||
load_skprx("ux0:app/LEGO00001/pamgr.skprx");
|
||||
|
||||
if (load_suprx("app0:libperf.suprx") >= 0) {
|
||||
}
|
||||
|
||||
if (load_suprx("app0:librazorhud_es4.suprx") >= 0) {
|
||||
with_razor_hud = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (with_razor) {
|
||||
//sceRazorGpuCaptureEnableSalvage("ux0:data/gpu_crash.sgx");
|
||||
}
|
||||
|
||||
if (with_razor_hud) {
|
||||
sceRazorGpuTraceSetFilename("ux0:data/gpu_trace", 3);
|
||||
}
|
||||
}
|
||||
|
||||
if (with_razor) {
|
||||
//sceRazorGpuCaptureEnableSalvage("ux0:data/gpu_crash.sgx");
|
||||
}
|
||||
|
||||
if (with_razor_hud) {
|
||||
sceRazorGpuTraceSetFilename("ux0:data/gpu_trace", 3);
|
||||
}
|
||||
}
|
||||
#else
|
||||
bool load_razor() {
|
||||
return true;
|
||||
}
|
||||
bool load_razor() {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
int gxm_library_init()
|
||||
@ -392,18 +391,34 @@ int GXMContext::init()
|
||||
tlsf_create(this->cdramPool);
|
||||
tlsf_add_pool(this->cdramPool, this->cdramMem, CDRAM_POOL_SIZE);
|
||||
|
||||
// clear shader
|
||||
// register plane, color, image shaders
|
||||
if (ret = SCE_ERR( sceGxmShaderPatcherRegisterProgram,
|
||||
this->shaderPatcher,
|
||||
planeVertexProgramGxp,
|
||||
&this->planeVertexProgramId
|
||||
); ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
if (ret = SCE_ERR(sceGxmShaderPatcherRegisterProgram,
|
||||
this->shaderPatcher,
|
||||
colorFragmentProgramGxp,
|
||||
&this->colorFragmentProgramId
|
||||
); ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
if (ret = SCE_ERR(sceGxmShaderPatcherRegisterProgram,
|
||||
this->shaderPatcher,
|
||||
imageFragmentProgramGxp,
|
||||
&this->imageFragmentProgramId
|
||||
); ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ret = SCE_ERR( sceGxmShaderPatcherRegisterProgram, this->shaderPatcher, clearVertexProgramGxp, &this->clearVertexProgramId); ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
if (ret = SCE_ERR( sceGxmShaderPatcherRegisterProgram, this->shaderPatcher, clearFragmentProgramGxp, &this->clearFragmentProgramId); ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
{
|
||||
GET_SHADER_PARAM(positionAttribute, clearVertexProgramGxp, "aPosition", -1);
|
||||
GET_SHADER_PARAM(positionAttribute, planeVertexProgramGxp, "aPosition", -1);
|
||||
GET_SHADER_PARAM(texCoordAttribute, planeVertexProgramGxp, "aTexCoord", -1);
|
||||
|
||||
SceGxmVertexAttribute vertexAttributes[1];
|
||||
SceGxmVertexAttribute vertexAttributes[2];
|
||||
SceGxmVertexStream vertexStreams[1];
|
||||
|
||||
// position
|
||||
@ -413,18 +428,25 @@ int GXMContext::init()
|
||||
vertexAttributes[0].componentCount = 2;
|
||||
vertexAttributes[0].regIndex = sceGxmProgramParameterGetResourceIndex(positionAttribute);
|
||||
|
||||
vertexStreams[0].stride = 4 * 2;
|
||||
// uv
|
||||
vertexAttributes[1].streamIndex = 0;
|
||||
vertexAttributes[1].offset = 8;
|
||||
vertexAttributes[1].format = SCE_GXM_ATTRIBUTE_FORMAT_F32;
|
||||
vertexAttributes[1].componentCount = 2;
|
||||
vertexAttributes[1].regIndex = sceGxmProgramParameterGetResourceIndex(texCoordAttribute);
|
||||
|
||||
vertexStreams[0].stride = sizeof(float) * 4;
|
||||
vertexStreams[0].indexSource = SCE_GXM_INDEX_SOURCE_INDEX_16BIT;
|
||||
|
||||
if (ret = SCE_ERR(
|
||||
sceGxmShaderPatcherCreateVertexProgram,
|
||||
this->shaderPatcher,
|
||||
this->clearVertexProgramId,
|
||||
this->planeVertexProgramId,
|
||||
vertexAttributes,
|
||||
1,
|
||||
2,
|
||||
vertexStreams,
|
||||
1,
|
||||
&this->clearVertexProgram
|
||||
&this->planeVertexProgram
|
||||
); ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
@ -432,25 +454,38 @@ int GXMContext::init()
|
||||
if (ret = SCE_ERR(
|
||||
sceGxmShaderPatcherCreateFragmentProgram,
|
||||
this->shaderPatcher,
|
||||
this->clearFragmentProgramId,
|
||||
this->colorFragmentProgramId,
|
||||
SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4,
|
||||
SCE_GXM_MULTISAMPLE_NONE,
|
||||
NULL,
|
||||
clearVertexProgramGxp,
|
||||
&this->clearFragmentProgram
|
||||
planeVertexProgramGxp,
|
||||
&this->colorFragmentProgram
|
||||
); ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ret = SCE_ERR(
|
||||
sceGxmShaderPatcherCreateFragmentProgram,
|
||||
this->shaderPatcher,
|
||||
this->imageFragmentProgramId,
|
||||
SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4,
|
||||
SCE_GXM_MULTISAMPLE_NONE,
|
||||
&blendInfoTransparent,
|
||||
planeVertexProgramGxp,
|
||||
&this->imageFragmentProgram
|
||||
); ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
// clear uniforms
|
||||
this->clear_uColor = sceGxmProgramFindParameterByName(clearFragmentProgramGxp, "uColor"); // vec4
|
||||
this->color_uColor = sceGxmProgramFindParameterByName(colorFragmentProgramGxp, "uColor"); // vec4
|
||||
|
||||
this->clearVertices = static_cast<Vertex2D*>(this->alloc(sizeof(Vertex2D)*4, 4));
|
||||
this->clearVertices[0] = Vertex2D{ .position = {-1.0, 1.0}, .texCoord = {0, 0} };
|
||||
this->clearVertices[1] = Vertex2D{ .position = {1.0, 1.0}, .texCoord = {0, 0} };
|
||||
this->clearVertices[2] = Vertex2D{ .position = {-1.0, -1.0}, .texCoord = {0, 0} };
|
||||
this->clearVertices[3] = Vertex2D{ .position = {1.0,-1.0}, .texCoord = {0, 0} };
|
||||
|
||||
this->clearVertices = static_cast<float*>(this->alloc(sizeof(float)*4*2, 4));
|
||||
this->clearVertices[0] = -1.0; this->clearVertices[1] = 1.0;
|
||||
this->clearVertices[2] = 1.0; this->clearVertices[3] = 1.0;
|
||||
this->clearVertices[4] = -1.0; this->clearVertices[5] = -1.0;
|
||||
this->clearVertices[6] = 1.0; this->clearVertices[7] = -1.0;
|
||||
this->clearIndices = static_cast<uint16_t*>(this->alloc(sizeof(uint16_t) * 4, 4));
|
||||
this->clearIndices[0] = 0;
|
||||
this->clearIndices[1] = 1;
|
||||
@ -495,21 +530,18 @@ void GXMContext::clear(float r, float g, float b, bool new_scene) {
|
||||
|
||||
float color[] = {r, g, b, 1};
|
||||
|
||||
sceGxmSetVertexProgram(this->context, this->clearVertexProgram);
|
||||
sceGxmSetFragmentProgram(this->context, this->clearFragmentProgram);
|
||||
sceGxmSetVertexProgram(this->context, this->planeVertexProgram);
|
||||
sceGxmSetFragmentProgram(this->context, this->colorFragmentProgram);
|
||||
|
||||
void* vertUniforms;
|
||||
void* fragUniforms;
|
||||
sceGxmReserveVertexDefaultUniformBuffer(gxm->context, &vertUniforms);
|
||||
sceGxmReserveFragmentDefaultUniformBuffer(gxm->context, &fragUniforms);
|
||||
|
||||
if(!fragUniforms) {
|
||||
SDL_Log("failed to reserve fragment uniform buffer!!");
|
||||
}
|
||||
|
||||
sceGxmSetVertexStream(gxm->context, 0, this->clearVertices);
|
||||
sceGxmSetUniformDataF(fragUniforms, this->clear_uColor, 0, 4, color);
|
||||
sceGxmSetUniformDataF(fragUniforms, this->color_uColor, 0, 4, color);
|
||||
|
||||
sceGxmSetFrontDepthFunc(gxm->context, SCE_GXM_DEPTH_FUNC_ALWAYS);
|
||||
sceGxmDraw(gxm->context, SCE_GXM_PRIMITIVE_TRIANGLE_STRIP, SCE_GXM_INDEX_FORMAT_U16, this->clearIndices, 4);
|
||||
if(new_scene) {
|
||||
sceGxmEndScene(this->context, nullptr, nullptr);
|
||||
@ -659,14 +691,6 @@ GXMRenderer::GXMRenderer(DWORD width, DWORD height)
|
||||
); ret < 0) {
|
||||
return;
|
||||
}
|
||||
if (ret = SCE_ERR(
|
||||
sceGxmShaderPatcherRegisterProgram,
|
||||
gxm->shaderPatcher,
|
||||
imageFragmentProgramGxp,
|
||||
&this->imageFragmentProgramId
|
||||
); ret < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// main shader
|
||||
{
|
||||
@ -770,40 +794,27 @@ GXMRenderer::GXMRenderer(DWORD width, DWORD height)
|
||||
return;
|
||||
}
|
||||
|
||||
// image
|
||||
if (ret = SCE_ERR(
|
||||
sceGxmShaderPatcherCreateFragmentProgram,
|
||||
gxm->shaderPatcher,
|
||||
this->imageFragmentProgramId,
|
||||
SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4,
|
||||
msaaMode,
|
||||
&blendInfoTransparent,
|
||||
mainVertexProgramGxp,
|
||||
&this->imageFragmentProgram
|
||||
); ret < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// vertex uniforms
|
||||
//this->uNormalMatrix = sceGxmProgramFindParameterByName(mainVertexProgramGxp, "uNormalMatrix");
|
||||
//this->uWorldViewProjection = sceGxmProgramFindParameterByName(mainVertexProgramGxp, "uWorldViewProjection");
|
||||
//this->uWorld = sceGxmProgramFindParameterByName(mainVertexProgramGxp, "uWorld");
|
||||
//this->uViewInverse = sceGxmProgramFindParameterByName(mainVertexProgramGxp, "uViewInverse");
|
||||
|
||||
this->uModelViewMatrix = sceGxmProgramFindParameterByName(mainVertexProgramGxp, "uModelViewMatrix");
|
||||
this->uNormalMatrix = sceGxmProgramFindParameterByName(mainVertexProgramGxp, "uNormalMatrix");
|
||||
this->uProjectionMatrix = sceGxmProgramFindParameterByName(mainVertexProgramGxp, "uProjectionMatrix");
|
||||
|
||||
// fragment uniforms
|
||||
this->color_uLights = sceGxmProgramFindParameterByName(mainColorFragmentProgramGxp, "uLights"); // SceneLight[3]
|
||||
this->color_uAmbientLight = sceGxmProgramFindParameterByName(mainColorFragmentProgramGxp, "uAmbientLight"); // vec3
|
||||
this->color_uShininess = sceGxmProgramFindParameterByName(mainColorFragmentProgramGxp, "uShininess"); // float
|
||||
this->color_uColor = sceGxmProgramFindParameterByName(mainColorFragmentProgramGxp, "uColor"); // vec4
|
||||
this->texture_uLights = sceGxmProgramFindParameterByName(mainTextureFragmentProgramGxp, "uLights"); // SceneLight[3]
|
||||
this->texture_uAmbientLight = sceGxmProgramFindParameterByName(mainTextureFragmentProgramGxp, "uAmbientLight"); // vec3
|
||||
this->texture_uShininess = sceGxmProgramFindParameterByName(mainTextureFragmentProgramGxp, "uShininess"); // float
|
||||
this->texture_uColor = sceGxmProgramFindParameterByName(mainTextureFragmentProgramGxp, "uColor"); // vec4
|
||||
this->uLights = sceGxmProgramFindParameterByName(mainColorFragmentProgramGxp, "uLights"); // SceneLight[2]
|
||||
this->uAmbientLight = sceGxmProgramFindParameterByName(mainColorFragmentProgramGxp, "uAmbientLight"); // vec3
|
||||
this->uShininess = sceGxmProgramFindParameterByName(mainColorFragmentProgramGxp, "uShininess"); // float
|
||||
this->uColor = sceGxmProgramFindParameterByName(mainColorFragmentProgramGxp, "uColor"); // vec4
|
||||
|
||||
for (int i = 0; i < GXM_FRAGMENT_BUFFER_COUNT; i++) {
|
||||
this->lights[i] = static_cast<GXMSceneLightUniform*>(gxm->alloc(sizeof(GXMSceneLightUniform), 4));
|
||||
}
|
||||
for (int i = 0; i < GXM_VERTEX_BUFFER_COUNT; i++) {
|
||||
this->quadVertices[i] = static_cast<Vertex*>(gxm->alloc(sizeof(Vertex) * 4 * 50, 4));
|
||||
this->quadVertices[i] = static_cast<Vertex2D*>(gxm->alloc(sizeof(Vertex2D) * 4 * 50, 4));
|
||||
}
|
||||
this->quadIndices = static_cast<uint16_t*>(gxm->alloc(sizeof(uint16_t) * 4, 4));
|
||||
this->quadIndices[0] = 0;
|
||||
@ -1407,15 +1418,17 @@ HRESULT GXMRenderer::BeginFrame()
|
||||
lightData->lights[i].color[2] = light.color.b;
|
||||
lightData->lights[i].color[3] = light.color.a;
|
||||
|
||||
lightData->lights[i].position[0] = light.position.x;
|
||||
lightData->lights[i].position[1] = light.position.y;
|
||||
lightData->lights[i].position[2] = light.position.z;
|
||||
lightData->lights[i].position[3] = light.positional;
|
||||
|
||||
lightData->lights[i].direction[0] = light.direction.x;
|
||||
lightData->lights[i].direction[1] = light.direction.y;
|
||||
lightData->lights[i].direction[2] = light.direction.z;
|
||||
lightData->lights[i].direction[3] = light.directional;
|
||||
bool isDirectional = light.directional == 1.0;
|
||||
if(isDirectional) {
|
||||
lightData->lights[i].vec[0] = light.direction.x;
|
||||
lightData->lights[i].vec[1] = light.direction.y;
|
||||
lightData->lights[i].vec[2] = light.direction.z;
|
||||
} else {
|
||||
lightData->lights[i].vec[0] = light.position.x;
|
||||
lightData->lights[i].vec[1] = light.position.y;
|
||||
lightData->lights[i].vec[2] = light.position.z;
|
||||
}
|
||||
lightData->lights[i].isDirectional = isDirectional;
|
||||
i++;
|
||||
}
|
||||
sceGxmSetFragmentUniformBuffer(gxm->context, 0, lightData);
|
||||
@ -1437,6 +1450,15 @@ static void transpose4x4(const float src[4][4], float dst[4][4])
|
||||
}
|
||||
}
|
||||
|
||||
static void transpose3x3(const float src[3][3], float dst[3][3])
|
||||
{
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
for (int j = 0; j < 3; ++j) {
|
||||
dst[j][i] = src[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const D3DRMMATRIX4D identity4x4 = {
|
||||
{1.0, 0.0, 0.0, 0.0},
|
||||
{0.0, 1.0, 0.0, 0.0},
|
||||
@ -1461,65 +1483,54 @@ void GXMRenderer::SubmitDraw(
|
||||
{
|
||||
auto& mesh = m_meshes[meshId];
|
||||
|
||||
#ifdef DEBUG
|
||||
char marker[256];
|
||||
snprintf(marker, sizeof(marker), "SubmitDraw: %d", meshId);
|
||||
sceGxmPushUserMarker(gxm->context, marker);
|
||||
#endif
|
||||
|
||||
sceGxmSetVertexProgram(gxm->context, this->mainVertexProgram);
|
||||
|
||||
bool textured = appearance.textureId != NO_TEXTURE_ID;
|
||||
|
||||
const SceGxmFragmentProgram *fragmentProgram;
|
||||
if(this->transparencyEnabled) {
|
||||
fragmentProgram = textured ? this->blendedTextureFragmentProgram : this->blendedColorFragmentProgram;
|
||||
} else {
|
||||
fragmentProgram = textured ? this->opaqueTextureFragmentProgram : this->opaqueColorFragmentProgram;
|
||||
}
|
||||
sceGxmSetVertexProgram(gxm->context, this->mainVertexProgram);
|
||||
sceGxmSetFragmentProgram(gxm->context, fragmentProgram);
|
||||
|
||||
const SceGxmProgramParameter* uColor = textured ? this->texture_uColor : this->color_uColor;
|
||||
const SceGxmProgramParameter* uShininess = textured ? this->texture_uShininess : this->color_uShininess;
|
||||
void* vertUniforms;
|
||||
void* fragUniforms;
|
||||
sceGxmReserveVertexDefaultUniformBuffer(gxm->context, &vertUniforms);
|
||||
sceGxmReserveFragmentDefaultUniformBuffer(gxm->context, &fragUniforms);
|
||||
|
||||
// vertex uniforms
|
||||
sceGxmSetUniformDataF(vertUniforms, this->uModelViewMatrix, 0, 4*4, &modelViewMatrix[0][0]);
|
||||
sceGxmSetUniformDataF(vertUniforms, this->uNormalMatrix, 0, 3*3, &normalMatrix[0][0]);
|
||||
sceGxmSetUniformDataF(vertUniforms, this->uProjectionMatrix, 0, 4*4, &this->m_projection[0][0]);
|
||||
|
||||
// fragment uniforms
|
||||
float color[4] = {
|
||||
appearance.color.r / 255.0f,
|
||||
appearance.color.g / 255.0f,
|
||||
appearance.color.b / 255.0f,
|
||||
appearance.color.a / 255.0f
|
||||
};
|
||||
|
||||
void* vertUniforms;
|
||||
void* fragUniforms;
|
||||
#ifdef GXM_PRECOMPUTE
|
||||
sceGxmSetPrecomputedVertexState(gxm->context, &mesh.vertexState[this->currentVertexBufferIndex]);
|
||||
sceGxmSetPrecomputedFragmentState(gxm->context, &mesh.fragmentState[this->currentFragmentBufferIndex]);
|
||||
vertUniforms = sceGxmPrecomputedVertexStateGetDefaultUniformBuffer(&mesh.vertexState[this->currentVertexBufferIndex]);
|
||||
fragUniforms = sceGxmPrecomputedFragmentStateGetDefaultUniformBuffer(&mesh.fragmentState[this->currentFragmentBufferIndex]);
|
||||
#else
|
||||
sceGxmReserveVertexDefaultUniformBuffer(gxm->context, &vertUniforms);
|
||||
sceGxmReserveFragmentDefaultUniformBuffer(gxm->context, &fragUniforms);
|
||||
#endif
|
||||
|
||||
SET_UNIFORM(vertUniforms, this->uModelViewMatrix, modelViewMatrix);
|
||||
SET_UNIFORM(vertUniforms, this->uProjectionMatrix, m_projection);
|
||||
sceGxmSetUniformDataF(vertUniforms, this->uNormalMatrix, 0, 9, static_cast<const float*>(normalMatrix[0]));
|
||||
|
||||
SET_UNIFORM(fragUniforms, uColor, color);
|
||||
SET_UNIFORM(fragUniforms, uShininess, appearance.shininess);
|
||||
sceGxmSetUniformDataF(fragUniforms, this->uColor, 0, 4, color);
|
||||
sceGxmSetUniformDataF(fragUniforms, this->uShininess, 0, 1, &appearance.shininess);
|
||||
|
||||
if (textured) {
|
||||
auto& texture = m_textures[appearance.textureId];
|
||||
this->UseTexture(texture);
|
||||
}
|
||||
|
||||
#ifdef GXM_PRECOMPUTE
|
||||
sceGxmDrawPrecomputed(gxm->context, &mesh.drawState);
|
||||
sceGxmSetPrecomputedVertexState(gxm->gxm->context, NULL);
|
||||
sceGxmSetPrecomputedFragmentState(gxm->context, NULL);
|
||||
#else
|
||||
sceGxmSetVertexStream(gxm->context, 0, mesh.vertexBuffer);
|
||||
sceGxmSetFrontDepthFunc(gxm->context, SCE_GXM_DEPTH_FUNC_LESS);
|
||||
sceGxmDraw(gxm->context, SCE_GXM_PRIMITIVE_TRIANGLES, SCE_GXM_INDEX_FORMAT_U16, mesh.indexBuffer, mesh.indexCount);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
sceGxmPopUserMarker(gxm->context);
|
||||
#endif
|
||||
}
|
||||
|
||||
HRESULT GXMRenderer::FinalizeFrame()
|
||||
@ -1564,15 +1575,17 @@ void GXMRenderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const S
|
||||
{
|
||||
this->StartScene();
|
||||
|
||||
#ifdef DEBUG
|
||||
char marker[256];
|
||||
snprintf(marker, sizeof(marker), "Draw2DImage: %d", textureId);
|
||||
sceGxmPushUserMarker(gxm->context, marker);
|
||||
#endif
|
||||
|
||||
sceGxmSetVertexProgram(gxm->context, this->mainVertexProgram);
|
||||
sceGxmSetVertexProgram(gxm->context, gxm->planeVertexProgram);
|
||||
if(textureId != NO_TEXTURE_ID) {
|
||||
sceGxmSetFragmentProgram(gxm->context, this->imageFragmentProgram);
|
||||
sceGxmSetFragmentProgram(gxm->context, gxm->imageFragmentProgram);
|
||||
} else {
|
||||
sceGxmSetFragmentProgram(gxm->context, gxm->clearFragmentProgram);
|
||||
sceGxmSetFragmentProgram(gxm->context, gxm->colorFragmentProgram);
|
||||
}
|
||||
|
||||
void* vertUniforms;
|
||||
@ -1585,8 +1598,8 @@ void GXMRenderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const S
|
||||
float top = -this->m_viewportTransform.offsetY / this->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)));
|
||||
#define virtualToNDCX(x) (((x - left) / (right - left)) * 2 - 1);
|
||||
#define virtualToNDCY(y) -(((y - top) / (bottom - top)) * 2 - 1);
|
||||
|
||||
float x1_virtual = static_cast<float>(dstRect.x);
|
||||
float y1_virtual = static_cast<float>(dstRect.y);
|
||||
@ -1598,25 +1611,6 @@ void GXMRenderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const S
|
||||
float x2 = virtualToNDCX(x2_virtual);
|
||||
float y2 = virtualToNDCY(y2_virtual);
|
||||
|
||||
D3DRMMATRIX4D projection;
|
||||
CreateOrthoMatrix(0.0, 1.0, 1.0, 0.0, projection);
|
||||
static const Matrix3x3 normal = {
|
||||
{1.f, 0.f, 0.f},
|
||||
{0.f, 1.f, 0.f},
|
||||
{0.f, 0.f, 1.f}
|
||||
};
|
||||
|
||||
D3DRMMATRIX4D 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;
|
||||
|
||||
SET_UNIFORM(vertUniforms, this->uModelViewMatrix, identity); // float4x4
|
||||
SET_UNIFORM(vertUniforms, this->uNormalMatrix, normal); // float3x3
|
||||
SET_UNIFORM(vertUniforms, this->uProjectionMatrix, projection); // float4x4
|
||||
|
||||
float u1 = 0.0;
|
||||
float v1 = 0.0;
|
||||
float u2 = 0.0;
|
||||
@ -1633,21 +1627,25 @@ void GXMRenderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const S
|
||||
u2 = static_cast<float>(srcRect.x + srcRect.w) / texW;
|
||||
v2 = static_cast<float>(srcRect.y + srcRect.h) / texH;
|
||||
} else {
|
||||
SET_UNIFORM(fragUniforms, gxm->clear_uColor, color);
|
||||
SET_UNIFORM(fragUniforms, gxm->color_uColor, color);
|
||||
}
|
||||
|
||||
Vertex* quadVertices = this->QuadVerticesBuffer();
|
||||
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[2] = Vertex{.position = {x1, y2, 0}, .normal = {0, 0, 0}, .texCoord = {u1, v2}};
|
||||
quadVertices[3] = Vertex{.position = {x2, y2, 0}, .normal = {0, 0, 0}, .texCoord = {u2, v2}};
|
||||
Vertex2D* quadVertices = this->QuadVerticesBuffer();
|
||||
quadVertices[0] = Vertex2D{.position = {x1, y1}, .texCoord = {u1, v1}};
|
||||
quadVertices[1] = Vertex2D{.position = {x2, y1}, .texCoord = {u2, v1}};
|
||||
quadVertices[2] = Vertex2D{.position = {x1, y2}, .texCoord = {u1, v2}};
|
||||
quadVertices[3] = Vertex2D{.position = {x2, y2}, .texCoord = {u2, v2}};
|
||||
|
||||
sceGxmSetVertexStream(gxm->context, 0, quadVertices);
|
||||
|
||||
sceGxmSetFrontDepthWriteEnable(gxm->context, SCE_GXM_DEPTH_WRITE_DISABLED);
|
||||
sceGxmSetFrontDepthFunc(gxm->context, SCE_GXM_DEPTH_FUNC_ALWAYS);
|
||||
sceGxmDraw(gxm->context, SCE_GXM_PRIMITIVE_TRIANGLE_STRIP, SCE_GXM_INDEX_FORMAT_U16, this->quadIndices, 4);
|
||||
sceGxmSetFrontDepthWriteEnable(gxm->context, SCE_GXM_DEPTH_WRITE_ENABLED);
|
||||
|
||||
#ifdef DEBUG
|
||||
sceGxmPopUserMarker(gxm->context);
|
||||
#endif
|
||||
}
|
||||
|
||||
void GXMRenderer::SetDither(bool dither)
|
||||
@ -1665,8 +1663,8 @@ void GXMRenderer::Download(SDL_Surface* target)
|
||||
SDL_Surface* src = SDL_CreateSurfaceFrom(
|
||||
VITA_GXM_SCREEN_WIDTH,
|
||||
VITA_GXM_SCREEN_HEIGHT,
|
||||
SDL_PIXELFORMAT_RGBA8888,
|
||||
gxm->displayBuffers[gxm->frontBufferIndex],
|
||||
SDL_PIXELFORMAT_BGRA8888,
|
||||
gxm->displayBuffers[gxm->backBufferIndex],
|
||||
VITA_GXM_SCREEN_STRIDE*4
|
||||
);
|
||||
SDL_BlitSurfaceScaled(src, &srcRect, target, nullptr, SDL_SCALEMODE_NEAREST);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
shaders += clear.vert.gxp clear.frag.gxp image.frag.gxp
|
||||
shaders += plane.vert.gxp color.frag.gxp image.frag.gxp
|
||||
shaders += main.vert.gxp main.color.frag.gxp main.texture.frag.gxp
|
||||
|
||||
PERFS = $(shaders:.gxp=.perf.txt)
|
||||
@ -24,4 +24,4 @@ main.texture.frag.gxp: main.frag.cg | cache
|
||||
./psp2cgc.exe $(CGCFLAGS) -DTEXTURED=1 -profile sce_fp_psp2 $< -o $@
|
||||
|
||||
%.perf.txt: %.gxp
|
||||
./psp2shaderperf.exe -disasm $< > $@
|
||||
./psp2shaderperf.exe -stats -symbols -disasm $< > $@
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
|
||||
float4 main(float2 aPosition : POSITION) : POSITION
|
||||
{
|
||||
return float4(aPosition, 1.f, 1.f);
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@ -1,8 +1,6 @@
|
||||
void main(
|
||||
float4 vPosition : POSITION,
|
||||
float3 vViewPos : TEXCOORD1,
|
||||
float3 vNormal : TEXCOORD2,
|
||||
float2 vTexCoord : TEXCOORD3,
|
||||
float2 vTexCoord : TEXCOORD0,
|
||||
|
||||
uniform sampler2D uTexture,
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@ -1,7 +1,7 @@
|
||||
struct SceneLight {
|
||||
float4 color;
|
||||
float4 position;
|
||||
float4 direction;
|
||||
float4 vec;
|
||||
float isDirectional;
|
||||
};
|
||||
|
||||
void main(
|
||||
@ -27,30 +27,21 @@ void main(
|
||||
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
float3 lightColor = uLights[i].color.rgb;
|
||||
float isDirectional = uLights[i].direction.w;
|
||||
float isPositional = uLights[i].position.w;
|
||||
float isDirectional = uLights[i].isDirectional;
|
||||
|
||||
// TODO: make faster by removing the if statements
|
||||
// directional
|
||||
float3 lightVec;
|
||||
if (isDirectional) {
|
||||
lightVec = -normalize(uLights[i].direction.xyz);
|
||||
} else {
|
||||
lightVec = uLights[i].position.xyz - vViewPos;
|
||||
}
|
||||
lightVec = normalize(lightVec);
|
||||
float3 lightVec = normalize(lerp(uLights[i].vec.xyz - vViewPos, -uLights[i].vec.xyz, isDirectional));
|
||||
|
||||
float3 halfVec = normalize(viewVec + lightVec);
|
||||
float dotNL = max(dot(vNormal, lightVec), 0.0);
|
||||
float dotNH = max(dot(vNormal, halfVec), 0.0);
|
||||
|
||||
// Diffuse contribution
|
||||
float dotNL = max(dot(vNormal, lightVec), 0.0);
|
||||
diffuse += dotNL * lightColor;
|
||||
|
||||
// Specular
|
||||
//float enableSpec = (dotNL > 0.0) * (uShininess > 0.0);
|
||||
if (dotNL > 0.0 && uShininess > 0.0) {
|
||||
float3 halfVec = normalize(lightVec + viewVec);
|
||||
float dotNH = max(dot(vNormal, halfVec), 0.0);
|
||||
float spec = pow(dotNH, uShininess);
|
||||
specular += spec * lightColor;
|
||||
float spec = pow(dotNH, uShininess);
|
||||
if(uShininess > 0.0) {
|
||||
specular += spec * lightColor * sign(dotNL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
11
miniwin/src/d3drm/backends/gxm/shaders/plane.vert.cg
Normal file
11
miniwin/src/d3drm/backends/gxm/shaders/plane.vert.cg
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
void main(
|
||||
float2 aPosition : POSITION,
|
||||
float2 aTexCoord : TEXCOORD0,
|
||||
|
||||
out float4 vPosition : POSITION,
|
||||
out float2 vTexCoord : TEXCOORD0
|
||||
) : POSITION {
|
||||
vPosition = float4(aPosition, 1.f, 1.f);
|
||||
vTexCoord = aTexCoord;
|
||||
}
|
||||
BIN
miniwin/src/d3drm/backends/gxm/shaders/plane.vert.gxp
Normal file
BIN
miniwin/src/d3drm/backends/gxm/shaders/plane.vert.gxp
Normal file
Binary file not shown.
@ -56,12 +56,11 @@ typedef struct GXMDisplayData {
|
||||
|
||||
struct SceneLightGXM {
|
||||
float color[4];
|
||||
float position[4];
|
||||
float direction[4];
|
||||
float vec[4];
|
||||
float isDirectional;
|
||||
float _align;
|
||||
};
|
||||
|
||||
static_assert(sizeof(SceneLightGXM) == 4*4*3);
|
||||
|
||||
struct GXMSceneLightUniform {
|
||||
SceneLightGXM lights[2];
|
||||
float ambientLight[3];
|
||||
@ -121,8 +120,8 @@ class GXMRenderer : public Direct3DRMRenderer {
|
||||
return gxmTexture;
|
||||
}
|
||||
|
||||
inline Vertex* QuadVerticesBuffer() {
|
||||
Vertex* verts = &this->quadVertices[this->currentVertexBufferIndex][this->quadsUsed*4];
|
||||
inline Vertex2D* QuadVerticesBuffer() {
|
||||
Vertex2D* verts = &this->quadVertices[this->currentVertexBufferIndex][this->quadsUsed*4];
|
||||
this->quadsUsed += 1;
|
||||
if(this->quadsUsed >= 50) {
|
||||
SDL_Log("QuadVerticesBuffer overflow");
|
||||
@ -146,35 +145,32 @@ class GXMRenderer : public Direct3DRMRenderer {
|
||||
SceGxmShaderPatcherId mainVertexProgramId;
|
||||
SceGxmShaderPatcherId mainColorFragmentProgramId;
|
||||
SceGxmShaderPatcherId mainTextureFragmentProgramId;
|
||||
SceGxmShaderPatcherId imageFragmentProgramId;
|
||||
|
||||
SceGxmVertexProgram* mainVertexProgram;
|
||||
// with lighting
|
||||
SceGxmFragmentProgram* opaqueColorFragmentProgram;
|
||||
SceGxmFragmentProgram* blendedColorFragmentProgram;
|
||||
SceGxmFragmentProgram* opaqueTextureFragmentProgram;
|
||||
SceGxmFragmentProgram* blendedTextureFragmentProgram;
|
||||
// no lighting
|
||||
SceGxmFragmentProgram* imageFragmentProgram;
|
||||
|
||||
// main shader vertex uniforms
|
||||
//const SceGxmProgramParameter* uNormalMatrix;
|
||||
//const SceGxmProgramParameter* uWorldViewProjection;
|
||||
//const SceGxmProgramParameter* uWorld;
|
||||
//const SceGxmProgramParameter* uViewInverse;
|
||||
const SceGxmProgramParameter* uModelViewMatrix;
|
||||
const SceGxmProgramParameter* uNormalMatrix;
|
||||
const SceGxmProgramParameter* uProjectionMatrix;
|
||||
|
||||
|
||||
// main shader fragment uniforms
|
||||
const SceGxmProgramParameter* color_uLights;
|
||||
const SceGxmProgramParameter* color_uAmbientLight;
|
||||
const SceGxmProgramParameter* color_uShininess;
|
||||
const SceGxmProgramParameter* color_uColor;
|
||||
const SceGxmProgramParameter* texture_uLights;
|
||||
const SceGxmProgramParameter* texture_uAmbientLight;
|
||||
const SceGxmProgramParameter* texture_uShininess;
|
||||
const SceGxmProgramParameter* texture_uColor;
|
||||
const SceGxmProgramParameter* uShininess;
|
||||
const SceGxmProgramParameter* uColor;
|
||||
const SceGxmProgramParameter* uLights;
|
||||
const SceGxmProgramParameter* uAmbientLight;
|
||||
|
||||
// uniforms / quad meshes
|
||||
GXMSceneLightUniform* lights[GXM_FRAGMENT_BUFFER_COUNT];
|
||||
Vertex* quadVertices[GXM_VERTEX_BUFFER_COUNT];
|
||||
Vertex2D* quadVertices[GXM_VERTEX_BUFFER_COUNT];
|
||||
uint16_t* quadIndices;
|
||||
int quadsUsed = 0;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user