render.cpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904
  1. /* SCE CONFIDENTIAL
  2. $PSLibId$
  3. * Copyright (C) 2011 Sony Computer Entertainment Inc.
  4. * All Rights Reserved.
  5. */
  6. #include "render.h"
  7. #include "common.h"
  8. #include <string.h>
  9. #include <libdbg.h>
  10. #include <sceconst.h>
  11. #include <vectormath.h>
  12. #include <gxm.h>
  13. #include <stdio.h>
  14. // Offscreen texture parameters
  15. #define OFFSCREEN_WIDTH 512
  16. #define OFFSCREEN_HEIGHT 512
  17. #define OFFSCREEN_COLOR_FORMAT SCE_GXM_COLOR_FORMAT_A8R8G8B8
  18. #define OFFSCREEN_TEXTURE_FORMAT SCE_GXM_TEXTURE_FORMAT_A8R8G8B8
  19. #define USE_DEFAULT_UB
  20. using namespace sce::Vectormath::Simd::Aos;
  21. // update data
  22. //float g_rotationAngle = 0.0f;
  23. //Matrix4 g_offscreenWvpMatrix;
  24. //Matrix4 g_mainWvpMatrix;
  25. //Matrix4 g_magMvpMatrix;
  26. //Matrix4 g_viewMatrix;
  27. //Matrix4 g_worldMatrix;
  28. //Matrix4 g_localMatrix;
  29. //Matrix4 g_projectionMatrix;
  30. static bool popup_ = false;
  31. // Embedded GXM shader programs
  32. extern const SceGxmProgram _binary_clear_v_gxp_start;
  33. extern const SceGxmProgram _binary_clear_f_gxp_start;
  34. extern const SceGxmProgram _binary_cube_v_gxp_start;
  35. extern const SceGxmProgram _binary_cube_f_gxp_start;
  36. // Data structure for clear geometry
  37. typedef struct ClearVertex {
  38. float x;
  39. float y;
  40. } ClearVertex;
  41. // Data structure for basic geometry
  42. typedef struct BasicVertex {
  43. float x;
  44. float y;
  45. float z;
  46. uint32_t color;
  47. // uint16_t u;
  48. // uint16_t v;
  49. float u;
  50. float v;
  51. } BasicVertex;
  52. // clear geometry data
  53. SceGxmShaderPatcherId g_clearVertexProgramId;
  54. SceGxmShaderPatcherId g_clearFragmentProgramId;
  55. SceGxmVertexProgram *g_clearVertexProgram = NULL;
  56. SceGxmFragmentProgram *g_clearFragmentProgram = NULL;
  57. ClearVertex *g_clearVertices = NULL;
  58. uint16_t *g_clearIndices = NULL;
  59. const SceGxmProgramParameter *g_clearColorParam = NULL;
  60. // cube geometry data
  61. SceGxmShaderPatcherId g_cubeVertexProgramId;
  62. SceGxmShaderPatcherId g_cubeFragmentProgramId;
  63. SceGxmVertexProgram *g_cubeVertexProgram = NULL;
  64. SceGxmFragmentProgram *g_cubeFragmentProgram = NULL;
  65. BasicVertex *g_cubeVertices = NULL;
  66. uint16_t *g_cubeIndices = NULL;
  67. BasicVertex* g_magVertices = NULL;
  68. uint16_t* g_magIndices = NULL;
  69. void* g_cubeUniformBuffer = NULL;
  70. void* g_magUniformBuffer = NULL;
  71. //const SceGxmProgramParameter *g_cubeWvpParam = NULL;
  72. // offscreen surface data and render target
  73. void *g_offscreenColorBufferData;
  74. SceGxmColorSurface g_offscreenColorSurface;
  75. SceGxmTexture g_offscreenTexture;
  76. void *g_offscreenDepthBufferData;
  77. SceGxmDepthStencilSurface g_offscreenDepthSurface;
  78. SceGxmRenderTarget *g_offscreenRenderTarget;
  79. // test texture
  80. uint8_t *g_testTextureData;
  81. SceGxmTexture g_testTexture;
  82. tilebackend::Target g_target;
  83. void createClearData(void)
  84. {
  85. int err = SCE_OK;
  86. UNUSED(err);
  87. // register programs with the shader patcher
  88. err = sceGxmShaderPatcherRegisterProgram(g_shaderPatcher, &_binary_clear_v_gxp_start, &g_clearVertexProgramId);
  89. SCE_DBG_ASSERT(err == SCE_OK);
  90. err = sceGxmShaderPatcherRegisterProgram(g_shaderPatcher, &_binary_clear_f_gxp_start, &g_clearFragmentProgramId);
  91. SCE_DBG_ASSERT(err == SCE_OK);
  92. // find attributes by name to create vertex format bindings
  93. const SceGxmProgram *clearVertexProgram = sceGxmShaderPatcherGetProgramFromId(g_clearVertexProgramId);
  94. const SceGxmProgramParameter *paramPositionAttribute = sceGxmProgramFindParameterByName(clearVertexProgram, "aPosition");
  95. SCE_DBG_ASSERT(paramPositionAttribute && (sceGxmProgramParameterGetCategory(paramPositionAttribute) == SCE_GXM_PARAMETER_CATEGORY_ATTRIBUTE));
  96. // find fragment uniforms by name and cache parameter info
  97. // note: name lookup is a slow load-time operation
  98. const SceGxmProgram *clearFragmentProgram = sceGxmShaderPatcherGetProgramFromId(g_clearFragmentProgramId);
  99. SCE_DBG_ASSERT(clearFragmentProgram);
  100. g_clearColorParam = sceGxmProgramFindParameterByName(clearFragmentProgram, "color");
  101. SCE_DBG_ASSERT(g_clearColorParam && (sceGxmProgramParameterGetCategory(g_clearColorParam) == SCE_GXM_PARAMETER_CATEGORY_UNIFORM));
  102. // create clear vertex format
  103. SceGxmVertexAttribute clearVertexAttributes[1];
  104. SceGxmVertexStream clearVertexStreams[1];
  105. clearVertexAttributes[0].streamIndex = 0;
  106. clearVertexAttributes[0].offset = 0;
  107. clearVertexAttributes[0].format = SCE_GXM_ATTRIBUTE_FORMAT_F32;
  108. clearVertexAttributes[0].componentCount = 2;
  109. clearVertexAttributes[0].regIndex = sceGxmProgramParameterGetResourceIndex(paramPositionAttribute);
  110. clearVertexStreams[0].stride = sizeof(ClearVertex);
  111. clearVertexStreams[0].indexSource = SCE_GXM_INDEX_SOURCE_INDEX_16BIT;
  112. // create clear programs
  113. err = sceGxmShaderPatcherCreateVertexProgram(
  114. g_shaderPatcher,
  115. g_clearVertexProgramId,
  116. clearVertexAttributes,
  117. 1,
  118. clearVertexStreams,
  119. 1,
  120. &g_clearVertexProgram);
  121. SCE_DBG_ASSERT(err == SCE_OK);
  122. err = sceGxmShaderPatcherCreateFragmentProgram(
  123. g_shaderPatcher,
  124. g_clearFragmentProgramId,
  125. SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4,
  126. MSAA_MODE,
  127. NULL,
  128. sceGxmShaderPatcherGetProgramFromId(g_clearVertexProgramId),
  129. &g_clearFragmentProgram);
  130. SCE_DBG_ASSERT(err == SCE_OK);
  131. #if !defined(USE_DEFAULT_UB)
  132. g_cubeUniformBuffer = heapAlloc(HEAP_TYPE_LPDDR_R, 128*sizeof(float), 16);
  133. #endif
  134. g_magUniformBuffer = heapAlloc(HEAP_TYPE_LPDDR_R, 128*sizeof(float), 16);
  135. // allocate vertices and indices
  136. g_clearVertices = (ClearVertex *)heapAlloc(HEAP_TYPE_LPDDR_R, 3*sizeof(ClearVertex), 4);
  137. g_clearIndices = (uint16_t *)heapAlloc(HEAP_TYPE_LPDDR_R, 3*sizeof(uint16_t), 2);
  138. // write vertex data
  139. g_clearVertices[0].x = -1.0f;
  140. g_clearVertices[0].y = -1.0f;
  141. g_clearVertices[1].x = 3.0f;
  142. g_clearVertices[1].y = -1.0f;
  143. g_clearVertices[2].x = -1.0f;
  144. g_clearVertices[2].y = 3.0f;
  145. // write index data
  146. g_clearIndices[0] = 0;
  147. g_clearIndices[1] = 1;
  148. g_clearIndices[2] = 2;
  149. }
  150. void destroyClearData(void)
  151. {
  152. int err = SCE_OK;
  153. UNUSED(err);
  154. // release the shaders
  155. err = sceGxmShaderPatcherReleaseFragmentProgram(g_shaderPatcher, g_clearFragmentProgram);
  156. SCE_DBG_ASSERT(err == SCE_OK);
  157. err = sceGxmShaderPatcherReleaseVertexProgram(g_shaderPatcher, g_clearVertexProgram);
  158. SCE_DBG_ASSERT(err == SCE_OK);
  159. // free the memory used for vertices and indices
  160. heapFree(g_clearIndices);
  161. heapFree(g_clearVertices);
  162. heapFree(g_magUniformBuffer);
  163. // unregister programs since we don't need them any more
  164. err = sceGxmShaderPatcherUnregisterProgram(g_shaderPatcher, g_clearFragmentProgramId);
  165. SCE_DBG_ASSERT(err == SCE_OK);
  166. err = sceGxmShaderPatcherUnregisterProgram(g_shaderPatcher, g_clearVertexProgramId);
  167. SCE_DBG_ASSERT(err == SCE_OK);
  168. }
  169. void createCubeData(void)
  170. {
  171. int err = SCE_OK;
  172. UNUSED(err);
  173. // register programs with the patcher
  174. err = sceGxmShaderPatcherRegisterProgram(g_shaderPatcher, &_binary_cube_v_gxp_start, &g_cubeVertexProgramId);
  175. SCE_DBG_ASSERT(err == SCE_OK);
  176. err = sceGxmShaderPatcherRegisterProgram(g_shaderPatcher, &_binary_cube_f_gxp_start, &g_cubeFragmentProgramId);
  177. SCE_DBG_ASSERT(err == SCE_OK);
  178. // find vertex uniforms by name and cache parameter info
  179. // note: name lookup is a slow load-time operation
  180. const SceGxmProgram *cubeVertexProgram = sceGxmShaderPatcherGetProgramFromId(g_cubeVertexProgramId);
  181. SCE_DBG_ASSERT(cubeVertexProgram);
  182. //g_cubeWvpParam = sceGxmProgramFindParameterByName(cubeVertexProgram, "wvp");
  183. //SCE_DBG_ASSERT(g_cubeWvpParam && (sceGxmProgramParameterGetCategory(g_cubeWvpParam) == SCE_GXM_PARAMETER_CATEGORY_UNIFORM));
  184. // find attributes by name to create vertex format bindings
  185. const SceGxmProgramParameter *paramPositionAttribute = sceGxmProgramFindParameterByName(cubeVertexProgram, "aPosition");
  186. SCE_DBG_ASSERT(paramPositionAttribute && (sceGxmProgramParameterGetCategory(paramPositionAttribute) == SCE_GXM_PARAMETER_CATEGORY_ATTRIBUTE));
  187. const SceGxmProgramParameter *paramColorAttribute = sceGxmProgramFindParameterByName(cubeVertexProgram, "aColor");
  188. SCE_DBG_ASSERT(paramColorAttribute && (sceGxmProgramParameterGetCategory(paramColorAttribute) == SCE_GXM_PARAMETER_CATEGORY_ATTRIBUTE));
  189. const SceGxmProgramParameter *paramTexCoordAttribute = sceGxmProgramFindParameterByName(cubeVertexProgram, "aTexCoord");
  190. SCE_DBG_ASSERT(paramTexCoordAttribute && (sceGxmProgramParameterGetCategory(paramTexCoordAttribute) == SCE_GXM_PARAMETER_CATEGORY_ATTRIBUTE));
  191. // create shaded triangle vertex format
  192. SceGxmVertexAttribute basicVertexAttributes[3];
  193. SceGxmVertexStream basicVertexStreams[1];
  194. basicVertexAttributes[0].streamIndex = 0;
  195. basicVertexAttributes[0].offset = 0;
  196. basicVertexAttributes[0].format = SCE_GXM_ATTRIBUTE_FORMAT_F32;
  197. basicVertexAttributes[0].componentCount = 3;
  198. basicVertexAttributes[0].regIndex = sceGxmProgramParameterGetResourceIndex(paramPositionAttribute);
  199. basicVertexAttributes[1].streamIndex = 0;
  200. basicVertexAttributes[1].offset = 12;
  201. basicVertexAttributes[1].format = SCE_GXM_ATTRIBUTE_FORMAT_U8N;
  202. basicVertexAttributes[1].componentCount = 4;
  203. basicVertexAttributes[1].regIndex = sceGxmProgramParameterGetResourceIndex(paramColorAttribute);
  204. basicVertexAttributes[2].streamIndex = 0;
  205. basicVertexAttributes[2].offset = 16;
  206. basicVertexAttributes[2].format = SCE_GXM_ATTRIBUTE_FORMAT_F32;
  207. basicVertexAttributes[2].componentCount = 2;
  208. basicVertexAttributes[2].regIndex = sceGxmProgramParameterGetResourceIndex(paramTexCoordAttribute);
  209. basicVertexStreams[0].stride = sizeof(BasicVertex);
  210. basicVertexStreams[0].indexSource = SCE_GXM_INDEX_SOURCE_INDEX_16BIT;
  211. // create cube vertex program
  212. err = sceGxmShaderPatcherCreateVertexProgram(
  213. g_shaderPatcher,
  214. g_cubeVertexProgramId,
  215. basicVertexAttributes,
  216. 3,
  217. basicVertexStreams,
  218. 1,
  219. &g_cubeVertexProgram);
  220. SCE_DBG_ASSERT(err == SCE_OK);
  221. // create cube fragment program
  222. err = sceGxmShaderPatcherCreateFragmentProgram(
  223. g_shaderPatcher,
  224. g_cubeFragmentProgramId,
  225. SCE_GXM_OUTPUT_REGISTER_FORMAT_UCHAR4,
  226. MSAA_MODE,
  227. NULL,
  228. sceGxmShaderPatcherGetProgramFromId(g_cubeVertexProgramId),
  229. &g_cubeFragmentProgram);
  230. SCE_DBG_ASSERT(err == SCE_OK);
  231. // allocate memory for vertex and index data
  232. g_cubeVertices = (BasicVertex *)heapAlloc(HEAP_TYPE_LPDDR_R, 24*sizeof(BasicVertex), 4);
  233. g_cubeIndices = (uint16_t *)heapAlloc(HEAP_TYPE_LPDDR_R, 36*sizeof(uint16_t), 2);
  234. g_magVertices = (BasicVertex*)heapAlloc(HEAP_TYPE_LPDDR_R, 4*sizeof(BasicVertex), 4);
  235. g_magIndices = (uint16_t *)heapAlloc(HEAP_TYPE_LPDDR_R, 6*sizeof(uint16_t), 2);
  236. // write vertices
  237. BasicVertex *vertexData = g_cubeVertices;
  238. // const uint16_t half0 = 0x0000;
  239. // const uint16_t half1 = 0x3c00;
  240. const float half0 = 0.f;
  241. const float half1 = 1.f;
  242. const float ratio = (float)DISPLAY_HEIGHT*(float)WEBVIEW_WIDTH/(float)DISPLAY_WIDTH/(float)WEBVIEW_HEIGHT;
  243. vertexData[0].x = -1.f * ratio;
  244. vertexData[0].y = 1.f;
  245. vertexData[0].z = 0.f;
  246. vertexData[0].color = 0xffffffff;
  247. vertexData[0].u = half0;
  248. vertexData[0].v = half0;
  249. vertexData[1].x = 1.f * ratio;
  250. vertexData[1].y = 1.f;
  251. vertexData[1].z = 0.f;
  252. vertexData[1].color = 0xffffffff;
  253. vertexData[1].u = half1;
  254. vertexData[1].v = half0;
  255. vertexData[2].x = 1.f * ratio;
  256. vertexData[2].y = -1.f;
  257. vertexData[2].z = 0.f;
  258. vertexData[2].color = 0xffffffff;
  259. vertexData[2].u = half1;
  260. vertexData[2].v = half1;
  261. vertexData[3].x = -1.f * ratio;
  262. vertexData[3].y = -1.f;
  263. vertexData[3].z = 0.f;
  264. vertexData[3].color = 0xffffffff;
  265. vertexData[3].u = half0;
  266. vertexData[3].v = half1;
  267. // write indices
  268. uint16_t *indexData = g_cubeIndices;
  269. indexData[0] = 0;
  270. indexData[1] = 1;
  271. indexData[2] = 3;
  272. indexData[3] = 3;
  273. indexData[4] = 1;
  274. indexData[5] = 2;
  275. vertexData = g_magVertices;
  276. vertexData[0].x = -0.5f;
  277. vertexData[0].y = 0.5f;
  278. vertexData[0].z = 0.f;
  279. vertexData[0].color = 0xffffffff;
  280. vertexData[0].u = half0;
  281. vertexData[0].v = half0;
  282. vertexData[1].x = 0.5f;
  283. vertexData[1].y = 0.5f;
  284. vertexData[1].z = 0.f;
  285. vertexData[1].color = 0xffffffff;
  286. vertexData[1].u = half1;
  287. vertexData[1].v = half0;
  288. vertexData[2].x = 0.5f;
  289. vertexData[2].y = -0.5f;
  290. vertexData[2].z = 0.f;
  291. vertexData[2].color = 0xffffffff;
  292. vertexData[2].u = half1;
  293. vertexData[2].v = half1;
  294. vertexData[3].x = -0.5f;
  295. vertexData[3].y = -0.5f;
  296. vertexData[3].z = 0.f;
  297. vertexData[3].color = 0xffffffff;
  298. vertexData[3].u = half0;
  299. vertexData[3].v = half1;
  300. indexData = g_magIndices;
  301. indexData[0] = 0;
  302. indexData[1] = 1;
  303. indexData[2] = 3;
  304. indexData[3] = 3;
  305. indexData[4] = 1;
  306. indexData[5] = 2;
  307. }
  308. void destroyCubeData(void)
  309. {
  310. int err = SCE_OK;
  311. UNUSED(err);
  312. // release the shaders
  313. err = sceGxmShaderPatcherReleaseFragmentProgram(g_shaderPatcher, g_cubeFragmentProgram);
  314. SCE_DBG_ASSERT(err == SCE_OK);
  315. err = sceGxmShaderPatcherReleaseVertexProgram(g_shaderPatcher, g_cubeVertexProgram);
  316. SCE_DBG_ASSERT(err == SCE_OK);
  317. // free the memory used for vertices and indices
  318. heapFree(g_magIndices);
  319. heapFree(g_magVertices);
  320. heapFree(g_cubeIndices);
  321. heapFree(g_cubeVertices);
  322. // unregister programs since we don't need them any more
  323. err = sceGxmShaderPatcherUnregisterProgram(g_shaderPatcher, g_cubeFragmentProgramId);
  324. SCE_DBG_ASSERT(err == SCE_OK);
  325. err = sceGxmShaderPatcherUnregisterProgram(g_shaderPatcher, g_cubeVertexProgramId);
  326. SCE_DBG_ASSERT(err == SCE_OK);
  327. }
  328. void createTestTextureData(uint32_t width, uint32_t height, SceGxmTextureFormat format)
  329. {
  330. int err = SCE_OK;
  331. UNUSED(err);
  332. // get the size of the texture data
  333. const uint32_t dataSize = width * height * 4;
  334. // allocate memory
  335. // g_testTextureData = (uint8_t *)heapAlloc(HEAP_TYPE_LPDDR_R, dataSize, SCE_GXM_TEXTURE_ALIGNMENT);
  336. g_testTextureData = (uint8_t *)heapAlloc(
  337. HEAP_TYPE_LPDDR_R,
  338. dataSize,
  339. SCE_GXM_TEXTURE_ALIGNMENT);
  340. // copy texture data
  341. memset(g_testTextureData, 0xff, dataSize);
  342. g_target.buffer = g_testTextureData;
  343. g_target.width = width;
  344. g_target.height = height;
  345. g_target.stride = width * 4;
  346. g_target.format = 0;
  347. // fill with (swizzled) checkerboard pattern
  348. const uint32_t size = width * height;
  349. const uint32_t mask = 0xc0;
  350. for (uint32_t i = 0; i < size; ++i) {
  351. uint32_t bits = mask & i;
  352. ((uint32_t *)g_testTextureData)[i] = (bits == 0 || bits == mask) ? 0xff : 0x00;
  353. }
  354. //for (int i = 0; i < 512; i ++) {
  355. // ((uint32_t*)g_testTextureData)[256+width*256 + i + i * width] = 0xffff0000;
  356. //}
  357. // set up the texture control words
  358. err = sceGxmTextureInitLinear(
  359. &g_testTexture,
  360. g_testTextureData,
  361. format,
  362. width,
  363. height,
  364. 1);
  365. SCE_DBG_ASSERT(err == SCE_OK);
  366. // set linear filtering
  367. err = sceGxmTextureSetMagFilter(
  368. &g_testTexture,
  369. SCE_GXM_TEXTURE_FILTER_POINT);
  370. SCE_DBG_ASSERT(err == SCE_OK);
  371. err = sceGxmTextureSetMinFilter(
  372. &g_testTexture,
  373. SCE_GXM_TEXTURE_FILTER_POINT);
  374. SCE_DBG_ASSERT(err == SCE_OK);
  375. }
  376. void destroyTestTextureData(void)
  377. {
  378. heapFree(g_testTextureData);
  379. }
  380. void createOffscreenBuffer(void)
  381. {
  382. int err = SCE_OK;
  383. UNUSED(err);
  384. // allocate memory
  385. g_offscreenColorBufferData = heapAlloc(
  386. HEAP_TYPE_CDRAM_RW,
  387. OFFSCREEN_WIDTH*OFFSCREEN_HEIGHT*4,
  388. MAX(SCE_GXM_TEXTURE_ALIGNMENT, SCE_GXM_COLOR_SURFACE_ALIGNMENT));
  389. // set up the surface
  390. err = sceGxmColorSurfaceInit(
  391. &g_offscreenColorSurface,
  392. OFFSCREEN_COLOR_FORMAT,
  393. SCE_GXM_COLOR_SURFACE_LINEAR,
  394. (MSAA_MODE != SCE_GXM_MULTISAMPLE_NONE) ? SCE_GXM_COLOR_SURFACE_SCALE_MSAA_DOWNSCALE : SCE_GXM_COLOR_SURFACE_SCALE_NONE,
  395. SCE_GXM_OUTPUT_REGISTER_SIZE_32BIT,
  396. OFFSCREEN_WIDTH,
  397. OFFSCREEN_HEIGHT,
  398. OFFSCREEN_WIDTH,
  399. g_offscreenColorBufferData);
  400. SCE_DBG_ASSERT(err == SCE_OK);
  401. // set up the texture
  402. err = sceGxmTextureInitLinear(
  403. &g_offscreenTexture,
  404. g_offscreenColorBufferData,
  405. OFFSCREEN_TEXTURE_FORMAT,
  406. OFFSCREEN_WIDTH,
  407. OFFSCREEN_HEIGHT,
  408. 1);
  409. SCE_DBG_ASSERT(err == SCE_OK);
  410. // set linear filtering
  411. err = sceGxmTextureSetMagFilter(&g_offscreenTexture, SCE_GXM_TEXTURE_FILTER_LINEAR);
  412. SCE_DBG_ASSERT(err == SCE_OK);
  413. err = sceGxmTextureSetMinFilter(&g_offscreenTexture, SCE_GXM_TEXTURE_FILTER_LINEAR);
  414. SCE_DBG_ASSERT(err == SCE_OK);
  415. // create the depth/stencil surface
  416. const uint32_t alignedWidth = ALIGN(DISPLAY_WIDTH, SCE_GXM_TILE_SIZEX);
  417. const uint32_t alignedHeight = ALIGN(DISPLAY_HEIGHT, SCE_GXM_TILE_SIZEY);
  418. uint32_t sampleCount = alignedWidth*alignedHeight;
  419. uint32_t depthStrideInSamples = alignedWidth;
  420. if (MSAA_MODE == SCE_GXM_MULTISAMPLE_4X) {
  421. // samples increase in X and Y
  422. sampleCount *= 4;
  423. depthStrideInSamples *= 2;
  424. } else if (MSAA_MODE == SCE_GXM_MULTISAMPLE_2X) {
  425. // samples increase in Y only
  426. sampleCount *= 2;
  427. }
  428. g_offscreenDepthBufferData = heapAlloc(
  429. HEAP_TYPE_LPDDR_RW,
  430. 4*sampleCount,
  431. SCE_GXM_DEPTHSTENCIL_SURFACE_ALIGNMENT);
  432. err = sceGxmDepthStencilSurfaceInit(
  433. &g_offscreenDepthSurface,
  434. SCE_GXM_DEPTH_STENCIL_FORMAT_S8D24,
  435. SCE_GXM_DEPTH_STENCIL_SURFACE_TILED,
  436. depthStrideInSamples,
  437. g_offscreenDepthBufferData,
  438. NULL);
  439. // create a render target
  440. g_offscreenRenderTarget = createRenderTarget(OFFSCREEN_WIDTH, OFFSCREEN_HEIGHT, MSAA_MODE);
  441. }
  442. void destroyOffscreenBuffer(void)
  443. {
  444. // destroy render target
  445. destroyRenderTarget(g_offscreenRenderTarget);
  446. // free the memory
  447. heapFree(g_offscreenDepthBufferData);
  448. heapFree(g_offscreenColorBufferData);
  449. }
  450. void updateRender(void)
  451. {
  452. // copmute our matrices
  453. //Matrix4 offscreenProjectionMatrix = Matrix4::perspective(
  454. // SCE_MATH_PI/4.0f,
  455. // (float)OFFSCREEN_WIDTH/(float)OFFSCREEN_HEIGHT,
  456. // 0.1f,
  457. // 10.0f);
  458. //Matrix4 mainProjectionMatrix = Matrix4::perspective(
  459. // SCE_MATH_PI/4.0f,
  460. // (float)DISPLAY_WIDTH/(float)DISPLAY_HEIGHT,
  461. // 0.1f,
  462. // 10.0f);
  463. //Matrix4 viewMatrix = Matrix4::translation(Vector3(0.0f, 0.0f, -5.0f));
  464. //Matrix4 worldMatrix = Matrix4::rotation(g_rotationAngle, Vector3(0.707f, 0.707f, 0.0f));
  465. //g_viewMatrix = viewMatrix;
  466. //g_worldMatrix = worldMatrix;
  467. //g_projectionMatrix = mainProjectionMatrix;
  468. //g_offscreenWvpMatrix = offscreenProjectionMatrix * viewMatrix * worldMatrix;
  469. //g_mainWvpMatrix = mainProjectionMatrix * viewMatrix * worldMatrix;
  470. }
  471. void renderOffscreen(void)
  472. {
  473. // set up a scene, offscreen render target, no sync required
  474. sceGxmBeginScene(
  475. g_context,
  476. 0,
  477. g_offscreenRenderTarget,
  478. NULL,
  479. NULL,
  480. NULL,
  481. &g_offscreenColorSurface,
  482. &g_offscreenDepthSurface);
  483. // set clear shaders
  484. sceGxmSetVertexProgram(g_context, g_clearVertexProgram);
  485. sceGxmSetFragmentProgram(g_context, g_clearFragmentProgram);
  486. // set the fragment program constants
  487. void *fragmentDefaultBuffer;
  488. sceGxmReserveFragmentDefaultUniformBuffer(g_context, &fragmentDefaultBuffer);
  489. float clearColor[4] = { 0.25f, 0.25f, 0.25f, 0.0f };
  490. sceGxmSetUniformDataF(fragmentDefaultBuffer, g_clearColorParam, 0, 4, clearColor);
  491. // draw geometry
  492. sceGxmSetVertexStream(g_context, 0, g_clearVertices);
  493. sceGxmDraw(g_context, SCE_GXM_PRIMITIVE_TRIANGLES, SCE_GXM_INDEX_FORMAT_U16, g_clearIndices, 3);
  494. // render the cube
  495. sceGxmSetVertexProgram(g_context, g_cubeVertexProgram);
  496. sceGxmSetFragmentProgram(g_context, g_cubeFragmentProgram);
  497. sceGxmSetVertexStream(g_context, 0, g_cubeVertices);
  498. sceGxmSetFragmentTexture(g_context, 0, &g_testTexture);
  499. // set the vertex program constants
  500. void *vertexDefaultBuffer;
  501. #if defined(USE_DEFAULT_UB)
  502. void* real_default;
  503. sceGxmReserveVertexDefaultUniformBuffer(g_context, &real_default);
  504. vertexDefaultBuffer = real_default;
  505. // printf("default uniform buffer:0x%x size:%d\n", real_default, sceGxmProgramGetDefaultUniformBufferSize(&_binary_cube_v_gxp_start));
  506. #else
  507. vertexDefaultBuffer = g_cubeUniformBuffer;
  508. #endif
  509. // sceGxmSetUniformDataF(vertexDefaultBuffer, g_cubeWvpParam, 0, 16, (float *)&g_offscreenWvpMatrix);
  510. // draw the cube
  511. sceGxmDraw(g_context, SCE_GXM_PRIMITIVE_TRIANGLES, SCE_GXM_INDEX_FORMAT_U16, g_cubeIndices, 6);
  512. // stop rendering to the offscreen render target
  513. sceGxmEndScene(g_context, NULL, NULL);
  514. }
  515. void renderMain(void)
  516. {
  517. // set up a scene, main render target, synchronised with the back buffer sync
  518. sceGxmBeginScene(
  519. g_context,
  520. 0,
  521. g_mainRenderTarget,
  522. NULL,
  523. NULL,
  524. g_displayBufferSync[g_displayBackBufferIndex],
  525. &g_displaySurface[g_displayBackBufferIndex],
  526. &g_mainDepthSurface);
  527. // set clear shaders
  528. sceGxmSetVertexProgram(g_context, g_clearVertexProgram);
  529. sceGxmSetFragmentProgram(g_context, g_clearFragmentProgram);
  530. // set the fragment program constants
  531. void *fragmentDefaultBuffer;
  532. sceGxmReserveFragmentDefaultUniformBuffer(g_context, &fragmentDefaultBuffer);
  533. float clearColor[4] = { 0.2f, 0.2f, 0.2f, 0.0f };
  534. sceGxmSetUniformDataF(fragmentDefaultBuffer, g_clearColorParam, 0, 4, clearColor);
  535. // draw geometry
  536. sceGxmSetVertexStream(g_context, 0, g_clearVertices);
  537. sceGxmDraw(g_context, SCE_GXM_PRIMITIVE_TRIANGLES, SCE_GXM_INDEX_FORMAT_U16, g_clearIndices, 3);
  538. // render the cube
  539. sceGxmSetVertexProgram(g_context, g_cubeVertexProgram);
  540. sceGxmSetFragmentProgram(g_context, g_cubeFragmentProgram);
  541. sceGxmSetVertexStream(g_context, 0, g_cubeVertices);
  542. // sceGxmSetFragmentTexture(g_context, 0, &g_offscreenTexture);
  543. sceGxmSetFragmentTexture(g_context, 0, &g_testTexture);
  544. #if defined(USE_DEFAULT_UB)
  545. // set the vertex program constants
  546. void *vertexDefaultBuffer;
  547. void* real_default;
  548. sceGxmReserveVertexDefaultUniformBuffer(g_context, &real_default);
  549. vertexDefaultBuffer = real_default;
  550. #else
  551. vertexDefaultBuffer = g_cubeUniformBuffer;
  552. #endif
  553. // sceGxmSetUniformDataF(vertexDefaultBuffer, g_cubeWvpParam, 0, 16, (float *)&g_mainWvpMatrix);
  554. // draw the cube
  555. sceGxmDraw(g_context, SCE_GXM_PRIMITIVE_TRIANGLES, SCE_GXM_INDEX_FORMAT_U16, g_cubeIndices, 6);
  556. if (popup_) {
  557. #if defined(USE_DEFAULT_UB)
  558. vertexDefaultBuffer = g_magUniformBuffer;
  559. #endif
  560. sceGxmSetVertexStream(g_context, 0, g_magVertices);
  561. sceGxmSetVertexDefaultUniformBuffer(g_context, vertexDefaultBuffer);
  562. // sceGxmSetUniformDataF(vertexDefaultBuffer, g_cubeWvpParam, 0, 16, (float *)&g_magMvpMatrix);
  563. sceGxmDraw(g_context, SCE_GXM_PRIMITIVE_TRIANGLES, SCE_GXM_INDEX_FORMAT_U16, g_magIndices, 6);
  564. }
  565. // stop rendering to the main render target
  566. sceGxmEndScene(g_context, NULL, NULL);
  567. // PA heartbeat to notify end of frame
  568. sceGxmPadHeartbeat(
  569. &g_displaySurface[g_displayBackBufferIndex],
  570. g_displayBufferSync[g_displayBackBufferIndex]);
  571. }
  572. void getOffset(uint32_t *x, uint32_t *y)
  573. {
  574. *x = 460;
  575. *y = 50;
  576. }
  577. inline Matrix4 get_viewmatrix(float x, float y, float w, float h, float zmin, float zmax)
  578. {
  579. float wh = w * 0.5f;
  580. float hh = h * 0.5f;
  581. Matrix4 scale = Matrix4::scale(Vector3(wh, -hh, (zmax - zmin) * 0.5f));
  582. Matrix4 offset = Matrix4::translation(Vector3(wh, hh, (zmax + zmin) * 0.5f));
  583. Matrix4 viewport = offset * scale;
  584. return viewport;
  585. }
  586. static bool pointIntersect(const Vector4& __restrict__ point,
  587. const Matrix4& __restrict__ mv,
  588. const Matrix4& __restrict__ proj,
  589. const BasicVertex* pl,
  590. const Matrix4& __restrict__ viewport,
  591. Vector4& __restrict__ hpos,
  592. bool dump)
  593. {
  594. // using namespace sce::Vectormath::Simd::Aos;
  595. Vector4 v0(pl[0].x, pl[0].y, pl[0].z, 1.0f);
  596. Vector4 v1(pl[3].x, pl[3].y, pl[3].z, 1.0f);
  597. Vector4 v2(pl[1].x, pl[1].y, pl[1].z, 1.0f);
  598. Vector4 v3(pl[2].x, pl[2].y, pl[2].z, 1.0f);
  599. float vw = (pl[2].x - pl[0].x);
  600. float vh = (pl[0].y - pl[2].y);
  601. #if 0
  602. printf("prj = [%vf;\n", proj.getRow(0).get128());
  603. printf(" %vf;\n", proj.getRow(1).get128());
  604. printf(" %vf;\n", proj.getRow(2).get128());
  605. printf(" %vf]\n", proj.getRow(3).get128());
  606. #endif
  607. #if 0
  608. printf("vp = [%wf;\n", viewport.getRow(0).get128());
  609. printf(" %wf;\n", viewport.getRow(1).get128());
  610. printf(" %wf;\n", viewport.getRow(2).get128());
  611. printf(" %wf]\n", viewport.getRow(3).get128());
  612. #endif
  613. Matrix4 mvp = proj * mv;
  614. v0 = mvp * v0;
  615. v1 = mvp * v1;
  616. v2 = mvp * v2;
  617. v3 = mvp * v3;
  618. vec_float4 v0w = vdupq_n_f32(vgetq_lane_f32(v0.get128(), 3));
  619. vec_float4 v1w = vdupq_n_f32(vgetq_lane_f32(v1.get128(), 3));
  620. vec_float4 v2w = vdupq_n_f32(vgetq_lane_f32(v2.get128(), 3));
  621. vec_float4 v3w = vdupq_n_f32(vgetq_lane_f32(v3.get128(), 3));
  622. v0 = divPerElem(v0, Vector4(v0w));
  623. v1 = divPerElem(v1, Vector4(v1w));
  624. v2 = divPerElem(v2, Vector4(v2w));
  625. v3 = divPerElem(v3, Vector4(v3w));
  626. v0 = viewport * v0;
  627. v1 = viewport * v1;
  628. v2 = viewport * v2;
  629. v3 = viewport * v3;
  630. #if 0
  631. printf("v0:%wf\n", v0.get128());
  632. printf("v1:%wf\n", v1.get128());
  633. printf("v2:%wf\n", v2.get128());
  634. printf("v3:%wf\n", v3.get128());
  635. #endif
  636. // Vector4 p = offset * point;
  637. Vector4 p = point;
  638. Vector3 p3 = point.getXYZ();
  639. Vector3 pv = Vector3(0.f, 0.f, -1.f);
  640. Vector3 u0 = (v1 - v0).getXYZ();
  641. Vector3 u1 = (v2 - v1).getXYZ();
  642. Vector3 u2 = (v0 - v2).getXYZ();
  643. Vector3 unorm = normalize(cross((v1 - v0).getXYZ(), (v2 - v0).getXYZ()));
  644. float n = dot(v0.getXYZ() - p3, unorm);
  645. float pvn = dot(pv, unorm);
  646. Vector4 upd = Vector4(p3 + pv * (n / pvn), 1.f); // p->p+v perspects on plane(v0 dot unorm)
  647. Vector3 l0 = (v2 - v1).getXYZ();
  648. Vector3 l1 = (v3 - v2).getXYZ();
  649. Vector3 l2 = (v1 - v3).getXYZ();
  650. Vector3 lnorm = normalize(cross((v2 - v1).getXYZ(), (v3 - v1).getXYZ()));
  651. // vec_uchar16 v2scale = (vec_uchar16){};
  652. // Matrix4 m = Matrix4::orthographic(v0.getX(), v2.getX(), v1.getY(), v0.getY(), v2.getZ(), v0.getZ());
  653. // upd = m * upd;
  654. // Vector4 updw(vec_splat(upd.get128(), 3));
  655. // upd = divPerElem(upd, updw);
  656. Vector3 ux0 = cross(u0, (p - v0).getXYZ());
  657. Vector3 ux1 = cross(u1, (p - v1).getXYZ());
  658. Vector3 ux2 = cross(u2, (p - v2).getXYZ());
  659. Vector3 lx0 = cross(l0, (p - v1).getXYZ());
  660. Vector3 lx1 = cross(l1, (p - v2).getXYZ());
  661. Vector3 lx2 = cross(l2, (p - v3).getXYZ());
  662. float fux0 = dot(ux0, unorm);
  663. float fux1 = dot(ux1, unorm);
  664. float fux2 = dot(ux2, unorm);
  665. Vector4 k = inverse(viewport * proj * mv) * upd;
  666. vec_float4 kw = vdupq_n_f32(vgetq_lane_f32(k.get128(), 3)); // vec_splat(v, 3)
  667. k = divPerElem(k, Vector4(kw));
  668. //printf("k:[%wf]\n", k.get128());
  669. hpos = mulPerElem(Vector4((float)WEBVIEW_WIDTH, (float)WEBVIEW_HEIGHT, 0.f, 1.f), mulPerElem(k - Vector4(-vw/2.f, vh/2.f, 0.f, 0.f), Vector4(1.f/vw, -1.f/vh, 0.f, 1.f)));
  670. // pivot = mulPerElem(mulPerElem(upd - v0, Vector4(v0w)), k);
  671. if ((fux0 > 0.f && fux1 > 0.f && fux2 > 0.f) || (fux0 < 0.f && fux1 < 0.f && fux2 < 0.f)) {
  672. #if 0
  673. if (dump) {
  674. printf("v: point0 = [%vf]\n", v0.get128());
  675. printf("v: point1 = [%vf]\n", v1.get128());
  676. printf("v: point2 = [%vf]\n", v2.get128());
  677. printf("v: point3 = [%vf]\n", v3.get128());
  678. printf("upd = [%vf]\n", upd.get128());
  679. printf("k = [%vf]\n", k.get128());
  680. }
  681. #endif
  682. // printf("org = [%vf]\n", org.get128());
  683. return true; // hit
  684. }
  685. float flx0 = dot(lx0, lnorm);
  686. float flx1 = dot(lx1, lnorm);
  687. float flx2 = dot(lx2, lnorm);
  688. if ((flx0 > 0.f && flx1 > 0.f && flx2 > 0.f) || (flx0 < 0.f && flx1 < 0.f && flx2 < 0.f)) {
  689. #if 0
  690. if (dump) {
  691. printf("v: point0 = [%vf]\n", v0.get128());
  692. printf("v: point1 = [%vf]\n", v1.get128());
  693. printf("v: point2 = [%vf]\n", v2.get128());
  694. printf("v: point3 = [%vf]\n", v3.get128());
  695. printf("upd = [%vf]\n", upd.get128());
  696. printf("k = [%vf]\n", k.get128());
  697. }
  698. #endif
  699. return true; // hit
  700. }
  701. return false; // miss
  702. }
  703. bool convertScreenToLocalCSS(short& x, short& y)
  704. {
  705. float X = x;
  706. float Y = y;
  707. X -= DISPLAY_WIDTH/2;
  708. Y -= DISPLAY_HEIGHT/2;
  709. X *= (float)WEBVIEW_WIDTH / DISPLAY_WIDTH;
  710. Y *= (float)WEBVIEW_HEIGHT / DISPLAY_HEIGHT;
  711. X += WEBVIEW_WIDTH/2;
  712. Y += WEBVIEW_HEIGHT/2;
  713. x = X;
  714. y = Y;
  715. return true;
  716. Vector4 pt((float)x, (float)y, 0.f, 1.f);
  717. Matrix4 viewport = get_viewmatrix(0.f, 0.f, (float)DISPLAY_WIDTH, (float)DISPLAY_HEIGHT, .1f, 10.f);
  718. #if 0
  719. Matrix4 mat = Matrix4::translation(viewport.getTranslation()) * Matrix4::scale(Vector3(1.f, -1.f, 1.f));
  720. Vector4 p = mat * Vector4(pt.getXYZ(), 1.f);
  721. // hit test
  722. #else
  723. Vector4 p = pt; // the point is in the dev-coord
  724. #endif
  725. Matrix4 local = Matrix4::identity();
  726. // Matrix4 mv = local *g_worldMatrix * g_viewMatrix;
  727. Vector4 hitpos;
  728. //printf("pt:(%d, %d) -> dev:[%vf]\n", x, y, p.get128());
  729. //if (pointIntersect(p, mv, g_projectionMatrix, g_cubeVertices, viewport, hitpos, false)) {
  730. // float tmp[4] __attribute__ ((aligned(16)));
  731. // memcpy(tmp, &hitpos, 16);
  732. // x = (short)tmp[0];
  733. // y = (short)tmp[1];
  734. // // printf("real pt:(%f, %f)\n", tmp[0], tmp[1]);
  735. // return true;
  736. //}
  737. return false;
  738. }
  739. void popup_mag(float x, float y, float z, float w, float h, float tx, float ty, float tw, float th)
  740. {
  741. //popup_ = true;
  742. //Matrix4 m = Matrix4::orthographic(-3.f, 3.f, -3.f, 3.f, 0.0001f, 100.f);
  743. //g_magMvpMatrix = m * Matrix4::translation(Vector3(x, y, z - 0.1f)) * Matrix4::scale(Vector3(w, h, 1.f));
  744. //update_mag(tx, ty, tw, th);
  745. }
  746. void update_mag(float x, float y, float rx, float ry)
  747. {
  748. float nx = x * (1.f /(float)WEBVIEW_WIDTH);
  749. float nw = rx * (0.5f/(float)WEBVIEW_WIDTH);
  750. float ny = y * (1.f /(float)WEBVIEW_HEIGHT);
  751. float nh = ry * (0.5f/(float)WEBVIEW_HEIGHT);
  752. float u0 = nx - nw;
  753. float u1 = nx + nw;
  754. float v0 = ny - nh;
  755. float v1 = ny + nh;
  756. //printf("uv0:(%f, %f) - uv1:(%f, %f) : w:%d h:%d\n", u0, v0, u1, v1, int((u1-u0)*(float)WEBVIEW_WIDTH), int((v1-v0)*(float)WEBVIEW_HEIGHT));
  757. g_magVertices[0].u = u0;
  758. g_magVertices[0].v = v0;
  759. g_magVertices[1].u = u1;
  760. g_magVertices[1].v = v0;
  761. g_magVertices[2].u = u1;
  762. g_magVertices[2].v = v1;
  763. g_magVertices[3].u = u0;
  764. g_magVertices[3].v = v1;
  765. }
  766. void dismiss_mag()
  767. {
  768. popup_ = false;
  769. }