need help with using multi-texture in pfx

This topic contains 5 replies, has 2 voices, and was last updated by  blamejane 2 years, 10 months ago.

Viewing 6 posts - 1 through 6 (of 6 total)
  • Author
    Posts
  • #31944

    blamejane
    Member

    I’m using a POD file with shaders in a PFX file. I’ve got a model of a car, which I have a base texture applied. I am trying to apply some decals to the car, by blending another texture onto the base. I’m seriously having problems though as I can’t figure out how exactly to do this. I know it’s possible as the Alpha Blend example uses transparency in the 1st quad. The problem is, I can’t figure out how to accomplish the same technique using shaders that are defined in the pfx.

    Here’s how my render mesh and draw mesh are defined:


    - (void) renderMeshes:(SPODNode *)pNode withIndex:(int)index andEffect:(GLuint)uiFXID
    {

    // Gets the node model matrix
    PVRTMat4 mWorld;
    PVRTMat4 mWorldView;

    mWorld = _broncoScene.GetWorldMatrix(*pNode);

    mWorld = [self sizeTiresAndWheels:index axis:mWorld node:pNode withIndex:index];

    mWorld = [self applySuspensionLift:index axis:mWorld];

    SPODMaterial* pMaterial = &_broncoScene.pMaterial[pNode->nIdxMaterial];

    mWorldView = _viewMatrix * _rotationX * mWorld;

    // Set the blend mode
    // Based in the info stored in the material by PVRShaman.
    // We check whether the blend mode is 'opaque' (ONE,ZERO).
    // Otherwise we enable blending and set the corresponding operations.
    if (_broncoScene.pMaterial[pNode->nIdxMaterial].eBlendSrcRGB == ePODBlendFunc_ONE && _broncoScene.pMaterial[pNode->nIdxMaterial].eBlendDstRGB == ePODBlendFunc_ZERO)
    {
    glDisable(GL_BLEND);
    }
    else
    {
    glEnable(GL_BLEND);
    // glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glBlendFunc(_broncoScene.pMaterial[pNode->nIdxMaterial].eBlendSrcRGB, _broncoScene.pMaterial[pNode->nIdxMaterial].eBlendDstRGB);
    }

    // Now process PVRShaman semantics and set-up the associated uniforms.
    const CPVRTArray& aUniforms = _pFX[uiFXID]->GetUniformArray();
    for(unsigned int j = 0; j < aUniforms.GetSize(); ++j)
    {
    switch(aUniforms[j].nSemantic)
    {
    case ePVRTPFX_UsWORLDVIEWPROJECTION:
    {
    PVRTMat4 mWVP;

    // Passes the world-view-projection matrix (WVP) to the shader to transform the vertices
    mWVP = _projectionMatrix * mWorldView;
    glUniformMatrix4fv(aUniforms[j].nLocation, 1, GL_FALSE, mWVP.f);
    }
    break;
    case ePVRTPFX_UsWORLDVIEWIT:
    {
    PVRTMat4 mWorldViewI, mWorldViewIT;

    // Passes the inverse transpose of the world-view matrix to the shader to transform the normals
    mWorldViewI = mWorldView.inverse();
    mWorldViewIT = mWorldViewI.transpose();

    PVRTMat3 WorldViewIT = PVRTMat3(mWorldViewIT);

    glUniformMatrix3fv(aUniforms[j].nLocation, 1, GL_FALSE, WorldViewIT.f);
    }
    break;
    case ePVRTPFX_UsWORLDVIEW:
    {
    glUniformMatrix4fv(aUniforms[j].nLocation, 1, GL_FALSE, _viewMatrix.f);
    }
    break;
    case ePVRTPFX_UsVIEWIT:
    {
    PVRTMat4 mViewI, mViewIT;

    /* Passes the inverse transpose of the model-view matrix to the shader to transform the normals */
    mViewI = _viewMatrix.inverse();
    mViewIT= mViewI.transpose();

    PVRTMat3 ViewIT = PVRTMat3(mViewIT);

    glUniformMatrix3fv(aUniforms[j].nLocation, 1, GL_FALSE, ViewIT.f);
    }
    break;
    case ePVRTPFX_UsLIGHTDIREYE:
    {

    //


    test...

    //


    // Reads the light direction from the scene.
    PVRTVec4 vLightDirection;
    PVRTVec3 vPos;
    // vLightDirection = _broncoScene.GetLightDirection(0);
    vLightDirection = PVRTVec4(0, 0, 0, 0);

    vLightDirection.x = -vLightDirection.x;
    vLightDirection.y = -vLightDirection.y;
    vLightDirection.z = -vLightDirection.z;

    /*
    Sets the w component to 0, so when passing it to glLight(), it is
    considered as a directional light (as opposed to a spot light).
    */
    vLightDirection.w = 0;

    // Passes the light direction in eye space to the shader
    PVRTVec4 vLightDirectionEyeSpace;
    vLightDirectionEyeSpace = _viewMatrix * vLightDirection;

    glUniform3f(aUniforms[j].nLocation, vLightDirectionEyeSpace.x, vLightDirectionEyeSpace.y, vLightDirectionEyeSpace.z);
    }
    break;
    case eCUSTOMSEMANTIC_DIFFUSECOLOUR:
    {
    glUniform4f(aUniforms[j].nLocation, pMaterial->pfMatDiffuse[0], pMaterial->pfMatDiffuse[1], pMaterial->pfMatDiffuse[2], 1.0f);
    }
    break;

    }
    }

    //set animation

    const CGFloat* components = CGColorGetComponents([self bodyColor].CGColor);

    glUniform4f(glGetUniformLocation(_pFX[uiFXID]->GetProgramHandle(), "diffuseColor"),components[0], components[1], components[2], 1);

    /*
    Now that the model-view matrix is set and the materials ready,
    call another function to actually draw the mesh.
    */
    [self drawMesh:index withEffect: _pFX[uiFXID]];
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    }

    - (void)drawMesh:(int)i32NodeIndex withEffect:(CPVRTPFXEffect *)pCurrentFX
    {
    // Get the mesh data from the POD file
    int i32MeshIndex = _broncoScene.pNode[i32NodeIndex].nIdx;
    SPODMesh* pMesh = &_broncoScene.pMesh[i32MeshIndex];

    // bind the VBO for the mesh
    glBindBuffer(GL_ARRAY_BUFFER, _puiVbo[i32MeshIndex]);

    // bind the index buffer, won't hurt if the handle is 0
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _puiIndexVbo[i32MeshIndex]);

    const CPVRTArray& Uniforms = pCurrentFX->GetUniformArray();

    // Set attributes and texture stages
    // The vertex data is already loaded into an VBO as 'interleaved data' (e.g. x,y,z,nx,ny,nz,u0,v0,...).
    // When using 'interleaved data' the last parameter in glVertexAttribPointer is just a numerical offset (in bytes) into the stream (e.g. 0, 12, 24).
    // Our tools use pMesh->sVertex.pData, etc. to store this offset only when using interleaved data.
    // If you do not want to use interleaved data you will need to create separated VBO from pMesh->sVertex.pData, pMesh->sNormals.pData, etc.
    // and set the offset (last parameter) to 0
    for(unsigned int j = 0; j < Uniforms.GetSize(); ++j)
    {
    switch(Uniforms[j].nSemantic)
    {
    case ePVRTPFX_UsPOSITION:
    {
    glVertexAttribPointer(Uniforms[j].nLocation, 3, GL_FLOAT, GL_FALSE, pMesh->sVertex.nStride, pMesh->sVertex.pData);
    glEnableVertexAttribArray(Uniforms[j].nLocation);
    }
    break;
    case ePVRTPFX_UsNORMAL:
    {
    glVertexAttribPointer(Uniforms[j].nLocation, 3, GL_FLOAT, GL_FALSE, pMesh->sNormals.nStride, pMesh->sNormals.pData);
    glEnableVertexAttribArray(Uniforms[j].nLocation);
    }
    break;
    case ePVRTPFX_UsUV:
    {
    glVertexAttribPointer(Uniforms[j].nLocation, 2, GL_FLOAT, GL_FALSE, pMesh->psUVW[0].nStride, pMesh->psUVW[0].pData);
    glEnableVertexAttribArray(Uniforms[j].nLocation);
    }
    break;

    case ePVRTPFX_UsTEXTURE:
    {
    // Set the sampler variable to the texture unit/stage 0,1,2,etc.
    glUniform1i(Uniforms[j].nLocation, Uniforms[j].nIdx);
    }
    break;
    case eCUSTOMSEMANTIC_TANGENT:
    {
    glVertexAttribPointer(Uniforms[j].nLocation, 3, GL_FLOAT, GL_FALSE, pMesh->sTangents.nStride, pMesh->sTangents.pData);

    }
    break;

    }
    }

    // Indexed Triangle list
    // Note: if you export you model and want to use this code, please export it as 'interleaved' triangle list.
    glDrawElements(GL_TRIANGLES, pMesh->nNumFaces*3, GL_UNSIGNED_SHORT, 0);

    // Safely disable the vertex attribute arrays
    for(unsigned int j = 0; j < Uniforms.GetSize(); ++j)
    {
    switch(Uniforms[j].nSemantic)
    {
    case ePVRTPFX_UsPOSITION:
    {
    glDisableVertexAttribArray(Uniforms[j].nLocation);
    }
    break;
    case ePVRTPFX_UsNORMAL:
    {
    glDisableVertexAttribArray(Uniforms[j].nLocation);
    }
    break;
    case ePVRTPFX_UsUV:
    {
    glDisableVertexAttribArray(Uniforms[j].nLocation);
    }
    break;
    }
    }

    // Un-bind our vertex and index buffers.
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    }

    #39368

    PaulL
    Admin

    Hi,

    Could you post the fragment shader code you are currently using to attempt this effect?

    Thanks,
    Paul.

    #39369

    blamejane
    Member

    Thanks PaulL, that’s the thing though, I don’t have the shaders. I’m trying to get help with creating them.

    #39370

    PaulL
    Admin

    You can use the PVRShaderEditor tool in the PowerVR SDK to view the .pfx file.

    PVRShaderEditor

    #39371

    PaulL
    Admin

    You achieve the effect by creating a POD for the car model, which should have a base texture, and a decal texture. You can then use a fragment shader defined in the PFX which takes two texture uniforms. The first texture handle would reference the car base texture, and the second handle should reference the decal you wish to use. The shader can then blend between the two textures on to the model.

    By changing the texture referenced by the shader handle, you can then apply different decals to several cars in a scene.

    #39372

    blamejane
    Member

    Thanks Pauil,

    Here’s how the effect looks applied.

    Not sure how to modify this further, but here’s my effect code:


    [TEXTURE]
    NAME cubemap
    PATH bronco_cubemap_rotated2.pvr
    MINIFICATION LINEAR
    MAGNIFICATION LINEAR
    MIPMAP LINEAR
    WRAP_S CLAMP
    WRAP_T CLAMP
    [/TEXTURE]

    [TEXTURE]
    NAME bodyBase
    PATH broncoBody0017_texture.pvr
    MINIFICATION LINEAR
    MAGNIFICATION LINEAR
    MIPMAP LINEAR
    WRAP_S REPEAT
    WRAP_T REPEAT

    [/TEXTURE]
    // ENVIRONMENT CUBEMAP /////////////////////////////////////////////////////////////////////
    //
    // Effect 3 from skybox2 example. Displays a textured bronco with diffuse lighting and a
    // second texture cube map of a garage, which is applied using a reflection vector as texture coordinates.
    // This makes it look like the bronco is reflecting the garage.
    //

    [VERTEXSHADER]
    NAME envMapVertShader

    [GLSL_CODE]
    attribute vec3 myVertex;
    attribute vec3 myNormal;
    attribute vec2 myUV;

    uniform mat4 myMVPMatrix;
    uniform mat3 myModelViewIT;
    uniform mat4 myModelView;
    uniform mediump vec3 EyePosModel;

    uniform mediump vec3 myLightDirection;
    varying highp float fDiffuse;
    varying lowp vec2 fTexCoord;

    uniform mediump float myFrame;
    uniform mediump float fAnim;
    varying lowp vec3 fReflectVec;

    uniform vec4 diffuseColor;
    varying vec4 baseColor;

    void main(void)
    {
    mediump vec4 myVertex4 = vec4(myVertex, 1);

    gl_Position = myMVPMatrix * myVertex4;
    mediump vec3 fTransNormal = myModelViewIT * myNormal;

    fDiffuse = (0.05 * dot(fTransNormal, myLightDirection) + 0.95) * 0.5;

    mediump vec3 EyeDir = vec3(0.0,-1.0,0.0) - vec3(myModelView * myVertex4);
    fReflectVec = myModelViewIT * reflect(EyeDir, normalize(fTransNormal) );

    baseColor = diffuseColor;

    fTexCoord = myUV.st;
    }
    [/GLSL_CODE]
    [/VERTEXSHADER]

    [FRAGMENTSHADER]
    NAME envMapFragShader

    [GLSL_CODE]
    const mediump float MixRatio = 0.15;

    varying lowp vec4 baseColor;
    varying lowp vec2 fTexCoord;
    varying lowp vec3 fReflectVec;

    uniform sampler2D sampler2d;
    uniform samplerCube myCubeMap;

    void main (void)
    {

    // Draw the static base
    mediump vec3 envColor = vec3 (texture2D(sampler2d, fTexCoord) * baseColor);

    // Do a lookup into the environment map.
    mediump vec3 envColor2 = vec3 (textureCube(myCubeMap, fReflectVec));

    // Mix them
    envColor = mix(envColor, envColor2, MixRatio);

    gl_FragColor = vec4 (envColor, 1.0);

    }

    [/GLSL_CODE]
    [/FRAGMENTSHADER]

    [EFFECT]
    NAME environmentMapEffect

    // GLOBALS UNIFORMS
    UNIFORM myModelViewIT WORLDVIEWIT
    UNIFORM myMVPMatrix WORLDVIEWPROJECTION
    UNIFORM myModelView WORLDVIEW
    UNIFORM myLightDirection LIGHTDIREYE
    UNIFORM sampler2d TEXTURE0
    UNIFORM myCubeMap TEXTURE1

    // ATTRIBUTES
    ATTRIBUTE myVertex POSITION
    ATTRIBUTE myNormal NORMAL
    ATTRIBUTE myUV UV

    VERTEXSHADER envMapVertShader
    FRAGMENTSHADER envMapFragShader
    TEXTURE 0 bodyBase
    TEXTURE 1 cubemap
    [/EFFECT]

Viewing 6 posts - 1 through 6 (of 6 total)
You must be logged in to reply to this topic.