render.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763
  1. #include "render.h"
  2. #include "texture.h"
  3. #include "bsp.h"
  4. #include "cache.h"
  5. #include "common.h"
  6. #include "profiler.h"
  7. #include "camera.h"
  8. #include "atto/app.h"
  9. #include "atto/platform.h"
  10. #ifdef ATTO_PLATFORM_X11
  11. #define GL_GLEXT_PROTOTYPES 1
  12. #include <GL/glx.h>
  13. #include <GL/gl.h>
  14. #include <GL/glext.h>
  15. #define ATTO_GL_DESKTOP
  16. #endif /* ifdef ATTO_PLATFORM_X11 */
  17. #ifdef ATTO_PLATFORM_RPI
  18. #include <GLES2/gl2.h>
  19. #include <GLES2/gl2ext.h>
  20. #define ATTO_GL_ES
  21. #endif /* ifdef ATTO_PLATFORM_RPI */
  22. #ifdef ATTO_PLATFORM_WINDOWS
  23. #include "libc.h"
  24. #include <GL/gl.h>
  25. #include <glext.h>
  26. #define ATTO_GL_DESKTOP
  27. #endif /* ifdef ATTO_PLATFORM_WINDOWS */
  28. #ifdef ATTO_PLATFORM_OSX
  29. #include <OpenGL/gl3.h>
  30. #define ATTO_GL_DESKTOP
  31. #endif
  32. #define RENDER_ERRORCHECK
  33. //#define RENDER_GL_TRACE
  34. #define RENDER_GL_PROFILE_FUNC profileEvent
  35. #ifndef RENDER_ASSERT
  36. #define RENDER_ASSERT(cond) \
  37. if (!(cond)) { \
  38. aAppDebugPrintf("ERROR @ %s:%d: (%s) failed", __FILE__, __LINE__, #cond); \
  39. aAppTerminate(-1); \
  40. }
  41. #endif /* ifndef RENDER_ASSERT */
  42. #ifdef RENDER_GL_PROFILE_FUNC
  43. #define RENDER_GL_PROFILE_PREAMBLE const ATimeUs profile_time_start__ = aAppTime();
  44. #define RENDER_GL_PROFILE_START const ATimeUs agl_profile_start_ = aAppTime();
  45. #define RENDER_GL_PROFILE_END RENDER_GL_PROFILE_FUNC(__FUNCTION__, aAppTime() - agl_profile_start_);
  46. #define RENDER_GL_PROFILE_END_NAME(name) RENDER_GL_PROFILE_FUNC(name, aAppTime() - agl_profile_start_);
  47. #else
  48. #define RENDER_GL_PROFILE_PREAMBLE
  49. #define RENDER_GL_PROFILE_FUNC(...)
  50. #endif
  51. //#define RENDER_GL_DEBUG
  52. #ifdef RENDER_GL_DEBUG
  53. static void a__GlPrintError(const char *message, int error) {
  54. const char *errstr = "UNKNOWN";
  55. switch (error) {
  56. case GL_INVALID_ENUM: errstr = "GL_INVALID_ENUM"; break;
  57. case GL_INVALID_VALUE: errstr = "GL_INVALID_VALUE"; break;
  58. case GL_INVALID_OPERATION: errstr = "GL_INVALID_OPERATION"; break;
  59. #ifdef GL_STACK_OVERFLOW
  60. case GL_STACK_OVERFLOW: errstr = "GL_STACK_OVERFLOW"; break;
  61. #endif
  62. #ifdef GL_STACK_UNDERFLOW
  63. case GL_STACK_UNDERFLOW: errstr = "GL_STACK_UNDERFLOW"; break;
  64. #endif
  65. case GL_OUT_OF_MEMORY: errstr = "GL_OUT_OF_MEMORY"; break;
  66. #ifdef GL_TABLE_TOO_LARGE
  67. case GL_TABLE_TOO_LARGE: errstr = "GL_TABLE_TOO_LARGE"; break;
  68. #endif
  69. };
  70. PRINTF("%s %s (%#x)", message, errstr, error);
  71. }
  72. #define RENDER_GL_GETERROR(f) \
  73. const int glerror = glGetError(); \
  74. if (glerror != GL_NO_ERROR) { \
  75. a__GlPrintError(__FILE__ ":" RENDER__GL_STR(__LINE__) ": " #f " returned ", glerror); \
  76. RENDER_ASSERT(!"GL error"); \
  77. }
  78. #else
  79. #define RENDER_GL_GETERROR(f)
  80. #endif
  81. #define RENDER__GL_STR__(s) #s
  82. #define RENDER__GL_STR(s) RENDER__GL_STR__(s)
  83. #ifdef RENDER_GL_TRACE
  84. #define RENDER_GL_TRACE_PRINT PRINTF
  85. #else
  86. #define RENDER_GL_TRACE_PRINT(...)
  87. #endif
  88. #define GL_CALL(f) do{\
  89. RENDER_GL_TRACE_PRINT("%s", #f); \
  90. RENDER_GL_PROFILE_PREAMBLE \
  91. f; \
  92. RENDER_GL_PROFILE_FUNC(#f, aAppTime() - profile_time_start__); \
  93. RENDER_GL_GETERROR(f) \
  94. } while(0)
  95. #ifdef _WIN32
  96. #define WGL__FUNCLIST \
  97. WGL__FUNCLIST_DO(PFNGLBLENDCOLORPROC, BlendColor) \
  98. WGL__FUNCLIST_DO(PFNGLBLENDEQUATIONPROC, BlendEquation) \
  99. WGL__FUNCLIST_DO(PFNGLGENBUFFERSPROC, GenBuffers) \
  100. WGL__FUNCLIST_DO(PFNGLBINDBUFFERPROC, BindBuffer) \
  101. WGL__FUNCLIST_DO(PFNGLBUFFERDATAPROC, BufferData) \
  102. WGL__FUNCLIST_DO(PFNGLGETATTRIBLOCATIONPROC, GetAttribLocation) \
  103. WGL__FUNCLIST_DO(PFNGLACTIVETEXTUREPROC, ActiveTexture) \
  104. WGL__FUNCLIST_DO(PFNGLCREATESHADERPROC, CreateShader) \
  105. WGL__FUNCLIST_DO(PFNGLSHADERSOURCEPROC, ShaderSource) \
  106. WGL__FUNCLIST_DO(PFNGLCOMPILESHADERPROC, CompileShader) \
  107. WGL__FUNCLIST_DO(PFNGLATTACHSHADERPROC, AttachShader) \
  108. WGL__FUNCLIST_DO(PFNGLDELETESHADERPROC, DeleteShader) \
  109. WGL__FUNCLIST_DO(PFNGLGETSHADERIVPROC, GetShaderiv) \
  110. WGL__FUNCLIST_DO(PFNGLGETSHADERINFOLOGPROC, GetShaderInfoLog) \
  111. WGL__FUNCLIST_DO(PFNGLCREATEPROGRAMPROC, CreateProgram) \
  112. WGL__FUNCLIST_DO(PFNGLLINKPROGRAMPROC, LinkProgram) \
  113. WGL__FUNCLIST_DO(PFNGLGETPROGRAMINFOLOGPROC, GetProgramInfoLog) \
  114. WGL__FUNCLIST_DO(PFNGLDELETEPROGRAMPROC, DeleteProgram) \
  115. WGL__FUNCLIST_DO(PFNGLGETPROGRAMIVPROC, GetProgramiv) \
  116. WGL__FUNCLIST_DO(PFNGLUSEPROGRAMPROC, UseProgram) \
  117. WGL__FUNCLIST_DO(PFNGLGETUNIFORMLOCATIONPROC, GetUniformLocation) \
  118. WGL__FUNCLIST_DO(PFNGLUNIFORM1FPROC, Uniform1f) \
  119. WGL__FUNCLIST_DO(PFNGLUNIFORM2FPROC, Uniform2f) \
  120. WGL__FUNCLIST_DO(PFNGLUNIFORM1IPROC, Uniform1i) \
  121. WGL__FUNCLIST_DO(PFNGLUNIFORMMATRIX4FVPROC, UniformMatrix4fv) \
  122. WGL__FUNCLIST_DO(PFNGLENABLEVERTEXATTRIBARRAYPROC, EnableVertexAttribArray) \
  123. WGL__FUNCLIST_DO(PFNGLDISABLEVERTEXATTRIBARRAYPROC, DisableVertexAttribArray) \
  124. WGL__FUNCLIST_DO(PFNGLVERTEXATTRIBPOINTERPROC, VertexAttribPointer) \
  125. WGL__FUNCLIST_DO(PFNGLGENERATEMIPMAPPROC, GenerateMipmap) \
  126. WGL__FUNCLIST_DO(PFNGLCOMPRESSEDTEXIMAGE2DPROC, CompressedTexImage2D) \
  127. #define WGL__FUNCLIST_DO(T,N) T gl##N = 0;
  128. WGL__FUNCLIST
  129. #undef WGL__FUNCLIST_DO
  130. #endif /* ifdef _WIN32 */
  131. static struct {
  132. int textures_count;
  133. int textures_size;
  134. int buffers_count;
  135. int buffers_size;
  136. } stats;
  137. static void renderPrintMemUsage() {
  138. PRINTF("Render Tc: %u, Ts: %uMiB, Bc: %u, Bs: %uMiB, Total: %uMiB",
  139. stats.textures_count, stats.textures_size >> 20,
  140. stats.buffers_count, stats.buffers_size >> 20,
  141. (stats.buffers_size + stats.textures_size) >> 20);
  142. }
  143. static GLint render_ShaderCreate(GLenum type, const char *sources[]) {
  144. int n;
  145. GLuint shader = glCreateShader(type);
  146. for (n = 0; sources[n]; ++n);
  147. GL_CALL(glShaderSource(shader, n, (const GLchar **)sources, 0));
  148. GL_CALL(glCompileShader(shader));
  149. #ifdef RENDER_ERRORCHECK
  150. {
  151. GLint status;
  152. GL_CALL(glGetShaderiv(shader, GL_COMPILE_STATUS, &status));
  153. if (status != GL_TRUE) {
  154. char buffer[1024];
  155. GL_CALL(glGetShaderInfoLog(shader, sizeof(buffer), 0, buffer));
  156. PRINTF("Shader compilation error: %s", buffer);
  157. GL_CALL(glDeleteShader(shader));
  158. shader = 0;
  159. }
  160. }
  161. #endif
  162. return shader;
  163. }
  164. void renderTextureUpload(RTexture *texture, RTextureUploadParams params) {
  165. int pixel_bits = 0;
  166. GLenum internal, format, type;
  167. if (texture->gl_name == -1) {
  168. GL_CALL(glGenTextures(1, (GLuint*)&texture->gl_name));
  169. texture->type_flags = 0;
  170. ++stats.textures_count;
  171. }
  172. const GLenum binding = (params.type == RTexType_2D) ? GL_TEXTURE_2D : GL_TEXTURE_CUBE_MAP;
  173. const GLint wrap = (params.type == RTexType_2D && params.wrap == RTexWrap_Repeat)
  174. ? GL_REPEAT : GL_CLAMP_TO_EDGE;
  175. GL_CALL(glBindTexture(binding, texture->gl_name));
  176. GLenum upload_binding = binding;
  177. switch (params.type) {
  178. case RTexType_2D: upload_binding = GL_TEXTURE_2D; break;
  179. case RTexType_CubePX: upload_binding = GL_TEXTURE_CUBE_MAP_POSITIVE_X; break;
  180. case RTexType_CubeNX: upload_binding = GL_TEXTURE_CUBE_MAP_NEGATIVE_X; break;
  181. case RTexType_CubePY: upload_binding = GL_TEXTURE_CUBE_MAP_POSITIVE_Y; break;
  182. case RTexType_CubeNY: upload_binding = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; break;
  183. case RTexType_CubePZ: upload_binding = GL_TEXTURE_CUBE_MAP_POSITIVE_Z; break;
  184. case RTexType_CubeNZ: upload_binding = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; break;
  185. }
  186. int compressed = 0;
  187. switch (params.format) {
  188. case RTexFormat_RGB565:
  189. pixel_bits = 16;
  190. internal = format = GL_RGB; type = GL_UNSIGNED_SHORT_5_6_5;
  191. break;
  192. #ifdef ATTO_PLATFORM_RPI
  193. case RTexFormat_Compressed_ETC1:
  194. pixel_bits = 4;
  195. internal = GL_ETC1_RGB8_OES;
  196. compressed = 1;
  197. break;
  198. #endif
  199. default:
  200. ATTO_ASSERT(!"Impossible texture format");
  201. }
  202. const int image_size = params.width * params.height * pixel_bits / 8;
  203. if (!compressed) {
  204. GL_CALL(glTexImage2D(upload_binding, params.mip_level < 0 ? 0 : params.mip_level, internal, params.width, params.height, 0,
  205. format, type, params.pixels));
  206. } else {
  207. GL_CALL(glCompressedTexImage2D(upload_binding, params.mip_level < 0 ? 0 : params.mip_level, internal, params.width, params.height,
  208. 0, image_size, params.pixels));
  209. }
  210. stats.textures_size += image_size;
  211. renderPrintMemUsage();
  212. if (params.mip_level == -1)
  213. GL_CALL(glGenerateMipmap(binding));
  214. GL_CALL(glTexParameteri(binding, GL_TEXTURE_MIN_FILTER, params.mip_level >= -1 ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR));
  215. GL_CALL(glTexParameteri(binding, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
  216. GL_CALL(glTexParameteri(binding, GL_TEXTURE_WRAP_S, wrap));
  217. GL_CALL(glTexParameteri(binding, GL_TEXTURE_WRAP_T, wrap));
  218. if (params.mip_level < 1) {
  219. texture->width = params.width;
  220. texture->height = params.height;
  221. }
  222. texture->format = params.format;
  223. texture->type_flags |= params.type;
  224. }
  225. void renderBufferCreate(RBuffer *buffer, RBufferType type, int size, const void *data) {
  226. switch (type) {
  227. case RBufferType_Vertex: buffer->type = GL_ARRAY_BUFFER; break;
  228. case RBufferType_Index: buffer->type = GL_ELEMENT_ARRAY_BUFFER; break;
  229. default: ASSERT(!"Invalid buffer type");
  230. }
  231. GL_CALL(glGenBuffers(1, (GLuint*)&buffer->gl_name));
  232. ++stats.buffers_count;
  233. GL_CALL(glBindBuffer(buffer->type, (GLuint)buffer->gl_name));
  234. GL_CALL(glBufferData(buffer->type, size, data, GL_STATIC_DRAW));
  235. stats.buffers_size += size;
  236. renderPrintMemUsage();
  237. }
  238. typedef struct {
  239. const char *name;
  240. int components;
  241. GLenum type;
  242. GLint normalize;
  243. int stride;
  244. const void *ptr;
  245. } RAttrib;
  246. typedef struct {
  247. const char *name;
  248. } RUniform;
  249. #define RENDER_LIST_ATTRIBS \
  250. RENDER_DECLARE_ATTRIB(vertex, 3, GL_FLOAT, GL_FALSE) \
  251. RENDER_DECLARE_ATTRIB(lightmap_uv, 2, GL_FLOAT, GL_FALSE) \
  252. RENDER_DECLARE_ATTRIB(tex_uv, 2, GL_FLOAT, GL_FALSE) \
  253. RENDER_DECLARE_ATTRIB(average_color, 3, GL_UNSIGNED_BYTE, GL_TRUE) \
  254. // RENDER_DECLARE_ATTRIB(normal, 3, GL_FLOAT)
  255. static const RAttrib attribs[] = {
  256. #define RENDER_DECLARE_ATTRIB(n,c,t,N) \
  257. {"a_" # n, c, t, N, sizeof(struct BSPModelVertex), (void*)offsetof(struct BSPModelVertex, n)},
  258. RENDER_LIST_ATTRIBS
  259. #undef RENDER_DECLARE_ATTRIB
  260. };
  261. enum RAttribKinds {
  262. #define RENDER_DECLARE_ATTRIB(n,c,t,N) \
  263. RAttribKind_ ## n,
  264. RENDER_LIST_ATTRIBS
  265. #undef RENDER_DECLARE_ATTRIB
  266. RAttribKind_COUNT
  267. };
  268. #define RENDER_LIST_UNIFORMS \
  269. RENDER_DECLARE_UNIFORM(mvp) \
  270. RENDER_DECLARE_UNIFORM(far) \
  271. RENDER_DECLARE_UNIFORM(lightmap) \
  272. RENDER_DECLARE_UNIFORM(tex0) \
  273. RENDER_DECLARE_UNIFORM(tex0_size) \
  274. RENDER_DECLARE_UNIFORM(tex0_scale) \
  275. RENDER_DECLARE_UNIFORM(tex0_translate) \
  276. static const RUniform uniforms[] = {
  277. #define RENDER_DECLARE_UNIFORM(n) {"u_" # n},
  278. RENDER_LIST_UNIFORMS
  279. #undef RENDER_DECLARE_UNIFORM
  280. };
  281. enum RUniformKinds {
  282. #define RENDER_DECLARE_UNIFORM(n) RUniformKind_ ## n,
  283. RENDER_LIST_UNIFORMS
  284. #undef RENDER_DECLARE_UNIFORM
  285. RUniformKind_COUNT
  286. };
  287. typedef struct RProgram {
  288. GLint name;
  289. struct {
  290. const char *common, *vertex, *fragment;
  291. } shader_sources;
  292. int attrib_locations[RAttribKind_COUNT];
  293. int uniform_locations[RUniformKind_COUNT];
  294. } RProgram;
  295. static RProgram programs[MShader_COUNT] = {
  296. /* MShader_Unknown */
  297. {-1, {
  298. /* common */
  299. "varying vec3 v_pos;\n",
  300. /* vertex */
  301. "attribute vec3 a_vertex;\n"
  302. "uniform mat4 u_mvp;\n"
  303. "void main() {\n"
  304. "v_pos = a_vertex;\n"
  305. "gl_Position = u_mvp * vec4(a_vertex, 1.);\n"
  306. "}\n",
  307. /* fragment */
  308. "void main() {\n"
  309. "gl_FragColor = vec4(mod(v_pos,100.)/100., 1.);\n"
  310. "}\n",
  311. },
  312. { -1 }, { -1 }
  313. },
  314. /* MShader_LightmappedOnly */
  315. {-1, {
  316. /*common*/
  317. "varying vec2 v_lightmap_uv;\n"
  318. "varying vec3 v_color;\n",
  319. /*vertex*/
  320. "attribute vec3 a_vertex, a_average_color;\n"
  321. "attribute vec2 a_lightmap_uv;\n"
  322. "uniform mat4 u_mvp;\n"
  323. "void main() {\n"
  324. "v_lightmap_uv = a_lightmap_uv;\n"
  325. "v_color = a_average_color;\n"
  326. "gl_Position = u_mvp * vec4(a_vertex, 1.);\n"
  327. "}\n",
  328. /*fragment*/
  329. "uniform sampler2D u_lightmap;\n"
  330. "void main() {\n"
  331. "gl_FragColor = vec4(v_color * texture2D(u_lightmap, v_lightmap_uv).xyz, 1.);\n"
  332. "}\n"
  333. },
  334. { -1 }, { -1 }
  335. },
  336. /* MShader_LightmappedGeneric */
  337. {-1, {
  338. /*common*/
  339. "varying vec2 v_lightmap_uv, v_tex_uv;\n",
  340. /*vertex*/
  341. "attribute vec3 a_vertex;\n"
  342. "attribute vec2 a_lightmap_uv, a_tex_uv;\n"
  343. "uniform mat4 u_mvp;\n"
  344. "void main() {\n"
  345. "v_lightmap_uv = a_lightmap_uv;\n"
  346. "v_tex_uv = a_tex_uv;\n"
  347. "gl_Position = u_mvp * vec4(a_vertex, 1.);\n"
  348. "}\n",
  349. /*fragment*/
  350. "uniform sampler2D u_lightmap, u_tex0;\n"
  351. "uniform vec2 u_lightmap_size, u_tex0_size;\n"
  352. "void main() {\n"
  353. "vec4 albedo = texture2D(u_tex0, v_tex_uv/u_tex0_size);\n"
  354. "vec3 lm = texture2D(u_lightmap, v_lightmap_uv).xyz;\n"
  355. "vec3 color = albedo.xyz * lm;\n"
  356. "gl_FragColor = vec4(color, 1.);\n"
  357. "}\n"
  358. },
  359. { -1 }, { -1 }
  360. },
  361. /* MShader_UnlitGeneric */
  362. {-1, { /* common */
  363. "varying vec2 v_uv;\n",
  364. /* vertex */
  365. "attribute vec3 a_vertex;\n"
  366. "attribute vec2 a_tex_uv;\n"
  367. "uniform mat4 u_mvp;\n"
  368. "uniform float u_far;\n"
  369. "uniform vec2 u_tex0_scale, u_tex0_translate;\n"
  370. "void main() {\n"
  371. "v_uv = a_tex_uv * u_tex0_scale + u_tex0_translate;\n"
  372. "gl_Position = u_mvp * vec4(u_far * .5 * a_vertex, 1.);\n"
  373. "}\n",
  374. /* fragment */
  375. "uniform sampler2D u_tex0;\n"
  376. "uniform vec2 u_tex0_size;\n"
  377. "void main() {\n"
  378. "gl_FragColor = texture2D(u_tex0, v_uv + vec2(.5) / u_tex0_size);\n"
  379. //"gl_FragColor = texture2D(u_tex0, v_uv);\n"
  380. "}\n",
  381. }, {-1}, {-1}},
  382. };
  383. static struct BSPModelVertex box[] = {
  384. {{ 1.f, -1.f, -1.f}, {0.f, 0.f}, {1.f, 1.f}, {0, 0, 0}},
  385. {{ 1.f, 1.f, -1.f}, {0.f, 0.f}, {0.f, 1.f}, {0, 0, 0}},
  386. {{ 1.f, 1.f, 1.f}, {0.f, 0.f}, {0.f, 0.f}, {0, 0, 0}},
  387. {{ 1.f, 1.f, 1.f}, {0.f, 0.f}, {0.f, 0.f}, {0, 0, 0}},
  388. {{ 1.f, -1.f, 1.f}, {0.f, 0.f}, {1.f, 0.f}, {0, 0, 0}},
  389. {{ 1.f, -1.f, -1.f}, {0.f, 0.f}, {1.f, 1.f}, {0, 0, 0}},
  390. {{-1.f, -1.f, 1.f}, {1.f, 0.f}, {0.f, 0.f}, {0, 0, 0}},
  391. {{-1.f, 1.f, 1.f}, {1.f, 0.f}, {1.f, 0.f}, {0, 0, 0}},
  392. {{-1.f, 1.f, -1.f}, {1.f, 0.f}, {1.f, 1.f}, {0, 0, 0}},
  393. {{-1.f, 1.f, -1.f}, {1.f, 0.f}, {1.f, 1.f}, {0, 0, 0}},
  394. {{-1.f, -1.f, -1.f}, {1.f, 0.f}, {0.f, 1.f}, {0, 0, 0}},
  395. {{-1.f, -1.f, 1.f}, {1.f, 0.f}, {0.f, 0.f}, {0, 0, 0}},
  396. {{ 1.f, -1.f, -1.f}, {2.f, 0.f}, {0.f, 1.f}, {0, 0, 0}},
  397. {{ 1.f, -1.f, 1.f}, {2.f, 0.f}, {0.f, 0.f}, {0, 0, 0}},
  398. {{-1.f, -1.f, 1.f}, {2.f, 0.f}, {1.f, 0.f}, {0, 0, 0}},
  399. {{-1.f, -1.f, 1.f}, {2.f, 0.f}, {1.f, 0.f}, {0, 0, 0}},
  400. {{-1.f, -1.f, -1.f}, {2.f, 0.f}, {1.f, 1.f}, {0, 0, 0}},
  401. {{ 1.f, -1.f, -1.f}, {2.f, 0.f}, {0.f, 1.f}, {0, 0, 0}},
  402. {{ 1.f, 1.f, 1.f}, {3.f, 0.f}, {1.f, 0.f}, {0, 0, 0}},
  403. {{ 1.f, 1.f, -1.f}, {3.f, 0.f}, {1.f, 1.f}, {0, 0, 0}},
  404. {{-1.f, 1.f, -1.f}, {3.f, 0.f}, {0.f, 1.f}, {0, 0, 0}},
  405. {{-1.f, 1.f, -1.f}, {3.f, 0.f}, {0.f, 1.f}, {0, 0, 0}},
  406. {{-1.f, 1.f, 1.f}, {3.f, 0.f}, {0.f, 0.f}, {0, 0, 0}},
  407. {{ 1.f, 1.f, 1.f}, {3.f, 0.f}, {1.f, 0.f}, {0, 0, 0}},
  408. {{ 1.f, -1.f, 1.f}, {4.f, 0.f}, {1.f, 1.f}, {0, 0, 0}},
  409. {{ 1.f, 1.f, 1.f}, {4.f, 0.f}, {0.f, 1.f}, {0, 0, 0}},
  410. {{-1.f, 1.f, 1.f}, {4.f, 0.f}, {0.f, 0.f}, {0, 0, 0}},
  411. {{-1.f, 1.f, 1.f}, {4.f, 0.f}, {0.f, 0.f}, {0, 0, 0}},
  412. {{-1.f, -1.f, 1.f}, {4.f, 0.f}, {1.f, 0.f}, {0, 0, 0}},
  413. {{ 1.f, -1.f, 1.f}, {4.f, 0.f}, {1.f, 1.f}, {0, 0, 0}},
  414. {{-1.f, -1.f, -1.f}, {5.f, 0.f}, {1.f, 0.f}, {0, 0, 0}},
  415. {{-1.f, 1.f, -1.f}, {5.f, 0.f}, {1.f, 1.f}, {0, 0, 0}},
  416. {{ 1.f, 1.f, -1.f}, {5.f, 0.f}, {0.f, 1.f}, {0, 0, 0}},
  417. {{ 1.f, 1.f, -1.f}, {5.f, 0.f}, {0.f, 1.f}, {0, 0, 0}},
  418. {{ 1.f, -1.f, -1.f}, {5.f, 0.f}, {0.f, 0.f}, {0, 0, 0}},
  419. {{-1.f, -1.f, -1.f}, {5.f, 0.f}, {1.f, 0.f}, {0, 0, 0}},
  420. };
  421. static RBuffer box_buffer;
  422. static struct {
  423. const RTexture *current_tex0;
  424. const RProgram *current_program;
  425. struct {
  426. const float *mvp;
  427. float far;
  428. } uniforms;
  429. struct {
  430. float distance;
  431. const struct BSPModel *model;
  432. } closest_map;
  433. } r;
  434. static void renderApplyAttribs(const RAttrib *attribs, const RBuffer *buffer, unsigned int vbo_offset) {
  435. for(int i = 0; i < RAttribKind_COUNT; ++i) {
  436. const RAttrib *a = attribs + i;
  437. const int loc = r.current_program->attrib_locations[i];
  438. if (loc < 0) continue;
  439. GL_CALL(glEnableVertexAttribArray(loc));
  440. GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, buffer->gl_name));
  441. GL_CALL(glVertexAttribPointer(loc, a->components, a->type, a->normalize, a->stride, (const char*)a->ptr + vbo_offset * sizeof(struct BSPModelVertex)));
  442. }
  443. }
  444. static int render_ProgramUse(RProgram *prog) {
  445. if (r.current_program == prog)
  446. return 0;
  447. if (r.current_program) {
  448. for (int i = 0; i < RAttribKind_COUNT; ++i) {
  449. const int loc = r.current_program->attrib_locations[i];
  450. if (loc >= 0)
  451. GL_CALL(glDisableVertexAttribArray(loc));
  452. }
  453. }
  454. GL_CALL(glUseProgram(prog->name));
  455. GL_CALL(glUniform1i(prog->uniform_locations[RUniformKind_lightmap], 0));
  456. GL_CALL(glUniform1i(prog->uniform_locations[RUniformKind_tex0], 1));
  457. GL_CALL(glUniformMatrix4fv(prog->uniform_locations[RUniformKind_mvp], 1, GL_FALSE, r.uniforms.mvp));
  458. GL_CALL(glUniform1f(prog->uniform_locations[RUniformKind_far], r.uniforms.far));
  459. r.current_program = prog;
  460. r.current_tex0 = NULL;
  461. return 1;
  462. }
  463. static int render_ProgramInit(RProgram *prog) {
  464. GLuint program;
  465. GLuint vertex_shader, fragment_shader;
  466. const char *sources[] = {
  467. prog->shader_sources.common, prog->shader_sources.fragment, 0
  468. };
  469. fragment_shader = render_ShaderCreate(GL_FRAGMENT_SHADER, sources);
  470. if (fragment_shader == 0)
  471. return -1;
  472. sources[1] = prog->shader_sources.vertex;
  473. vertex_shader = render_ShaderCreate(GL_VERTEX_SHADER, sources);
  474. if (vertex_shader == 0) {
  475. GL_CALL(glDeleteShader(fragment_shader));
  476. return -2;
  477. }
  478. program = glCreateProgram();
  479. GL_CALL(glAttachShader(program, fragment_shader));
  480. GL_CALL(glAttachShader(program, vertex_shader));
  481. GL_CALL(glLinkProgram(program));
  482. GL_CALL(glDeleteShader(fragment_shader));
  483. GL_CALL(glDeleteShader(vertex_shader));
  484. #ifdef RENDER_ERRORCHECK
  485. {
  486. GLint status;
  487. GL_CALL(glGetProgramiv(program, GL_LINK_STATUS, &status));
  488. if (status != GL_TRUE) {
  489. char buffer[1024];
  490. GL_CALL(glGetProgramInfoLog(program, sizeof(buffer), 0, buffer));
  491. PRINTF("Program linking error: %s", buffer);
  492. GL_CALL(glDeleteProgram(program));
  493. return -3;
  494. }
  495. }
  496. #endif
  497. prog->name = program;
  498. for(int i = 0; i < RAttribKind_COUNT; ++i) {
  499. prog->attrib_locations[i] = glGetAttribLocation(prog->name, attribs[i].name);
  500. if (prog->attrib_locations[i] < 0)
  501. PRINTF("Cannot locate attribute %s", attribs[i].name);
  502. }
  503. for(int i = 0; i < RUniformKind_COUNT; ++i) {
  504. prog->uniform_locations[i] = glGetUniformLocation(prog->name, uniforms[i].name);
  505. if (prog->uniform_locations[i] < 0)
  506. PRINTF("Cannot locate uniform %s", uniforms[i].name);
  507. }
  508. return 0;
  509. }
  510. int renderInit() {
  511. PRINTF("GL extensions: %s", glGetString(GL_EXTENSIONS));
  512. #ifdef _WIN32
  513. #define WGL__FUNCLIST_DO(T, N) \
  514. gl##N = (T)wglGetProcAddress("gl" #N); \
  515. ASSERT(gl##N);
  516. WGL__FUNCLIST
  517. #undef WGL__FUNCLIST_DO
  518. #endif
  519. memset(&stats, 0, sizeof(stats));
  520. r.current_program = NULL;
  521. r.current_tex0 = NULL;
  522. r.uniforms.mvp = NULL;
  523. for (int i = 0; i < MShader_COUNT; ++i) {
  524. if (render_ProgramInit(programs + i) != 0) {
  525. PRINTF("Cannot create program %d", i);
  526. return 0;
  527. }
  528. }
  529. struct Texture default_texture;
  530. RTextureUploadParams params;
  531. params.type = RTexType_2D;
  532. params.format = RTexFormat_RGB565;
  533. params.width = 2;
  534. params.height = 2;
  535. params.pixels = (uint16_t[]){0xffffu, 0, 0, 0xffffu};
  536. params.mip_level = -2;
  537. params.wrap = RTexWrap_Clamp;
  538. renderTextureInit(&default_texture.texture);
  539. renderTextureUpload(&default_texture.texture, params);
  540. cachePutTexture("opensource/placeholder", &default_texture);
  541. {
  542. struct Material default_material;
  543. memset(&default_material, 0, sizeof default_material);
  544. default_material.average_color = aVec3f(0.f, 1.f, 0.f);
  545. default_material.shader = MShader_Unknown;
  546. cachePutMaterial("opensource/placeholder", &default_material);
  547. }
  548. {
  549. struct Material lightmap_color_material;
  550. memset(&lightmap_color_material, 0, sizeof lightmap_color_material);
  551. lightmap_color_material.average_color = aVec3f(1.f, 1.f, 0.f);
  552. lightmap_color_material.shader = MShader_LightmappedOnly;
  553. cachePutMaterial("opensource/coarse", &lightmap_color_material);
  554. }
  555. renderBufferCreate(&box_buffer, RBufferType_Vertex, sizeof(box), box);
  556. GL_CALL(glEnable(GL_DEPTH_TEST));
  557. GL_CALL(glEnable(GL_CULL_FACE));
  558. return 1;
  559. }
  560. static void renderBindTexture(const RTexture *texture, int slot, int norepeat) {
  561. GL_CALL(glActiveTexture(GL_TEXTURE0 + slot));
  562. GL_CALL(glBindTexture(GL_TEXTURE_2D, texture->gl_name));
  563. if (norepeat) {
  564. const GLuint wrap = GL_CLAMP_TO_EDGE;
  565. GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap));
  566. GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap));
  567. }
  568. }
  569. static int renderUseMaterial(const Material *m) {
  570. const int program_changed = render_ProgramUse(programs + m->shader);
  571. if (m->base_texture.texture) {
  572. const RTexture *t = &m->base_texture.texture->texture;
  573. if (t != r.current_tex0) {
  574. renderBindTexture(&m->base_texture.texture->texture, 1, m->shader == MShader_UnlitGeneric);
  575. GL_CALL(glUniform2f(r.current_program->uniform_locations[RUniformKind_tex0_size], (float)t->width, (float)t->height));
  576. GL_CALL(glUniform2f(r.current_program->uniform_locations[RUniformKind_tex0_scale], m->base_texture.transform.scale.x, m->base_texture.transform.scale.y));
  577. GL_CALL(glUniform2f(r.current_program->uniform_locations[RUniformKind_tex0_translate], m->base_texture.transform.translate.x, m->base_texture.transform.translate.y));
  578. r.current_tex0 = t;
  579. }
  580. }
  581. return program_changed;
  582. }
  583. static void renderDrawSet(const struct BSPModel *model, const struct BSPDrawSet *drawset) {
  584. unsigned int vbo_offset = 0;
  585. for (int i = 0; i < drawset->draws_count; ++i) {
  586. const struct BSPDraw *draw = drawset->draws + i;
  587. if (renderUseMaterial(draw->material) || i == 0 || draw->vbo_offset != vbo_offset) {
  588. vbo_offset = draw->vbo_offset;
  589. renderApplyAttribs(attribs, &model->vbo, draw->vbo_offset);
  590. }
  591. GL_CALL(glDrawElements(GL_TRIANGLES, draw->count, GL_UNSIGNED_SHORT, (void*)(sizeof(uint16_t) * draw->start)));
  592. }
  593. }
  594. static void renderSkybox(const struct Camera *camera, const struct BSPModel *model) {
  595. const struct AMat4f op = aMat4fMul(camera->projection, aMat4f3(camera->orientation, aVec3ff(0)));
  596. r.uniforms.mvp = &op.X.x;
  597. GL_CALL(glDisable(GL_CULL_FACE));
  598. for (int i = 0; i < BSPSkyboxDir_COUNT; ++i) {
  599. if (!model->skybox[i] || !model->skybox[i]->base_texture.texture)
  600. continue;
  601. renderUseMaterial(model->skybox[i]);
  602. renderApplyAttribs(attribs, &box_buffer, 0);
  603. GL_CALL(glDrawArrays(GL_TRIANGLES, i*6, 6));
  604. }
  605. GL_CALL(glEnable(GL_CULL_FACE));
  606. }
  607. static float aMaxf(float a, float b) { return a > b ? a : b; }
  608. //static float aMinf(float a, float b) { return a < b ? a : b; }
  609. void renderModelDraw(const RDrawParams *params, const struct BSPModel *model) {
  610. if (!model->detailed.draws_count) return;
  611. const struct AMat4f mvp = aMat4fMul(params->camera->view_projection,
  612. aMat4fTranslation(params->translation));
  613. GL_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model->ibo.gl_name));
  614. renderBindTexture(&model->lightmap, 0, 0);
  615. const struct AVec3f rel_pos = aVec3fSub(params->camera->pos, params->translation);
  616. r.current_program = NULL;
  617. r.uniforms.mvp = &mvp.X.x;
  618. r.uniforms.far = params->camera->z_far;
  619. const float distance =
  620. aMaxf(aMaxf(
  621. aMaxf(rel_pos.x - model->aabb.max.x, model->aabb.min.x - rel_pos.x),
  622. aMaxf(rel_pos.y - model->aabb.max.y, model->aabb.min.y - rel_pos.y)),
  623. aMaxf(rel_pos.z - model->aabb.max.z, model->aabb.min.z - rel_pos.z));
  624. /*
  625. PRINTF("%f %f %f -> %f",
  626. rel_pos.x, rel_pos.y, rel_pos.z, distance);
  627. */
  628. if (distance < r.closest_map.distance) {
  629. r.closest_map.distance = distance;
  630. r.closest_map.model = model;
  631. }
  632. if (params->selected) {
  633. GL_CALL(glEnable(GL_BLEND));
  634. GL_CALL(glBlendColor(1, 1, 1, .5f));
  635. //GL_CALL(glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE));
  636. GL_CALL(glBlendFunc(GL_ONE, GL_CONSTANT_ALPHA));
  637. GL_CALL(glBlendEquation(GL_FUNC_ADD));
  638. }
  639. if (distance < 0.f)
  640. renderDrawSet(model, &model->detailed);
  641. else
  642. renderDrawSet(model, &model->coarse);
  643. if (params->selected) {
  644. GL_CALL(glDisable(GL_BLEND));
  645. }
  646. }
  647. void renderResize(int w, int h) {
  648. glViewport(0, 0, w, h);
  649. }
  650. void renderBegin() {
  651. glClearColor(0.f,1.f,0.f,0);
  652. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  653. r.closest_map.distance = 1e9f;
  654. }
  655. void renderEnd(const struct Camera *camera) {
  656. renderSkybox(camera, r.closest_map.model);
  657. }