OpenSource.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637
  1. #include "bsp.h"
  2. #include "cache.h"
  3. #include "collection.h"
  4. #include "mempools.h"
  5. #include "common.h"
  6. #include "texture.h"
  7. #include "atto/app.h"
  8. #define ATTO_GL_DEBUG
  9. #define ATTO_GL_H_IMPLEMENT
  10. #include "atto/gl.h"
  11. #include "atto/math.h"
  12. static char persistent_data[32*1024*1024];
  13. static char temp_data[32*1024*1024];
  14. static struct Stack stack_temp = {
  15. .storage = temp_data,
  16. .size = sizeof(temp_data),
  17. .cursor = 0
  18. };
  19. static struct Stack stack_persistent = {
  20. .storage = persistent_data,
  21. .size = sizeof(persistent_data),
  22. .cursor = 0
  23. };
  24. struct SimpleCamera {
  25. struct AVec3f pos, dir, up;
  26. struct AMat3f axes;
  27. struct AMat4f projection;
  28. struct AMat4f view_projection;
  29. };
  30. static void simplecamRecalc(struct SimpleCamera *cam) {
  31. cam->dir = aVec3fNormalize(cam->dir);
  32. const struct AVec3f
  33. z = aVec3fNeg(cam->dir),
  34. x = aVec3fNormalize(aVec3fCross(cam->up, z)),
  35. y = aVec3fCross(z, x);
  36. cam->axes = aMat3fv(x, y, z);
  37. const struct AMat3f axes_inv = aMat3fTranspose(cam->axes);
  38. cam->view_projection = aMat4fMul(cam->projection,
  39. aMat4f3(axes_inv, aVec3fMulMat(axes_inv, aVec3fNeg(cam->pos))));
  40. }
  41. static void simplecamProjection(struct SimpleCamera *cam, float near, float far, float horizfov, float aspect) {
  42. const float w = 2.f * near * tanf(horizfov / 2.f), h = w / aspect;
  43. //aAppDebugPrintf("%f %f %f %f -> %f %f", near, far, horizfov, aspect, w, h);
  44. cam->projection = aMat4fPerspective(near, far, w, h);
  45. }
  46. static void simplecamLookAt(struct SimpleCamera *cam, struct AVec3f pos, struct AVec3f at, struct AVec3f up) {
  47. cam->pos = pos;
  48. cam->dir = aVec3fNormalize(aVec3fSub(at, pos));
  49. cam->up = up;
  50. simplecamRecalc(cam);
  51. }
  52. static void simplecamMove(struct SimpleCamera *cam, struct AVec3f v) {
  53. cam->pos = aVec3fAdd(cam->pos, aVec3fMulf(cam->axes.X, v.x));
  54. cam->pos = aVec3fAdd(cam->pos, aVec3fMulf(cam->axes.Y, v.y));
  55. cam->pos = aVec3fAdd(cam->pos, aVec3fMulf(cam->axes.Z, v.z));
  56. }
  57. static void simplecamRotateYaw(struct SimpleCamera *cam, float yaw) {
  58. const struct AMat3f rot = aMat3fRotateAxis(cam->up, yaw);
  59. cam->dir = aVec3fMulMat(rot, cam->dir);
  60. }
  61. static void simplecamRotatePitch(struct SimpleCamera *cam, float pitch) {
  62. /* TODO limit pitch */
  63. const struct AMat3f rot = aMat3fRotateAxis(cam->axes.X, pitch);
  64. cam->dir = aVec3fMulMat(rot, cam->dir);
  65. }
  66. #define COUNTOF(v) (sizeof(v) / sizeof(*(v)))
  67. static const float fsquad_vertices[] = {
  68. -1.f, 1.f, -1.f, -1.f, 1.f, 1.f, 1.f, -1.f
  69. };
  70. static const char fsquad_vertex_src[] =
  71. "attribute vec2 av2_pos;\n"
  72. "varying vec2 vv2_pos;\n"
  73. "void main() {\n"
  74. "vv2_pos = av2_pos;\n"
  75. "gl_Position = vec4(vv2_pos, 0., 1.);\n"
  76. "}\n";
  77. static const char fsquad_fragment_src[] =
  78. "uniform sampler2D us2_tex;\n"
  79. "varying vec2 vv2_pos;\n"
  80. "void main() {\n"
  81. "gl_FragColor = texture2D(us2_tex, vv2_pos * .5 + .5);\n"
  82. "}\n";
  83. static struct {
  84. AGLDrawSource source;
  85. AGLDrawMerge merge;
  86. AGLProgramUniform uniforms[2];
  87. AGLAttribute attrib_pos;
  88. } fsquad;
  89. static void fsquadInit() {
  90. fsquad.merge.depth.mode = AGLDM_Disabled;
  91. fsquad.merge.blend.enable = 0;
  92. fsquad.source.program = aGLProgramCreateSimple(fsquad_vertex_src, fsquad_fragment_src);
  93. if (fsquad.source.program < 1) {
  94. aAppDebugPrintf("Shader compilation error: %s", a_gl_error);
  95. aAppTerminate(-1);
  96. }
  97. fsquad.source.primitive.mode = GL_TRIANGLE_STRIP;
  98. fsquad.source.primitive.cull_mode = AGLCM_Disable;
  99. fsquad.source.primitive.front_face = AGLFF_CounterClockwise;
  100. fsquad.source.primitive.first = 0;
  101. fsquad.source.primitive.index.buffer = 0;
  102. fsquad.source.primitive.index.type = 0;
  103. fsquad.source.primitive.index.data.ptr = 0;
  104. fsquad.source.primitive.count = 4;
  105. fsquad.source.uniforms.p = fsquad.uniforms;
  106. fsquad.source.uniforms.n = COUNTOF(fsquad.uniforms);
  107. fsquad.source.attribs.p = &fsquad.attrib_pos;
  108. fsquad.source.attribs.n = 1;
  109. fsquad.attrib_pos.name = "av2_pos";
  110. fsquad.attrib_pos.size = 2;
  111. fsquad.attrib_pos.type = GL_FLOAT;
  112. fsquad.attrib_pos.normalized = GL_FALSE;
  113. fsquad.attrib_pos.stride = 2 * sizeof(float);
  114. fsquad.attrib_pos.ptr = fsquad_vertices;
  115. fsquad.attrib_pos.buffer = 0;
  116. fsquad.uniforms[0].name = "uf_aspect";
  117. fsquad.uniforms[0].type = AGLAT_Float;
  118. fsquad.uniforms[0].count = 1;
  119. fsquad.uniforms[1].name = "us2_tex";
  120. fsquad.uniforms[1].type = AGLAT_Texture;
  121. fsquad.uniforms[1].count = 1;
  122. }
  123. static void fsquadDraw(float aspect, const AGLTexture *tex, const AGLDrawTarget *target) {
  124. fsquad.uniforms[0].value.pf = &aspect;
  125. fsquad.uniforms[1].value.texture = tex;
  126. aGLDraw(&fsquad.source, &fsquad.merge, target);
  127. }
  128. static const float aabb_draw_vertices[] = {
  129. 0.f, 0.f, 0.f,
  130. 0.f, 0.f, 1.f,
  131. 0.f, 1.f, 1.f,
  132. 0.f, 1.f, 0.f,
  133. 1.f, 0.f, 0.f,
  134. 1.f, 0.f, 1.f,
  135. 1.f, 1.f, 1.f,
  136. 1.f, 1.f, 0.f
  137. };
  138. static const uint16_t aabb_draw_indices[] = {
  139. 0, 1, 1, 2, 2, 3, 3, 0,
  140. 4, 5, 5, 6, 6, 7, 7, 4,
  141. 0, 4, 1, 5, 2, 6, 3, 7
  142. };
  143. static const char aabb_draw_vertex_src[] =
  144. "attribute vec3 av3_pos;\n"
  145. "uniform mat4 um4_MVP;\n"
  146. "uniform vec3 uv3_mul, uv3_add;\n"
  147. "varying vec3 vv3_pos;\n"
  148. "void main() {\n"
  149. "vv3_pos = av3_pos;\n"
  150. "gl_Position = um4_MVP * vec4(av3_pos * uv3_mul + uv3_add, 1.);\n"
  151. "}\n";
  152. static const char aabb_draw_fragment_src[] =
  153. "uniform vec3 uv3_color;\n"
  154. "varying vec3 vv3_pos;\n"
  155. "void main() {\n"
  156. "gl_FragColor = vec4(vv3_pos * uv3_color, 1.);\n"
  157. "}\n";
  158. enum { AABBDUniformMVP, AABBDUniformMul, AABBDUniformAdd, AABBDUniformColor, AABBDUniform_COUNT };
  159. struct AABBDraw {
  160. struct AVec3f min, max, color;
  161. const struct AMat4f *mvp;
  162. const AGLDrawTarget *target;
  163. };
  164. static struct {
  165. AGLProgram program;
  166. } aabb_draw;
  167. static void aabbDraw(const struct AABBDraw *draw) {
  168. AGLDrawSource source;
  169. AGLDrawMerge merge;
  170. AGLProgramUniform uniforms[AABBDUniform_COUNT];
  171. AGLAttribute attrib_pos;
  172. const struct AVec3f mul = aVec3fSub(draw->max, draw->min);
  173. merge.depth.mode = AGLDM_Disabled;
  174. merge.blend.enable = 0;
  175. if (aabb_draw.program < 1) {
  176. aabb_draw.program = aGLProgramCreateSimple(aabb_draw_vertex_src, aabb_draw_fragment_src);
  177. if (aabb_draw.program < 1) {
  178. aAppDebugPrintf("Shader compilation error: %s", a_gl_error);
  179. aAppTerminate(-1);
  180. }
  181. }
  182. source.program = aabb_draw.program;
  183. source.primitive.mode = GL_LINES;
  184. source.primitive.cull_mode = AGLCM_Back;//AGLCM_Disable;
  185. source.primitive.front_face = AGLFF_CounterClockwise;
  186. source.primitive.first = 0;
  187. source.primitive.index.buffer = 0;
  188. #if 1
  189. source.primitive.index.type = GL_UNSIGNED_SHORT;
  190. source.primitive.index.data.ptr = aabb_draw_indices;
  191. source.primitive.count = COUNTOF(aabb_draw_indices);
  192. #else
  193. source.primitive.index.type = 0;//GL_UNSIGNED_SHORT;
  194. source.primitive.index.data.ptr = 0;//aabb_draw_indices;
  195. source.primitive.count = 8;(void)(aabb_draw_indices);//COUNTOF(aabb_draw_indices);
  196. #endif
  197. source.uniforms.p = uniforms;
  198. source.uniforms.n = AABBDUniform_COUNT;
  199. source.attribs.p = &attrib_pos;
  200. source.attribs.n = 1;
  201. attrib_pos.name = "av3_pos";
  202. attrib_pos.size = 3;
  203. attrib_pos.type = GL_FLOAT;
  204. attrib_pos.normalized = GL_FALSE;
  205. attrib_pos.stride = 3 * sizeof(float);
  206. attrib_pos.ptr = aabb_draw_vertices;
  207. attrib_pos.buffer = 0;
  208. uniforms[AABBDUniformMVP].name = "um4_MVP";
  209. uniforms[AABBDUniformMVP].type = AGLAT_Mat4;
  210. uniforms[AABBDUniformMVP].count = 1;
  211. uniforms[AABBDUniformMVP].value.pf = &draw->mvp->X.x;
  212. uniforms[AABBDUniformMul].name = "uv3_mul";
  213. uniforms[AABBDUniformMul].type = AGLAT_Vec3;
  214. uniforms[AABBDUniformMul].count = 1;
  215. uniforms[AABBDUniformMul].value.pf = &mul.x;
  216. uniforms[AABBDUniformAdd].name = "uv3_add";
  217. uniforms[AABBDUniformAdd].type = AGLAT_Vec3;
  218. uniforms[AABBDUniformAdd].count = 1;
  219. uniforms[AABBDUniformAdd].value.pf = &draw->min.x;
  220. uniforms[AABBDUniformColor].name = "uv3_color";
  221. uniforms[AABBDUniformColor].type = AGLAT_Vec3;
  222. uniforms[AABBDUniformColor].count = 1;
  223. uniforms[AABBDUniformColor].value.pf = &draw->color.x;
  224. aGLDraw(&source, &merge, draw->target);
  225. }
  226. static const char vertex_src[] =
  227. "attribute vec3 av3_pos, av3_normal;\n"
  228. "attribute vec2 av2_lightmap, av2_base0_uv;\n"
  229. "uniform mat4 um4_VP;\n"
  230. "varying vec2 vv2_lightmap, vv2_base0_uv;\n"
  231. "varying vec3 vv3_normal;\n"
  232. "void main() {\n"
  233. "vv2_lightmap = av2_lightmap;\n"
  234. "vv2_base0_uv = av2_base0_uv;\n"
  235. "vv3_normal = av3_normal;\n"
  236. "gl_Position = um4_VP * vec4(av3_pos, 1.);\n"
  237. "}\n";
  238. static const char fragment_src[] =
  239. "uniform sampler2D us2_lightmap, tex_base0, tex_base1;\n"
  240. "uniform vec2 uv2_lightmap_size;\n"
  241. "uniform vec2 tex_base0_size, tex_base1_size;\n"
  242. "varying vec2 vv2_lightmap, vv2_base0_uv;\n"
  243. "varying vec3 vv3_normal;\n"
  244. "uniform float uf_lmn;\n"
  245. "void main() {\n"
  246. "vec3 tc = vec3(fract(vv2_base0_uv/tex_base0_size), 0.);\n"
  247. //"vec4 albedo = vec4(fract(vv2_base0_uv/tex_base1_size), 0., 1.);\n"
  248. "vec4 albedo = texture2D(tex_base0, vv2_base0_uv/tex_base0_size);\n"
  249. // "+ texture2D(tex_base1, vv2_base0_uv/tex_base1_size);\n"
  250. "vec3 lm = texture2D(us2_lightmap, vv2_lightmap).xyz;\n"
  251. "vec3 color = albedo.xyz * lm;\n"
  252. "gl_FragColor = vec4(mix(color, tc, uf_lmn), 1.);\n"
  253. //"gl_FragColor = texture2D(us2_lightmap, vv2_lightmap);\n"
  254. "}\n";
  255. enum {
  256. UniformM, UniformVP,
  257. UniformLightmap, UniformLightmapSize,
  258. UniformTextureBase0, UniformTextureBase0Size,
  259. UniformTextureBase1, UniformTextureBase1Size,
  260. UniformLMN, Uniform_COUNT };
  261. enum { AttribPos, AttribNormal, AttribLightmapUV, AttribTextureUV, Attrib_COUNT };
  262. static struct {
  263. struct SimpleCamera camera;
  264. int forward, right, run;
  265. struct AVec3f center;
  266. float R;
  267. float lmn;
  268. AGLDrawTarget screen;
  269. AGLDrawSource source;
  270. AGLDrawMerge merge;
  271. AGLAttribute attribs[Attrib_COUNT];
  272. AGLProgramUniform uniforms[Uniform_COUNT];
  273. struct BSPModel worldspawn;
  274. struct AMat4f model;
  275. } g;
  276. static void opensrcInit(struct ICollection *collection, const char *map) {
  277. g.source.program = aGLProgramCreateSimple(vertex_src, fragment_src);
  278. if (g.source.program < 1) {
  279. aAppDebugPrintf("Shader compilation error: %s", a_gl_error);
  280. aAppTerminate(-1);
  281. }
  282. fsquadInit();
  283. cacheInit(&stack_persistent);
  284. {
  285. Texture tex_placeholder;
  286. const uint16_t pixels[] = {
  287. 0xf81f, 0x07e0, 0x07e0, 0xf81f
  288. };
  289. tex_placeholder.gltex = aGLTextureCreate();
  290. AGLTextureUploadData up = {
  291. .width = 2,
  292. .height = 2,
  293. .format = AGLTF_U565_RGB,
  294. .pixels = pixels
  295. };
  296. aGLTextureUpload(&tex_placeholder.gltex, &up);
  297. cachePutTexture("opensource/placeholder", &tex_placeholder);
  298. }
  299. struct BSPLoadModelContext loadctx = {
  300. .collection = collection,
  301. .persistent = &stack_persistent,
  302. .tmp = &stack_temp,
  303. .model = &g.worldspawn
  304. };
  305. const enum BSPLoadResult result = bspLoadWorldspawn(loadctx, map);
  306. if (result != BSPLoadResult_Success) {
  307. aAppDebugPrintf("Cannot load map \"%s\": %d", map, result);
  308. aAppTerminate(-2);
  309. }
  310. aAppDebugPrintf("Loaded %s to %u draw calls", map, g.worldspawn.draws_count);
  311. aAppDebugPrintf("AABB (%f, %f, %f) - (%f, %f, %f)",
  312. g.worldspawn.aabb.min.x,
  313. g.worldspawn.aabb.min.y,
  314. g.worldspawn.aabb.min.z,
  315. g.worldspawn.aabb.max.x,
  316. g.worldspawn.aabb.max.y,
  317. g.worldspawn.aabb.max.z);
  318. g.center = aVec3fMulf(aVec3fAdd(g.worldspawn.aabb.min, g.worldspawn.aabb.max), .5f);
  319. g.R = aVec3fLength(aVec3fSub(g.worldspawn.aabb.max, g.worldspawn.aabb.min)) * .5f;
  320. aAppDebugPrintf("Center %f, %f, %f, R~=%f", g.center.x, g.center.y, g.center.z, g.R);
  321. g.model = aMat4fIdentity();
  322. g.source.primitive.mode = GL_TRIANGLES;
  323. g.source.primitive.first = 0;
  324. g.source.primitive.cull_mode = AGLCM_Back;
  325. g.source.primitive.front_face = AGLFF_CounterClockwise;
  326. g.source.primitive.index.type = GL_UNSIGNED_SHORT;
  327. g.source.uniforms.p = g.uniforms;
  328. g.source.uniforms.n = Uniform_COUNT;
  329. g.source.attribs.p = g.attribs;
  330. g.source.attribs.n = Attrib_COUNT;
  331. g.attribs[AttribPos].name = "av3_pos";
  332. g.attribs[AttribPos].size = 3;
  333. g.attribs[AttribPos].type = GL_FLOAT;
  334. g.attribs[AttribPos].normalized = GL_FALSE;
  335. g.attribs[AttribPos].stride = sizeof(struct BSPModelVertex);
  336. g.attribs[AttribPos].ptr = 0;
  337. g.attribs[AttribNormal].name = "av3_normal";
  338. g.attribs[AttribNormal].size = 3;
  339. g.attribs[AttribNormal].type = GL_FLOAT;
  340. g.attribs[AttribNormal].normalized = GL_FALSE;
  341. g.attribs[AttribNormal].stride = sizeof(struct BSPModelVertex);
  342. g.attribs[AttribNormal].ptr = (void*)offsetof(struct BSPModelVertex, normal);
  343. g.attribs[AttribLightmapUV].name = "av2_lightmap";
  344. g.attribs[AttribLightmapUV].size = 2;
  345. g.attribs[AttribLightmapUV].type = GL_FLOAT;
  346. g.attribs[AttribLightmapUV].normalized = GL_FALSE;
  347. g.attribs[AttribLightmapUV].stride = sizeof(struct BSPModelVertex);
  348. g.attribs[AttribLightmapUV].ptr = (void*)offsetof(struct BSPModelVertex, lightmap_uv);
  349. g.attribs[AttribTextureUV].name = "av2_base0_uv";
  350. g.attribs[AttribTextureUV].size = 2;
  351. g.attribs[AttribTextureUV].type = GL_FLOAT;
  352. g.attribs[AttribTextureUV].normalized = GL_FALSE;
  353. g.attribs[AttribTextureUV].stride = sizeof(struct BSPModelVertex);
  354. g.attribs[AttribTextureUV].ptr = (void*)offsetof(struct BSPModelVertex, base0_uv);
  355. g.uniforms[UniformM].name = "um4_M";
  356. g.uniforms[UniformM].type = AGLAT_Mat4;
  357. g.uniforms[UniformM].count = 1;
  358. g.uniforms[UniformM].value.pf = &g.model.X.x;
  359. g.uniforms[UniformVP].name = "um4_VP";
  360. g.uniforms[UniformVP].type = AGLAT_Mat4;
  361. g.uniforms[UniformVP].count = 1;
  362. g.uniforms[UniformVP].value.pf = &g.camera.view_projection.X.x;
  363. g.uniforms[UniformLightmap].name = "us2_lightmap";
  364. g.uniforms[UniformLightmap].type = AGLAT_Texture;
  365. g.uniforms[UniformLightmap].count = 1;
  366. g.uniforms[UniformLightmapSize].name = "uv2_lightmap_size";
  367. g.uniforms[UniformLightmapSize].type = AGLAT_Vec2;
  368. g.uniforms[UniformLightmapSize].count = 1;
  369. g.uniforms[UniformTextureBase0].name = "tex_base0";
  370. g.uniforms[UniformTextureBase0].type = AGLAT_Texture;
  371. g.uniforms[UniformTextureBase0].count = 1;
  372. g.uniforms[UniformTextureBase0Size].name = "tex_base0_size";
  373. g.uniforms[UniformTextureBase0Size].type = AGLAT_Vec2;
  374. g.uniforms[UniformTextureBase0Size].count = 1;
  375. g.uniforms[UniformTextureBase1].name = "tex_base1";
  376. g.uniforms[UniformTextureBase1].type = AGLAT_Texture;
  377. g.uniforms[UniformTextureBase1].count = 1;
  378. g.uniforms[UniformTextureBase1Size].name = "tex_base1_size";
  379. g.uniforms[UniformTextureBase1Size].type = AGLAT_Vec2;
  380. g.uniforms[UniformTextureBase1Size].count = 1;
  381. g.uniforms[UniformLMN].name = "uf_lmn";
  382. g.uniforms[UniformLMN].type = AGLAT_Float;
  383. g.uniforms[UniformLMN].count = 1;
  384. g.uniforms[UniformLMN].value.pf = &g.lmn;
  385. g.lmn = 0;
  386. g.merge.blend.enable = 0;
  387. g.merge.depth.mode = AGLDM_TestAndWrite;
  388. g.merge.depth.func = AGLDF_Less;
  389. g.screen.framebuffer = 0;
  390. const float t = 0;
  391. simplecamLookAt(&g.camera,
  392. aVec3fAdd(g.center, aVec3fMulf(aVec3f(cosf(t*.5), sinf(t*.5), .25f), g.R*.5f)),
  393. g.center, aVec3f(0.f, 0.f, 1.f));
  394. }
  395. static void drawBSPDraw(const struct BSPDraw *draw) {
  396. g.source.primitive.index.data.offset = sizeof(uint16_t) * draw->start;
  397. g.source.primitive.count = draw->count;
  398. g.attribs[AttribPos].buffer =
  399. g.attribs[AttribNormal].buffer =
  400. g.attribs[AttribTextureUV].buffer =
  401. g.attribs[AttribLightmapUV].buffer = &draw->vbo;
  402. struct AVec2f tex0_size = aVec2f(1.f, 1.f);
  403. struct AVec2f tex1_size = aVec2f(1.f, 1.f);
  404. const struct Texture *texture = draw->material->base_texture[0];
  405. if (!texture)
  406. texture = cacheGetTexture("opensource/placeholder");
  407. g.uniforms[UniformTextureBase0Size].value.pf = &tex0_size.x;
  408. tex0_size = aVec2f(texture->gltex.width, texture->gltex.height);
  409. g.uniforms[UniformTextureBase0].value.texture = &texture->gltex;
  410. texture = draw->material->base_texture[1];
  411. if (!texture)
  412. texture = cacheGetTexture("opensource/placeholder");
  413. tex1_size = aVec2f(texture->gltex.width, texture->gltex.height);
  414. g.uniforms[UniformTextureBase1Size].value.pf = &tex1_size.x;
  415. g.uniforms[UniformTextureBase1].value.texture = &texture->gltex;
  416. aGLDraw(&g.source, &g.merge, &g.screen);
  417. }
  418. static void drawModel(const struct BSPModel *model) {
  419. const struct AVec2f lm_size = aVec2f(model->lightmap.width, model->lightmap.height);
  420. g.uniforms[UniformLightmap].value.texture = &model->lightmap;
  421. g.uniforms[UniformLightmapSize].value.pf = &lm_size.x;
  422. g.source.primitive.index.buffer = &model->ibo;
  423. for (int i = 0; i < model->draws_count /*&& i < 200*/; ++i)
  424. drawBSPDraw(model->draws + i);
  425. }
  426. static void opensrcResize(ATimeUs timestamp, unsigned int old_w, unsigned int old_h) {
  427. (void)(timestamp); (void)(old_w); (void)(old_h);
  428. g.screen.viewport.x = g.screen.viewport.y = 0;
  429. g.screen.viewport.w = a_app_state->width;
  430. g.screen.viewport.h = a_app_state->height;
  431. simplecamProjection(&g.camera, 1.f, g.R * 10.f, 3.1415926f/2.f, (float)a_app_state->width / (float)a_app_state->height);
  432. simplecamRecalc(&g.camera);
  433. }
  434. static void opensrcPaint(ATimeUs timestamp, float dt) {
  435. (void)(timestamp); (void)(dt);
  436. if (0) {
  437. const float t = timestamp * 1e-6f;
  438. simplecamLookAt(&g.camera,
  439. aVec3fAdd(g.center, aVec3fMulf(aVec3f(cosf(t*.5), sinf(t*.5), .25f), g.R*.5f)),
  440. g.center, aVec3f(0.f, 0.f, 1.f));
  441. } else {
  442. float move = dt * (g.run?3000.f:300.f);
  443. simplecamMove(&g.camera, aVec3f(g.right * move, 0.f, -g.forward * move));
  444. simplecamRecalc(&g.camera);
  445. }
  446. AGLClearParams clear;
  447. clear.r = clear.g = clear.b = 0;
  448. clear.depth = 1.f;
  449. clear.bits = AGLCB_ColorAndDepth;
  450. aGLClear(&clear, &g.screen);
  451. if (0)
  452. fsquadDraw(1., &g.worldspawn.lightmap, &g.screen);
  453. drawModel(&g.worldspawn);
  454. if (0) {
  455. const struct AABBDraw aabb = {
  456. .min = g.worldspawn.aabb.min,
  457. .max = g.worldspawn.aabb.max,
  458. .color = aVec3ff(1),
  459. .mvp = &g.camera.view_projection,
  460. .target = &g.screen
  461. };
  462. aabbDraw(&aabb);
  463. }
  464. }
  465. static void opensrcKeyPress(ATimeUs timestamp, AKey key, int pressed) {
  466. (void)(timestamp); (void)(key); (void)(pressed);
  467. //printf("KEY %u %d %d\n", timestamp, key, pressed);
  468. switch (key) {
  469. case AK_Esc:
  470. if (!pressed) break;
  471. if (a_app_state->grabbed)
  472. aAppGrabInput(0);
  473. else
  474. aAppTerminate(0);
  475. break;
  476. case AK_W: g.forward += pressed?1:-1; break;
  477. case AK_S: g.forward += pressed?-1:1; break;
  478. case AK_A: g.right += pressed?-1:1; break;
  479. case AK_D: g.right += pressed?1:-1; break;
  480. case AK_LeftShift: g.run = pressed; break;
  481. case AK_E: g.lmn = pressed; break;
  482. default: break;
  483. }
  484. }
  485. static void opensrcPointer(ATimeUs timestamp, int dx, int dy, unsigned int btndiff) {
  486. (void)(timestamp); (void)(dx); (void)(dy); (void)(btndiff);
  487. //printf("PTR %u %d %d %x\n", timestamp, dx, dy, btndiff);
  488. if (a_app_state->grabbed) {
  489. simplecamRotatePitch(&g.camera, dy * -4e-3f);
  490. simplecamRotateYaw(&g.camera, dx * -4e-3f);
  491. simplecamRecalc(&g.camera);
  492. } else if (btndiff)
  493. aAppGrabInput(1);
  494. }
  495. void attoAppInit(struct AAppProctable *proctable) {
  496. aGLInit();
  497. const int max_collections = 16;
  498. struct FilesystemCollection collections[max_collections];
  499. int free_collection = 0;
  500. const char *map = 0;
  501. for (int i = 1; i < a_app_state->argc; ++i) {
  502. const char *argv = a_app_state->argv[i];
  503. if (strcmp(argv, "-d") == 0) {
  504. if (i == a_app_state->argc - 1) {
  505. aAppDebugPrintf("-d requires an argument");
  506. goto print_usage_and_exit;
  507. }
  508. const char *value = a_app_state->argv[++i];
  509. if (free_collection >= max_collections) {
  510. aAppDebugPrintf("Too many fs collections specified: %s", value);
  511. goto print_usage_and_exit;
  512. }
  513. filesystemCollectionCreate(collections + (free_collection++), value);
  514. } else {
  515. if (map) {
  516. aAppDebugPrintf("Only one map can be specified");
  517. goto print_usage_and_exit;
  518. }
  519. map = argv;
  520. }
  521. }
  522. if (!map || !free_collection) {
  523. aAppDebugPrintf("At least one map and one collection required");
  524. goto print_usage_and_exit;
  525. }
  526. for (int i = 0; i < free_collection - 1; ++i)
  527. collections[i].head.next = &collections[i+1].head;
  528. opensrcInit(&collections[0].head, map);
  529. proctable->resize = opensrcResize;
  530. proctable->paint = opensrcPaint;
  531. proctable->key = opensrcKeyPress;
  532. proctable->pointer = opensrcPointer;
  533. return;
  534. print_usage_and_exit:
  535. aAppDebugPrintf("usage: %s <-d path> ... mapname", a_app_state->argv[0]);
  536. aAppTerminate(1);
  537. }