PDA

View Full Version : listview + shader



kadet.89
30th July 2013, 18:02
I need to merge two programs from qt examples
1) expandingdelegates (listview example)
2) QML + OpenGL shader program

Each cell of listview must contain a shader program:
9381

List model:

ListModel {
ListElement {
title: "Pancakes"
picture: "content/pics/pancakes.jpg"
ingredients: "<html><ul><li> 1 cup (150g) self-raising flour<li> 1 tbs caster sugar<li> 3/4 cup (185ml) milk<li> 1 egg</ul></html>"
method: "<html><ol><li> Sift flour and sugar together into a bowl. Add a pinch of salt.</ol></html>"
}
ListElement {
title: "Fruit Salad"
picture: "content/pics/fruit-salad.jpg"
ingredients: "* Seasonal Fruit"
method: "* Chop fruit and place in a bowl."
}
ListElement {
...
}
}

shader program:

Squircle {
SequentialAnimation on t {
NumberAnimation { to: 1; duration: 2500; easing.type: Easing.InQuad }
NumberAnimation { to: 0; duration: 2500; easing.type: Easing.OutQuad }
loops: Animation.Infinite
running: true
}
}

When I add Squircle, it always appears in the background of the program

wysota
30th July 2013, 18:12
When I add Squircle, it always appears in the background of the program
That's the whole point of the example. Instead, what you want to use is something called ShaderEffect.

kadet.89
30th July 2013, 18:26
But I create the texture for the shader program in QGLWidget. How can I pass the coordinates of the polygon and texture in ShaderEffect ? Or how can I bind ShaderEffect in QGLWidget as QGLShaderProgram?

wysota
30th July 2013, 18:29
If you have a texture then just use Image as your element. There is no need for a shader effect then. However I would say that's a very odd use-case to create a texture in QGLWidget and then use it in QtQuick scene. Why don't you create the texture directly in the scene (e.g. using an FBO).

kadet.89
31st July 2013, 17:56
ListModel {

ListElement {
}


ListElement {}
ListElement {}
ListElement {}
ListElement {}
ListElement {}
ListElement {}
ListElement {}
ListElement {}
}


Rectangle {
id: page
width: 400; height: 70*9
color: "black"

property color col: "lightsteelblue"
gradient: Gradient {
GradientStop { position: 0.0; color: Qt.tint(root.col, "#20FFFFFF") }
GradientStop { position: 0.1; color: Qt.tint(root.col, "#20AAAAAA") }
GradientStop { position: 0.9; color: Qt.tint(root.col, "#20666666") }
GradientStop { position: 1.0; color: Qt.tint(root.col, "#20000000") }
}


function saturate(x) {
return Math.min(Math.max(x, 0), 1)
}

function sliderToColor(x) {
return Qt.rgba(saturate(Math.max(2 - 6 * x, 6 * x - 4)),
saturate(Math.min(6 * x, 4 - 6 * x)),
saturate(Math.min(6 * x - 2, 6 - 6 * x)))
}



Component {
id: recipeDelegate

Item {
id: recipe
property string cc: "green"

property real detailsOpacity : 0
width: listView.width
height: 70

MouseArea {
anchors.fill: parent
onClicked: recipe.state = 'Details';
}

ShaderEffectSource {
id: theSource
sourceItem: theItem
hideSource: true
Image {
id: theItem
width: 311
height: 65
source: "content/img.png"
}
}
ShaderEffect {
x: 2; y: 2; width: parent.width - x*2; height: parent.height - y*2
property variant source: theSource
fragmentShader:
"uniform sampler2D source;" +
"varying highp vec2 qt_TexCoord0;" +
"void main() {" +
" gl_FragColor = texture2D(source, qt_TexCoord0);" +
" gl_FragColor.r = 0.5;" +
"}"
}
Rectangle {
id: background
x: 2; y: 2; width: parent.width - x*2; height: parent.height - y*2
color: "#00000000"
border.color: "orange"
radius: 5
}


// A button to close the detailed view, i.e. set the state back to default ('').
TextButton {
y: 10
anchors { right: background.right; rightMargin: 10 }
opacity: recipe.detailsOpacity
text: "Close"

onClicked: recipe.state = '';
}

states: State {
name: "Details"

PropertyChanges { target: recipeImage; width: 130; height: 130 } // Make picture bigger
PropertyChanges { target: recipe; detailsOpacity: 1; x: 0 } // Make details visible
PropertyChanges { target: recipe; height: listView.height } // Fill the entire list area with the detailed view

// Move the list so that this item is at the top.
PropertyChanges { target: recipe.ListView.view; explicit: true; contentY: recipe.y }
PropertyChanges { target: recipe.ListView.view; }

// Disallow flicking while we're in detailed view
PropertyChanges { target: recipe.ListView.view; interactive: false }
}

transitions: Transition {
// Make the state changes smooth
ParallelAnimation {
ColorAnimation { property: "color"; duration: 500 }
NumberAnimation { duration: 300; properties: "detailsOpacity,x,contentY,height,width" }
}
}
}
}
// The actual list
ListView {
id: listView
anchors.fill: parent
model: RecipesModel {}
delegate: recipeDelegate
}
}

I have 9 different ShaderEffects, but I can only add one to all cells (code above). How can I assign each cell individual ShaderEffect?

wysota
31st July 2013, 18:51
There are many solutions... For example you could use VisualItemModel.