matrix_cubesphere: use separate light shader
This commit is contained in:
parent
ae38604ba3
commit
1c1e7483a7
6
src/light.fs.asm
Normal file
6
src/light.fs.asm
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
-- temp[0] -- color
|
||||||
|
|
||||||
|
OUT TEX_SEM_WAIT
|
||||||
|
src0.rgb = temp[0] :
|
||||||
|
out[0].a = MAX src0.1 src0.1 ,
|
||||||
|
out[0].rgb = MAX src0.rgb src0.rgb ;
|
||||||
BIN
src/light.fs.bin
Normal file
BIN
src/light.fs.bin
Normal file
Binary file not shown.
13
src/light.vs.asm
Normal file
13
src/light.vs.asm
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
-- input[0] -- position
|
||||||
|
-- input[1] -- color
|
||||||
|
|
||||||
|
-- position clip space
|
||||||
|
temp[1].x = VE_DOT const[0].xyzw input[0].xyzw ;
|
||||||
|
temp[1].y = VE_DOT const[1].xyzw input[0].xyzw ;
|
||||||
|
temp[1].z = VE_DOT const[2].xyzw input[0].xyzw ;
|
||||||
|
temp[1].w = VE_DOT const[3].xyzw input[0].xyzw ;
|
||||||
|
|
||||||
|
-- position (clip space)
|
||||||
|
out[0].xyzw = VE_ADD temp[1].xyzw const[0].0000 ;
|
||||||
|
-- color
|
||||||
|
out[1].xyzw = VE_ADD const[4].xyzw const[4].0000 ;
|
||||||
BIN
src/light.vs.bin
Normal file
BIN
src/light.vs.bin
Normal file
Binary file not shown.
@ -28,17 +28,20 @@
|
|||||||
#include "../model/model2.h"
|
#include "../model/model2.h"
|
||||||
#include "../model/cubesphere.h"
|
#include "../model/cubesphere.h"
|
||||||
|
|
||||||
#define CUBESPHERE_SHADER 0
|
#define CLEAR_SHADER 0
|
||||||
#define CLEAR_SHADER 1
|
#define CUBESPHERE_SHADER 1
|
||||||
|
#define LIGHT_SHADER 2
|
||||||
|
|
||||||
const char * vertex_shader_paths[] = {
|
const char * vertex_shader_paths[] = {
|
||||||
"matrix_cubesphere.vs.bin",
|
|
||||||
"clear.vs.bin",
|
"clear.vs.bin",
|
||||||
|
"matrix_cubesphere.vs.bin",
|
||||||
|
"light.vs.bin",
|
||||||
};
|
};
|
||||||
const int vertex_shader_paths_length = (sizeof (vertex_shader_paths)) / (sizeof (vertex_shader_paths[0]));
|
const int vertex_shader_paths_length = (sizeof (vertex_shader_paths)) / (sizeof (vertex_shader_paths[0]));
|
||||||
const char * fragment_shader_paths[] = {
|
const char * fragment_shader_paths[] = {
|
||||||
"matrix_cubesphere.fs.bin",
|
|
||||||
"clear.fs.bin",
|
"clear.fs.bin",
|
||||||
|
"matrix_cubesphere.fs.bin",
|
||||||
|
"light.fs.bin"
|
||||||
};
|
};
|
||||||
const int fragment_shader_paths_length = (sizeof (fragment_shader_paths)) / (sizeof (fragment_shader_paths[0]));
|
const int fragment_shader_paths_length = (sizeof (fragment_shader_paths)) / (sizeof (fragment_shader_paths[0]));
|
||||||
|
|
||||||
@ -60,7 +63,7 @@ void _3d_clear(struct shaders& shaders)
|
|||||||
T0V(VAP_OUT_VTX_FMT_0
|
T0V(VAP_OUT_VTX_FMT_0
|
||||||
, VAP_OUT_VTX_FMT_0__VTX_POS_PRESENT(1));
|
, VAP_OUT_VTX_FMT_0__VTX_POS_PRESENT(1));
|
||||||
T0V(VAP_OUT_VTX_FMT_1
|
T0V(VAP_OUT_VTX_FMT_1
|
||||||
, 0x0);
|
, 0);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
@ -107,10 +110,6 @@ void _3d_clear(struct shaders& shaders)
|
|||||||
, VAP_CNTL_STATUS__PVS_BYPASS(0)
|
, VAP_CNTL_STATUS__PVS_BYPASS(0)
|
||||||
);
|
);
|
||||||
|
|
||||||
T0V(VAP_VTX_SIZE
|
|
||||||
, VAP_VTX_SIZE__DWORDS_PER_VTX(2)
|
|
||||||
);
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// GA POINT SIZE
|
// GA POINT SIZE
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@ -124,17 +123,24 @@ void _3d_clear(struct shaders& shaders)
|
|||||||
// 3D_DRAW
|
// 3D_DRAW
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const int dwords_per_vtx = 2;
|
||||||
|
|
||||||
|
T0V(VAP_VTX_SIZE
|
||||||
|
, VAP_VTX_SIZE__DWORDS_PER_VTX(dwords_per_vtx)
|
||||||
|
);
|
||||||
|
|
||||||
const float center[] = {
|
const float center[] = {
|
||||||
800.0f, 600.0f,
|
800.0f, 600.0f,
|
||||||
};
|
};
|
||||||
T3(_3D_DRAW_IMMD_2, (1 + 2) - 1);
|
const int vertex_count = 1;
|
||||||
|
T3(_3D_DRAW_IMMD_2, (1 + vertex_count * dwords_per_vtx) - 1);
|
||||||
TU( VAP_VF_CNTL__PRIM_TYPE(1) // point list
|
TU( VAP_VF_CNTL__PRIM_TYPE(1) // point list
|
||||||
| VAP_VF_CNTL__PRIM_WALK(3)
|
| VAP_VF_CNTL__PRIM_WALK(3)
|
||||||
| VAP_VF_CNTL__INDEX_SIZE(0)
|
| VAP_VF_CNTL__INDEX_SIZE(0)
|
||||||
| VAP_VF_CNTL__VTX_REUSE_DIS(0)
|
| VAP_VF_CNTL__VTX_REUSE_DIS(0)
|
||||||
| VAP_VF_CNTL__DUAL_INDEX_MODE(0)
|
| VAP_VF_CNTL__DUAL_INDEX_MODE(0)
|
||||||
| VAP_VF_CNTL__USE_ALT_NUM_VERTS(0)
|
| VAP_VF_CNTL__USE_ALT_NUM_VERTS(0)
|
||||||
| VAP_VF_CNTL__NUM_VERTICES(1)
|
| VAP_VF_CNTL__NUM_VERTICES(vertex_count)
|
||||||
);
|
);
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
TF(center[i]);
|
TF(center[i]);
|
||||||
@ -200,7 +206,13 @@ void _3d_cube_inner(mat4x4 trans,
|
|||||||
const int triangle_count = obj->triangle_count;
|
const int triangle_count = obj->triangle_count;
|
||||||
const int vertex_count = triangle_count * 3;
|
const int vertex_count = triangle_count * 3;
|
||||||
|
|
||||||
T3(_3D_DRAW_IMMD_2, (1 + vertex_count * 8) - 1);
|
const int dwords_per_vtx = 8;
|
||||||
|
|
||||||
|
T0V(VAP_VTX_SIZE
|
||||||
|
, VAP_VTX_SIZE__DWORDS_PER_VTX(dwords_per_vtx)
|
||||||
|
);
|
||||||
|
|
||||||
|
T3(_3D_DRAW_IMMD_2, (1 + vertex_count * dwords_per_vtx) - 1);
|
||||||
TU( VAP_VF_CNTL__PRIM_TYPE(4)
|
TU( VAP_VF_CNTL__PRIM_TYPE(4)
|
||||||
| VAP_VF_CNTL__PRIM_WALK(3)
|
| VAP_VF_CNTL__PRIM_WALK(3)
|
||||||
| VAP_VF_CNTL__INDEX_SIZE(0)
|
| VAP_VF_CNTL__INDEX_SIZE(0)
|
||||||
@ -228,8 +240,152 @@ void _3d_cube_inner(mat4x4 trans,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _3d_light_inner(mat4x4 trans)
|
||||||
|
{
|
||||||
|
T0V(VAP_PVS_STATE_FLUSH_REG, 0x00000000);
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// VAP_PVS
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const vec4 color = {1, 1, 0, 1};
|
||||||
|
|
||||||
|
const float consts[] = {
|
||||||
|
// 0
|
||||||
|
trans[0][0], trans[0][1], trans[0][2], trans[0][3],
|
||||||
|
trans[1][0], trans[1][1], trans[1][2], trans[1][3],
|
||||||
|
trans[2][0], trans[2][1], trans[2][2], trans[2][3],
|
||||||
|
trans[3][0], trans[3][1], trans[3][2], trans[3][3],
|
||||||
|
|
||||||
|
// 4
|
||||||
|
color[0], color[1], color[2], color[2],
|
||||||
|
};
|
||||||
|
ib_vap_pvs_const_cntl(consts, (sizeof (consts)));
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// 3D_DRAW
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const model * model = &cubesphere_model;
|
||||||
|
const object * obj = model->object[0];
|
||||||
|
const int triangle_count = obj->triangle_count;
|
||||||
|
const int vertex_count = triangle_count * 3;
|
||||||
|
|
||||||
|
int dwords_per_vtx = 3;
|
||||||
|
|
||||||
|
T0V(VAP_VTX_SIZE
|
||||||
|
, VAP_VTX_SIZE__DWORDS_PER_VTX(dwords_per_vtx)
|
||||||
|
);
|
||||||
|
|
||||||
|
T3(_3D_DRAW_IMMD_2, (1 + vertex_count * dwords_per_vtx) - 1);
|
||||||
|
TU( VAP_VF_CNTL__PRIM_TYPE(4)
|
||||||
|
| VAP_VF_CNTL__PRIM_WALK(3)
|
||||||
|
| VAP_VF_CNTL__INDEX_SIZE(0)
|
||||||
|
| VAP_VF_CNTL__VTX_REUSE_DIS(0)
|
||||||
|
| VAP_VF_CNTL__DUAL_INDEX_MODE(0)
|
||||||
|
| VAP_VF_CNTL__USE_ALT_NUM_VERTS(0)
|
||||||
|
| VAP_VF_CNTL__NUM_VERTICES(vertex_count)
|
||||||
|
);
|
||||||
|
|
||||||
|
for (int i = 0; i < triangle_count; i++) {
|
||||||
|
for (int j = 0; j < 3; j++) {
|
||||||
|
vec3 p = model->position[obj->triangle[i][j].position];
|
||||||
|
|
||||||
|
TF(p.x);
|
||||||
|
TF(p.y);
|
||||||
|
TF(p.z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 _3d_light(struct shaders& shaders,
|
||||||
|
const mat4x4& view_to_clip,
|
||||||
|
float theta)
|
||||||
|
{
|
||||||
|
ib_rs_instructions(1);
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// VAP OUT
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
T0V(VAP_OUT_VTX_FMT_0
|
||||||
|
, VAP_OUT_VTX_FMT_0__VTX_POS_PRESENT(1));
|
||||||
|
T0V(VAP_OUT_VTX_FMT_1
|
||||||
|
, VAP_OUT_VTX_FMT_1__TEX_0_COMP_CNT(4));
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
ib_zbuffer(ZBUFFER_RELOC_INDEX, 1); // less
|
||||||
|
|
||||||
|
ib_texture__0();
|
||||||
|
|
||||||
|
ib_vap_stream_cntl__3();
|
||||||
|
|
||||||
|
// shaders
|
||||||
|
T0V(US_PIXSIZE
|
||||||
|
, US_PIXSIZE__PIX_SIZE(1)
|
||||||
|
);
|
||||||
|
ib_ga_us(&shaders.fragment[LIGHT_SHADER]);
|
||||||
|
ib_vap_pvs(&shaders.vertex[LIGHT_SHADER]);
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// VAP
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
T0V(VAP_CLIP_CNTL
|
||||||
|
, VAP_CLIP_CNTL__PS_UCP_MODE(3)
|
||||||
|
);
|
||||||
|
|
||||||
|
T0V(VAP_VTE_CNTL
|
||||||
|
, VAP_VTE_CNTL__VPORT_X_SCALE_ENA(1)
|
||||||
|
| VAP_VTE_CNTL__VPORT_X_OFFSET_ENA(1)
|
||||||
|
| VAP_VTE_CNTL__VPORT_Y_SCALE_ENA(1)
|
||||||
|
| VAP_VTE_CNTL__VPORT_Y_OFFSET_ENA(1)
|
||||||
|
| VAP_VTE_CNTL__VPORT_Z_SCALE_ENA(0)
|
||||||
|
| VAP_VTE_CNTL__VPORT_Z_OFFSET_ENA(0)
|
||||||
|
| VAP_VTE_CNTL__VTX_XY_FMT(0) // enable W division
|
||||||
|
| VAP_VTE_CNTL__VTX_Z_FMT(1) // disable W division
|
||||||
|
| VAP_VTE_CNTL__VTX_W0_FMT(1)
|
||||||
|
| VAP_VTE_CNTL__SERIAL_PROC_ENA(0)
|
||||||
|
);
|
||||||
|
|
||||||
|
T0V(VAP_CNTL_STATUS
|
||||||
|
, VAP_CNTL_STATUS__PVS_BYPASS(0)
|
||||||
|
);
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// VAP INDEX
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
T0V(VAP_INDEX_OFFSET, 0);
|
||||||
|
|
||||||
|
T0V(VAP_VF_MAX_VTX_INDX
|
||||||
|
, VAP_VF_MAX_VTX_INDX__MAX_INDX(0)
|
||||||
|
);
|
||||||
|
T0V(VAP_VF_MIN_VTX_INDX
|
||||||
|
, VAP_VF_MIN_VTX_INDX__MIN_INDX(0)
|
||||||
|
);
|
||||||
|
|
||||||
|
// light
|
||||||
|
mat4x4 t1 = translate(vec3(1, 0, 0));
|
||||||
|
mat4x4 s = scale(0.1f);
|
||||||
|
mat4x4 rz = rotate_y(theta * 2.f);
|
||||||
|
|
||||||
|
mat4x4 world_trans = rz * t1 * s;
|
||||||
|
|
||||||
|
mat4x4 trans = view_to_clip * world_trans;
|
||||||
|
|
||||||
|
_3d_light_inner(trans);
|
||||||
|
|
||||||
|
vec3 light_pos = world_trans * light_pos;
|
||||||
|
|
||||||
|
return light_pos;
|
||||||
|
}
|
||||||
|
|
||||||
void _3d_cube(struct shaders& shaders,
|
void _3d_cube(struct shaders& shaders,
|
||||||
float theta)
|
const mat4x4& view_to_clip,
|
||||||
|
float theta,
|
||||||
|
const vec3& light_pos)
|
||||||
{
|
{
|
||||||
ib_rs_instructions(4);
|
ib_rs_instructions(4);
|
||||||
|
|
||||||
@ -264,10 +420,6 @@ void _3d_cube(struct shaders& shaders,
|
|||||||
// VAP
|
// VAP
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
T0V(VAP_VTX_SIZE
|
|
||||||
, VAP_VTX_SIZE__DWORDS_PER_VTX(8)
|
|
||||||
);
|
|
||||||
|
|
||||||
T0V(VAP_CLIP_CNTL
|
T0V(VAP_CLIP_CNTL
|
||||||
, VAP_CLIP_CNTL__PS_UCP_MODE(3)
|
, VAP_CLIP_CNTL__PS_UCP_MODE(3)
|
||||||
);
|
);
|
||||||
@ -306,51 +458,16 @@ void _3d_cube(struct shaders& shaders,
|
|||||||
// matrix
|
// matrix
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
float theta1 = theta;
|
// cube
|
||||||
float theta2 = theta;
|
mat4x4 rx = rotate_x(1 * theta * 0.5f);
|
||||||
|
mat4x4 ry = rotate_y(0 * theta * 0.8f + 1.4f);
|
||||||
|
mat4x4 s = scale(0.9f);
|
||||||
|
|
||||||
mat4x4 aspect = scale(vec3(3.0f/4.0f, 1, 1));
|
mat4x4 world_trans = rx * ry * s;
|
||||||
|
|
||||||
mat4x4 p = perspective(0.01f, 5.0f,
|
mat4x4 trans = view_to_clip * world_trans;
|
||||||
0.001f, 0.999f,
|
|
||||||
0.5f, 2.0f);
|
|
||||||
|
|
||||||
vec4 light_pos = vec4(0, 0, 0, 1.0f);
|
_3d_cube_inner(trans, world_trans, light_pos);
|
||||||
|
|
||||||
// light
|
|
||||||
if (1) {
|
|
||||||
mat4x4 t = translate(vec3(0, 0, 3));
|
|
||||||
mat4x4 t1 = translate(vec3(1, 0, 0));
|
|
||||||
mat4x4 s = scale(0.1f);
|
|
||||||
mat4x4 rz = rotate_y(theta * 2.f);
|
|
||||||
|
|
||||||
mat4x4 world_trans = rz * t1 * s;
|
|
||||||
|
|
||||||
//mat3x3 normal_trans = transpose(inverse(submatrix(world_trans, 3, 3)));
|
|
||||||
|
|
||||||
mat4x4 trans = aspect * p * t * world_trans;
|
|
||||||
|
|
||||||
light_pos = world_trans * light_pos;
|
|
||||||
|
|
||||||
_3d_cube_inner(trans, world_trans, light_pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// object
|
|
||||||
if (1) {
|
|
||||||
mat4x4 t = translate(vec3(0, 0, 3));
|
|
||||||
mat4x4 rx = rotate_x(1 * theta1 * 0.5f);
|
|
||||||
mat4x4 ry = rotate_y(0 * theta2 * 0.8f + 1.4f);
|
|
||||||
mat4x4 s = scale(0.9f);
|
|
||||||
|
|
||||||
mat4x4 world_trans = rx * ry * s;
|
|
||||||
|
|
||||||
//mat3x3 normal_trans = transpose(inverse(submatrix(world_trans, 3, 3)));
|
|
||||||
|
|
||||||
mat4x4 trans = aspect * p * t * world_trans;
|
|
||||||
|
|
||||||
_3d_cube_inner(trans, world_trans, light_pos);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int indirect_buffer(shaders& shaders,
|
int indirect_buffer(shaders& shaders,
|
||||||
@ -387,8 +504,16 @@ int indirect_buffer(shaders& shaders,
|
|||||||
// DRAW
|
// DRAW
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
mat4x4 aspect = scale(vec3(3.0f/4.0f, 1, 1));
|
||||||
|
mat4x4 p = perspective(0.01f, 5.0f,
|
||||||
|
0.001f, 0.999f,
|
||||||
|
0.5f, 2.0f);
|
||||||
|
mat4x4 t = translate(vec3(0, 0, 3));
|
||||||
|
mat4x4 view_to_clip = aspect * p * t;
|
||||||
|
|
||||||
_3d_clear(shaders);
|
_3d_clear(shaders);
|
||||||
_3d_cube(shaders, theta);
|
vec3 light_pos = _3d_light(shaders, view_to_clip, theta);
|
||||||
|
_3d_cube(shaders, view_to_clip, theta, light_pos);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// padding
|
// padding
|
||||||
|
|||||||
@ -650,6 +650,27 @@ void ib_vap_stream_cntl__2()
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ib_vap_stream_cntl__3()
|
||||||
|
{
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
// VAP_PROG_STREAM_CNTL
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
T0V(VAP_PROG_STREAM_CNTL_0
|
||||||
|
, VAP_PROG_STREAM_CNTL__DATA_TYPE_0__FLOAT_3
|
||||||
|
| VAP_PROG_STREAM_CNTL__SKIP_DWORDS_0(0)
|
||||||
|
| VAP_PROG_STREAM_CNTL__DST_VEC_LOC_0(0)
|
||||||
|
| VAP_PROG_STREAM_CNTL__LAST_VEC_0(1)
|
||||||
|
);
|
||||||
|
T0V(VAP_PROG_STREAM_CNTL_EXT_0
|
||||||
|
, VAP_PROG_STREAM_CNTL_EXT__SWIZZLE_SELECT_X_0__SELECT_X
|
||||||
|
| VAP_PROG_STREAM_CNTL_EXT__SWIZZLE_SELECT_Y_0__SELECT_Y
|
||||||
|
| VAP_PROG_STREAM_CNTL_EXT__SWIZZLE_SELECT_Z_0__SELECT_Z
|
||||||
|
| VAP_PROG_STREAM_CNTL_EXT__SWIZZLE_SELECT_W_0__SELECT_FP_ONE
|
||||||
|
| VAP_PROG_STREAM_CNTL_EXT__WRITE_ENA_0(0b1111)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
void ib_vap_stream_cntl__323()
|
void ib_vap_stream_cntl__323()
|
||||||
{
|
{
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@ -64,6 +64,7 @@ void ib_vap_pvs(struct shader_offset * offset);
|
|||||||
void ib_ga_us(struct shader_offset * offset);
|
void ib_ga_us(struct shader_offset * offset);
|
||||||
void ib_vap_pvs_const_cntl(const float * consts, int size);
|
void ib_vap_pvs_const_cntl(const float * consts, int size);
|
||||||
void ib_vap_stream_cntl__2();
|
void ib_vap_stream_cntl__2();
|
||||||
|
void ib_vap_stream_cntl__3();
|
||||||
void ib_vap_stream_cntl__323();
|
void ib_vap_stream_cntl__323();
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user