VertexBuffer, Flexible, using your own data

I’ve been trying to use texCoord8 (unused by me) with a single byte. But I’m having an issue. If I define a buffer using TexCoord8. I can inside the shader use

.java

        setBuffer(Type.TexCoord8, 1, new float[] {0.22f});

.vert (Shader)
       attribute float inTexCoord8;    // This is holding light level

function main()
{
    // I used the inTexCoord8  bit 1,2  to indicate  level of light on that Quad to adjust the lighting from the ambient, weather and other area that affects the quad.

My problem is that this works only for the 1st vertices. It passing in the data of 0.22f, but for the other vertices (3 quad) it has a value of 0.0.

The only way I get data to all vertices is if I do the following. But this requires that your array matches the total number of vertices.

        setBuffer(Type.TexCoord8, 1, new float[] {0.22f, 0.22f, 0.22f, 0.22f});

What am I doing wrong?

Yes, normally you need to have an entry for every vertex because that’s how vertex attributes work.

What is it that you expect to happen for the other three vertexes in your quad? What if you had 50 quads?

I’m not asking facetiously. In order to really answer your question, I need to understand what you are actually trying to do overall.

I’m trying to send data down to the shader in a vertexBuffer. Because I’m using BatchNode that merges them into one geometry. So if I want something special for a special geometry the only solution is through a vertexBuffer.

I need to send an extra byte of data down to certain (Quads) of the batchNode. So I have chunk management in 16x16 grid, with a N,S,W,E ceiling, floor possible for each grid. and certain grids will have been afffected by a torch, so I need to send data down so the shader can make certain Quads brighter based on the distance which is calculated on launch of the map. The map basically is static, I only have a few torches that move or burn out. 99% of them are static and never change. So I calculate them at launch by processing the map. But I need to send that data down.

I don’t want to send all the torches down to the shader and calculate distance and light inside the shader. It would be to much to do,

But you said you can put what ever you want in them, did you mean you could put a float but ARE REQUIRED a float for every vertexBuffer.

You are able to define a vertexBuffer to what ever you want. One Color not a color for every vertices.

The vertext shader is going to need to know what TexCoord8 value to use for that particular vertex. It has no concept of “quad”.

Is it that you want the value to repeat for all of the vertexes in the quad?

If you are using BatchNode then you will have to give a value for every vertex. OpenGL won’t be able to guess which float you want, otherwise.

I mean that each vertex can have a float or a vec2 or a vec3… but you still need a value per vertex. That’s how vertex attributes work… an attribute for the vertex.

So what is the best way to get an extra byte down when the Geometries where batched together. You can’t use parameters in the material, they get merged into one material. So you can’t use OverRideParameter to adjust a variable per geometry.

So what is the best way to do this.
in my engine. I would use

        glBindBuffer(GL_ARRAY_BUFFER, colorMatrixVBO);
        glBufferData(GL_ARRAY_BUFFER, colorMatrixBuffer, GL_DYNAMIC_DRAW);

To send down the extra data.

I just need to send down a byte but since they where batched into one geometry, you can’t use the normal methods, and only option I see is a VBO buffer, but I’m not sure how to do this under JME.

If it were me, I’d just send a byte per vertex and remember that every four is a quad and so four should repeat. It’s just not that big of a deal to me.

Your glBindBuffer() calls don’t really explain how the GPU knows to repeat this byte for four vertexes and the next byte for the next four vertexes, and so on. Either something in your buffer setup is special or you are only drawing one quad at a time anyway.

Yes, that is what I did, just repeated the float for all the different vertices.

I tried using vertex for every verticies, but my lighting comes out weird. What happens is the value gets there but everything has the same lighting. Its like they have the same value for everything.

Excerpts

#ifdef NEED_TEXCOORD8
	attribute int inTexCoord8;    // This is holding light level
#endif

void main()
{
basicLightAdjustment = ((inTexCoord8)  >> 1) * 0.31;
}

Java code - Define the Quad and load it with a ‘0’ in all the texCoord values

    public static LBQuad createLowerQuad(float x, float y, float z)
    {
    	LBQuad quad = new LBQuad(x, y, false);
        VertexBuffer inBuf = quad.getBuffer(VertexBuffer.Type.TexCoord);
        int numElements = inBuf.getNumElements();

        VertexBuffer inBuf = quad.getBuffer(VertexBuffer.Type.TexCoord);
        int numElements = inBuf.getNumElements();
        initBuffer(quad, VertexBuffer.Type.TexCoord8, BufferUtils.createByteBuffer(numElements), Usage.Dynamic, 1,  Format.UnsignedByte, false);
        VertexBuffer buf = quad.getBuffer(VertexBuffer.Type.TexCoord8);
        final ByteBuffer quadVerticies = (ByteBuffer) buf.getData();
        numElements = buf.getNumElements();
        quadVerticies.rewind();
        quadVerticies.put((byte) 0).put((byte)0).put((byte)0).put((byte)0);
        quadVerticies.flip();
        buf.updateData(quadVerticies);

        return quad;
    }	

Now we process the torches and set the light level for all the affect Grid position. The function before this loops through all the torches and figures based on grid distance which grid positions are affect and calls setBasicLightLevel()

	protected void setBasicLightLevel(WorldLocationData location, int lightLevel, int torchActive)
	{
		for(LOCATION  loc : WorldLocationData.LOCATION.values())
		{
			GameItem item = location.getLocation(loc);
			if (item != null)
			{
				Mesh mesh = item.getMesh();
				final VertexBuffer cvb = mesh.getBuffer(VertexBuffer.Type.TexCoord8);
				if (cvb != null)
				{
			        int numElements = cvb.getNumElements();
		       		final ByteBuffer lightLevelFB = (ByteBuffer) cvb.getData();

		            // update data in vertex buffers
		       		lightLevelFB.rewind();
					
		       		//Need to update the light level
		       		int newLevel = torchActive + (lightLevel << 1);
	System.out.println("num Elements "+numElements+"new level "+newLevel +" LightLevel "+lightLevel+" active torch "+torchActive);							       		
		            for(int index =0; index < numElements; index++)
		            	lightLevelFB.put((byte)newLevel);
		       		lightLevelFB.flip();
		            
		            cvb.updateData(lightLevelFB);
		            mesh.updateBound();
				}
			}

		}
	}

Output when the game runs, so I can see the levels and the light level each grid should be. Light is in grid 36x32. Same grid space gets level 7 light, and the rest range from 0 - 5. So there should be different light levels in different grid spaces, but they are all the same on the output.

It doesn’t seem like the value inside the shader is anything like what I’m putting them in

basic light level x,y-1,-1 2   35,31
num Elements 4new level 3 LightLevel 1 active torch 1
basic light level x,y0,-1 1   36,31
num Elements 4new level 5 LightLevel 2 active torch 1
num Elements 4new level 5 LightLevel 2 active torch 1
basic light level x,y1,-1 2   37,31
num Elements 4new level 0 LightLevel 0 active torch 0
num Elements 4new level 0 LightLevel 0 active torch 0
num Elements 4new level 0 LightLevel 0 active torch 0
num Elements 4new level 0 LightLevel 0 active torch 0
basic light level x,y-1,0 1   35,32
num Elements 4new level 5 LightLevel 2 active torch 1
num Elements 4new level 5 LightLevel 2 active torch 1
basic light level x,y0,0 0   36,32
num Elements 4new level 7 LightLevel 3 active torch 1
num Elements 4new level 7 LightLevel 3 active torch 1
basic light level x,y1,0 1   37,32
num Elements 4new level 0 LightLevel 0 active torch 0
num Elements 4new level 0 LightLevel 0 active torch 0
num Elements 4new level 0 LightLevel 0 active torch 0
num Elements 4new level 0 LightLevel 0 active torch 0
basic light level x,y-1,1 2   35,33
num Elements 4new level 3 LightLevel 1 active torch 1
num Elements 4new level 3 LightLevel 1 active torch 1
num Elements 4new level 3 LightLevel 1 active torch 1
num Elements 4new level 3 LightLevel 1 active torch 1
num Elements 4new level 3 LightLevel 1 active torch 1
basic light level x,y0,1 1   36,33
num Elements 4new level 5 LightLevel 2 active torch 1
num Elements 4new level 5 LightLevel 2 active torch 1
basic light level x,y1,1 2   37,33
num Elements 4new level 3 LightLevel 1 active torch 1
num Elements 4new level 3 LightLevel 1 active torch 1
num Elements 4new level 3 LightLevel 1 active torch 1

I’m not sure what I did wrong. I hope I supplied enough info to see something. If you need something else, let me know.

Is this in the .vert or .frag part of your shader?

The vert shader runs per-vertex, and the frag shader runs per pixel, so if you are doing lighting calculation and want it to be smooth, then I think you would need to do it in the frag shader.

Sorry, it is vertex shader, and then the ’ basicLightAdjustment ’ is passed to the frag shader with an ‘out’ int variable. and then the ‘color’ variable gets adjusted based on this lighting value.

vertex shader.

varying float basicLightAdjustment ;
#ifdef NEED_TEXCOORD8
	attribute int inTexCoord8;    // This is holding light level
#endif

void main()
{
basicLightAdjustment = ((inTexCoord8)  >> 1) * 0.31;
}

Frag shader

varying float basicLightAdjustment ;

void main()
{
    #ifdef HAS_COLORMAP
        color = texture2D(m_ColorMap, newTexCoord1);     
    #endif
   color =color * basicLightAdjustment ;
.....

    gl_FragColor = color ;

}

1 Like

I think it could be related to the way that you’re storing light level as an int. The standard tex coord buffer is a vector with 2 floats, so when that gets passed to the frag shader as a varying variable it automatically interpolates the texCoord values for every pixel between vertices

But IDK if this interpolating will be happening if you’re storing light level in a buffer as an int.

I would try storing the light level as a float rather than an int. Otherwise I’m not quite sure what could be causing the hard edges on the lighting.

1 Like

That did it, I changed it to a float. and this is how it came out.

The grid spaces on the left or brighter and the ones on the right are darker, they are farther from the torch. Now I can work on fixing everything.

Thanks…

2 Likes

Now, I put in the torch lighting, that affects those spaces. This is a still image, but it flickers with the torch, smooth adjustment from Redish to Yellowish color, to simulate torch flickering. Works for the 17bit style game.

image

3 Likes