using if/else to select between single or multiple colors

Hi,

I’m trying to create a single program to draw a point/line/rectangle and point array. The code is below:


#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);
}

The shader code compiles and links without errors; however, all i get is a black screen. If i change the shader code to:


#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;" \
      "void main() {gl_FragColor = v_Color;}"

static void initPoints()
{
   pointsProgram = glCreateProgram();
   glAttachShader(pointsProgram, loadShader(GL_VERTEX_SHADER, POINTS_VERTEX_CODE));
   glAttachShader(pointsProgram, loadShader(GL_FRAGMENT_SHADER, POINTS_FRAGMENT_CODE));
   glLinkProgram(pointsProgram);
   glUseProgram(pointsProgram);

   pointsColor = glGetAttribLocation(pointsProgram, "a_Color");
   pointsPosition = glGetAttribLocation(pointsProgram, "a_Position"); // get handle to vertex shader's vPosition member
   glEnableVertexAttribArray(pointsColor); // Enable a handle to the colors - since this is the only one used, keep it enabled all the time
   glEnableVertexAttribArray(pointsPosition); // Enable a handle to the vertices - since this is the only one used, keep it enabled all the time
}

void glDrawPixels(Context c, int32 n)
{
   glUseProgram(pointsProgram);
   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;
   GLfloat* colors = c->glcolors;
   PixelConv pc;
   pc.pixel = rgb;
   coords[0] = x;
   coords[1] = y;

   colors[0] = f255[pc.r];
   colors[1] = f255[pc.g];
   colors[2] = f255[pc.b];
   colors[3] = 1;
   glUseProgram(pointsProgram);
   glVertexAttribPointer(pointsColor, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), colors);
   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;
   GLfloat* colors = c->glcolors;
   PixelConv pc;
   pc.pixel = rgb;
   coords[0] = x1;
   coords[1] = y1;
   coords[3] = x2;
   coords[4] = y2;

   colors[0] = colors[4] = f255[pc.r];
   colors[1] = colors[5] = f255[pc.g];
   colors[2] = colors[6] = f255[pc.b];
   colors[3] = colors[7] = 1;
   glUseProgram(pointsProgram);
   glVertexAttribPointer(pointsColor, 4*2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), colors);
   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;
   GLfloat* colors = c->glcolors;
   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;

   colors[0] = colors[4] = colors[8]  = colors[12] = colors[16] = colors[20] = f255[pc.r];
   colors[1] = colors[5] = colors[9]  = colors[13] = colors[17] = colors[21] = f255[pc.g];
   colors[2] = colors[6] = colors[10] = colors[14] = colors[18] = colors[22] = f255[pc.b];
   colors[3] = colors[7] = colors[11] = colors[15] = colors[19] = colors[23] = 1;
   glUseProgram(pointsProgram);
   glVertexAttribPointer(pointsColor, 4*6, GL_FLOAT, GL_FALSE, 4 * sizeof(float), colors);
   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
}


… then everything works. Actually, i’m trying to figure how to make the if/else (or ?: ) work to use with other things too.

Thanks in advance,

guich

Found the problem: i was calling glVertexAttribPointer with incorrect value in the 2nd parameter.