Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you enable a GL function in Qt3D with QML

Tags:

qt

opengl

qml

qt3d

I am writing an application using Qt3D. Most of the 3D handling I have been doing has used QML not the C++ interface. I have created a QML effect that loads my shader programs similar to the PerVertex color effect QML that ships with Qt5.9.

The problem I am having is I am trying to write a fragment shader and utilize glBlendFunc(sfactor, dfactor). According to the OpenGL documentation, I need to set glEnable(GL_BLEND) and use glBlendFunc, but I don't know how to do that using QML. I can see how it is done on the C++ side of things, but as I am using QML Scene3D, that would take a great deal of rewriting to accomplish. Can anyone tell me how to enable OpenGL functions (like GL_BLEND) via Qt3D QML?

As requested, the fragment shader:

#version 330 core

// TODO: Replace with a struct
uniform vec3 ka;            // Ambient reflectivity
uniform vec3 kd;            // Diffuse reflectivity
uniform vec3 ks;            // Specular reflectivity
uniform float shininess;    // Specular shininess factor
uniform float alpha;

uniform vec3 eyePosition;

in vec3 worldPosition;
in vec3 worldNormal;
in vec3 color;

out vec4 fragColor;

#pragma include light.inc.frag

void main()
{
    vec3 diffuseColor, specularColor;
    adsModel(worldPosition, worldNormal, eyePosition, shininess, diffuseColor, specularColor);
    fragColor = vec4( ka * color + kd * color * diffuseColor + ks * color * specularColor, 1.0 );
}

Here is also the Effect component:

import Qt3D.Core 2.0
import Qt3D.Render 2.0

Effect {
    id: root

parameters: [
    Parameter { name: "k";         value: Qt.vector3d( 0.1, 0.1, 0.1 )    },
    Parameter { name: "kd";        value: Qt.vector3d( 0.7, 0.7, 0.7 )    },
    Parameter { name: "ks";        value: Qt.vector3d( 0.95, 0.95, 0.95 ) },
    Parameter { name: "shininess"; value: 150.0                           }
]

techniques: [
    Technique {
        graphicsApiFilter {
            api: GraphicsApiFilter.OpenGL
            profile: GraphicsApiFilter.CoreProfile
            majorVersion: 3
            minorVersion: 1
        }

        filterKeys: [ FilterKey { name: "renderingStyle"; value: "forward" } ]

        parameters: [
            Parameter { name: "light.position";  value: Qt.vector4d( 0.0, 0.0, 0.0, 1.0 ) },
            Parameter { name: "light.intensity"; value: Qt.vector3d( 1.0, 1.0, 1.0 )      }
        ]

        renderPasses: [
            RenderPass {
                filterKeys: [ FilterKey { name: "pass"; value: "forward" } ]

                shaderProgram: ShaderProgram {
                    vertexShaderCode:   loadSource("qrc:/shaders/thermal.vert")
                    fragmentShaderCode: loadSource("qrc:/shaders/thermal.frag")
                }
            }
        ]
    }
]
}
like image 797
Cinder Biscuits Avatar asked Oct 06 '17 18:10

Cinder Biscuits


1 Answers

Calling the glBlendFunc directly is not possible in Qt3D. You need to set the renderStates property of your RenderPass. It should be something similar to this, depending on which blend function and other states you want to enable:

renderPasses: [
    RenderPass {
        filterKeys: [ FilterKey { name: "pass"; value: "forward" } ]
        renderStates: [
            CullFace { mode : CullFace.Back },       
            DepthTest { depthFunction: DepthTest.Less },         
            NoDepthMask { },         
            BlendEquationArguments {         
                sourceRgb: BlendEquationArguments.SourceAlpha        
                destinationRgb: BlendEquationArguments.OneMinusSourceAlpha       
            },
            BlendEquation {blendFunction: BlendEquation.Add}
        ]

        shaderProgram: ShaderProgram {
            vertexShaderCode:   loadSource("qrc:/shaders/thermal.vert")
            fragmentShaderCode: loadSource("qrc:/shaders/thermal.frag")
        }
    }
]
like image 162
dragly Avatar answered Oct 11 '22 00:10

dragly