You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1351 lines
38KB

  1. //
  2. // Copyright (c) 2009-2013 Mikko Mononen memon@inside.org
  3. //
  4. // This software is provided 'as-is', without any express or implied
  5. // warranty. In no event will the authors be held liable for any damages
  6. // arising from the use of this software.
  7. // Permission is granted to anyone to use this software for any purpose,
  8. // including commercial applications, and to alter it and redistribute it
  9. // freely, subject to the following restrictions:
  10. // 1. The origin of this software must not be misrepresented; you must not
  11. // claim that you wrote the original software. If you use this software
  12. // in a product, an acknowledgment in the product documentation would be
  13. // appreciated but is not required.
  14. // 2. Altered source versions must be plainly marked as such, and must not be
  15. // misrepresented as being the original software.
  16. // 3. This notice may not be removed or altered from any source distribution.
  17. //
  18. #ifndef NANOVG_GL_H
  19. #define NANOVG_GL_H
  20. #ifdef __cplusplus
  21. extern "C" {
  22. #endif
  23. #define NVG_ANTIALIAS 1
  24. #if defined NANOVG_GL2_IMPLEMENTATION
  25. # define NANOVG_GL2 1
  26. # define NANOVG_GL_IMPLEMENTATION 1
  27. #elif defined NANOVG_GL3_IMPLEMENTATION
  28. # define NANOVG_GL3 1
  29. # define NANOVG_GL_IMPLEMENTATION 1
  30. # define NANOVG_GL_USE_UNIFORMBUFFER 1
  31. #elif defined NANOVG_GLES2_IMPLEMENTATION
  32. # define NANOVG_GLES2 1
  33. # define NANOVG_GL_IMPLEMENTATION 1
  34. #elif defined NANOVG_GLES3_IMPLEMENTATION
  35. # define NANOVG_GLES3 1
  36. # define NANOVG_GL_IMPLEMENTATION 1
  37. #endif
  38. #if defined NANOVG_GL2
  39. struct NVGcontext* nvgCreateGL2(int atlasw, int atlash, int edgeaa);
  40. void nvgDeleteGL2(struct NVGcontext* ctx);
  41. #elif defined NANOVG_GL3
  42. struct NVGcontext* nvgCreateGL3(int atlasw, int atlash, int edgeaa);
  43. void nvgDeleteGL3(struct NVGcontext* ctx);
  44. #elif defined NANOVG_GLES2
  45. struct NVGcontext* nvgCreateGLES2(int atlasw, int atlash, int edgeaa);
  46. void nvgDeleteGLES2(struct NVGcontext* ctx);
  47. #elif defined NANOVG_GLES3
  48. struct NVGcontext* nvgCreateGLES3(int atlasw, int atlash, int edgeaa);
  49. void nvgDeleteGLES3(struct NVGcontext* ctx);
  50. #endif
  51. enum NVGLtextureflags {
  52. NVGL_TEXTURE_FLIP_Y = 0x01,
  53. NVGL_TEXTURE_NODELETE = 0x02,
  54. };
  55. int nvglCreateImageFromHandle(struct NVGcontext* ctx, GLuint textureId, int flags);
  56. GLuint nvglImageHandle(struct NVGcontext* ctx, int image);
  57. void nvglImageFlags(struct NVGcontext* ctx, int image, int flags);
  58. #ifdef __cplusplus
  59. }
  60. #endif
  61. #endif /* NANOVG_GL_H */
  62. #ifdef NANOVG_GL_IMPLEMENTATION
  63. #include <stdlib.h>
  64. #include <stdio.h>
  65. #include <string.h>
  66. #include <math.h>
  67. #include "nanovg.h"
  68. enum GLNVGuniformLoc {
  69. GLNVG_LOC_VIEWSIZE,
  70. GLNVG_LOC_TEX,
  71. #if NANOVG_GL_USE_UNIFORMBUFFER
  72. GLNVG_LOC_FRAG,
  73. #else
  74. GLNVG_LOC_SCISSORMAT,
  75. GLNVG_LOC_SCISSOREXT,
  76. GLNVG_LOC_SCISSORSCALE,
  77. GLNVG_LOC_PAINTMAT,
  78. GLNVG_LOC_EXTENT,
  79. GLNVG_LOC_RADIUS,
  80. GLNVG_LOC_FEATHER,
  81. GLNVG_LOC_INNERCOL,
  82. GLNVG_LOC_OUTERCOL,
  83. GLNVG_LOC_STROKEMULT,
  84. GLNVG_LOC_TEXTYPE,
  85. GLNVG_LOC_TYPE,
  86. #endif
  87. GLNVG_MAX_LOCS
  88. };
  89. enum GLNVGshaderType {
  90. NSVG_SHADER_FILLGRAD,
  91. NSVG_SHADER_FILLIMG,
  92. NSVG_SHADER_SIMPLE,
  93. NSVG_SHADER_IMG
  94. };
  95. #if NANOVG_GL_USE_UNIFORMBUFFER
  96. enum GLNVGuniformBindings {
  97. GLNVG_FRAG_BINDING = 0,
  98. };
  99. #endif
  100. struct GLNVGshader {
  101. GLuint prog;
  102. GLuint frag;
  103. GLuint vert;
  104. GLint loc[GLNVG_MAX_LOCS];
  105. };
  106. struct GLNVGtexture {
  107. int id;
  108. GLuint tex;
  109. int width, height;
  110. int type;
  111. int flags;
  112. };
  113. enum GLNVGcallType {
  114. GLNVG_NONE = 0,
  115. GLNVG_FILL,
  116. GLNVG_CONVEXFILL,
  117. GLNVG_STROKE,
  118. GLNVG_TRIANGLES,
  119. };
  120. struct GLNVGcall {
  121. int type;
  122. int image;
  123. int pathOffset;
  124. int pathCount;
  125. int triangleOffset;
  126. int triangleCount;
  127. int uniformOffset;
  128. };
  129. struct GLNVGpath {
  130. int fillOffset;
  131. int fillCount;
  132. int strokeOffset;
  133. int strokeCount;
  134. };
  135. struct GLNVGfragUniforms {
  136. float scissorMat[12]; // matrices are actually 3 vec4s
  137. float paintMat[12];
  138. struct NVGcolor innerCol;
  139. struct NVGcolor outerCol;
  140. float scissorExt[2];
  141. float scissorScale[2];
  142. float extent[2];
  143. float radius;
  144. float feather;
  145. float strokeMult;
  146. int texType;
  147. int type;
  148. };
  149. struct GLNVGcontext {
  150. struct GLNVGshader shader;
  151. struct GLNVGtexture* textures;
  152. float view[2];
  153. int ntextures;
  154. int ctextures;
  155. int textureId;
  156. GLuint vertBuf;
  157. #if defined NANOVG_GL3
  158. GLuint vertArr;
  159. #endif
  160. #if NANOVG_GL_USE_UNIFORMBUFFER
  161. GLuint fragBuf;
  162. #endif
  163. int fragSize;
  164. int edgeAntiAlias;
  165. // Per frame buffers
  166. struct GLNVGcall* calls;
  167. int ccalls;
  168. int ncalls;
  169. struct GLNVGpath* paths;
  170. int cpaths;
  171. int npaths;
  172. struct NVGvertex* verts;
  173. int cverts;
  174. int nverts;
  175. unsigned char* uniforms;
  176. int cuniforms;
  177. int nuniforms;
  178. };
  179. static int glnvg__maxi(int a, int b) { return a > b ? a : b; }
  180. static struct GLNVGtexture* glnvg__allocTexture(struct GLNVGcontext* gl)
  181. {
  182. struct GLNVGtexture* tex = NULL;
  183. int i;
  184. for (i = 0; i < gl->ntextures; i++) {
  185. if (gl->textures[i].id == 0) {
  186. tex = &gl->textures[i];
  187. break;
  188. }
  189. }
  190. if (tex == NULL) {
  191. if (gl->ntextures+1 > gl->ctextures) {
  192. struct GLNVGtexture* textures;
  193. int ctextures = glnvg__maxi(gl->ntextures+1, 4) + gl->ctextures/2; // 1.5x Overallocate
  194. textures = (struct GLNVGtexture*)realloc(gl->textures, sizeof(struct GLNVGtexture)*ctextures);
  195. if (textures == NULL) return NULL;
  196. gl->textures = textures;
  197. gl->ctextures = ctextures;
  198. }
  199. tex = &gl->textures[gl->ntextures++];
  200. }
  201. memset(tex, 0, sizeof(*tex));
  202. tex->id = ++gl->textureId;
  203. return tex;
  204. }
  205. static struct GLNVGtexture* glnvg__findTexture(struct GLNVGcontext* gl, int id)
  206. {
  207. int i;
  208. for (i = 0; i < gl->ntextures; i++)
  209. if (gl->textures[i].id == id)
  210. return &gl->textures[i];
  211. return NULL;
  212. }
  213. static int glnvg__deleteTexture(struct GLNVGcontext* gl, int id)
  214. {
  215. int i;
  216. for (i = 0; i < gl->ntextures; i++) {
  217. if (gl->textures[i].id == id) {
  218. if (gl->textures[i].tex != 0 && (gl->textures[i].flags & NVGL_TEXTURE_NODELETE) == 0)
  219. glDeleteTextures(1, &gl->textures[i].tex);
  220. memset(&gl->textures[i], 0, sizeof(gl->textures[i]));
  221. return 1;
  222. }
  223. }
  224. return 0;
  225. }
  226. static void glnvg__dumpShaderError(GLuint shader, const char* name, const char* type)
  227. {
  228. char str[512+1];
  229. int len = 0;
  230. glGetShaderInfoLog(shader, 512, &len, str);
  231. if (len > 512) len = 512;
  232. str[len] = '\0';
  233. printf("Shader %s/%s error:\n%s\n", name, type, str);
  234. }
  235. static void glnvg__dumpProgramError(GLuint prog, const char* name)
  236. {
  237. char str[512+1];
  238. int len = 0;
  239. glGetProgramInfoLog(prog, 512, &len, str);
  240. if (len > 512) len = 512;
  241. str[len] = '\0';
  242. printf("Program %s error:\n%s\n", name, str);
  243. }
  244. static int glnvg__checkError(const char* str)
  245. {
  246. GLenum err = glGetError();
  247. if (err != GL_NO_ERROR) {
  248. printf("Error %08x after %s\n", err, str);
  249. return 1;
  250. }
  251. return 0;
  252. }
  253. static int glnvg__createShader(struct GLNVGshader* shader, const char* name, const char* header, const char* opts, const char* vshader, const char* fshader)
  254. {
  255. GLint status;
  256. GLuint prog, vert, frag;
  257. const char* str[3];
  258. str[0] = header;
  259. str[1] = opts != NULL ? opts : "";
  260. memset(shader, 0, sizeof(*shader));
  261. prog = glCreateProgram();
  262. vert = glCreateShader(GL_VERTEX_SHADER);
  263. frag = glCreateShader(GL_FRAGMENT_SHADER);
  264. str[2] = vshader;
  265. glShaderSource(vert, 3, str, 0);
  266. str[2] = fshader;
  267. glShaderSource(frag, 3, str, 0);
  268. glCompileShader(vert);
  269. glGetShaderiv(vert, GL_COMPILE_STATUS, &status);
  270. if (status != GL_TRUE) {
  271. glnvg__dumpShaderError(vert, name, "vert");
  272. return 0;
  273. }
  274. glCompileShader(frag);
  275. glGetShaderiv(frag, GL_COMPILE_STATUS, &status);
  276. if (status != GL_TRUE) {
  277. glnvg__dumpShaderError(frag, name, "frag");
  278. return 0;
  279. }
  280. glAttachShader(prog, vert);
  281. glAttachShader(prog, frag);
  282. glBindAttribLocation(prog, 0, "vertex");
  283. glBindAttribLocation(prog, 1, "tcoord");
  284. glLinkProgram(prog);
  285. glGetProgramiv(prog, GL_LINK_STATUS, &status);
  286. if (status != GL_TRUE) {
  287. glnvg__dumpProgramError(prog, name);
  288. return 0;
  289. }
  290. shader->prog = prog;
  291. shader->vert = vert;
  292. shader->frag = frag;
  293. return 1;
  294. }
  295. static void glnvg__deleteShader(struct GLNVGshader* shader)
  296. {
  297. if (shader->prog != 0)
  298. glDeleteProgram(shader->prog);
  299. if (shader->vert != 0)
  300. glDeleteShader(shader->vert);
  301. if (shader->frag != 0)
  302. glDeleteShader(shader->frag);
  303. }
  304. static void glnvg__getUniforms(struct GLNVGshader* shader)
  305. {
  306. shader->loc[GLNVG_LOC_VIEWSIZE] = glGetUniformLocation(shader->prog, "viewSize");
  307. shader->loc[GLNVG_LOC_TEX] = glGetUniformLocation(shader->prog, "tex");
  308. #if NANOVG_GL_USE_UNIFORMBUFFER
  309. shader->loc[GLNVG_LOC_FRAG] = glGetUniformBlockIndex(shader->prog, "frag");
  310. #else
  311. shader->loc[GLNVG_LOC_SCISSORMAT] = glGetUniformLocation(shader->prog, "scissorMat");
  312. shader->loc[GLNVG_LOC_SCISSOREXT] = glGetUniformLocation(shader->prog, "scissorExt");
  313. shader->loc[GLNVG_LOC_SCISSORSCALE] = glGetUniformLocation(shader->prog, "scissorScale");
  314. shader->loc[GLNVG_LOC_PAINTMAT] = glGetUniformLocation(shader->prog, "paintMat");
  315. shader->loc[GLNVG_LOC_EXTENT] = glGetUniformLocation(shader->prog, "extent");
  316. shader->loc[GLNVG_LOC_RADIUS] = glGetUniformLocation(shader->prog, "radius");
  317. shader->loc[GLNVG_LOC_FEATHER] = glGetUniformLocation(shader->prog, "feather");
  318. shader->loc[GLNVG_LOC_INNERCOL] = glGetUniformLocation(shader->prog, "innerCol");
  319. shader->loc[GLNVG_LOC_OUTERCOL] = glGetUniformLocation(shader->prog, "outerCol");
  320. shader->loc[GLNVG_LOC_STROKEMULT] = glGetUniformLocation(shader->prog, "strokeMult");
  321. shader->loc[GLNVG_LOC_TEXTYPE] = glGetUniformLocation(shader->prog, "texType");
  322. shader->loc[GLNVG_LOC_TYPE] = glGetUniformLocation(shader->prog, "type");
  323. #endif
  324. }
  325. static int glnvg__renderCreate(void* uptr)
  326. {
  327. struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr;
  328. int align = 4;
  329. // TODO: mediump float may not be enough for GLES2 in iOS.
  330. // see the following discussion: https://github.com/memononen/nanovg/issues/46
  331. static const char* shaderHeader =
  332. #if defined NANOVG_GL2
  333. "#define NANOVG_GL2 1\n";
  334. #elif defined NANOVG_GL3
  335. "#version 150 core\n"
  336. #if NANOVG_GL_USE_UNIFORMBUFFER
  337. "#define USE_UNIFORMBUFFER 1\n"
  338. #endif
  339. "#define NANOVG_GL3 1\n";
  340. #elif defined NANOVG_GLES2
  341. "#version 100\n"
  342. "#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
  343. " precision highp float;\n"
  344. "#else\n"
  345. " precision mediump float;\n"
  346. "#endif\n"
  347. "#define NANOVG_GL2 1\n";
  348. #elif defined NANOVG_GLES3
  349. "#version 300 es\n"
  350. "precision highp float;\n"
  351. "#define NANOVG_GL3 1\n";
  352. #endif
  353. static const char* fillVertShader =
  354. "#ifdef NANOVG_GL3\n"
  355. " uniform vec2 viewSize;\n"
  356. " in vec2 vertex;\n"
  357. " in vec2 tcoord;\n"
  358. " out vec2 ftcoord;\n"
  359. " out vec2 fpos;\n"
  360. "#else\n"
  361. " uniform vec2 viewSize;\n"
  362. " attribute vec2 vertex;\n"
  363. " attribute vec2 tcoord;\n"
  364. " varying vec2 ftcoord;\n"
  365. " varying vec2 fpos;\n"
  366. "#endif\n"
  367. "void main(void) {\n"
  368. " ftcoord = tcoord;\n"
  369. " fpos = vertex;\n"
  370. " gl_Position = vec4(2.0*vertex.x/viewSize.x - 1.0, 1.0 - 2.0*vertex.y/viewSize.y, 0, 1);\n"
  371. "}\n";
  372. static const char* fillFragShader =
  373. "#ifdef NANOVG_GL3\n"
  374. "#ifdef USE_UNIFORMBUFFER\n"
  375. " layout(std140) uniform frag {\n"
  376. " mat3 scissorMat;\n"
  377. " mat3 paintMat;\n"
  378. " vec4 innerCol;\n"
  379. " vec4 outerCol;\n"
  380. " vec2 scissorExt;\n"
  381. " vec2 scissorScale;\n"
  382. " vec2 extent;\n"
  383. " float radius;\n"
  384. " float feather;\n"
  385. " float strokeMult;\n"
  386. " int texType;\n"
  387. " int type;\n"
  388. " };\n"
  389. "#else\n"
  390. " uniform mat3 scissorMat;\n"
  391. " uniform mat3 paintMat;\n"
  392. " uniform vec4 innerCol;\n"
  393. " uniform vec4 outerCol;\n"
  394. " uniform vec2 scissorExt;\n"
  395. " uniform vec2 scissorScale;\n"
  396. " uniform vec2 extent;\n"
  397. " uniform float radius;\n"
  398. " uniform float feather;\n"
  399. " uniform float strokeMult;\n"
  400. " uniform int texType;\n"
  401. " uniform int type;\n"
  402. "#endif\n"
  403. " uniform sampler2D tex;\n"
  404. " in vec2 ftcoord;\n"
  405. " in vec2 fpos;\n"
  406. " out vec4 outColor;\n"
  407. "#else\n"
  408. " uniform mat3 scissorMat;\n"
  409. " uniform mat3 paintMat;\n"
  410. " uniform vec4 innerCol;\n"
  411. " uniform vec4 outerCol;\n"
  412. " uniform vec2 scissorExt;\n"
  413. " uniform vec2 scissorScale;\n"
  414. " uniform vec2 extent;\n"
  415. " uniform float radius;\n"
  416. " uniform float feather;\n"
  417. " uniform float strokeMult;\n"
  418. " uniform int texType;\n"
  419. " uniform int type;\n"
  420. " uniform sampler2D tex;\n"
  421. " varying vec2 ftcoord;\n"
  422. " varying vec2 fpos;\n"
  423. "#endif\n"
  424. "\n"
  425. "float sdroundrect(vec2 pt, vec2 ext, float rad) {\n"
  426. " vec2 ext2 = ext - vec2(rad,rad);\n"
  427. " vec2 d = abs(pt) - ext2;\n"
  428. " return min(max(d.x,d.y),0.0) + length(max(d,0.0)) - rad;\n"
  429. "}\n"
  430. "\n"
  431. "// Scissoring\n"
  432. "float scissorMask(vec2 p) {\n"
  433. " vec2 sc = (abs((scissorMat * vec3(p,1.0)).xy) - scissorExt);\n"
  434. " sc = vec2(0.5,0.5) - sc * scissorScale;\n"
  435. " return clamp(sc.x,0.0,1.0) * clamp(sc.y,0.0,1.0);\n"
  436. "}\n"
  437. "#ifdef EDGE_AA\n"
  438. "// Stroke - from [0..1] to clipped pyramid, where the slope is 1px.\n"
  439. "float strokeMask() {\n"
  440. " return min(1.0, (1.0-abs(ftcoord.x*2.0-1.0))*strokeMult) * min(1.0, ftcoord.y);\n"
  441. "}\n"
  442. "#endif\n"
  443. "\n"
  444. "void main(void) {\n"
  445. " vec4 result;\n"
  446. " float scissor = scissorMask(fpos);\n"
  447. "#ifdef EDGE_AA\n"
  448. " float strokeAlpha = strokeMask();\n"
  449. "#else\n"
  450. " float strokeAlpha = 1.0;\n"
  451. "#endif\n"
  452. " if (type == 0) { // Gradient\n"
  453. " // Calculate gradient color using box gradient\n"
  454. " vec2 pt = (paintMat * vec3(fpos,1.0)).xy;\n"
  455. " float d = clamp((sdroundrect(pt, extent, radius) + feather*0.5) / feather, 0.0, 1.0);\n"
  456. " vec4 color = mix(innerCol,outerCol,d);\n"
  457. " // Combine alpha\n"
  458. " color.w *= strokeAlpha * scissor;\n"
  459. " result = color;\n"
  460. " } else if (type == 1) { // Image\n"
  461. " // Calculate color fron texture\n"
  462. " vec2 pt = (paintMat * vec3(fpos,1.0)).xy / extent;\n"
  463. "#ifdef NANOVG_GL3\n"
  464. " vec4 color = texture(tex, pt);\n"
  465. "#else\n"
  466. " vec4 color = texture2D(tex, pt);\n"
  467. "#endif\n"
  468. " color = texType == 0 ? color : vec4(1,1,1,color.x);\n"
  469. " // Combine alpha\n"
  470. " color.w *= strokeAlpha * scissor;\n"
  471. " result = color;\n"
  472. " } else if (type == 2) { // Stencil fill\n"
  473. " result = vec4(1,1,1,1);\n"
  474. " } else if (type == 3) { // Textured tris\n"
  475. "#ifdef NANOVG_GL3\n"
  476. " vec4 color = texture(tex, ftcoord);\n"
  477. "#else\n"
  478. " vec4 color = texture2D(tex, ftcoord);\n"
  479. "#endif\n"
  480. " color = texType == 0 ? color : vec4(1,1,1,color.x);\n"
  481. " color.w *= scissor;\n"
  482. " result = color * innerCol;\n"
  483. " }\n"
  484. "#ifdef NANOVG_GL3\n"
  485. " outColor = result;\n"
  486. "#else\n"
  487. " gl_FragColor = result;\n"
  488. "#endif\n"
  489. "}\n";
  490. glnvg__checkError("init");
  491. if (gl->edgeAntiAlias) {
  492. if (glnvg__createShader(&gl->shader, "shader", shaderHeader, "#define EDGE_AA 1\n", fillVertShader, fillFragShader) == 0)
  493. return 0;
  494. } else {
  495. if (glnvg__createShader(&gl->shader, "shader", shaderHeader, NULL, fillVertShader, fillFragShader) == 0)
  496. return 0;
  497. }
  498. glnvg__checkError("uniform locations");
  499. glnvg__getUniforms(&gl->shader);
  500. // Create dynamic vertex array
  501. #if defined NANOVG_GL3
  502. glGenVertexArrays(1, &gl->vertArr);
  503. #endif
  504. glGenBuffers(1, &gl->vertBuf);
  505. #if NANOVG_GL_USE_UNIFORMBUFFER
  506. // Create UBOs
  507. glUniformBlockBinding(gl->shader.prog, gl->shader.loc[GLNVG_LOC_FRAG], GLNVG_FRAG_BINDING);
  508. glGenBuffers(1, &gl->fragBuf);
  509. glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &align);
  510. #endif
  511. gl->fragSize = sizeof(struct GLNVGfragUniforms) + align - sizeof(struct GLNVGfragUniforms) % align;
  512. glnvg__checkError("create done");
  513. glFinish();
  514. return 1;
  515. }
  516. static int glnvg__renderCreateTexture(void* uptr, int type, int w, int h, const unsigned char* data)
  517. {
  518. struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr;
  519. struct GLNVGtexture* tex = glnvg__allocTexture(gl);
  520. if (tex == NULL) return 0;
  521. glGenTextures(1, &tex->tex);
  522. tex->width = w;
  523. tex->height = h;
  524. tex->type = type;
  525. glBindTexture(GL_TEXTURE_2D, tex->tex);
  526. glPixelStorei(GL_UNPACK_ALIGNMENT,1);
  527. #ifndef NANOVG_GLES2
  528. glPixelStorei(GL_UNPACK_ROW_LENGTH, tex->width);
  529. glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
  530. glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
  531. #endif
  532. if (type == NVG_TEXTURE_RGBA)
  533. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
  534. else
  535. #if defined(NANOVG_GLES2)
  536. glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, w, h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
  537. #elif defined(NANOVG_GLES3)
  538. glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, w, h, 0, GL_RED, GL_UNSIGNED_BYTE, data);
  539. #else
  540. glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, w, h, 0, GL_RED, GL_UNSIGNED_BYTE, data);
  541. #endif
  542. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  543. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  544. glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
  545. #ifndef NANOVG_GLES2
  546. glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
  547. glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
  548. glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
  549. #endif
  550. if (glnvg__checkError("create tex"))
  551. return 0;
  552. glBindTexture(GL_TEXTURE_2D, 0);
  553. return tex->id;
  554. }
  555. static int glnvg__renderDeleteTexture(void* uptr, int image)
  556. {
  557. struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr;
  558. return glnvg__deleteTexture(gl, image);
  559. }
  560. static int glnvg__renderUpdateTexture(void* uptr, int image, int x, int y, int w, int h, const unsigned char* data)
  561. {
  562. struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr;
  563. struct GLNVGtexture* tex = glnvg__findTexture(gl, image);
  564. if (tex == NULL) return 0;
  565. glBindTexture(GL_TEXTURE_2D, tex->tex);
  566. glPixelStorei(GL_UNPACK_ALIGNMENT,1);
  567. #ifndef NANOVG_GLES2
  568. glPixelStorei(GL_UNPACK_ROW_LENGTH, tex->width);
  569. glPixelStorei(GL_UNPACK_SKIP_PIXELS, x);
  570. glPixelStorei(GL_UNPACK_SKIP_ROWS, y);
  571. #else
  572. // No support for all of skip, need to update a whole row at a time.
  573. if (tex->type == NVG_TEXTURE_RGBA)
  574. data += y*tex->width*4;
  575. else
  576. data += y*tex->width;
  577. x = 0;
  578. w = tex->width;
  579. #endif
  580. if (tex->type == NVG_TEXTURE_RGBA)
  581. glTexSubImage2D(GL_TEXTURE_2D, 0, x,y, w,h, GL_RGBA, GL_UNSIGNED_BYTE, data);
  582. else
  583. #ifdef NANOVG_GLES2
  584. glTexSubImage2D(GL_TEXTURE_2D, 0, x,y, w,h, GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
  585. #else
  586. glTexSubImage2D(GL_TEXTURE_2D, 0, x,y, w,h, GL_RED, GL_UNSIGNED_BYTE, data);
  587. #endif
  588. glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
  589. #ifndef NANOVG_GLES2
  590. glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
  591. glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
  592. glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
  593. #endif
  594. glBindTexture(GL_TEXTURE_2D, 0);
  595. return 1;
  596. }
  597. static int glnvg__renderGetTextureSize(void* uptr, int image, int* w, int* h)
  598. {
  599. struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr;
  600. struct GLNVGtexture* tex = glnvg__findTexture(gl, image);
  601. if (tex == NULL) return 0;
  602. *w = tex->width;
  603. *h = tex->height;
  604. return 1;
  605. }
  606. static void glnvg__xformToMat3x4(float* m3, float* t)
  607. {
  608. m3[0] = t[0];
  609. m3[1] = t[1];
  610. m3[2] = 0.0f;
  611. m3[3] = 0.0f;
  612. m3[4] = t[2];
  613. m3[5] = t[3];
  614. m3[6] = 0.0f;
  615. m3[7] = 0.0f;
  616. m3[8] = t[4];
  617. m3[9] = t[5];
  618. m3[10] = 1.0f;
  619. m3[11] = 0.0f;
  620. }
  621. static int glnvg__convertPaint(struct GLNVGcontext* gl, struct GLNVGfragUniforms* frag, struct NVGpaint* paint,
  622. struct NVGscissor* scissor, float width, float fringe)
  623. {
  624. struct GLNVGtexture* tex = NULL;
  625. float invxform[6];
  626. memset(frag, 0, sizeof(*frag));
  627. frag->innerCol = paint->innerColor;
  628. frag->outerCol = paint->outerColor;
  629. if (scissor->extent[0] < 0.5f || scissor->extent[1] < 0.5f) {
  630. memset(frag->scissorMat, 0, sizeof(frag->scissorMat));
  631. frag->scissorExt[0] = 1.0f;
  632. frag->scissorExt[1] = 1.0f;
  633. frag->scissorScale[0] = 1.0f;
  634. frag->scissorScale[1] = 1.0f;
  635. } else {
  636. nvgTransformInverse(invxform, scissor->xform);
  637. glnvg__xformToMat3x4(frag->scissorMat, invxform);
  638. frag->scissorExt[0] = scissor->extent[0];
  639. frag->scissorExt[1] = scissor->extent[1];
  640. frag->scissorScale[0] = sqrtf(scissor->xform[0]*scissor->xform[0] + scissor->xform[2]*scissor->xform[2]) / fringe;
  641. frag->scissorScale[1] = sqrtf(scissor->xform[1]*scissor->xform[1] + scissor->xform[3]*scissor->xform[3]) / fringe;
  642. }
  643. memcpy(frag->extent, paint->extent, sizeof(frag->extent));
  644. frag->strokeMult = (width*0.5f + fringe*0.5f) / fringe;
  645. if (paint->image != 0) {
  646. tex = glnvg__findTexture(gl, paint->image);
  647. if (tex == NULL) return 0;
  648. if ((tex->flags & NVGL_TEXTURE_FLIP_Y) != 0) {
  649. float flipped[6];
  650. nvgTransformScale(flipped, 1.0f, -1.0f);
  651. nvgTransformMultiply(flipped, paint->xform);
  652. nvgTransformInverse(invxform, flipped);
  653. } else {
  654. nvgTransformInverse(invxform, paint->xform);
  655. }
  656. frag->type = NSVG_SHADER_FILLIMG;
  657. frag->texType = tex->type == NVG_TEXTURE_RGBA ? 0 : 1;
  658. } else {
  659. frag->type = NSVG_SHADER_FILLGRAD;
  660. frag->radius = paint->radius;
  661. frag->feather = paint->feather;
  662. nvgTransformInverse(invxform, paint->xform);
  663. }
  664. glnvg__xformToMat3x4(frag->paintMat, invxform);
  665. return 1;
  666. }
  667. static struct GLNVGfragUniforms* nvg__fragUniformPtr(struct GLNVGcontext* gl, int i);
  668. #if !NANOVG_GL_USE_UNIFORMBUFFER
  669. static void glnvg__mat3(float* dst, float* src)
  670. {
  671. dst[0] = src[0];
  672. dst[1] = src[1];
  673. dst[2] = src[2];
  674. dst[3] = src[4];
  675. dst[4] = src[5];
  676. dst[5] = src[6];
  677. dst[6] = src[8];
  678. dst[7] = src[9];
  679. dst[8] = src[10];
  680. }
  681. #endif
  682. static void glnvg__setUniforms(struct GLNVGcontext* gl, int uniformOffset, int image)
  683. {
  684. #if NANOVG_GL_USE_UNIFORMBUFFER
  685. glBindBufferRange(GL_UNIFORM_BUFFER, GLNVG_FRAG_BINDING, gl->fragBuf, uniformOffset, sizeof(struct GLNVGfragUniforms));
  686. #else
  687. struct GLNVGfragUniforms* frag = nvg__fragUniformPtr(gl, uniformOffset);
  688. float tmp[9]; // Maybe there's a way to get rid of this...
  689. glnvg__mat3(tmp, frag->scissorMat);
  690. glUniformMatrix3fv(gl->shader.loc[GLNVG_LOC_SCISSORMAT], 1, GL_FALSE, tmp);
  691. glnvg__mat3(tmp, frag->paintMat);
  692. glUniformMatrix3fv(gl->shader.loc[GLNVG_LOC_PAINTMAT], 1, GL_FALSE, tmp);
  693. glUniform4fv(gl->shader.loc[GLNVG_LOC_INNERCOL], 1, frag->innerCol.rgba);
  694. glUniform4fv(gl->shader.loc[GLNVG_LOC_OUTERCOL], 1, frag->outerCol.rgba);
  695. glUniform2fv(gl->shader.loc[GLNVG_LOC_SCISSOREXT], 1, frag->scissorExt);
  696. glUniform2fv(gl->shader.loc[GLNVG_LOC_SCISSORSCALE], 1, frag->scissorScale);
  697. glUniform2fv(gl->shader.loc[GLNVG_LOC_EXTENT], 1, frag->extent);
  698. glUniform1f(gl->shader.loc[GLNVG_LOC_RADIUS], frag->radius);
  699. glUniform1f(gl->shader.loc[GLNVG_LOC_FEATHER], frag->feather);
  700. glUniform1f(gl->shader.loc[GLNVG_LOC_STROKEMULT], frag->strokeMult);
  701. glUniform1i(gl->shader.loc[GLNVG_LOC_TEXTYPE], frag->texType);
  702. glUniform1i(gl->shader.loc[GLNVG_LOC_TYPE], frag->type);
  703. #endif
  704. if (image != 0) {
  705. struct GLNVGtexture* tex = glnvg__findTexture(gl, image);
  706. glBindTexture(GL_TEXTURE_2D, tex != NULL ? tex->tex : 0);
  707. glnvg__checkError("tex paint tex");
  708. } else {
  709. glBindTexture(GL_TEXTURE_2D, 0);
  710. }
  711. }
  712. static void glnvg__renderViewport(void* uptr, int width, int height, int alphaBlend)
  713. {
  714. struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr;
  715. NVG_NOTUSED(alphaBlend);
  716. gl->view[0] = (float)width;
  717. gl->view[1] = (float)height;
  718. }
  719. static void glnvg__fill(struct GLNVGcontext* gl, struct GLNVGcall* call)
  720. {
  721. struct GLNVGpath* paths = &gl->paths[call->pathOffset];
  722. int i, npaths = call->pathCount;
  723. // Draw shapes
  724. glEnable(GL_STENCIL_TEST);
  725. glStencilMask(0xff);
  726. glStencilFunc(GL_ALWAYS, 0, ~0L);
  727. glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  728. // set bindpoint for solid loc
  729. glnvg__setUniforms(gl, call->uniformOffset, 0);
  730. glnvg__checkError("fill simple");
  731. glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR_WRAP);
  732. glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR_WRAP);
  733. glDisable(GL_CULL_FACE);
  734. for (i = 0; i < npaths; i++)
  735. glDrawArrays(GL_TRIANGLE_FAN, paths[i].fillOffset, paths[i].fillCount);
  736. glEnable(GL_CULL_FACE);
  737. // Draw aliased off-pixels
  738. glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  739. glnvg__setUniforms(gl, call->uniformOffset + gl->fragSize, call->image);
  740. glnvg__checkError("fill fill");
  741. if (gl->edgeAntiAlias) {
  742. glStencilFunc(GL_EQUAL, 0x00, 0xff);
  743. glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
  744. // Draw fringes
  745. for (i = 0; i < npaths; i++)
  746. glDrawArrays(GL_TRIANGLE_STRIP, paths[i].strokeOffset, paths[i].strokeCount);
  747. }
  748. // Draw fill
  749. glStencilFunc(GL_NOTEQUAL, 0x0, 0xff);
  750. glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO);
  751. glDrawArrays(GL_TRIANGLES, call->triangleOffset, call->triangleCount);
  752. glDisable(GL_STENCIL_TEST);
  753. }
  754. static void glnvg__convexFill(struct GLNVGcontext* gl, struct GLNVGcall* call)
  755. {
  756. struct GLNVGpath* paths = &gl->paths[call->pathOffset];
  757. int i, npaths = call->pathCount;
  758. glnvg__setUniforms(gl, call->uniformOffset, call->image);
  759. glnvg__checkError("convex fill");
  760. for (i = 0; i < npaths; i++)
  761. glDrawArrays(GL_TRIANGLE_FAN, paths[i].fillOffset, paths[i].fillCount);
  762. if (gl->edgeAntiAlias) {
  763. // Draw fringes
  764. for (i = 0; i < npaths; i++)
  765. glDrawArrays(GL_TRIANGLE_STRIP, paths[i].strokeOffset, paths[i].strokeCount);
  766. }
  767. }
  768. static void glnvg__stroke(struct GLNVGcontext* gl, struct GLNVGcall* call)
  769. {
  770. struct GLNVGpath* paths = &gl->paths[call->pathOffset];
  771. int npaths = call->pathCount, i;
  772. glnvg__setUniforms(gl, call->uniformOffset, call->image);
  773. glnvg__checkError("stroke fill");
  774. // Draw Strokes
  775. for (i = 0; i < npaths; i++)
  776. glDrawArrays(GL_TRIANGLE_STRIP, paths[i].strokeOffset, paths[i].strokeCount);
  777. }
  778. static void glnvg__triangles(struct GLNVGcontext* gl, struct GLNVGcall* call)
  779. {
  780. glnvg__setUniforms(gl, call->uniformOffset, call->image);
  781. glnvg__checkError("triangles fill");
  782. glDrawArrays(GL_TRIANGLES, call->triangleOffset, call->triangleCount);
  783. }
  784. static void glnvg__renderFlush(void* uptr, int alphaBlend)
  785. {
  786. struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr;
  787. int i;
  788. if (gl->ncalls > 0) {
  789. // Setup require GL state.
  790. glUseProgram(gl->shader.prog);
  791. if (alphaBlend == NVG_PREMULTIPLIED_ALPHA)
  792. glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  793. else
  794. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  795. glEnable(GL_CULL_FACE);
  796. glCullFace(GL_BACK);
  797. glFrontFace(GL_CCW);
  798. glEnable(GL_BLEND);
  799. glDisable(GL_DEPTH_TEST);
  800. glDisable(GL_SCISSOR_TEST);
  801. glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  802. glStencilMask(0xffffffff);
  803. glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
  804. glStencilFunc(GL_ALWAYS, 0, 0xffffffff);
  805. glActiveTexture(GL_TEXTURE0);
  806. #if NANOVG_GL_USE_UNIFORMBUFFER
  807. // Upload ubo for frag shaders
  808. glBindBuffer(GL_UNIFORM_BUFFER, gl->fragBuf);
  809. glBufferData(GL_UNIFORM_BUFFER, gl->nuniforms * gl->fragSize, gl->uniforms, GL_STREAM_DRAW);
  810. #endif
  811. // Upload vertex data
  812. #if defined NANOVG_GL3
  813. glBindVertexArray(gl->vertArr);
  814. #endif
  815. glBindBuffer(GL_ARRAY_BUFFER, gl->vertBuf);
  816. glBufferData(GL_ARRAY_BUFFER, gl->nverts * sizeof(struct NVGvertex), gl->verts, GL_STREAM_DRAW);
  817. glEnableVertexAttribArray(0);
  818. glEnableVertexAttribArray(1);
  819. glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(struct NVGvertex), (const GLvoid*)(size_t)0);
  820. glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(struct NVGvertex), (const GLvoid*)(0 + 2*sizeof(float)));
  821. // Set view and texture just once per frame.
  822. glUniform1i(gl->shader.loc[GLNVG_LOC_TEX], 0);
  823. glUniform2fv(gl->shader.loc[GLNVG_LOC_VIEWSIZE], 1, gl->view);
  824. #if NANOVG_GL_USE_UNIFORMBUFFER
  825. glBindBuffer(GL_UNIFORM_BUFFER, gl->fragBuf);
  826. #endif
  827. for (i = 0; i < gl->ncalls; i++) {
  828. struct GLNVGcall* call = &gl->calls[i];
  829. if (call->type == GLNVG_FILL)
  830. glnvg__fill(gl, call);
  831. else if (call->type == GLNVG_CONVEXFILL)
  832. glnvg__convexFill(gl, call);
  833. else if (call->type == GLNVG_STROKE)
  834. glnvg__stroke(gl, call);
  835. else if (call->type == GLNVG_TRIANGLES)
  836. glnvg__triangles(gl, call);
  837. }
  838. glDisableVertexAttribArray(0);
  839. glDisableVertexAttribArray(1);
  840. #if defined NANOVG_GL3
  841. glBindVertexArray(0);
  842. #endif
  843. glUseProgram(0);
  844. glBindTexture(GL_TEXTURE_2D, 0);
  845. }
  846. // Reset calls
  847. gl->nverts = 0;
  848. gl->npaths = 0;
  849. gl->ncalls = 0;
  850. gl->nuniforms = 0;
  851. }
  852. static int glnvg__maxVertCount(const struct NVGpath* paths, int npaths)
  853. {
  854. int i, count = 0;
  855. for (i = 0; i < npaths; i++) {
  856. count += paths[i].nfill;
  857. count += paths[i].nstroke;
  858. }
  859. return count;
  860. }
  861. static struct GLNVGcall* glnvg__allocCall(struct GLNVGcontext* gl)
  862. {
  863. struct GLNVGcall* ret = NULL;
  864. if (gl->ncalls+1 > gl->ccalls) {
  865. struct GLNVGcall* calls;
  866. int ccalls = glnvg__maxi(gl->ncalls+1, 128) + gl->ccalls; // 1.5x Overallocate
  867. calls = (struct GLNVGcall*)realloc(gl->calls, sizeof(struct GLNVGcall) * ccalls);
  868. if (calls == NULL) return NULL;
  869. gl->calls = calls;
  870. gl->ccalls = ccalls;
  871. }
  872. ret = &gl->calls[gl->ncalls++];
  873. memset(ret, 0, sizeof(struct GLNVGcall));
  874. return ret;
  875. }
  876. static int glnvg__allocPaths(struct GLNVGcontext* gl, int n)
  877. {
  878. int ret = 0;
  879. if (gl->npaths+n > gl->cpaths) {
  880. struct GLNVGpath* paths;
  881. int cpaths = glnvg__maxi(gl->npaths + n, 128) + gl->cpaths; // 1.5x Overallocate
  882. paths = (struct GLNVGpath*)realloc(gl->paths, sizeof(struct GLNVGpath) * cpaths);
  883. if (paths == NULL) return -1;
  884. gl->paths = paths;
  885. gl->cpaths = cpaths;
  886. }
  887. ret = gl->npaths;
  888. gl->npaths += n;
  889. return ret;
  890. }
  891. static int glnvg__allocVerts(struct GLNVGcontext* gl, int n)
  892. {
  893. int ret = 0;
  894. if (gl->nverts+n > gl->cverts) {
  895. struct NVGvertex* verts;
  896. int cverts = glnvg__maxi(gl->nverts + n, 4096) + gl->cverts/2; // 1.5x Overallocate
  897. verts = (struct NVGvertex*)realloc(gl->verts, sizeof(struct NVGvertex) * cverts);
  898. if (verts == NULL) return -1;
  899. gl->verts = verts;
  900. gl->cverts = cverts;
  901. }
  902. ret = gl->nverts;
  903. gl->nverts += n;
  904. return ret;
  905. }
  906. static int glnvg__allocFragUniforms(struct GLNVGcontext* gl, int n)
  907. {
  908. int ret = 0, structSize = gl->fragSize;
  909. if (gl->nuniforms+n > gl->cuniforms) {
  910. unsigned char* uniforms;
  911. int cuniforms = glnvg__maxi(gl->nuniforms+n, 128) + gl->cuniforms/2; // 1.5x Overallocate
  912. uniforms = (unsigned char*)realloc(gl->uniforms, structSize * cuniforms);
  913. if (uniforms == NULL) return -1;
  914. gl->uniforms = uniforms;
  915. gl->cuniforms = cuniforms;
  916. }
  917. ret = gl->nuniforms * structSize;
  918. gl->nuniforms += n;
  919. return ret;
  920. }
  921. static struct GLNVGfragUniforms* nvg__fragUniformPtr(struct GLNVGcontext* gl, int i)
  922. {
  923. return (struct GLNVGfragUniforms*)&gl->uniforms[i];
  924. }
  925. static void glnvg__vset(struct NVGvertex* vtx, float x, float y, float u, float v)
  926. {
  927. vtx->x = x;
  928. vtx->y = y;
  929. vtx->u = u;
  930. vtx->v = v;
  931. }
  932. static void glnvg__renderFill(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, float fringe,
  933. const float* bounds, const struct NVGpath* paths, int npaths)
  934. {
  935. struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr;
  936. struct GLNVGcall* call = glnvg__allocCall(gl);
  937. struct NVGvertex* quad;
  938. struct GLNVGfragUniforms* frag;
  939. int i, maxverts, offset;
  940. if (call == NULL) return;
  941. call->type = GLNVG_FILL;
  942. call->pathOffset = glnvg__allocPaths(gl, npaths);
  943. if (call->pathOffset == -1) goto error;
  944. call->pathCount = npaths;
  945. call->image = paint->image;
  946. if (npaths == 1 && paths[0].convex)
  947. call->type = GLNVG_CONVEXFILL;
  948. // Allocate vertices for all the paths.
  949. maxverts = glnvg__maxVertCount(paths, npaths) + 6;
  950. offset = glnvg__allocVerts(gl, maxverts);
  951. if (offset == -1) goto error;
  952. for (i = 0; i < npaths; i++) {
  953. struct GLNVGpath* copy = &gl->paths[call->pathOffset + i];
  954. const struct NVGpath* path = &paths[i];
  955. memset(copy, 0, sizeof(struct GLNVGpath));
  956. if (path->nfill > 0) {
  957. copy->fillOffset = offset;
  958. copy->fillCount = path->nfill;
  959. memcpy(&gl->verts[offset], path->fill, sizeof(struct NVGvertex) * path->nfill);
  960. offset += path->nfill;
  961. }
  962. if (path->nstroke > 0) {
  963. copy->strokeOffset = offset;
  964. copy->strokeCount = path->nstroke;
  965. memcpy(&gl->verts[offset], path->stroke, sizeof(struct NVGvertex) * path->nstroke);
  966. offset += path->nstroke;
  967. }
  968. }
  969. // Quad
  970. call->triangleOffset = offset;
  971. call->triangleCount = 6;
  972. quad = &gl->verts[call->triangleOffset];
  973. glnvg__vset(&quad[0], bounds[0], bounds[3], 0.5f, 1.0f);
  974. glnvg__vset(&quad[1], bounds[2], bounds[3], 0.5f, 1.0f);
  975. glnvg__vset(&quad[2], bounds[2], bounds[1], 0.5f, 1.0f);
  976. glnvg__vset(&quad[3], bounds[0], bounds[3], 0.5f, 1.0f);
  977. glnvg__vset(&quad[4], bounds[2], bounds[1], 0.5f, 1.0f);
  978. glnvg__vset(&quad[5], bounds[0], bounds[1], 0.5f, 1.0f);
  979. // Setup uniforms for draw calls
  980. if (call->type == GLNVG_FILL) {
  981. call->uniformOffset = glnvg__allocFragUniforms(gl, 2);
  982. if (call->uniformOffset == -1) goto error;
  983. // Simple shader for stencil
  984. frag = nvg__fragUniformPtr(gl, call->uniformOffset);
  985. memset(frag, 0, sizeof(*frag));
  986. frag->type = NSVG_SHADER_SIMPLE;
  987. // Fill shader
  988. glnvg__convertPaint(gl, nvg__fragUniformPtr(gl, call->uniformOffset + gl->fragSize), paint, scissor, fringe, fringe);
  989. } else {
  990. call->uniformOffset = glnvg__allocFragUniforms(gl, 1);
  991. if (call->uniformOffset == -1) goto error;
  992. // Fill shader
  993. glnvg__convertPaint(gl, nvg__fragUniformPtr(gl, call->uniformOffset), paint, scissor, fringe, fringe);
  994. }
  995. return;
  996. error:
  997. // We get here if call alloc was ok, but something else is not.
  998. // Roll back the last call to prevent drawing it.
  999. if (gl->ncalls > 0) gl->ncalls--;
  1000. }
  1001. static void glnvg__renderStroke(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor, float fringe,
  1002. float strokeWidth, const struct NVGpath* paths, int npaths)
  1003. {
  1004. struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr;
  1005. struct GLNVGcall* call = glnvg__allocCall(gl);
  1006. int i, maxverts, offset;
  1007. if (call == NULL) return;
  1008. call->type = GLNVG_STROKE;
  1009. call->pathOffset = glnvg__allocPaths(gl, npaths);
  1010. if (call->pathOffset == -1) goto error;
  1011. call->pathCount = npaths;
  1012. call->image = paint->image;
  1013. // Allocate vertices for all the paths.
  1014. maxverts = glnvg__maxVertCount(paths, npaths);
  1015. offset = glnvg__allocVerts(gl, maxverts);
  1016. if (offset == -1) goto error;
  1017. for (i = 0; i < npaths; i++) {
  1018. struct GLNVGpath* copy = &gl->paths[call->pathOffset + i];
  1019. const struct NVGpath* path = &paths[i];
  1020. memset(copy, 0, sizeof(struct GLNVGpath));
  1021. if (path->nstroke) {
  1022. copy->strokeOffset = offset;
  1023. copy->strokeCount = path->nstroke;
  1024. memcpy(&gl->verts[offset], path->stroke, sizeof(struct NVGvertex) * path->nstroke);
  1025. offset += path->nstroke;
  1026. }
  1027. }
  1028. // Fill shader
  1029. call->uniformOffset = glnvg__allocFragUniforms(gl, 1);
  1030. if (call->uniformOffset == -1) goto error;
  1031. glnvg__convertPaint(gl, nvg__fragUniformPtr(gl, call->uniformOffset), paint, scissor, strokeWidth, fringe);
  1032. return;
  1033. error:
  1034. // We get here if call alloc was ok, but something else is not.
  1035. // Roll back the last call to prevent drawing it.
  1036. if (gl->ncalls > 0) gl->ncalls--;
  1037. }
  1038. static void glnvg__renderTriangles(void* uptr, struct NVGpaint* paint, struct NVGscissor* scissor,
  1039. const struct NVGvertex* verts, int nverts)
  1040. {
  1041. struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr;
  1042. struct GLNVGcall* call = glnvg__allocCall(gl);
  1043. struct GLNVGfragUniforms* frag;
  1044. if (call == NULL) return;
  1045. call->type = GLNVG_TRIANGLES;
  1046. call->image = paint->image;
  1047. // Allocate vertices for all the paths.
  1048. call->triangleOffset = glnvg__allocVerts(gl, nverts);
  1049. if (call->triangleOffset == -1) goto error;
  1050. call->triangleCount = nverts;
  1051. memcpy(&gl->verts[call->triangleOffset], verts, sizeof(struct NVGvertex) * nverts);
  1052. // Fill shader
  1053. call->uniformOffset = glnvg__allocFragUniforms(gl, 1);
  1054. if (call->uniformOffset == -1) goto error;
  1055. frag = nvg__fragUniformPtr(gl, call->uniformOffset);
  1056. glnvg__convertPaint(gl, frag, paint, scissor, 1.0f, 1.0f);
  1057. frag->type = NSVG_SHADER_IMG;
  1058. return;
  1059. error:
  1060. // We get here if call alloc was ok, but something else is not.
  1061. // Roll back the last call to prevent drawing it.
  1062. if (gl->ncalls > 0) gl->ncalls--;
  1063. }
  1064. static void glnvg__renderDelete(void* uptr)
  1065. {
  1066. struct GLNVGcontext* gl = (struct GLNVGcontext*)uptr;
  1067. int i;
  1068. if (gl == NULL) return;
  1069. glnvg__deleteShader(&gl->shader);
  1070. #if NANOVG_GL3
  1071. #if NANOVG_GL_USE_UNIFORMBUFFER
  1072. if (gl->fragBuf != 0)
  1073. glDeleteBuffers(1, &gl->fragBuf);
  1074. #endif
  1075. if (gl->vertArr != 0)
  1076. glDeleteVertexArrays(1, &gl->vertArr);
  1077. #endif
  1078. if (gl->vertBuf != 0)
  1079. glDeleteBuffers(1, &gl->vertBuf);
  1080. for (i = 0; i < gl->ntextures; i++) {
  1081. if (gl->textures[i].tex != 0 && (gl->textures[i].flags & NVGL_TEXTURE_NODELETE) == 0)
  1082. glDeleteTextures(1, &gl->textures[i].tex);
  1083. }
  1084. free(gl->textures);
  1085. free(gl);
  1086. }
  1087. #if defined NANOVG_GL2
  1088. struct NVGcontext* nvgCreateGL2(int atlasw, int atlash, int edgeaa)
  1089. #elif defined NANOVG_GL3
  1090. struct NVGcontext* nvgCreateGL3(int atlasw, int atlash, int edgeaa)
  1091. #elif defined NANOVG_GLES2
  1092. struct NVGcontext* nvgCreateGLES2(int atlasw, int atlash, int edgeaa)
  1093. #elif defined NANOVG_GLES3
  1094. struct NVGcontext* nvgCreateGLES3(int atlasw, int atlash, int edgeaa)
  1095. #endif
  1096. {
  1097. struct NVGparams params;
  1098. struct NVGcontext* ctx = NULL;
  1099. struct GLNVGcontext* gl = (struct GLNVGcontext*)malloc(sizeof(struct GLNVGcontext));
  1100. if (gl == NULL) goto error;
  1101. memset(gl, 0, sizeof(struct GLNVGcontext));
  1102. memset(&params, 0, sizeof(params));
  1103. params.renderCreate = glnvg__renderCreate;
  1104. params.renderCreateTexture = glnvg__renderCreateTexture;
  1105. params.renderDeleteTexture = glnvg__renderDeleteTexture;
  1106. params.renderUpdateTexture = glnvg__renderUpdateTexture;
  1107. params.renderGetTextureSize = glnvg__renderGetTextureSize;
  1108. params.renderViewport = glnvg__renderViewport;
  1109. params.renderFlush = glnvg__renderFlush;
  1110. params.renderFill = glnvg__renderFill;
  1111. params.renderStroke = glnvg__renderStroke;
  1112. params.renderTriangles = glnvg__renderTriangles;
  1113. params.renderDelete = glnvg__renderDelete;
  1114. params.userPtr = gl;
  1115. params.atlasWidth = atlasw;
  1116. params.atlasHeight = atlash;
  1117. params.edgeAntiAlias = edgeaa;
  1118. gl->edgeAntiAlias = edgeaa;
  1119. ctx = nvgCreateInternal(&params);
  1120. if (ctx == NULL) goto error;
  1121. return ctx;
  1122. error:
  1123. // 'gl' is freed by nvgDeleteInternal.
  1124. if (ctx != NULL) nvgDeleteInternal(ctx);
  1125. return NULL;
  1126. }
  1127. #if NANOVG_GL2
  1128. void nvgDeleteGL2(struct NVGcontext* ctx)
  1129. #elif NANOVG_GL3
  1130. void nvgDeleteGL3(struct NVGcontext* ctx)
  1131. #elif NANOVG_GLES2
  1132. void nvgDeleteGLES2(struct NVGcontext* ctx)
  1133. #elif NANOVG_GLES3
  1134. void nvgDeleteGLES3(struct NVGcontext* ctx)
  1135. #endif
  1136. {
  1137. nvgDeleteInternal(ctx);
  1138. }
  1139. int nvglCreateImageFromHandle(struct NVGcontext* ctx, GLuint textureId, int flags)
  1140. {
  1141. struct GLNVGcontext* gl = (struct GLNVGcontext*)nvgInternalParams(ctx)->userPtr;
  1142. struct GLNVGtexture* tex = glnvg__allocTexture(gl);
  1143. if (tex == NULL) return 0;
  1144. tex->tex = textureId;
  1145. tex->type = NVG_TEXTURE_RGBA;
  1146. tex->flags = 0;
  1147. glBindTexture(GL_TEXTURE_2D, tex->tex);
  1148. glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &tex->width);
  1149. glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &tex->height);
  1150. glBindTexture(GL_TEXTURE_2D, 0);
  1151. return tex->id;
  1152. }
  1153. GLuint nvglImageHandle(struct NVGcontext* ctx, int image)
  1154. {
  1155. struct GLNVGcontext* gl = (struct GLNVGcontext*)nvgInternalParams(ctx)->userPtr;
  1156. struct GLNVGtexture* tex = glnvg__findTexture(gl, image);
  1157. return tex->tex;
  1158. }
  1159. void nvglImageFlags(struct NVGcontext* ctx, int image, int flags)
  1160. {
  1161. struct GLNVGcontext* gl = (struct GLNVGcontext*)nvgInternalParams(ctx)->userPtr;
  1162. struct GLNVGtexture* tex = glnvg__findTexture(gl, image);
  1163. tex->flags = flags;
  1164. }
  1165. #endif /* NANOVG_GL_IMPLEMENTATION */