#define COORDS_PER_VERTEX 3
GLfloat ftransp[16], f255[256];
#define POINTS_VERTEX_CODE \
"attribute vec4 a_Position; " \
"attribute vec4 a_Color; " \
"varying vec4 v_Color; " \
"uniform mat4 projectionMatrix; " \
"void main() {v_Color = a_Color; gl_Position = a_Position * projectionMatrix;}"
#define POINTS_FRAGMENT_CODE \
"precision mediump float;" \
"varying vec4 v_Color;" \
"uniform vec4 one_Color;" \
"uniform bool singleColor;" \
"void main() {gl_FragColor = singleColor ? one_Color : v_Color;}"
static GLuint pointsProgram;
static GLuint pointsPosition;
static GLuint pointsColor;
static GLuint pointsSingleColor,pointsOneColor;
static GLushort rectOrder[] = { 0, 1, 2, 0, 2, 3 }; // order to draw vertices
GLuint loadShader(GLenum shaderType, const char* pSource)
{
GLint ret=1;
GLuint shader = glCreateShader(shaderType);
glShaderSource(shader, 1, &pSource, NULL);
glCompileShader(shader);
glGetShaderiv(shader, GL_COMPILE_STATUS, &ret);
if(!ret)
{
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &ret);
GLchar buffer[ret];
glGetShaderInfoLog(shader, ret, &ret, buffer);
debug("Shader compiler error: %s",buffer);
}
return shader;
}
static void initPoints()
{
GLint ret=1;
pointsProgram = glCreateProgram();
glAttachShader(pointsProgram, loadShader(GL_VERTEX_SHADER, POINTS_VERTEX_CODE));
glAttachShader(pointsProgram, loadShader(GL_FRAGMENT_SHADER, POINTS_FRAGMENT_CODE));
glLinkProgram(pointsProgram);
glGetProgramiv(pointsProgram, GL_LINK_STATUS, &ret);
if (!ret)
{
glGetProgramiv(pointsProgram, GL_INFO_LOG_LENGTH, &ret);
GLchar buffer[ret];
glGetProgramInfoLog(pointsProgram, ret, &ret, buffer);
debug("Link error: %s",buffer);
}
glUseProgram(pointsProgram);
pointsOneColor = glGetUniformLocation(pointsProgram, "one_Color");
pointsSingleColor = glGetUniformLocation(pointsProgram, "singleColor");
pointsColor = glGetAttribLocation(pointsProgram, "a_Color");
pointsPosition = glGetAttribLocation(pointsProgram, "a_Position");
glEnableVertexAttribArray(pointsColor);
glEnableVertexAttribArray(pointsPosition);
}
void glDrawPixels(Context c, int32 n)
{
glUniform1i(pointsSingleColor, 0);
glVertexAttribPointer(pointsColor, 4 * n, GL_FLOAT, GL_FALSE, 4 * sizeof(float), c->glcolors);
glVertexAttribPointer(pointsPosition, COORDS_PER_VERTEX * n, GL_FLOAT, GL_FALSE, COORDS_PER_VERTEX * sizeof(float), c->glcoords);
glDrawArrays(GL_POINTS, 0,n);
}
void glDrawPixel(Context c, int32 x, int32 y, int32 rgb)
{
GLfloat* coords = c->glcoords;
PixelConv pc;
pc.pixel = rgb;
coords[0] = x;
coords[1] = y;
glUniform1i(pointsSingleColor, 1);
glUniform4f(pointsOneColor, f255[pc.r], f255[pc.g], f255[pc.b], 1);
glVertexAttribPointer(pointsPosition, COORDS_PER_VERTEX, GL_FLOAT, GL_FALSE, COORDS_PER_VERTEX * sizeof(float), coords); // Prepare the triangle coordinate data
glDrawArrays(GL_POINTS, 0,1);
}
void glDrawLine(Context c, int32 x1, int32 y1, int32 x2, int32 y2, int32 rgb)
{
GLfloat* coords = c->glcoords;
PixelConv pc;
pc.pixel = rgb;
coords[0] = x1;
coords[1] = y1;
coords[3] = x2;
coords[4] = y2;
glUniform1i(pointsSingleColor, 1);
glUniform4f(pointsOneColor, f255[pc.r], f255[pc.g], f255[pc.b], 1);
glVertexAttribPointer(pointsPosition, COORDS_PER_VERTEX, GL_FLOAT, GL_FALSE, COORDS_PER_VERTEX * sizeof(float), coords); // Prepare the triangle coordinate data
glDrawArrays(GL_LINES, 0,2);
}
void glFillRect(Context c, int32 x, int32 y, int32 w, int32 h, int32 rgb)
{
GLfloat* coords = c->glcoords;
PixelConv pc;
pc.pixel = rgb;
coords[0] = x;
coords[1] = y;
coords[3] = x;
coords[4] = y+h;
coords[6] = x+w;
coords[7] = y+h;
coords[9] = x+w;
coords[10] = y;
glUniform1i(pointsSingleColor, 0);
glUniform4f(pointsOneColor, f255[pc.r], f255[pc.g], f255[pc.b], 1);
glVertexAttribPointer(pointsPosition, COORDS_PER_VERTEX, GL_FLOAT, GL_FALSE, COORDS_PER_VERTEX * sizeof(float), coords); // Prepare the triangle coordinate data
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, rectOrder); // GL_LINES, GL_TRIANGLES, GL_POINTS
}
static void setProjectionMatrix(GLfloat w, GLfloat h)
{
GLfloat mat[16] =
{
2.0/w, 0.0, 0.0, -1.0,
0.0, -2.0/h, 0.0, 1.0,
0.0, 0.0, -1.0, 0.0,
0.0, 0.0, 0.0, 1.0
};
glUniformMatrix4fv(glGetUniformLocation(pointsProgram , "projectionMatrix"), 1, 0, mat);
}