Created
March 12, 2018 11:14
-
-
Save wwylele/8d35017e6b9d54e243007a4201422b4b to your computer and use it in GitHub Desktop.
shadow map test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <3ds.h> | |
#include <citro3d.h> | |
#include <string.h> | |
#include "vshader_shbin.h" | |
#include <stdio.h> | |
#define CLEAR_COLOR 0xFFB0D8D5 | |
#define DISPLAY_TRANSFER_FLAGS \ | |
(GX_TRANSFER_FLIP_VERT(0) | GX_TRANSFER_OUT_TILED(0) | GX_TRANSFER_RAW_COPY(0) | \ | |
GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGBA8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGB8) | \ | |
GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO)) | |
typedef struct { float x, y, z; } vertex; | |
static const vertex vertex_list[] = | |
{ | |
{ 200.0f, 200.0f, 0.5f }, | |
{ 100.0f, 40.0f, 0.5f }, | |
{ 300.0f, 40.0f, 0.5f }, | |
}; | |
#define vertex_list_count (sizeof(vertex_list)/sizeof(vertex_list[0])) | |
static DVLB_s* vshader_dvlb; | |
static shaderProgram_s program; | |
static int uLoc_projection, uLoc_depth; | |
static C3D_Mtx projection; | |
static void* vbo_data; | |
int d = 2, s = 0; | |
int D = 10, S = 10; | |
int bb = 10, ss = 0; | |
int BB = 10, SS = 10; | |
static void sceneInit(void) | |
{ | |
// Load the vertex shader, create a shader program and bind it | |
vshader_dvlb = DVLB_ParseFile((u32*)vshader_shbin, vshader_shbin_size); | |
shaderProgramInit(&program); | |
shaderProgramSetVsh(&program, &vshader_dvlb->DVLE[0]); | |
C3D_BindProgram(&program); | |
// Get the location of the uniforms | |
uLoc_projection = shaderInstanceGetUniformLocation(program.vertexShader, "projection"); | |
uLoc_depth = shaderInstanceGetUniformLocation(program.vertexShader, "depth"); | |
// Configure attributes for use with the vertex shader | |
C3D_AttrInfo* attrInfo = C3D_GetAttrInfo(); | |
AttrInfo_Init(attrInfo); | |
AttrInfo_AddLoader(attrInfo, 0, GPU_FLOAT, 3); // v0=position | |
AttrInfo_AddFixed(attrInfo, 1); // v1=color | |
// Compute the projection matrix | |
Mtx_OrthoTilt(&projection, 0.0, 400.0, 0.0, 240.0, 0.0, 1.0, true); | |
// Create the VBO (vertex buffer object) | |
vbo_data = linearAlloc(sizeof(vertex_list)); | |
memcpy(vbo_data, vertex_list, sizeof(vertex_list)); | |
// Configure buffers | |
C3D_BufInfo* bufInfo = C3D_GetBufInfo(); | |
BufInfo_Init(bufInfo); | |
BufInfo_Add(bufInfo, vbo_data, sizeof(vertex), 1, 0x0); | |
// Configure the first fragment shading substage to just pass through the vertex color | |
// See https://www.opengl.org/sdk/docs/man2/xhtml/glTexEnv.xml for more insight | |
C3D_TexEnv* env = C3D_GetTexEnv(0); | |
C3D_TexEnvSrc(env, C3D_Both, GPU_PRIMARY_COLOR, 0, 0); | |
C3D_TexEnvOp(env, C3D_Both, 0, 0, 0); | |
C3D_TexEnvFunc(env, C3D_Both, GPU_REPLACE); | |
} | |
C3D_Tex renderBuffer; | |
unsigned char* result; | |
static void sceneRender(void) | |
{ | |
// Update the uniforms | |
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, uLoc_projection, &projection); | |
C3D_FVUnifSet(GPU_VERTEX_SHADER, uLoc_depth, (float)d/D, 0.0f, 0.0f, 0.0f); | |
C3D_FragOpMode(GPU_FRAGOPMODE_SHADOW); | |
// Set the fixed attribute (color) | |
C3D_FixedAttribSet(1, 1.0, (float)s/S, 1.0, 1.0); | |
C3D_DepthMap(false, -1.0f, 0.0f); | |
C3D_DepthTest(false, 0, 0); | |
C3D_FragOpShadow((float)ss / SS, (float)bb / BB); | |
// Draw the VBO | |
C3D_DrawArrays(GPU_TRIANGLES, 0, vertex_list_count); | |
C3D_FrameSplit(0); | |
GX_TextureCopy(renderBuffer.data, 0, (u32*)result, 0, 16 * 16 * 4, 8); | |
} | |
static void sceneExit(void) | |
{ | |
// Free the VBO | |
linearFree(vbo_data); | |
// Free the shader program | |
shaderProgramFree(&program); | |
DVLB_Free(vshader_dvlb); | |
} | |
void Decode(const unsigned char* data, float* d, float* s) { | |
*d = (data[0] * 65536 + data[1] * 256 + data[2]) / 16777215.0f; | |
*s = data[3] / 255.0f; | |
} | |
void updateText() { | |
consoleClear(); | |
unsigned char* data = result; | |
float d0, s0, d1, s1; | |
GSPGPU_InvalidateDataCache(data, 16 * 16 * 4); | |
Decode(data, &d0, &s0); | |
Decode(data + 8 * 8 * 3 * 4, &d1, &s1); | |
float scale = (float)ss / SS, bias = (float)bb / BB; | |
printf("scale=%f, bias=%f\n", scale, bias); | |
printf("before: d=%f, s=%f\n", d0, s0); | |
float draw_d = (float)d/D, draw_s = (float)s/S; | |
printf("draw: d=%f, s=%f\n", draw_d, draw_s); | |
printf("after: d=%f, s=%f\n", d1, s1); | |
float st = 1 / (bias + scale * (1 - draw_d / d0)); | |
st *= draw_s; | |
if (st < 0) st = 0; | |
if (st > s0) st = s0; | |
printf("s theory = %f\n", st); | |
} | |
static PrintConsole bottomScreen; | |
int main() | |
{ | |
result = linearAlloc(16 * 16 * 4); | |
// Initialize graphics | |
gfxInitDefault(); | |
consoleInit(GFX_BOTTOM, &bottomScreen); | |
consoleSelect(&bottomScreen); | |
gfxSetDoubleBuffering(GFX_BOTTOM, true); | |
C3D_Init(C3D_DEFAULT_CMDBUF_SIZE); | |
C3D_TexInitVRAM(&renderBuffer, 16, 16, GPU_RGBA8); | |
// Initialize the render target | |
C3D_RenderTarget* target = C3D_RenderTargetCreateFromTex(&renderBuffer, GPU_TEXFACE_2D, 0, -1); | |
C3D_RenderTargetSetClear(target, C3D_CLEAR_COLOR, CLEAR_COLOR, 0); | |
// Initialize the scene | |
sceneInit(); | |
// Main loop | |
while (aptMainLoop()) | |
{ | |
hidScanInput(); | |
// Respond to user input | |
u32 kDown = hidKeysDown(); | |
if (kDown & KEY_START) | |
break; // break in order to return to hbmenu | |
if (kDown & KEY_A) { | |
d++; | |
if (d == D+1) | |
d = 0; | |
} | |
if (kDown & KEY_B) { | |
s++; | |
if (s == S+1) | |
s = 0; | |
} | |
if (kDown & KEY_X) { | |
ss++; | |
if (ss == SS * 2 + 1) | |
ss = -SS * 2; | |
} | |
if (kDown & KEY_Y) { | |
bb++; | |
if (bb == BB * 2 + 1) | |
bb = -BB * 2; | |
} | |
// Render the scene | |
C3D_FrameBegin(C3D_FRAME_SYNCDRAW); | |
C3D_FrameDrawOn(target); | |
sceneRender(); | |
C3D_FrameEnd(0); | |
static int k = 0; | |
if (k == 4)updateText(); | |
++k; | |
k %= 8; | |
} | |
// Deinitialize the scene | |
sceneExit(); | |
// Deinitialize graphics | |
C3D_Fini(); | |
gfxExit(); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; Example PICA200 vertex shader | |
; Uniforms | |
.fvec projection[4] | |
.fvec depth | |
; Constants | |
.constf myconst(0.0, 1.0, -1.0, 0.1) | |
.constf myconst2(0.3, 0.0, 0.0, 0.0) | |
.alias zeros myconst.xxxx ; Vector full of zeros | |
.alias ones myconst.yyyy ; Vector full of ones | |
; Outputs | |
.out outpos position | |
.out outclr color | |
; Inputs (defined as aliases for convenience) | |
.alias inpos v0 | |
.alias inclr v1 | |
.bool test | |
.proc main | |
; Force the w component of inpos to be 1.0 | |
mov r0.xyz, inpos | |
mov r0.w, ones | |
; outpos = projectionMatrix * inpos | |
dp4 outpos.x, projection[0], r0 | |
dp4 outpos.y, projection[1], r0 | |
;dp4 outpos.z, projection[2], r0 | |
mov outpos.z, -depth.x | |
dp4 outpos.w, projection[3], r0 | |
; outclr = inclr | |
mov outclr, inclr | |
; We're finished | |
end | |
.end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment