Texturing MPxSurfaceShape in Viewport 2.0

Texturing MPxSurfaceShape in Viewport 2.0

Anonymous
Not applicable
2,568 Views
10 Replies
Message 1 of 11

Texturing MPxSurfaceShape in Viewport 2.0

Anonymous
Not applicable

 

Hi all,

 

I coded a custom MPxSurfaceShape similar to that of apiMeshShape SDK, displayed in Viewport 2.0 with SubSceneOverride and GeometryOverride.

 

I want to implement texturing in Viewport 2.0 but I don't know how to use the texture container (MTexture or MTextureManager, I guess) in SubSceneOverride/GeometryOverride, and there's not any example inside apiMeshShape.

 

Could anybody post a simple example? What would be the equivalent in Viewport 2.0 to classical uv containers and glTexCoord2f() used in old Maya Viewport?

 

Many thanks.

0 Likes
Accepted solutions (1)
2,569 Views
10 Replies
Replies (10)
Message 2 of 11

cheng_xi_li
Autodesk Support
Autodesk Support

Hi Pablomarko,

 

I think for these override, you can assign shader with for the renderItem and you can assign textures for those shaders. Otherwise, Maya will use assigned shader for your shape.

 

For MTexture and MTextureManager, you can use fileTexture sample as a reference. The parameter update should be the same. 

 

You also need to implement populateGeometry for populate semantics value like Position, Normal, UV etc... 

 

Yours,

Li

0 Likes
Message 3 of 11

Anonymous
Not applicable

 

Hello Li,

I tried to do it for the SubSceneOverride with the apiMeshShape example. I created an MShaderInstance fTexturedShader similar to fShadedShader, and an MVertexBuffer fUVBuffer among fPositionBuffer and fNormalBuffer, as well as an MIndexBuffer fTexturedIndexBuffer.

When updating geometry I added positions, normals and uvs:
        MVertexBufferArray texturedBuffers;
        texturedBuffers.addBuffer("positions", fPositionBuffer);
        texturedBuffers.addBuffer("normals", fNormalBuffer);
        texturedBuffers.addBuffer("uvs", fUVBuffer);
        setGeometryForRenderItem(*texturedItem, texturedBuffers, *fTexturedIndexBuffer, &bounds);

When filling the buffers I did:
    // Acquire vertex buffer resources
    const MVertexBufferDescriptor posDesc("", MGeometry::kPosition, MGeometry::kFloat, 3);
    const MVertexBufferDescriptor normalDesc("", MGeometry::kNormal, MGeometry::kFloat, 3);
    const MVertexBufferDescriptor uvDesc("", MGeometry::kTexture, MGeometry::kFloat, 2);

    fPositionBuffer = new MVertexBuffer(posDesc);
    fNormalBuffer = new MVertexBuffer(normalDesc);
    fUVBuffer = new MVertexBuffer(uvDesc);

    float* positions = (float*)fPositionBuffer->acquire(meshGeom->vertices.length(), true);
    float* normals = (float*)fNormalBuffer->acquire(meshGeom->vertices.length(), true);
    float* uvs = (float*)fUVBuffer->acquire(meshGeom->vertices.length(), true);

    // Fill vertex data for shaded/wireframe
    int vid = 0;
    int pid = 0;
    int nid = 0;
    int uvid = 0;
    int uv_len = meshGeom->uvcoords.uvcount();
    for (unsigned int i=0; i<meshGeom->vertices.length(); i++)
    {
        MPoint position = meshGeom->vertices[i];
        positions[pid++] = (float)position[0];
        positions[pid++] = (float)position[1];
        positions[pid++] = (float)position[2];

        MVector normal = meshGeom->normals[i];
        normals[nid++] = (float)normal[0];
        normals[nid++] = (float)normal[1];
        normals[nid++] = (float)normal[2];
       
        if (uv_len > 0)
        {
            // If we are drawing the texture, make sure the  coord
            // arrays are in bounds.
            float u, v;
            int uvId1 = meshGeom->uvcoords.uvId(vid);
            if ( uvId1 < uv_len ) {
                meshGeom->uvcoords.getUV( uvId1, u, v );
                uvs[uvid++] = u;
                uvs[uvid++] = v;
            }
        }
       
        vid++;
    }
    fPositionBuffer->commit(positions); positions = NULL;
    fNormalBuffer->commit(normals); normals = NULL;
    fUVBuffer->commit(uvs); uvs = NULL;

To fill the index buffers I coded:
    fTexturedIndexBuffer = new MIndexBuffer(MGeometry::kUnsignedInt32);
    unsigned int* texturedBuffer = (unsigned int*)fTexturedIndexBuffer->acquire(3*numTriangles, true);
    // Fill index data for textured
    unsigned int base = 0;
    idx = 0;
    for (int faceIdx=0; faceIdx<meshGeom->faceCount; faceIdx++)
    {
        // Ignore degenerate faces
        int numVerts = meshGeom->face_counts[faceIdx];
        if (numVerts > 2)
        {
            for (int v=1; v<numVerts-1; v++)
            {
                texturedBuffer[idx++] = meshGeom->face_connects[base];
                texturedBuffer[idx++] = meshGeom->face_connects[base+v];
                texturedBuffer[idx++] = meshGeom->face_connects[base+v+1];
            }
            base += numVerts;
        }
    }
    fTexturedIndexBuffer->commit(texturedBuffer); texturedBuffer = NULL;

However, the plugin does not work. When plugging a texture from a surfaceShader node, no shader is shown.
Is the code properly written? At least the way how the UVBuffer and the index buffer are filled?

I attach here the full .cpp and .h with the implementation, just in case.

Many thanks!

0 Likes
Message 4 of 11

cheng_xi_li
Autodesk Support
Autodesk Support

Hi pablomarko,

 

How do you plug that? I tried to assign a blinn shader with texture to yours and original apiMeshShape, they are both working.

 

Yours,

Li

0 Likes
Message 5 of 11

Anonymous
Not applicable

 

Hi Li,

 

When I load the plugin and launch apiMeshShape.mel, I see the cube with a blinn shader and its wireframe in green (also, a text displaying "subSceneUIDraw"). I select it, go to initialShadingGroup in the Attribute editor, Shading Group Attributes -> Surface material. I click on the arrow to display the surface material (which is lambert1), then the checker box next to Color to open a Create Render Node window. Finally I select the 2D Texture Checker, and the drawMode Textured.

 

If I display Legacy Default Viewport, the checker texture is correctly displayed on the cube. However, with Viewport 2.0 it is not displayed (it remains the blinn shader).

 

Please tell me if I'm doing something wrong with the way of coding the SubSceneOverride, or if it's related with the way I connect the surfaceShaders in Maya (which is something I'm really noob at).

 

Thank you for your help!

0 Likes
Message 6 of 11

cheng_xi_li
Autodesk Support
Autodesk Support

Hi pablomarko,

 

I did the same thing as you said.

 

1. I run the script attached with apiMeshShape

2. I clicked at intialShadingGroup

3. I clicked the arrow next to the lambert1 of surface shader

4. I clicked at the checker of Color attribute

5. I choose the checker of 2d Texture

6. I switched to Shaded display (with texture)

 

The checker texture is displayed in VP2.

 

I checked the devkit sample code and I think apiMeshShape is implemented properly with shaded display. So, I think something else might be wrong there. I tested with Maya 2016 SP5 on Windows 10 and my graphic card is Geforce Titan X with 364.72.

 

Yours,

Li

 

 

0 Likes
Message 7 of 11

Anonymous
Not applicable

 

Hello Li,

 

This is indeed very strange! So you run it with my code and the texture of the checkers was on the cube with VP2?? Would you mind posting a .ma with it? What could be the reason?

 

I'm on Maya 2016 in OS X El Capitan 10.11.1, with Intel HD Graphics 6000, though this very same issue is happening with other Macbooks with Maya 2015/16. Maybe it's a Mac issue?

 

Thank you a lot!

Pablo

0 Likes
Message 8 of 11

cheng_xi_li
Autodesk Support
Autodesk Support

Hi pablomarko,

 

I've attached the .ma file as your requested. maya_apimeshshape.png

 

Yours,

Li

0 Likes
Message 9 of 11

Anonymous
Not applicable

 

Hello Li,

 

You're right, now it works!! Thank you very much!

 

However, when I create such a node and delete it, or just remove the scene, Maya crashes. Apparently, it's because something is being accessed out of memory. Did you notice that? Maybe I didn't properly release a buffer in the code?

 

Thanks,

Pablo

0 Likes
Message 10 of 11

cheng_xi_li
Autodesk Support
Autodesk Support
Accepted solution
Hi,


It seems that there is no problem with sample from the devkit. The buffers you created in your sample are not required and released properly. Simply remove it will solve the problem I think.


Yours,

Li
0 Likes
Message 11 of 11

Anonymous
Not applicable

 

Hi Li,

 

Indeed, it works without all that! So in the end the problem was that I was not properly launching the surfaceShader node within Maya interface, and of me being dumb...

 

Thank you for your help!

Pablo

0 Likes