Created
July 5, 2018 07:43
-
-
Save wwylele/543f1d82b045077b05fe8f1160fe27c5 to your computer and use it in GitHub Desktop.
proctex mipmap 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 <tex3ds.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#include "vshader_shbin.h" | |
#define CLEAR_COLOR 0x68B0D8FF | |
#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 position[3]; float texcoord[2]; float normal[3]; } vertex; | |
static const vertex vertex_list[] = | |
{ | |
// First face (PZ) | |
// First triangle | |
{ {-1.0f, -0.5f, -6.0f}, {0.0f, 0.0f}, {0.0f, 0.0f, +1.0f} }, | |
{ {+1.0f, -0.5f, +0.5f}, {1.0f, 1.0f}, {0.0f, 0.0f, +1.0f} }, | |
{ {+1.0f, -0.5f, -6.0f}, {1.0f, 0.0f}, {0.0f, 0.0f, +1.0f} }, | |
// Second triangle | |
{ {+1.0f, -0.5f, +0.5f}, {1.0f, 1.0f}, {0.0f, 0.0f, +1.0f} }, | |
{ {-1.0f, -0.5f, -6.0f}, {0.0f, 0.0f}, {0.0f, 0.0f, +1.0f} }, | |
{ {-1.0f, -0.5f, +0.5f}, {0.0f, 1.0f}, {0.0f, 0.0f, +1.0f} }, | |
}; | |
#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_modelView; | |
static int uLoc_lightVec, uLoc_lightHalfVec, uLoc_lightClr, uLoc_material; | |
static C3D_Mtx projection; | |
static C3D_Mtx material = | |
{ | |
{ | |
{ { 0.0f, 0.2f, 0.2f, 0.2f } }, // Ambient | |
{ { 0.0f, 0.4f, 0.4f, 0.4f } }, // Diffuse | |
{ { 0.0f, 0.8f, 0.8f, 0.8f } }, // Specular | |
{ { 1.0f, 0.0f, 0.0f, 0.0f } }, // Emission | |
} | |
}; | |
static void* vbo_data; | |
static C3D_Tex logo_tex; | |
float bias = 0.0f; | |
bool linear = false; | |
static C3D_ProcTex pt; | |
static C3D_ProcTexLut pt_map; | |
static C3D_ProcTexLut pt_noise; | |
static C3D_ProcTexColorLut pt_clr; | |
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_modelView = shaderInstanceGetUniformLocation(program.vertexShader, "modelView"); | |
uLoc_lightVec = shaderInstanceGetUniformLocation(program.vertexShader, "lightVec"); | |
uLoc_lightHalfVec = shaderInstanceGetUniformLocation(program.vertexShader, "lightHalfVec"); | |
uLoc_lightClr = shaderInstanceGetUniformLocation(program.vertexShader, "lightClr"); | |
uLoc_material = shaderInstanceGetUniformLocation(program.vertexShader, "material"); | |
// 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_AddLoader(attrInfo, 1, GPU_FLOAT, 2); // v1=texcoord | |
AttrInfo_AddLoader(attrInfo, 2, GPU_FLOAT, 3); // v2=normal | |
// Compute the projection matrix | |
Mtx_PerspTilt(&projection, C3D_AngleFromDegrees(80.0f), C3D_AspectRatioTop, 0.01f, 20.0f, false); | |
// 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), 3, 0x210); | |
C3D_ProcTexInit(&pt, 0, 128); | |
C3D_ProcTexClamp(&pt, GPU_PT_MIRRORED_REPEAT, GPU_PT_MIRRORED_REPEAT); | |
C3D_ProcTexCombiner(&pt, false, GPU_PT_ADD2, GPU_PT_ADD2); | |
float data[129]; | |
int i; | |
for (i = 0; i <= 128; i ++) | |
{ | |
float x = i/128.0f; | |
data[i] = fabsf(sinf(C3D_Angle(6*(x+0.125f)))); // 6*2 = 12 stripes | |
} | |
ProcTexLut_FromArray(&pt_map, data); | |
C3D_ProcTexLutBind(GPU_LUT_RGBMAP, &pt_map); | |
// Noise smooth step equation | |
for (i = 0; i <= 128; i ++) | |
{ | |
float x = i/128.0f; | |
data[i] = x*x*(3-2*x); | |
} | |
ProcTexLut_FromArray(&pt_noise, data); | |
C3D_ProcTexLutBind(GPU_LUT_NOISE, &pt_noise); | |
u32 mipmap_color[8] = { | |
0xFFFF0000, | |
0xFF00FF00, | |
0xFF0000FF, | |
0xFFFFFF00, | |
0xFFFF00FF, | |
0xFF00FFFF, | |
0xFFFFFFFF, | |
0xFF000000, | |
}; | |
u32* pcolor = pt_clr.color; | |
u32 width = 128; | |
for (u32 level = 0; level < 7; ++level, pcolor += width, width /= 2) { | |
for (u32 i = 0; i < width/2; ++i) { | |
pcolor[i] = mipmap_color[level]; | |
} | |
for (u32 i = width/2; i < width; ++i) { | |
pcolor[i] = 0xFF888888; | |
} | |
} | |
memset(pt_clr.diff, 0, sizeof(pt_clr.diff)); | |
C3D_ProcTexColorLutBind(&pt_clr); | |
// Configure the first fragment shading substage to blend the texture color with | |
// the vertex color (calculated by the vertex shader using a lighting algorithm) | |
// See https://www.opengl.org/sdk/docs/man2/xhtml/glTexEnv.xml for more insight | |
C3D_TexEnv* env = C3D_GetTexEnv(0); | |
C3D_TexEnvInit(env); | |
C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE3, GPU_PRIMARY_COLOR, 0); | |
C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE); | |
} | |
static void sceneRender(void) | |
{ | |
// Calculate the modelView matrix | |
C3D_Mtx modelView; | |
Mtx_Identity(&modelView); | |
Mtx_Translate(&modelView, 0.0, 0.0, -1.1, true); | |
// Update the uniforms | |
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, uLoc_projection, &projection); | |
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, uLoc_modelView, &modelView); | |
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, uLoc_material, &material); | |
C3D_FVUnifSet(GPU_VERTEX_SHADER, uLoc_lightVec, 0.0f, 0.0f, -1.0f, 0.0f); | |
C3D_FVUnifSet(GPU_VERTEX_SHADER, uLoc_lightHalfVec, 0.0f, 0.0f, -1.0f, 0.0f); | |
C3D_FVUnifSet(GPU_VERTEX_SHADER, uLoc_lightClr, 1.0f, 1.0f, 1.0f, 1.0f); | |
C3D_ProcTexLodBias(&pt, bias); | |
C3D_ProcTexFilter(&pt, linear ? GPU_PT_NEAREST_MIP_LINEAR : GPU_PT_NEAREST_MIP_NEAREST); | |
C3D_ProcTexBind(0, &pt); | |
static float phase = 0; | |
C3D_ProcTexNoiseCoefs(&pt, C3D_ProcTex_UV, 0.1f, 0.3f, phase); | |
phase += 0.001f; | |
// Draw the VBO | |
C3D_DrawArrays(GPU_TRIANGLES, 0, vertex_list_count); | |
} | |
static void sceneExit(void) | |
{ | |
// Free the texture | |
C3D_TexDelete(&logo_tex); | |
// Free the VBO | |
linearFree(vbo_data); | |
// Free the shader program | |
shaderProgramFree(&program); | |
DVLB_Free(vshader_dvlb); | |
} | |
int main() | |
{ | |
// Initialize graphics | |
gfxInitDefault(); | |
consoleInit(GFX_BOTTOM, NULL); | |
C3D_Init(C3D_DEFAULT_CMDBUF_SIZE); | |
// Initialize the render target | |
C3D_RenderTarget* target = C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8); | |
C3D_RenderTargetSetOutput(target, GFX_TOP, GFX_LEFT, DISPLAY_TRANSFER_FLAGS); | |
// 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) { | |
linear = !linear; | |
} | |
if (kDown & KEY_B) { | |
bias = 0; | |
} | |
if (kDown & KEY_X) { | |
bias += 0.2f; | |
} | |
if (kDown & KEY_Y) { | |
bias -= 0.2f; | |
} | |
// Render the scene | |
C3D_FrameBegin(C3D_FRAME_SYNCDRAW); | |
C3D_RenderTargetClear(target, C3D_CLEAR_ALL, CLEAR_COLOR, 0); | |
C3D_FrameDrawOn(target); | |
sceneRender(); | |
C3D_FrameEnd(0); | |
} | |
// 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], modelView[4] | |
.fvec lightVec, lightHalfVec, lightClr, material[4] | |
.alias mat_amb material[0] | |
.alias mat_dif material[1] | |
.alias mat_spe material[2] | |
.alias mat_emi material[3] | |
; Constants | |
.constf myconst(0.0, 1.0, -1.0, -0.5) | |
.alias zeros myconst.xxxx ; Vector full of zeros | |
.alias ones myconst.yyyy ; Vector full of ones | |
; Outputs | |
.out outpos position | |
.out outtc0 texcoord0 | |
.out outclr color | |
; Inputs (defined as aliases for convenience) | |
.alias inpos v0 | |
.alias intex v1 | |
.alias innrm v2 | |
.proc main | |
; Force the w component of inpos to be 1.0 | |
mov r0.xyz, inpos | |
mov r0.w, ones | |
; r1 = modelView * inpos | |
dp4 r1.x, modelView[0], r0 | |
dp4 r1.y, modelView[1], r0 | |
dp4 r1.z, modelView[2], r0 | |
dp4 r1.w, modelView[3], r0 | |
; outpos = projection * r1 | |
dp4 outpos.x, projection[0], r1 | |
dp4 outpos.y, projection[1], r1 | |
dp4 outpos.z, projection[2], r1 | |
dp4 outpos.w, projection[3], r1 | |
; outtex = intex | |
mov outtc0, intex | |
; Transform the normal vector with the modelView matrix | |
; r1 = normalize(modelView * innrm) | |
mov r0.xyz, innrm | |
mov r0.w, zeros | |
dp4 r1.x, modelView[0], r0 | |
dp4 r1.y, modelView[1], r0 | |
dp4 r1.z, modelView[2], r0 | |
mov r1.w, zeros | |
dp3 r2, r1, r1 ; r2 = x^2+y^2+z^2 for each component | |
rsq r2, r2 ; r2 = 1/sqrt(r2) '' | |
mul r1, r2, r1 ; r1 = r1*r2 | |
; Calculate the diffuse level (r0.x) and the shininess level (r0.y) | |
; r0.x = max(0, -(lightVec * r1)) | |
; r0.y = max(0, (-lightHalfVec[i]) * r1) ^ 2 | |
dp3 r0.x, lightVec, r1 | |
add r0.x, zeros, -r0 | |
dp3 r0.y, -lightHalfVec, r1 | |
max r0, zeros, r0 | |
mul r0.y, r0, r0 | |
; Accumulate the vertex color in r1, initializing it to the emission color | |
mov r1, mat_emi | |
; r1 += specularColor * lightClr * shininessLevel | |
mul r2, lightClr, r0.yyyy | |
mad r1, r2, mat_spe, r1 | |
; r1 += diffuseColor * lightClr * diffuseLevel | |
mul r2, lightClr, r0.xxxx | |
mad r1, r2, mat_dif, r1 | |
; r1 += ambientColor * lightClr | |
mov r2, lightClr | |
mad r1, r2, mat_amb, r1 | |
; outclr = clamp r1 to [0,1] | |
min outclr, ones, r1 | |
; We're finished | |
end | |
.end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment