Mockarutan
Mockarutan

Reputation: 442

4 float color to one float in java, and back again in openGL ES 2.0 shader

I am trying to send one color with every vertex that goes in to the shader, but in only one float value. I think is weird that you cannot send 4 bytes as attributes with every vertex, but sense it's not possible I am going to try to pack RGBA in a single float variable, so this is my code:

Jave code (that packs the values in one float):

private float fourfColor2One(float r, float g, float b, float a)
{
    long temp = (byte) (r * 255);
    float res = temp << 24;

    temp = (byte) (g * 255);
    res += temp << 16;

    temp = (byte) (b * 255);
    res += temp << 8;

    temp = (byte) (a * 255);
    res += temp;

    return res;
}

Shadercode (that packs it up): Vertex shader:

attribute vec4 vPosition;
attribute float fColor;
uniform vec2 vCamPos;
uniform float fZoom;
uniform mat4 m_projectionMat;
varying float v_Color;
void main() {
  vec4 position = vec4(vPosition.x - vCamPos.x - 16., vPosition.y - vCamPos.y - ((32. / "+ GraphicsRenderer.mScnR +") / 2.), -1., 1.);
  position = position * m_projectionMat;
  gl_Position = vec4(position.xy * fZoom, -1, 1);
  v_Color = fColor;
}

fragment shader:

precision mediump float;
varying float v_Color;
void main() {
   uint temp = uint(v_Color);
   float r = temp & 0xf000;
   float g = temp & 0x0f00;
   float b = temp & 0x00f0;
   float a = temp & 0x000f;
    gl_FragColor = vec4(r, g, b, a);
}

So I have three questions:

  1. Is this concept even possible?

  2. The conversions is not correct, right? I assume that when I convert from and to float, the conversion does not retain the order of the bit, but rather the values it represent in that datatype, right?

  3. Right now the shader gives me -1 back when i run: glGetAttribLocation(mShaderHandle, "fColor"); But this one works one line before: glGetAttribLocation(mShaderHandle, "vPosition");

So, any ideas?

Thanks in advance!

Upvotes: 2

Views: 1784

Answers (1)

Peter Lawrey
Peter Lawrey

Reputation: 533500

I would convert

private static int fourfColor2One(float r, float g, float b, float a) {
    return (Math.round(r * 255) << 24) + 
           (Math.round(g * 255) << 16) +
           (Math.round(b * 255) << 8) +
           Math.round(a * 255);
}

This assumes your scale is 0.0 to 1.0 in your "shader" you assume the scale is 0.0 to 255.0


Some "pseudo code" to reverse this

float r = (temp & 0xf000)/255.0;
float g = (temp & 0x0f00)/255.0;
float b = (temp & 0x00f0)/255.0;
float a = (temp & 0x000f)/255.0;

Upvotes: 2

Related Questions