Last active
May 27, 2017 07:17
-
-
Save yuriks/e5b9fbacbc558587525fb22733a14fa1 to your computer and use it in GitHub Desktop.
Quaternion Interpolation 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" | |
#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; | |
#define COS_70 0.34202f | |
#define SIN_70 0.93969f | |
#define COS_80 0.17364f | |
#define SIN_80 0.98480f | |
#define COS_85 0.08716f | |
#define SIN_85 0.99619f | |
#define COS_T COS_70 | |
#define SIN_T SIN_70 | |
static const vertex vertex_list[] = | |
{ | |
// First face (PZ) | |
// First triangle | |
{ {-1.0f, -1.0f, +0.0f}, {0.0f, 0.0f}, {-SIN_T, 0.0f, -COS_T} }, | |
{ {+1.0f, -1.0f, +0.0f}, {1.0f, 0.0f}, { SIN_T, 0.0f, -COS_T} }, | |
{ {+1.0f, +1.0f, +0.0f}, {1.0f, 1.0f}, { SIN_T, 0.0f, -COS_T} }, | |
// Second triangle | |
{ {+1.0f, +1.0f, +0.0f}, {1.0f, 1.0f}, {0.0f, SIN_T, -COS_T} }, | |
{ {-1.0f, +1.0f, +0.0f}, {0.0f, 1.0f}, {0.0f, -SIN_T, -COS_T} }, | |
{ {-1.0f, -1.0f, +0.0f}, {0.0f, 0.0f}, {0.0f, -SIN_T, -COS_T} }, | |
}; | |
#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 C3D_Mtx projection; | |
static C3D_LightEnv lightEnv; | |
static C3D_Light light; | |
static C3D_LightLut lut_Identity; | |
static void* vbo_data; | |
static float quantizeFloat(float x, float steps) { | |
float i = truncf(x * steps); | |
return (float)i * (1.0f / steps); | |
} | |
static float identityFunc(float x, float param) { | |
//x = acosf(x); | |
x = quantizeFloat(fabs(x), param); | |
return x; | |
} | |
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"); | |
// 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 | |
// 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); | |
// Configure the first fragment shading substage to blend the fragment primary color | |
// with the fragment secondary 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_FRAGMENT_SECONDARY_COLOR, GPU_FRAGMENT_SECONDARY_COLOR, 0); | |
C3D_TexEnvOp(env, C3D_Both, 0, 0, 0); | |
C3D_TexEnvFunc(env, C3D_Both, GPU_REPLACE); | |
static const C3D_Material material = | |
{ | |
{ 0.0f, 0.0f, 0.0f }, //ambient | |
{ 0.0f, 0.0f, 0.0f }, //diffuse | |
{ 1.0f, 1.0f, 1.0f }, //specular0 | |
{ 0.0f, 0.0f, 0.0f }, //specular1 | |
{ 0.0f, 0.0f, 0.0f }, //emission | |
}; | |
C3D_LightEnvInit(&lightEnv); | |
C3D_LightEnvBind(&lightEnv); | |
C3D_LightEnvMaterial(&lightEnv, &material); | |
LightLut_FromFunc(&lut_Identity, identityFunc, 10.0f, true); | |
C3D_LightEnvLut(&lightEnv, GPU_LUT_D0, GPU_LUTINPUT_LN, false, &lut_Identity); | |
C3D_FVec lightVec = FVec4_New(0.0, 0.0, -1.0, 0.0); | |
C3D_LightInit(&light, &lightEnv); | |
C3D_LightColor(&light, 1.0, 1.0, 1.0); | |
C3D_LightPosition(&light, &lightVec); | |
} | |
static void sceneRender(float iod) | |
{ | |
// Compute the projection matrix | |
Mtx_OrthoTilt(&projection, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, false); | |
// Calculate the modelView matrix | |
C3D_Mtx modelView; | |
Mtx_Identity(&modelView); | |
// Update the uniforms | |
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, uLoc_projection, &projection); | |
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, uLoc_modelView, &modelView); | |
// Draw the VBO | |
C3D_DrawArrays(GPU_TRIANGLES, 0, vertex_list_count); | |
} | |
static void sceneExit(void) | |
{ | |
// Free the VBO | |
linearFree(vbo_data); | |
// Free the shader program | |
shaderProgramFree(&program); | |
DVLB_Free(vshader_dvlb); | |
} | |
int main() | |
{ | |
// Initialize graphics | |
gfxInitDefault(); | |
gfxSet3D(true); // Enable stereoscopic 3D | |
C3D_Init(C3D_DEFAULT_CMDBUF_SIZE); | |
// Initialize the render targets | |
C3D_RenderTarget* targetLeft = C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8); | |
C3D_RenderTarget* targetRight = C3D_RenderTargetCreate(240, 400, GPU_RB_RGBA8, GPU_RB_DEPTH24_STENCIL8); | |
C3D_RenderTargetSetClear(targetLeft, C3D_CLEAR_ALL, CLEAR_COLOR, 0); | |
C3D_RenderTargetSetClear(targetRight, C3D_CLEAR_ALL, CLEAR_COLOR, 0); | |
C3D_RenderTargetSetOutput(targetLeft, GFX_TOP, GFX_LEFT, DISPLAY_TRANSFER_FLAGS); | |
C3D_RenderTargetSetOutput(targetRight, GFX_TOP, GFX_RIGHT, 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 | |
float slider = osGet3DSliderState(); | |
float iod = slider/3; | |
// Render the scene | |
C3D_FrameBegin(C3D_FRAME_SYNCDRAW); | |
{ | |
C3D_FrameDrawOn(targetLeft); | |
sceneRender(-iod); | |
if (iod > 0.0f) | |
{ | |
C3D_FrameDrawOn(targetRight); | |
sceneRender(iod); | |
} | |
} | |
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] | |
; 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 | |
.alias half myconst.wwww | |
; Outputs | |
.out outpos position | |
.out outtc0 texcoord0 | |
.out outclr color | |
.out outview view | |
.out outnq normalquat | |
; 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 | |
; outview = -r1 | |
mov outview, -r1 | |
; 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 | |
; TODO: use a separate normal matrix that is the transpose of the inverse of modelView | |
dp3 r14.x, modelView[0], innrm | |
dp3 r14.y, modelView[1], innrm | |
dp3 r14.z, modelView[2], innrm | |
dp3 r6.x, r14, r14 | |
rsq r6.x, r6.x | |
mul r14.xyz, r14.xyz, r6.x | |
mov r0, myconst.yxxx | |
add r4, ones, r14.z | |
mul r4, half, r4 | |
cmp zeros, ge, ge, r4.x | |
rsq r4, r4.x | |
mul r5, half, r14 | |
jmpc cmp.x, degenerate | |
rcp r0.z, r4.x | |
mul r0.xy, r5, r4 | |
degenerate: | |
mov outnq, r0 | |
mov outclr, ones | |
; We're finished | |
end | |
.end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment