FloatBuffer to Short buffer

Sorry I couldn’t understand how to make a simple rectangle when changing from floatbuffer to shortbuffer.
This is my code:

//vertices[0] = new Vector3f(position.x,position.y,-1.0f);
vertices[0] =(short)position.x;
vertices[1] = (short)position.y;
vertices[2] = (short)-1;
//vertices[1] = new Vector3f(position.x+width,position.y,-1.0f);
vertices[3] =(short)(position.x+width);
vertices[4] = (short)position.y;
vertices[5] = (short)-1;
//vertices[2] = new Vector3f(position.x,position.y+height,-1.0f);
vertices[6] =(short)(position.x);
vertices[7] = (short)(position.y+height);
vertices[8] = (short)-1;
//vertices[3] = new Vector3f(position.x+width,position.y+height,-1.0f);
vertices[9] =(short)(position.x+width);
vertices[10] = (short)(position.y+height);
vertices[11] = (short)-1;

which the commented ones are related to “Vector3f[] vertices” for float buffer and the others are for “short [] vertices” for short buffer.
But as I change floatbuffer to shortbuffer in:

mesh.setBuffer(Type.Position, 3, BufferUtils.createShortBuffer(vertices));

the rectangle is not shown and if I change vertices order it will result strange shapes. What is the right way to arrange my vertices in a short array?

Also the rest parts are similar:

texCoord[0] = new Vector2f(0,0);
texCoord[1] = new Vector2f((float)width/(float)100+tile_x,0);
texCoord[2] = new Vector2f(0,(float)height/(float)100+tile_y);
texCoord[3] = new Vector2f((float)width/(float)100+tile_x,(float)height/(float)100+tile_y);

indexes[0]=(short)(1);
indexes[1]=(short)(2);
indexes[2]=(short)(0);
indexes[3]=(short)(1);
indexes[4]=(short)(3);
indexes[5]=(short)(2);

I wonder if “Vector3s” existed!

Well, which is it… it isn’t shown or results in strange shapes? I wonder how you would see the strange shapes if it wasn’t shown?

What strange shapes?

What is width and height?

Include more of your code since we can only see a little soda-straw view of it. A simple one class test case that is stand-alone is usually best.

The correct floatbuffer is like this:

package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.VertexBuffer;
import com.jme3.scene.shape.Box;
import com.jme3.texture.Texture;
import com.jme3.util.BufferUtils;


public class Main extends SimpleApplication {

public static void main(String[] args) {
    Main app = new Main();
    app.start();
}

@Override
public void simpleInitApp() {
Vector3f[] vertices;
//short[] vertices;
Vector2f[] texCoord;
short[] indexes;
    
vertices=new Vector3f[1*4];
//vertices=new short[1*4*3];
texCoord = new Vector2f[1*4];
indexes=new short[1*6];
    
float width=10;
float height=5;
    
vertices[0] = new Vector3f(1,1,-1.0f);
//vertices[0] =(short)1;
//vertices[1] = (short)1;
//vertices[2] = (short)-1;
vertices[1] = new Vector3f(1+width,1,-1.0f);
//vertices[3] =(short)(1+width);
//vertices[4] = (short)1;
//vertices[5] = (short)-1;
vertices[2] = new Vector3f(1,1+height,-1.0f);
//vertices[6] =(short)(1);
//vertices[7] = (short)(1+height);
//vertices[8] = (short)-1;
vertices[3] = new Vector3f(1+width,1+height,-1.0f);
//vertices[9] =(short)(1+width);
//vertices[10] = (short)(1+height);
//vertices[11] = (short)-1;
    
texCoord[0] = new Vector2f(0,0);
texCoord[1] = new Vector2f((float)width/(float)100+1,0);
texCoord[2] = new Vector2f(0,(float)height/(float)100+2);
texCoord[3] = new Vector2f((float)width/(float)100+1,(float)width/(float)100+2);

indexes[0]=(short)(1);
indexes[1]=(short)(2);
indexes[2]=(short)(0);
indexes[3]=(short)(1);
indexes[4]=(short)(3);
indexes[5]=(short)(2);
    
flyCam.setMoveSpeed(50);
    
Mesh my_mesh = new Mesh();
my_mesh.setBuffer(VertexBuffer.Type.Position, 3, BufferUtils.createFloatBuffer(vertices));
//my_mesh.setBuffer(VertexBuffer.Type.Position, 3, BufferUtils.createShortBuffer(vertices));
my_mesh.setBuffer(VertexBuffer.Type.TexCoord, 2, BufferUtils.createFloatBuffer(texCoord));
my_mesh.setBuffer(VertexBuffer.Type.Index,    3, BufferUtils.createShortBuffer(indexes));
Geometry geo = new Geometry("Floor", my_mesh);
Material mat = new Material( assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
geo.setMaterial(mat);
    
cam.setLocation(new Vector3f(5,2.5f,22));
    
rootNode.attachChild(geo);
}

@Override
public void simpleUpdate(float tpf) {
//TODO: add update code
}

@Override
public void simpleRender(RenderManager rm) {
//TODO: add render code
}
}

and the way I think might be right is this:

package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.VertexBuffer;
import com.jme3.scene.shape.Box;
import com.jme3.texture.Texture;
import com.jme3.util.BufferUtils;


public class Main extends SimpleApplication {

public static void main(String[] args) {
Main app = new Main();
app.start();
}

@Override
public void simpleInitApp() {
//Vector3f[] vertices;
short[] vertices;
Vector2f[] texCoord;
short[] indexes;
    
//vertices=new Vector3f[1*4];
vertices=new short[1*4*3];
texCoord = new Vector2f[1*4];
indexes=new short[1*6];
    
float width=10;
float height=5;
    
//vertices[0] = new Vector3f(1,1,-1.0f);
vertices[0] =(short)1;
vertices[1] = (short)1;
vertices[2] = (short)-1;
//vertices[1] = new Vector3f(1+width,1,-1.0f);
vertices[3] =(short)(1+width);
vertices[4] = (short)1;
vertices[5] = (short)-1;
//vertices[2] = new Vector3f(1,1+height,-1.0f);
vertices[6] =(short)(1);
vertices[7] = (short)(1+height);
vertices[8] = (short)-1;
//vertices[3] = new Vector3f(1+width,1+height,-1.0f);
vertices[9] =(short)(1+width);
vertices[10] = (short)(1+height);
vertices[11] = (short)-1;
    
texCoord[0] = new Vector2f(0,0);
texCoord[1] = new Vector2f((float)width/(float)100+1,0);
texCoord[2] = new Vector2f(0,(float)height/(float)100+2);
texCoord[3] = new Vector2f((float)width/(float)100+1,(float)width/(float)100+2);

indexes[0]=(short)(1);
indexes[1]=(short)(2);
indexes[2]=(short)(0);
indexes[3]=(short)(1);
indexes[4]=(short)(3);
indexes[5]=(short)(2);
    
flyCam.setMoveSpeed(50);
    
Mesh my_mesh = new Mesh();
//my_mesh.setBuffer(VertexBuffer.Type.Position, 3, BufferUtils.createFloatBuffer(vertices));
my_mesh.setBuffer(VertexBuffer.Type.Position, 3, BufferUtils.createShortBuffer(vertices));
my_mesh.setBuffer(VertexBuffer.Type.TexCoord, 2, BufferUtils.createFloatBuffer(texCoord));
my_mesh.setBuffer(VertexBuffer.Type.Index,    3, BufferUtils.createShortBuffer(indexes));
Geometry geo = new Geometry("Floor", my_mesh);
Material mat = new Material( assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
geo.setMaterial(mat);
    
cam.setLocation(new Vector3f(5,2.5f,22));
    
rootNode.attachChild(geo);
}

@Override
public void simpleUpdate(float tpf) {
//TODO: add update code
}

@Override
public void simpleRender(RenderManager rm) {
//TODO: add render code
}
}

I’ve just broke vectors to single short elements but I’ve got invisible rectangle!

My intention of strange results is that if I do it wrong, it draws something at least so I’m sure it’s not just an invisible rectangle but my way of defining vertices is wrong like this code:



package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.VertexBuffer;
import com.jme3.scene.shape.Box;
import com.jme3.texture.Texture;
import com.jme3.util.BufferUtils;
public class Main extends SimpleApplication {

    public static void main(String[] args) {
        Main app = new Main();
        app.start();
    }

    @Override
    public void simpleInitApp() {
        //Vector3f[] vertices;
        short[] vertices;
        Vector2f[] texCoord;
        short[] indexes;
        
        //vertices=new Vector3f[1*4];
        vertices=new short[1*4*3];
        texCoord = new Vector2f[1*4];
        indexes=new short[1*6];
        
        float width=10;
        float height=5;
        
        //vertices[0] = new Vector3f(1,1,-1.0f);
        vertices[9] =(short)1;
        vertices[11] = (short)1;
        vertices[10] = (short)-1;
        //vertices[1] = new Vector3f(1+width,1,-1.0f);
        vertices[7] =(short)(1+width);
        vertices[8] = (short)1;
        vertices[6] = (short)-1;
        //vertices[2] = new Vector3f(1,1+height,-1.0f);
        vertices[0] =(short)(1);
        vertices[2] = (short)(1+height);
        vertices[1] = (short)-1;
        //vertices[3] = new Vector3f(1+width,1+height,-1.0f);
        vertices[7] =(short)(1+width);
        vertices[6] = (short)(1+height);
        vertices[8] = (short)-1;
        
        texCoord[0] = new Vector2f(0,0);
        texCoord[1] = new Vector2f((float)width/(float)100+1,0);
        texCoord[2] = new Vector2f(0,(float)height/(float)100+2);
        texCoord[3] = new Vector2f((float)width/(float)100+1,(float)width/(float)100+2);

        indexes[0]=(short)(1);
        indexes[1]=(short)(2);
        indexes[2]=(short)(0);
        indexes[3]=(short)(1);
        indexes[4]=(short)(3);
        indexes[5]=(short)(2);
        
        flyCam.setMoveSpeed(50);
        
        Mesh my_mesh = new Mesh();
        //my_mesh.setBuffer(VertexBuffer.Type.Position, 3, BufferUtils.createFloatBuffer(vertices));
        my_mesh.setBuffer(VertexBuffer.Type.Position, 3, BufferUtils.createShortBuffer(vertices));
        my_mesh.setBuffer(VertexBuffer.Type.TexCoord, 2, BufferUtils.createFloatBuffer(texCoord));
        my_mesh.setBuffer(VertexBuffer.Type.Index,    3, BufferUtils.createShortBuffer(indexes));
        Geometry geo = new Geometry("Floor", my_mesh);
        Material mat = new Material( assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        geo.setMaterial(mat);
        
        cam.setLocation(new Vector3f(5,2.5f,22));
        
        rootNode.attachChild(geo);
    }

    @Override
    public void simpleUpdate(float tpf) {
        //TODO: add update code
    }

    @Override
    public void simpleRender(RenderManager rm) {
        //TODO: add render code
    }
}




How can I make a shortbuffer? my own way results invisible rectangle.

Are short integers for vertex position possible in jME? I don’t think so.
OpenGL fixed function supported integer, float, double, etc. but that’s a long time ago now.
Still wait for pspeed’s answer (or any other experienced person).

It should be supported because the last code with wrong vertices will draw something! So I think this means that it is supported.

By default Mesh.setBuffer(…) creates an unsigned vertex buffer, since its almost always used for unsigned data like vertex indices or colors.

If you create it manually you can make it a signed buffer:

Mesh mesh = new Mesh();

short[] data = new short[]{
    -1, -1,
     1, -1,
    -1,  1,
     1,  1
};

VertexBuffer vb = new VertexBuffer(Type.Position);
vb.setupData(Usage.Static, 2, VertexBuffer.Format.Short, BufferUtils.createShortBuffer(data));
mesh.setBuffer(vb);
mesh.setMode(Mesh.Mode.TriangleStrip);
mesh.setBound(new BoundingBox(Vector3f.ZERO, 2, 2, 0));

Also note that you have to set the bounding volume manually, since Mesh.updateBound() only supports floating point positions.

2 Likes

Excellent help @Momoko_Fan .
Thank you.
At first I didn’t find out why you spoke about setBound but later I got that it helps culling process.
Thank you.