1#include "line.h"
2#include "shaders.h"
3
4#include "../util/shader.h"
5#include "../util/transform.h"
6
7#include "config.h"
8
9#ifdef USE_GLES
10 #include <GLES2/gl2.h>
11 #include <GLES2/gl2ext.h>
12#else
13 #include <GL/glew.h>
14#endif
15
16#include <stdlib.h>
17
18#define MAX_LINE_GROUP_SIZE 1024
19
20#ifndef USE_GLES
21 static GLuint sliLineVAO = 0;
22#endif
23static GLuint sliLineVBOs[1] = {0};
24
25static GLfloat *sliLineAttributes;
26
27static int sliLineCount;
28static GLfloat *sliLineAttributesPtr;
29
30void sliLineInit()
31{
32 // initialize our state object
33 #ifndef USE_GLES
34 glGenVertexArrays(1, &sliLineVAO);
35 glBindVertexArray(sliLineVAO);
36 #endif
37 glGenBuffers(1, sliLineVBOs);
38
39 // configure vertex attribute data
40 glBindBuffer(GL_ARRAY_BUFFER, sliLineVBOs[0]);
41 glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * MAX_LINE_GROUP_SIZE * 12, NULL, GL_DYNAMIC_DRAW);
42
43 // configure vertex position attribute
44 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, NULL);
45 glEnableVertexAttribArray(0);
46
47 // configure vertex color attribute
48 glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, (GLvoid*)(sizeof(GLfloat) * 2));
49 glEnableVertexAttribArray(1);
50
51 // initialize our vertex data buffer
52 sliLineAttributes = (GLfloat*)malloc(sizeof(GLfloat) * MAX_LINE_GROUP_SIZE * 12);
53 sliLineAttributesPtr = sliLineAttributes;
54
55 // no lines buffered yet
56 sliLineCount = 0;
57}
58
59void sliLineDestroy()
60{
61 // free up dynamically-allocated vertex and color data
62 free(sliLineAttributes);
63
64 // free OpenGL objects
65 glDeleteBuffers(1, sliLineVBOs);
66 #ifndef USE_GLES
67 glDeleteVertexArrays(1, &sliLineVAO);
68 #endif
69}
70
71void sliLine(Vec4 *color, double x1, double y1, double x2, double y2)
72{
73 // assign vertex positions for first point of incoming line
74 *(sliLineAttributesPtr++) = (float)x1;
75 *(sliLineAttributesPtr++) = (float)y1;
76
77 // assign color values for first point of incoming line
78 *(sliLineAttributesPtr++) = (float)color -> x;
79 *(sliLineAttributesPtr++) = (float)color -> y;
80 *(sliLineAttributesPtr++) = (float)color -> z;
81 *(sliLineAttributesPtr++) = (float)color -> w;
82
83 // assign vertex positions for second point of incoming line
84 *(sliLineAttributesPtr++) = (float)x2;
85 *(sliLineAttributesPtr++) = (float)y2;
86
87 // assign color values for second point of incoming line
88 *(sliLineAttributesPtr++) = (float)color -> x;
89 *(sliLineAttributesPtr++) = (float)color -> y;
90 *(sliLineAttributesPtr++) = (float)color -> z;
91 *(sliLineAttributesPtr++) = (float)color -> w;
92
93 // track the number of lines we've cached; render if the buffer is full
94 sliLineCount ++;
95 if(sliLineCount >= MAX_LINE_GROUP_SIZE)
96 {
97 sliLinesFlush();
98 }
99}
100
101void sliLinesFlush()
102{
103 // nothing to do if no lines are waiting to be drawn
104 if(sliLineCount > 0)
105 {
106 // activate our state object
107 #ifndef USE_GLES
108 glBindVertexArray(sliLineVAO);
109 #endif
110
111 // send vertex attributes to graphics card
112 glBindBuffer(GL_ARRAY_BUFFER, sliLineVBOs[0]);
113 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(GLfloat) * sliLineCount * 12, sliLineAttributes);
114 #ifdef USE_GLES
115 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, NULL);
116 glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 6, (GLvoid*)(sizeof(GLfloat) * 2));
117 #endif
118
119 // prepare our shader object
120 shaderBind(sliPointShader);
121
122 // render the lines
123 glDrawArrays(GL_LINES, 0, sliLineCount * 2);
124
125 // reset the lines buffer
126 sliLineAttributesPtr = sliLineAttributes;
127 sliLineCount = 0;
128 }
129}
130