render.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696
  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 "atto/app.h"
  8. #include "atto/platform.h"
  9. #ifdef ATTO_PLATFORM_X11
  10. #define GL_GLEXT_PROTOTYPES 1
  11. #include <GL/glx.h>
  12. #include <GL/gl.h>
  13. #include <GL/glext.h>
  14. #define ATTO_GL_DESKTOP
  15. #endif /* ifdef ATTO_PLATFORM_X11 */
  16. #ifdef ATTO_PLATFORM_RPI
  17. #include <GLES2/gl2.h>
  18. #include <GLES2/gl2ext.h>
  19. #define ATTO_GL_ES
  20. #endif /* ifdef ATTO_PLATFORM_RPI */
  21. #ifdef ATTO_PLATFORM_WINDOWS
  22. #include "libc.h"
  23. #include <GL/gl.h>
  24. #include <glext.h>
  25. #define ATTO_GL_DESKTOP
  26. #endif /* ifdef ATTO_PLATFORM_WINDOWS */
  27. #ifdef ATTO_PLATFORM_OSX
  28. #include <OpenGL/gl3.h>
  29. #define ATTO_GL_DESKTOP
  30. #endif
  31. #define RENDER_ERRORCHECK
  32. //#define RENDER_GL_TRACE
  33. #define RENDER_GL_PROFILE_FUNC profileEvent
  34. #ifndef RENDER_ASSERT
  35. #define RENDER_ASSERT(cond) \
  36. if (!(cond)) { \
  37. aAppDebugPrintf("ERROR @ %s:%d: (%s) failed", __FILE__, __LINE__, #cond); \
  38. aAppTerminate(-1); \
  39. }
  40. #endif /* ifndef RENDER_ASSERT */
  41. #ifdef RENDER_GL_PROFILE_FUNC
  42. #define RENDER_GL_PROFILE_PREAMBLE const ATimeUs profile_time_start__ = aAppTime();
  43. #define RENDER_GL_PROFILE_START const ATimeUs agl_profile_start_ = aAppTime();
  44. #define RENDER_GL_PROFILE_END RENDER_GL_PROFILE_FUNC(__FUNCTION__, aAppTime() - agl_profile_start_);
  45. #define RENDER_GL_PROFILE_END_NAME(name) RENDER_GL_PROFILE_FUNC(name, aAppTime() - agl_profile_start_);
  46. #else
  47. #define RENDER_GL_PROFILE_PREAMBLE
  48. #define RENDER_GL_PROFILE_FUNC(...)
  49. #endif
  50. #if 0 //ndef RENDER_GL_DEBUG
  51. #define GL_CALL(f) (f)
  52. #else
  53. #if 0
  54. static void a__GlPrintError(const char *message, int error) {
  55. const char *errstr = "UNKNOWN";
  56. switch (error) {
  57. case GL_INVALID_ENUM: errstr = "GL_INVALID_ENUM"; break;
  58. case GL_INVALID_VALUE: errstr = "GL_INVALID_VALUE"; break;
  59. case GL_INVALID_OPERATION: errstr = "GL_INVALID_OPERATION"; break;
  60. #ifdef GL_STACK_OVERFLOW
  61. case GL_STACK_OVERFLOW: errstr = "GL_STACK_OVERFLOW"; break;
  62. #endif
  63. #ifdef GL_STACK_UNDERFLOW
  64. case GL_STACK_UNDERFLOW: errstr = "GL_STACK_UNDERFLOW"; break;
  65. #endif
  66. case GL_OUT_OF_MEMORY: errstr = "GL_OUT_OF_MEMORY"; break;
  67. #ifdef GL_TABLE_TOO_LARGE
  68. case GL_TABLE_TOO_LARGE: errstr = "GL_TABLE_TOO_LARGE"; break;
  69. #endif
  70. };
  71. PRINTF("%s %s (%#x)", message, errstr, error);
  72. }
  73. #define RENDER_GL_GETERROR(f) \
  74. const int glerror = glGetError(); \
  75. if (glerror != GL_NO_ERROR) { \
  76. a__GlPrintError(__FILE__ ":" RENDER__GL_STR(__LINE__) ": " #f " returned ", glerror); \
  77. RENDER_ASSERT(!"GL error"); \
  78. }
  79. #else
  80. #define RENDER_GL_GETERROR(f)
  81. #endif
  82. #define RENDER__GL_STR__(s) #s
  83. #define RENDER__GL_STR(s) RENDER__GL_STR__(s)
  84. #ifdef RENDER_GL_TRACE
  85. #define RENDER_GL_TRACE_PRINT PRINTF
  86. #else
  87. #define RENDER_GL_TRACE_PRINT(...)
  88. #endif
  89. #define GL_CALL(f) do{\
  90. RENDER_GL_TRACE_PRINT("%s", #f); \
  91. RENDER_GL_PROFILE_PREAMBLE \
  92. f; \
  93. RENDER_GL_PROFILE_FUNC(#f, aAppTime() - profile_time_start__); \
  94. RENDER_GL_GETERROR(f) \
  95. } while(0)
  96. #endif /* RENDER_GL_DEBUG */
  97. #ifdef _WIN32
  98. #define WGL__FUNCLIST \
  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(PFNGLVERTEXATTRIBPOINTERPROC, VertexAttribPointer) \
  124. WGL__FUNCLIST_DO(PFNGLGENERATEMIPMAPPROC, GenerateMipmap) \
  125. #define WGL__FUNCLIST_DO(T,N) T gl##N = 0;
  126. WGL__FUNCLIST
  127. #undef WGL__FUNCLIST_DO
  128. #endif /* ifdef _WIN32 */
  129. static GLint render_ShaderCreate(GLenum type, const char *sources[]) {
  130. int n;
  131. GLuint shader = glCreateShader(type);
  132. for (n = 0; sources[n]; ++n);
  133. GL_CALL(glShaderSource(shader, n, (const GLchar **)sources, 0));
  134. GL_CALL(glCompileShader(shader));
  135. #ifdef RENDER_ERRORCHECK
  136. {
  137. GLint status;
  138. GL_CALL(glGetShaderiv(shader, GL_COMPILE_STATUS, &status));
  139. if (status != GL_TRUE) {
  140. char buffer[1024];
  141. GL_CALL(glGetShaderInfoLog(shader, sizeof(buffer), 0, buffer));
  142. PRINTF("Shader compilation error: %s", buffer);
  143. GL_CALL(glDeleteShader(shader));
  144. shader = 0;
  145. }
  146. }
  147. #endif
  148. return shader;
  149. }
  150. void renderTextureUpload(RTexture *texture, RTextureUploadParams params) {
  151. GLenum internal, format, type;
  152. if (texture->gl_name == -1) {
  153. GL_CALL(glGenTextures(1, (GLuint*)&texture->gl_name));
  154. texture->type_flags = 0;
  155. }
  156. switch (params.format) {
  157. case RTexFormat_RGB565:
  158. internal = format = GL_RGB; type = GL_UNSIGNED_SHORT_5_6_5; break;
  159. default:
  160. ATTO_ASSERT(!"Impossible texture format");
  161. }
  162. const GLenum binding = (params.type == RTexType_2D) ? GL_TEXTURE_2D : GL_TEXTURE_CUBE_MAP;
  163. const GLint wrap = (params.type == RTexType_2D) ? GL_REPEAT : GL_CLAMP;
  164. GL_CALL(glBindTexture(binding, texture->gl_name));
  165. GLenum upload_binding = binding;
  166. switch (params.type) {
  167. case RTexType_2D: upload_binding = GL_TEXTURE_2D; break;
  168. case RTexType_CubePX: upload_binding = GL_TEXTURE_CUBE_MAP_POSITIVE_X; break;
  169. case RTexType_CubeNX: upload_binding = GL_TEXTURE_CUBE_MAP_NEGATIVE_X; break;
  170. case RTexType_CubePY: upload_binding = GL_TEXTURE_CUBE_MAP_POSITIVE_Y; break;
  171. case RTexType_CubeNY: upload_binding = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; break;
  172. case RTexType_CubePZ: upload_binding = GL_TEXTURE_CUBE_MAP_POSITIVE_Z; break;
  173. case RTexType_CubeNZ: upload_binding = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; break;
  174. }
  175. GL_CALL(glTexImage2D(upload_binding, 0, internal, params.width, params.height, 0,
  176. format, type, params.pixels));
  177. if (params.generate_mipmaps)
  178. GL_CALL(glGenerateMipmap(binding));
  179. GL_CALL(glTexParameteri(binding, GL_TEXTURE_MIN_FILTER, params.generate_mipmaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR));
  180. GL_CALL(glTexParameteri(binding, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
  181. GL_CALL(glTexParameteri(binding, GL_TEXTURE_WRAP_S, wrap));
  182. GL_CALL(glTexParameteri(binding, GL_TEXTURE_WRAP_T, wrap));
  183. texture->width = params.width;
  184. texture->height = params.height;
  185. texture->format = params.format;
  186. texture->type_flags |= params.type;
  187. }
  188. void renderBufferCreate(RBuffer *buffer, RBufferType type, int size, const void *data) {
  189. switch (type) {
  190. case RBufferType_Vertex: buffer->type = GL_ARRAY_BUFFER; break;
  191. case RBufferType_Index: buffer->type = GL_ELEMENT_ARRAY_BUFFER; break;
  192. default: ASSERT(!"Invalid buffer type");
  193. }
  194. GL_CALL(glGenBuffers(1, (GLuint*)&buffer->gl_name));
  195. GL_CALL(glBindBuffer(buffer->type, (GLuint)buffer->gl_name));
  196. GL_CALL(glBufferData(buffer->type, size, data, GL_STATIC_DRAW));
  197. }
  198. typedef struct {
  199. const char *name;
  200. int components;
  201. GLenum type;
  202. GLint normalize;
  203. int stride;
  204. const void *ptr;
  205. } RAttrib;
  206. typedef struct {
  207. const char *name;
  208. } RUniform;
  209. #define RENDER_LIST_ATTRIBS \
  210. RENDER_DECLARE_ATTRIB(vertex, 3, GL_FLOAT, GL_FALSE) \
  211. RENDER_DECLARE_ATTRIB(lightmap_uv, 2, GL_FLOAT, GL_FALSE) \
  212. RENDER_DECLARE_ATTRIB(tex_uv, 2, GL_FLOAT, GL_FALSE) \
  213. RENDER_DECLARE_ATTRIB(average_color, 3, GL_UNSIGNED_BYTE, GL_TRUE) \
  214. // RENDER_DECLARE_ATTRIB(normal, 3, GL_FLOAT)
  215. static const RAttrib attribs[] = {
  216. #define RENDER_DECLARE_ATTRIB(n,c,t,N) \
  217. {"a_" # n, c, t, N, sizeof(struct BSPModelVertex), (void*)offsetof(struct BSPModelVertex, n)},
  218. RENDER_LIST_ATTRIBS
  219. #undef RENDER_DECLARE_ATTRIB
  220. };
  221. enum RAttribKinds {
  222. #define RENDER_DECLARE_ATTRIB(n,c,t,N) \
  223. RAttribKind_ ## n,
  224. RENDER_LIST_ATTRIBS
  225. #undef RENDER_DECLARE_ATTRIB
  226. RAttribKind_COUNT
  227. };
  228. #define RENDER_LIST_UNIFORMS \
  229. RENDER_DECLARE_UNIFORM(mvp) \
  230. RENDER_DECLARE_UNIFORM(lmn) \
  231. RENDER_DECLARE_UNIFORM(lightmap) \
  232. RENDER_DECLARE_UNIFORM(tex0) \
  233. RENDER_DECLARE_UNIFORM(tex1) \
  234. RENDER_DECLARE_UNIFORM(tex0_size) \
  235. RENDER_DECLARE_UNIFORM(tex1_size) \
  236. RENDER_DECLARE_UNIFORM(tex2) \
  237. RENDER_DECLARE_UNIFORM(tex3) \
  238. RENDER_DECLARE_UNIFORM(tex4) \
  239. RENDER_DECLARE_UNIFORM(tex5) \
  240. RENDER_DECLARE_UNIFORM(cam_pos) \
  241. static const RUniform uniforms[] = {
  242. #define RENDER_DECLARE_UNIFORM(n) {"u_" # n},
  243. RENDER_LIST_UNIFORMS
  244. #undef RENDER_DECLARE_UNIFORM
  245. };
  246. enum RUniformKinds {
  247. #define RENDER_DECLARE_UNIFORM(n) RUniformKind_ ## n,
  248. RENDER_LIST_UNIFORMS
  249. #undef RENDER_DECLARE_UNIFORM
  250. RUniformKind_COUNT
  251. };
  252. typedef struct RProgram {
  253. GLint name;
  254. struct {
  255. const char *common, *vertex, *fragment;
  256. } shader_sources;
  257. int attrib_locations[RAttribKind_COUNT];
  258. int uniform_locations[RUniformKind_COUNT];
  259. } RProgram;
  260. enum {
  261. Program_LightmapColor,
  262. Program_LightmapTexture,
  263. Program_Skybox,
  264. Program_COUNT
  265. };
  266. static RProgram programs[Program_COUNT] = {
  267. /*LightmapColor*/
  268. {-1, {
  269. /*common*/
  270. "varying vec2 v_lightmap_uv;\n"
  271. "varying vec3 v_color;\n",
  272. /*vertex*/
  273. "attribute vec3 a_vertex, a_average_color;\n"
  274. "attribute vec2 a_lightmap_uv;\n"
  275. "uniform mat4 u_mvp;\n"
  276. "void main() {\n"
  277. "v_lightmap_uv = a_lightmap_uv;\n"
  278. "v_color = a_average_color;\n"
  279. "gl_Position = u_mvp * vec4(a_vertex, 1.);\n"
  280. "}\n",
  281. /*fragment*/
  282. "uniform sampler2D u_lightmap;\n"
  283. "void main() {\n"
  284. "gl_FragColor = vec4(v_color * texture2D(u_lightmap, v_lightmap_uv).xyz, 1.);\n"
  285. "}\n"
  286. },
  287. { -1 }, { -1 }
  288. },
  289. /*LightmapTexture*/
  290. {-1, {
  291. /*common*/
  292. "varying vec2 v_lightmap_uv, v_tex_uv;\n",
  293. /*vertex*/
  294. "attribute vec3 a_vertex;\n"
  295. "attribute vec2 a_lightmap_uv, a_tex_uv;\n"
  296. "uniform mat4 u_mvp;\n"
  297. "void main() {\n"
  298. "v_lightmap_uv = a_lightmap_uv;\n"
  299. "v_tex_uv = a_tex_uv;\n"
  300. "gl_Position = u_mvp * vec4(a_vertex, 1.);\n"
  301. "}\n",
  302. /*fragment*/
  303. "uniform sampler2D u_lightmap, u_tex0, u_tex1;\n"
  304. "uniform vec2 u_lightmap_size, u_tex0_size, u_tex1_size;\n"
  305. "uniform float u_lmn;\n"
  306. "void main() {\n"
  307. "vec3 tc = vec3(fract(v_tex_uv/u_tex0_size), 0.);\n"
  308. "vec4 albedo = texture2D(u_tex0, v_tex_uv/u_tex0_size);\n"
  309. "albedo = mix(albedo, texture2D(u_tex1, v_tex_uv/u_tex1_size), .0);\n"
  310. "vec3 lm = texture2D(u_lightmap, v_lightmap_uv).xyz;\n"
  311. "vec3 color = albedo.xyz * lm;\n"
  312. "gl_FragColor = vec4(mix(color, tc, u_lmn), 1.);\n"
  313. "}\n"
  314. },
  315. { -1 }, { -1 }
  316. },
  317. /* Skybox */
  318. {-1, { /* common */
  319. "varying vec2 v_uv;\n"
  320. "varying float texid;\n",
  321. /* vertex */
  322. "attribute vec3 a_vertex;\n"
  323. "uniform vec3 u_cam_pos;\n"
  324. "attribute vec2 a_tex_uv;\n"
  325. "attribute vec2 a_lightmap_uv;\n"
  326. "uniform mat4 u_mvp;\n"
  327. "void main() {\n"
  328. "v_uv = a_tex_uv;\n"
  329. "texid = a_lightmap_uv.x;\n"
  330. "gl_Position = u_mvp * vec4(u_cam_pos + 100000. * a_vertex, 1.);\n"
  331. "}\n",
  332. /* fragment */
  333. "uniform sampler2D u_tex0, u_tex1, u_tex2, u_tex3, u_tex4, u_tex5;\n"
  334. "void main() {\n"
  335. "if (texid < 1.) gl_FragColor = texture2D(u_tex0, v_uv);\n"
  336. "else if (texid < 2.) gl_FragColor = texture2D(u_tex1, v_uv);\n"
  337. "else if (texid < 3.) gl_FragColor = texture2D(u_tex2, v_uv);\n"
  338. "else if (texid < 4.) gl_FragColor = texture2D(u_tex3, v_uv);\n"
  339. "else if (texid < 5.) gl_FragColor = texture2D(u_tex4, v_uv);\n"
  340. "else gl_FragColor = texture2D(u_tex5, v_uv);\n"
  341. "}\n"
  342. }, {-1}, {-1}},
  343. };
  344. static struct BSPModelVertex box[] = {
  345. {{ 1.f, -1.f, -1.f}, {0.f, 0.f}, {1.f, 0.f}, {0, 0, 0}},
  346. {{ 1.f, 1.f, -1.f}, {0.f, 0.f}, {1.f, 1.f}, {0, 0, 0}},
  347. {{ 1.f, 1.f, 1.f}, {0.f, 0.f}, {0.f, 1.f}, {0, 0, 0}},
  348. {{ 1.f, 1.f, 1.f}, {0.f, 0.f}, {0.f, 1.f}, {0, 0, 0}},
  349. {{ 1.f, -1.f, 1.f}, {0.f, 0.f}, {0.f, 0.f}, {0, 0, 0}},
  350. {{ 1.f, -1.f, -1.f}, {0.f, 0.f}, {1.f, 0.f}, {0, 0, 0}},
  351. {{-1.f, -1.f, 1.f}, {1.f, 0.f}, {1.f, 0.f}, {0, 0, 0}},
  352. {{-1.f, 1.f, 1.f}, {1.f, 0.f}, {1.f, 1.f}, {0, 0, 0}},
  353. {{-1.f, 1.f, -1.f}, {1.f, 0.f}, {0.f, 1.f}, {0, 0, 0}},
  354. {{-1.f, 1.f, -1.f}, {1.f, 0.f}, {0.f, 1.f}, {0, 0, 0}},
  355. {{-1.f, -1.f, -1.f}, {1.f, 0.f}, {0.f, 0.f}, {0, 0, 0}},
  356. {{-1.f, -1.f, 1.f}, {1.f, 0.f}, {1.f, 0.f}, {0, 0, 0}},
  357. {{ 1.f, -1.f, 1.f}, {2.f, 0.f}, {1.f, 0.f}, {0, 0, 0}},
  358. {{ 1.f, 1.f, 1.f}, {2.f, 0.f}, {1.f, 1.f}, {0, 0, 0}},
  359. {{-1.f, 1.f, 1.f}, {2.f, 0.f}, {0.f, 1.f}, {0, 0, 0}},
  360. {{-1.f, 1.f, 1.f}, {2.f, 0.f}, {0.f, 1.f}, {0, 0, 0}},
  361. {{-1.f, -1.f, 1.f}, {2.f, 0.f}, {0.f, 0.f}, {0, 0, 0}},
  362. {{ 1.f, -1.f, 1.f}, {2.f, 0.f}, {1.f, 0.f}, {0, 0, 0}},
  363. {{-1.f, -1.f, -1.f}, {3.f, 0.f}, {1.f, 0.f}, {0, 0, 0}},
  364. {{-1.f, 1.f, -1.f}, {3.f, 0.f}, {1.f, 1.f}, {0, 0, 0}},
  365. {{ 1.f, 1.f, -1.f}, {3.f, 0.f}, {0.f, 1.f}, {0, 0, 0}},
  366. {{ 1.f, 1.f, -1.f}, {3.f, 0.f}, {0.f, 1.f}, {0, 0, 0}},
  367. {{ 1.f, -1.f, -1.f}, {3.f, 0.f}, {0.f, 0.f}, {0, 0, 0}},
  368. {{-1.f, -1.f, -1.f}, {3.f, 0.f}, {1.f, 0.f}, {0, 0, 0}},
  369. {{ 1.f, 1.f, 1.f}, {4.f, 0.f}, {1.f, 0.f}, {0, 0, 0}},
  370. {{ 1.f, 1.f, -1.f}, {4.f, 0.f}, {1.f, 1.f}, {0, 0, 0}},
  371. {{-1.f, 1.f, -1.f}, {4.f, 0.f}, {0.f, 1.f}, {0, 0, 0}},
  372. {{-1.f, 1.f, -1.f}, {4.f, 0.f}, {0.f, 1.f}, {0, 0, 0}},
  373. {{-1.f, 1.f, 1.f}, {4.f, 0.f}, {0.f, 0.f}, {0, 0, 0}},
  374. {{ 1.f, 1.f, 1.f}, {4.f, 0.f}, {1.f, 0.f}, {0, 0, 0}},
  375. {{ 1.f, -1.f, -1.f}, {5.f, 0.f}, {1.f, 0.f}, {0, 0, 0}},
  376. {{ 1.f, -1.f, 1.f}, {5.f, 0.f}, {1.f, 1.f}, {0, 0, 0}},
  377. {{-1.f, -1.f, 1.f}, {5.f, 0.f}, {0.f, 1.f}, {0, 0, 0}},
  378. {{-1.f, -1.f, 1.f}, {5.f, 0.f}, {0.f, 1.f}, {0, 0, 0}},
  379. {{-1.f, -1.f, -1.f}, {5.f, 0.f}, {0.f, 0.f}, {0, 0, 0}},
  380. {{ 1.f, -1.f, -1.f}, {5.f, 0.f}, {1.f, 0.f}, {0, 0, 0}},
  381. };
  382. static RBuffer box_buffer;
  383. static struct {
  384. const RTexture *current_tex0;
  385. const RProgram *current_program;
  386. struct {
  387. const float *mvp;
  388. float lmn;
  389. struct AVec3f campos;
  390. } uniforms;
  391. } r;
  392. static void renderApplyAttribs(const RAttrib *attribs, const RBuffer *buffer, unsigned int vbo_offset) {
  393. for(int i = 0; i < RAttribKind_COUNT; ++i) {
  394. const RAttrib *a = attribs + i;
  395. const int loc = r.current_program->attrib_locations[i];
  396. if (loc < 0) continue;
  397. GL_CALL(glEnableVertexAttribArray(loc));
  398. GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, buffer->gl_name));
  399. GL_CALL(glVertexAttribPointer(loc, a->components, a->type, a->normalize, a->stride, (const char*)a->ptr + vbo_offset * sizeof(struct BSPModelVertex)));
  400. }
  401. }
  402. static int render_ProgramUse(RProgram *prog) {
  403. if (r.current_program == prog)
  404. return 0;
  405. if (r.current_program) {
  406. for (int i = 0; i < RAttribKind_COUNT; ++i) {
  407. const int loc = r.current_program->attrib_locations[i];
  408. if (loc >= 0)
  409. GL_CALL(glDisableVertexAttribArray(loc));
  410. }
  411. }
  412. GL_CALL(glUseProgram(prog->name));
  413. GL_CALL(glUniform1i(prog->uniform_locations[RUniformKind_lightmap], 0));
  414. GL_CALL(glUniform1i(prog->uniform_locations[RUniformKind_tex0], 1));
  415. GL_CALL(glUniform1i(prog->uniform_locations[RUniformKind_tex1], 2));
  416. GL_CALL(glUniform1i(prog->uniform_locations[RUniformKind_tex2], 3));
  417. GL_CALL(glUniform1i(prog->uniform_locations[RUniformKind_tex3], 4));
  418. GL_CALL(glUniform1i(prog->uniform_locations[RUniformKind_tex4], 5));
  419. GL_CALL(glUniform1i(prog->uniform_locations[RUniformKind_tex5], 6));
  420. GL_CALL(glUniformMatrix4fv(prog->uniform_locations[RUniformKind_mvp], 1, GL_FALSE, r.uniforms.mvp));
  421. GL_CALL(glUniform1f(prog->uniform_locations[RUniformKind_lmn], r.uniforms.lmn));
  422. GL_CALL(glUniform3f(prog->uniform_locations[RUniformKind_cam_pos], r.uniforms.campos.x, r.uniforms.campos.y, r.uniforms.campos.z));
  423. r.current_program = prog;
  424. r.current_tex0 = NULL;
  425. return 1;
  426. }
  427. static int render_ProgramInit(RProgram *prog) {
  428. GLuint program;
  429. GLuint vertex_shader, fragment_shader;
  430. const char *sources[] = {
  431. prog->shader_sources.common, prog->shader_sources.fragment, 0
  432. };
  433. fragment_shader = render_ShaderCreate(GL_FRAGMENT_SHADER, sources);
  434. if (fragment_shader == 0)
  435. return -1;
  436. sources[1] = prog->shader_sources.vertex;
  437. vertex_shader = render_ShaderCreate(GL_VERTEX_SHADER, sources);
  438. if (vertex_shader == 0) {
  439. GL_CALL(glDeleteShader(fragment_shader));
  440. return -2;
  441. }
  442. program = glCreateProgram();
  443. GL_CALL(glAttachShader(program, fragment_shader));
  444. GL_CALL(glAttachShader(program, vertex_shader));
  445. GL_CALL(glLinkProgram(program));
  446. GL_CALL(glDeleteShader(fragment_shader));
  447. GL_CALL(glDeleteShader(vertex_shader));
  448. #ifdef RENDER_ERRORCHECK
  449. {
  450. GLint status;
  451. GL_CALL(glGetProgramiv(program, GL_LINK_STATUS, &status));
  452. if (status != GL_TRUE) {
  453. char buffer[1024];
  454. GL_CALL(glGetProgramInfoLog(program, sizeof(buffer), 0, buffer));
  455. PRINTF("Program linking error: %s", buffer);
  456. GL_CALL(glDeleteProgram(program));
  457. return -3;
  458. }
  459. }
  460. #endif
  461. prog->name = program;
  462. for(int i = 0; i < RAttribKind_COUNT; ++i) {
  463. prog->attrib_locations[i] = glGetAttribLocation(prog->name, attribs[i].name);
  464. if (prog->attrib_locations[i] < 0)
  465. PRINTF("Cannot locate attribute %s", attribs[i].name);
  466. }
  467. for(int i = 0; i < RUniformKind_COUNT; ++i) {
  468. prog->uniform_locations[i] = glGetUniformLocation(prog->name, uniforms[i].name);
  469. if (prog->uniform_locations[i] < 0)
  470. PRINTF("Cannot locate uniform %s", uniforms[i].name);
  471. }
  472. return 0;
  473. }
  474. int renderInit() {
  475. #ifdef _WIN32
  476. #define WGL__FUNCLIST_DO(T, N) \
  477. gl##N = (T)wglGetProcAddress("gl" #N); \
  478. ASSERT(gl##N);
  479. WGL__FUNCLIST
  480. #undef WGL__FUNCLIST_DO
  481. #endif
  482. r.current_program = NULL;
  483. r.current_tex0 = NULL;
  484. r.uniforms.mvp = NULL;
  485. r.uniforms.lmn = 0;
  486. for (int i = 0; i < Program_COUNT; ++i) {
  487. if (render_ProgramInit(programs + i) != 0) {
  488. PRINTF("Cannot create program %d", i);
  489. return 0;
  490. }
  491. }
  492. struct Texture default_texture;
  493. RTextureUploadParams params;
  494. params.type = RTexType_2D;
  495. params.format = RTexFormat_RGB565;
  496. params.width = 2;
  497. params.height = 2;
  498. params.pixels = (uint16_t[]){0xffffu, 0, 0, 0xffffu};
  499. params.generate_mipmaps = 0;
  500. renderTextureInit(&default_texture.texture);
  501. renderTextureUpload(&default_texture.texture, params);
  502. cachePutTexture("opensource/placeholder", &default_texture);
  503. {
  504. struct Material default_material;
  505. memset(&default_material, 0, sizeof default_material);
  506. default_material.average_color = aVec3f(0.f, 1.f, 0.f);
  507. default_material.shader = MaterialShader_LightmappedAverageColor;
  508. cachePutMaterial("opensource/placeholder", &default_material);
  509. }
  510. {
  511. struct Material lightmap_color_material;
  512. memset(&lightmap_color_material, 0, sizeof lightmap_color_material);
  513. lightmap_color_material.average_color = aVec3f(0.f, 1.f, 0.f);
  514. lightmap_color_material.shader = MaterialShader_LightmappedAverageColor;
  515. cachePutMaterial("opensource/coarse", &lightmap_color_material);
  516. }
  517. renderBufferCreate(&box_buffer, RBufferType_Vertex, sizeof(box), box);
  518. GL_CALL(glEnable(GL_DEPTH_TEST));
  519. GL_CALL(glEnable(GL_CULL_FACE));
  520. return 1;
  521. }
  522. static int renderPrepareProgram(const struct BSPDraw *draw) {
  523. const struct Material *m = draw->material;
  524. int program_changed = 0;
  525. switch (m->shader) {
  526. case MaterialShader_LightmappedAverageColor:
  527. program_changed = render_ProgramUse(programs + Program_LightmapColor);
  528. break;
  529. case MaterialShader_LightmappedGeneric:
  530. program_changed = render_ProgramUse(programs + Program_LightmapTexture);
  531. break;
  532. default:
  533. ATTO_ASSERT(!"Impossible");
  534. }
  535. if (m->base_texture[0]) {
  536. const RTexture *t = &m->base_texture[0]->texture;
  537. if (t != r.current_tex0) {
  538. GL_CALL(glBindTexture(GL_TEXTURE_2D, t->gl_name));
  539. GL_CALL(glUniform2f(r.current_program->uniform_locations[RUniformKind_tex0_size], (float)t->width, (float)t->height));
  540. r.current_tex0 = t;
  541. }
  542. }
  543. return program_changed;
  544. }
  545. static void renderDrawSet(const struct BSPModel *model, const struct BSPDrawSet *drawset) {
  546. unsigned int vbo_offset = 0;
  547. for (int i = 0; i < drawset->draws_count; ++i) {
  548. const struct BSPDraw *draw = drawset->draws + i;
  549. if (renderPrepareProgram(draw) || i == 0 || draw->vbo_offset != vbo_offset) {
  550. vbo_offset = draw->vbo_offset;
  551. renderApplyAttribs(attribs, &model->vbo, draw->vbo_offset);
  552. }
  553. GL_CALL(glDrawElements(GL_TRIANGLES, draw->count, GL_UNSIGNED_SHORT, (void*)(sizeof(uint16_t) * draw->start)));
  554. }
  555. }
  556. static void renderBindTexture(const RTexture *texture, int slot) {
  557. GL_CALL(glActiveTexture(GL_TEXTURE0 + slot));
  558. GL_CALL(glBindTexture(GL_TEXTURE_2D, texture->gl_name));
  559. }
  560. static void renderSkybox(const struct BSPModel *model) {
  561. render_ProgramUse(programs + Program_Skybox);
  562. for (int i = 0; i < 6; ++i)
  563. renderBindTexture(&model->skybox[i]->texture, 1+i);
  564. renderApplyAttribs(attribs, &box_buffer, 0);
  565. GL_CALL(glDisable(GL_CULL_FACE));
  566. GL_CALL(glDrawArrays(GL_TRIANGLES, 0, COUNTOF(box)));
  567. GL_CALL(glEnable(GL_CULL_FACE));
  568. }
  569. static float aMaxf(float a, float b) { return a > b ? a : b; }
  570. //static float aMinf(float a, float b) { return a < b ? a : b; }
  571. void renderModelDraw(const struct AMat4f *mvp, struct AVec3f camera_position, float lmn, const struct BSPModel *model) {
  572. if (!model->detailed.draws_count) return;
  573. GL_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model->ibo.gl_name));
  574. renderBindTexture(&model->lightmap, 0);
  575. GL_CALL(glActiveTexture(GL_TEXTURE0 + 1));
  576. r.current_program = NULL;
  577. r.uniforms.mvp = &mvp->X.x;
  578. r.uniforms.lmn = lmn;
  579. r.uniforms.campos = camera_position;
  580. const float distance =
  581. aMaxf(aMaxf(
  582. aMaxf(camera_position.x - model->aabb.max.x, model->aabb.min.x - camera_position.x),
  583. aMaxf(camera_position.y - model->aabb.max.y, model->aabb.min.y - camera_position.y)),
  584. aMaxf(camera_position.z - model->aabb.max.z, model->aabb.min.z - camera_position.z));
  585. /*
  586. PRINTF("%f %f %f -> %f",
  587. camera_position.x, camera_position.y, camera_position.z, distance);
  588. */
  589. if (distance < 5000.f)
  590. renderDrawSet(model, &model->detailed);
  591. else
  592. renderDrawSet(model, &model->coarse);
  593. renderSkybox(model);
  594. }
  595. void renderResize(int w, int h) {
  596. glViewport(0, 0, w, h);
  597. }
  598. void renderClear() {
  599. glClearColor(.5f,.4f,.2f,0);
  600. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  601. }