Vertex colouring from last jPCT-AE version

Started by mxar, September 29, 2014, 11:57:20 AM

Previous topic - Next topic

mxar

Hi,

vertex colouring is supported by the latest jPCT-AE version?

Thanks in advance.

EgonOlsen

Yes and no. There's no direct support but you can use VertexAttributes for this. Do something like


int vertices = obj.getMesh().getUniqueVertexCount();
data = new float[vertices * 4];
for (int i = 0; i < data.length; i++) {
// set your color values here for each vertex...
}

VertexAttributes vas = new VertexAttributes("colorinfo", data, VertexAttributes.TYPE_FOUR_FLOATS);
obj.getMesh().addVertexAttributes(vas);


and then write a shader (or modify one of the default shaders) and add


attribute vec4 colorinfo;


to the vertex shader. You can then use these color values in the shader for your own horrifying purposes... ;)



mxar

Hi again,

How  can i assign the vertex color colorinfo in the vertex shader?

I need to use the position of vertex inside the vertex shader program?

I wrote a program based on previews reply but compiler shows the following error message:

"Error missing attribute position in vertex shader"

Also, should I write and a fragment shader?

Can you give me an idea of how the vertex and (if needed) fragment shader must be?


Thanks in advance

EgonOlsen

Seems like as if you vertex shader consists solely of this one line...that's not what i meant. You have to provide a vertex and a fragment shader and the vertex shader has to have this colorinfo (or whatever name you choose) attribute in addition to the other attributes. You can modify one of the default shaders for this, i.e. unzip the jpct_shaders.zip in the lib directory of the distribution and pick a shader that fits. Which one that is, highly depends on your scene. If you want to be sure, you can simply pick defaultFragmentShader and defaultVertexShader. They include every feature that a scene in jPCT can use but if it doesn't, they might be slower than needed. Anyway, i would start with them. Add the colorinfo attribute to the vertex shader and do something with it. You most likely don't have to modify the fragment shader.
If you want to use vertex colors only without lighting or even textures, the shader can look a whole simpler than the default shaders. It depends, what you want to do with it...

mxar


Thanks for your answer.

I wrote the following code:

       int vertices = object3D.getMesh().getUniqueVertexCount();
        Log.d(TAG," vertices = " + vertices);

        float[] data = new float[4*vertices];

        for(int i = 0; i < data.length; i++){
           
            data = 0.0f;
           
            if(i%3 == 1)
                data = 1f;
           
           
        }
         
        VertexAttributes  vattrs = new VertexAttributes("colorinfo",data,VertexAttributes.TYPE_FOUR_FLOATS);

        object3D.getMesh().addVertexAttributes(vattrs);
       
        GLSLShader  shader = new  GLSLShader( Loader.loadTextFile(mActivity.getResources().openRawResource(R.raw.vertexshader)),Loader.loadTextFile(mActivity.getResources().openRawResource(R.raw.fragmentshader)));

        object3D.setShader(shader);
       
       object3D.strip();
       object3D.build();
       world.addObject(object3D);

The vertex shader is:

attribute vec4 colorinfo;
uniform mat4 modelViewProjectionMatrix;
attribute vec4 position;
varying vec4 vertexColor;


void main(void)
{
     vertexColor = colorinfo;
     gl_Position = modelViewProjectionMatrix * position;

}

And the fragment shader is:

varying vec4 theColor;
varying vec4 vertexColor;


void main(void)
{
gl_FragColor = vertexColor;
}

I think that works . Am i correct? 

Also I have a question about the  method:


Object3D obj = Object3D(float[] coordinates, float[] uvs, int[] indices, int textureId) 

How can I apply material info in this case to Object3D obj?

Thanks in advance.

EgonOlsen

Looks ok at first glace, except for the definition of the "theColor" variant in the fragment shader. I don't see where this is supposed to be filled or used.

That special constructor is for a very special case...i'm not sure, if you really need it. If you do, what exactly do you mean by material info? TextureInfo instances? If that's the case, you can't use them in this constructor but a simple array of texture ids instead (which limits you to one texture layer of course). You can of course anything you like after creating the object but that will influence the object as a whole.

mxar

Thanks for the answer.

I forgot to remove the unused vec4 theColor from fragment shader.

My current project is an Augmented Reality project.

I need to read the Augmented Object3D models from a data buffer not from a file.

This means that i dont know the format (.3ds, .obj,. md2 ..)  of the Object3D model stored in the data buffer.

The Object3D obj = Object3D(float[] coordinates, float[] uvs, int[] indices, int textureId)   method could be a good candidate in this case.

One part of the data buffer can store the float[] coordinates,
other parts the float[] uvs, int[] indices  and textureID.

But  some Object3D formats like .obj provide the material info in a separate .mtl file.

For example a .mtl file can have a content like this:

newmtl policecar.png
Ns 0
Kd 0.8 0.8 0.8
Ks 0.0 0.0 0.0
Ka 0.2 0.2 0.2
d 1
illum 2
map_Kd policecar.png


I think that the previews Object3D constructor doesn't provide this kind of info.

What do you think about this issue?


Thanks in advance








EgonOlsen

No, it doesn't but actually, it doesn't have to. All that jPCT uses from this file (when using it's own loader) is newmtl (as an indicator that something new comes after) and the name, Kd, map_Kd/map_Ka and d. If map_Kd/map_Ka is present, it uses that as a texture name. If not, it creates a texture with the colors of Kd and uses that one. Plus is uses d for transparency. If you want to support file of that kind in the same way that the default loaders do it, just mimic that behaviour.

mxar

Thanks for your answer,

I want to ask you if other type of Object3D models (like .3ds,.obj ..) are planned to be supported in the near future.

Also i found some 3D models with non square textures and having not power of 2 width and size.

I know that these kind of textures are not supported by jPCT-ae, but do you know any way to be used by jPCT-ae? (scaling?,some tranformation? ..).

Thanks in advance

EgonOlsen

No need to do anything for rescaling the texture. uv coordinates are normalized, so it doesn't matter which physical dimensions the actual texture has. BTW, this power of two limit is no engine limitation, it's an OpenGL/hardware limitation. jPCT does support other formats by using the NPOTTexture class, but you'll lose mip mapping and performance when doing this. It's intended for some special purpose stuff only.

mxar



Ok

but I want to ask you if more types of Object3D models (like the supported .3ds,.obj ..) are planned to be supported in the near future by jPCT-ae.

Also non square texures with power of 2 sizes (like 512x256,128x64) are accepted and are safe ?

Thanks in advance


EgonOlsen

#12
Quote from: mxar on October 16, 2014, 10:41:44 AM
but I want to ask you if more types of Object3D models (like the supported .3ds,.obj ..) are planned to be supported in the near future by jPCT-ae.
There are no current plans to support than what's there. If there's a damn good reason, then i'll consider it. However, one can always write his/her own importers. Nothing in the API prevents you from doing so.

Quote from: mxar on October 16, 2014, 10:41:44 AM
Also non square texures with power of 2 sizes (like 512x256,128x64) are accepted and are safe ?
Accepted yes, safe...to a degree. Non-square texture are undefined for OpenGL ES 2.0. And so are the results. If you want to be safe, use square ones whenever possible.


mxar

Hi again,

I wrote a code to apply vertex colors to loaded 3D model.

The part of the code that assignes vertex color is:

int vertices = object3D.getMesh().getUniqueVertexCount();

        float[] data = new float[4*vertices];

        for(int i = 0; i < data.length; i++){
           
           data = 0.0f;
                   
              if(i%4 == 0)
                data = 0.0f; //red color
             
              if(i%4 == 1)
                 data = 0.0f; //green color
             
              if(i%4 == 2)
                  data = 1f; //blue color
             
              if(i%4 == 3)
                   data = 0.5f; //transparency
               
        }
         
        VertexAttributes  vattrs = new VertexAttributes("colorinfo",data,VertexAttributes.TYPE_FOUR_FLOATS);

        object3D.getMesh().addVertexAttributes(vattrs);
       
        GLSLShader  shader = new  GLSLShader( Loader.loadTextFile(mActivity.getResources().openRawResource(R.raw.vertexshader)),Loader.loadTextFile(mActivity.getResources().openRawResource(R.raw.fragmentshader)));

        object3D.setShader(shader);
       
       object3D.strip();
       object3D.build();
       world.addObject(object3D);

The vertex shader is:

attribute vec4 colorinfo;
uniform mat4 modelViewProjectionMatrix;
attribute vec4 position;
varying vec4 vertexColor;


void main(void)
{
     vertexColor = colorinfo;
     gl_Position = modelViewProjectionMatrix * position;

}

And the fragment shader is:


varying vec4 vertexColor;


void main(void)
{
gl_FragColor = vertexColor;
}


The problem is that i dont see any transparency. I see only a blue 3D model.

It looks like the code : 
             if(i%4 == 3)
                 data = 0.5f; //transparency

doesnt create any transparency.

How can i produce transparency with vertex colors?

Thanks in advance