Source

Target

Commits (34)
Showing with 788 additions and 56 deletions
load(qt_build_config)
CONFIG += qt_example_installs
MODULE_VERSION = 5.5.0
MODULE_VERSION = 5.6.0
CMAKE_MODULE_TESTS=-
TEMPLATE = subdirs
SUBDIRS += canvas3d
......@@ -3,6 +3,7 @@ SUBDIRS += textureandlight \
framebuffer \
interaction \
jsonmodels \
quickitemtexture \
threejs
OTHER_FILES += 3rdparty/*
......@@ -58,7 +58,7 @@
\snippet canvas3d/framebuffer/qml/framebuffer/framebuffer.js 0
Then, in the \c initGL function, we create the framebuffer object:
Then, in the \c initializeGL function, we create the framebuffer object:
\snippet canvas3d/framebuffer/qml/framebuffer/framebuffer.js 1
......@@ -75,7 +75,7 @@
\section1 Rendering into the Framebuffer
In \c renderGL function, we first need to draw the scene into the
In \c paintGL function, we first need to draw the scene into the
framebuffer. We start by binding the framebuffer object and setting a
viewport:
......
......@@ -41,11 +41,12 @@ import QtQuick.Layouts 1.0
import "framebuffer.js" as GLCode
Item {
Rectangle {
id: mainview
width: 1280
height: 768
visible: true
color: "#f2f2f2"
Canvas3D {
id: canvas3d
......
......@@ -43,11 +43,12 @@ import QtQuick.Layouts 1.0
import "interaction.js" as GLCode
Item {
Rectangle {
id: mainview
width: 1280
height: 768
visible: true
color: "#fafafa"
Canvas3D {
id: canvas3d
......
......@@ -58,7 +58,7 @@
First we include a JSON model parser, which handles parsing the JSON
models into our internal models:
\snippet canvas3d/jsonmodels/jsonmodels.js 0
\snippet canvas3d/jsonmodels/qml/jsonmodels/jsonmodels.js 0
The \c{ThreeJSLoader.js} includes a reimplementation of the JSON parser
in \c{three.js}, but we will not go into its implementation details.
......@@ -67,22 +67,22 @@
First we need to initialize all array buffers for the models:
\snippet canvas3d/jsonmodels/jsonmodels.js 1
\snippet canvas3d/jsonmodels/qml/jsonmodels/jsonmodels.js 1
\dots
Then we request the models to be loaded:
\snippet canvas3d/jsonmodels/jsonmodels.js 2
\snippet canvas3d/jsonmodels/qml/jsonmodels/jsonmodels.js 2
\dots
Then, when the load requests return, we handle the models:
\snippet canvas3d/jsonmodels/jsonmodels.js 3
\snippet canvas3d/jsonmodels/qml/jsonmodels/jsonmodels.js 3
\dots
Each buffer is bound and filled with the data parsed from the json models:
\snippet canvas3d/jsonmodels/jsonmodels.js 4
\snippet canvas3d/jsonmodels/qml/jsonmodels/jsonmodels.js 4
\section1 Loading the Textures
......@@ -91,42 +91,42 @@
\c imageLoadingFailed signals. In the \c imageLoaded signal
handlers we create the OpenGL textures:
\snippet canvas3d/jsonmodels/jsonmodels.js 5
\snippet canvas3d/jsonmodels/qml/jsonmodels/jsonmodels.js 5
\dots
\section1 Input Handling
First we add a MouseArea to fill the Canvas3D:
\snippet canvas3d/jsonmodels/jsonmodels.qml 0
\snippet canvas3d/jsonmodels/qml/jsonmodels/jsonmodels.qml 0
\dots
Before adding some functionality on it, we need to add properties to the
canvas with initial values set:
\snippet canvas3d/jsonmodels/jsonmodels.qml 1
\snippet canvas3d/jsonmodels/qml/jsonmodels/jsonmodels.qml 1
After that, we add rotation on mouse movement when the left mouse button
is pressed:
\snippet canvas3d/jsonmodels/jsonmodels.qml 2
\snippet canvas3d/jsonmodels/qml/jsonmodels/jsonmodels.qml 2
We need to keep the previous x and y values to avoid rotation jumping
when the mouse button is released and pressed again. We store them in
these properties:
\snippet canvas3d/jsonmodels/jsonmodels.qml 3
\snippet canvas3d/jsonmodels/qml/jsonmodels/jsonmodels.qml 3
Then we add zooming by mouse wheel:
\snippet canvas3d/jsonmodels/jsonmodels.qml 4
\snippet canvas3d/jsonmodels/qml/jsonmodels/jsonmodels.qml 4
These properties are then used in the JavaScript side when calculating
eye/camera movement:
\snippet canvas3d/jsonmodels/jsonmodels.js 7
\snippet canvas3d/jsonmodels/qml/jsonmodels/jsonmodels.js 7
Converting the rotation values into movement is done as follows:
\snippet canvas3d/jsonmodels/jsonmodels.js 8
\snippet canvas3d/jsonmodels/qml/jsonmodels/jsonmodels.js 8
*/
......@@ -253,7 +253,8 @@ function paintGL(canvas) {
// Draw the model
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, modelOne.indexVBO);
if (stateDumpExt)
// Getting state dump is a synchronous operation, so only do it when logging is enabled
if (isLogEnabled && stateDumpExt)
log("GL STATE DUMP:\n"+stateDumpExt.getGLStateDump(stateDumpExt.DUMP_FULL));
gl.drawElements(drawMode, modelOne.count, gl.UNSIGNED_SHORT, 0);
......@@ -621,7 +622,7 @@ function fillModel(modelData, model) {
new Float32Array(modelData.vertices),
gl.STATIC_DRAW);
log(" "+model.normalsVBO.name);
if (stateDumpExt)
if (isLogEnabled && stateDumpExt)
log("GL STATE DUMP:\n"+stateDumpExt.getGLStateDump(stateDumpExt.DUMP_VERTEX_ATTRIB_ARRAYS_BIT || stateDumpExt.DUMP_VERTEX_ATTRIB_ARRAYS_CONTENTS_BIT));
gl.bindBuffer(gl.ARRAY_BUFFER, model.normalsVBO);
......
......@@ -46,6 +46,7 @@ Window {
visible: true
width: 1200
height: 900
color: "#e6e6e6"
property int previousY: 0
property int previousX: 0
......
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtCanvas3D module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\example canvas3d/quickitemtexture
\since QtCanvas3D 1.0
\title Qt Quick Item as Texture Example
\ingroup qtcanvas3d-examples
\brief A simple cube with a Qt Quick item as a texture
The Qt Quick Item as Texture example shows how to use other Qt Quick items as
a texture source for Qt Canvas3D textures.
\image quickitemtexture-example.png
\section1 Using Qt Quick Item as a Texture
First we create a \l Rectangle with a label that displays the current frame rate and rotation
values of the cube:
\snippet canvas3d/quickitemtexture/qml/quickitemtexture/main.qml 0
We want to use the above \l Rectangle as the texture on our 3D cube. As a \l Rectangle item
doesn't implement QQuickItem::textureProvider() by itself, we make it layered by setting the
\c{layer.enabled} property to \c{true}.
To create a Canvas3DTexture out of our layered \l{Rectangle}, we create a
\l{Canvas3DTextureProvider}{QTCANVAS3D_texture_provider} extension and the texture
in the \c initializeGL() function in our JavaScript implementation:
\snippet canvas3d/quickitemtexture/qml/quickitemtexture/quickitemtexture.js 0
Once the \c cubeTexture item is created, it can be used like any other texture item in
the JavaScript.
\note The method of creating the texture from a Qt Quick item differs from how one would create
texture from an HTML item in WebGL API. Textures created with
\l{Canvas3DTextureProvider}{QTCANVAS3D_texture_provider} extension
support automatic live updates, without having to call textureImage2D each frame
to re-upload fresh texture data from the item.
*/
......@@ -34,30 +34,16 @@
**
****************************************************************************/
import QtQuick 2.2
import QtCanvas3D 1.0
import QtTest 1.0
#include <QtGui/QGuiApplication>
#include <QQmlApplicationEngine>
Item {
id: top
height: 150
width: 150
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
Canvas3D {
id: basic_context
anchors.fill: parent
function initializeGL() {}
function paintGL() {}
}
QQmlApplicationEngine engine;
TestCase {
name: "Canvas3D_creation_basic_context"
when: windowShown
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
function test_basic_context() {
waitForRendering(basic_context)
basic_context.getContext("basic")
compare(basic_context.context.canvas, basic_context)
}
}
return app.exec();
}
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtCanvas3D module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.2
import QtCanvas3D 1.1
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
import QtQuick.Window 2.2
import "quickitemtexture.js" as GLCode
Window {
id: mainview
width: 800
height: 600
visible: true
title: "Qt Quick Item as Texture"
color: "#f9f9f9"
ColumnLayout {
Layout.fillWidth: true
x: 4
y: 4
//! [0]
Rectangle {
id: textureSource
color: "lightgreen"
width: 256
height: 256
border.color: "blue"
border.width: 4
layer.enabled: true
layer.smooth: true
Label {
anchors.fill: parent
anchors.margins: 16
text: "X Rot:" + (canvas3d.xRotAnim | 0) + "\n"
+ "Y Rot:" + (canvas3d.yRotAnim | 0) + "\n"
+ "Z Rot:" + (canvas3d.zRotAnim | 0) + "\n"
+ "FPS:" + canvas3d.fps
color: "red"
font.pointSize: 30
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
}
}
//! [0]
Button {
Layout.fillWidth: true
Layout.minimumWidth: 256
text: textureSource.visible ? "Hide texture source" : "Show texture source"
onClicked: textureSource.visible = !textureSource.visible
}
Button {
Layout.fillWidth: true
Layout.minimumWidth: 256
text: "Quit"
onClicked: Qt.quit()
}
}
Canvas3D {
id: canvas3d
anchors.fill:parent
focus: true
property double xRotAnim: 0
property double yRotAnim: 0
property double zRotAnim: 0
property bool isRunning: true
// Emitted when one time initializations should happen
onInitializeGL: {
GLCode.initializeGL(canvas3d, textureSource);
}
// Emitted each time Canvas3D is ready for a new frame
onPaintGL: {
GLCode.paintGL(canvas3d);
}
onResizeGL: {
GLCode.resizeGL(canvas3d);
}
Keys.onSpacePressed: {
canvas3d.isRunning = !canvas3d.isRunning
if (canvas3d.isRunning) {
objAnimationX.pause();
objAnimationY.pause();
objAnimationZ.pause();
} else {
objAnimationX.resume();
objAnimationY.resume();
objAnimationZ.resume();
}
}
SequentialAnimation {
id: objAnimationX
loops: Animation.Infinite
running: true
NumberAnimation {
target: canvas3d
property: "xRotAnim"
from: 0.0
to: 120.0
duration: 7000
easing.type: Easing.InOutQuad
}
NumberAnimation {
target: canvas3d
property: "xRotAnim"
from: 120.0
to: 0.0
duration: 7000
easing.type: Easing.InOutQuad
}
}
SequentialAnimation {
id: objAnimationY
loops: Animation.Infinite
running: true
NumberAnimation {
target: canvas3d
property: "yRotAnim"
from: 0.0
to: 240.0
duration: 5000
easing.type: Easing.InOutCubic
}
NumberAnimation {
target: canvas3d
property: "yRotAnim"
from: 240.0
to: 0.0
duration: 5000
easing.type: Easing.InOutCubic
}
}
SequentialAnimation {
id: objAnimationZ
loops: Animation.Infinite
running: true
NumberAnimation {
target: canvas3d
property: "zRotAnim"
from: -100.0
to: 100.0
duration: 3000
easing.type: Easing.InOutSine
}
NumberAnimation {
target: canvas3d
property: "zRotAnim"
from: 100.0
to: -100.0
duration: 3000
easing.type: Easing.InOutSine
}
}
}
}
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtCanvas3D module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
Qt.include("/gl-matrix.js")
//
// Draws a cube that has a Qt Quick item as decal texture on each face.
// A simple per vertex lighting equation is used to emulate light landing on the rotating cube.
//
var gl;
var cubeTexture = 0;
var vertexPositionAttribute;
var textureCoordAttribute;
var vertexNormalAttribute;
var mvMatrix = mat4.create();
var pMatrix = mat4.create();
var nMatrix = mat4.create();
var pMatrixUniform;
var mvMatrixUniform;
var nUniform;
var width = 0;
var height = 0;
var canvas3d;
var pixelSize;
var canvasTextureProvider = null;
var textureSourceItem = null;
function initializeGL(canvas, textureSource) {
canvas3d = canvas;
textureSourceItem = textureSource;
// Get the OpenGL context object that represents the API we call
gl = canvas.getContext("canvas3d", {depth:true, antialias:true});
// Setup the OpenGL state
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(gl.LESS);
gl.enable(gl.CULL_FACE);
gl.cullFace(gl.BACK);
gl.clearDepth(1.0);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
// Use fully transparent clear color to allow other QML components to be seen through
// Canvas3D where not obscured by the rotating cube.
gl.clearColor(0.0, 0.0, 0.0, 0.0);
// Set viewport
gl.viewport(0, 0, canvas.width, canvas.height);
// Initialize the shader program
initShaders();
// Initialize vertex and color buffers
initBuffers();
// Create a texture from the Qt Quick item
//! [0]
canvasTextureProvider = gl.getExtension("QTCANVAS3D_texture_provider");
cubeTexture = canvasTextureProvider.createTextureFromSource(textureSourceItem);
//! [0]
gl.bindTexture(gl.TEXTURE_2D, cubeTexture);
}
function resizeGL(canvas)
{
var pixelRatio = canvas.devicePixelRatio;
canvas.pixelSize = Qt.size(canvas.width * pixelRatio,
canvas.height * pixelRatio);
}
function degToRad(degrees) {
return degrees * Math.PI / 180;
}
function paintGL(canvas) {
var pixelRatio = canvas.devicePixelRatio;
var currentWidth = canvas.width * pixelRatio;
var currentHeight = canvas.height * pixelRatio;
if (currentWidth !== width || currentHeight !== height ) {
width = currentWidth;
height = currentHeight;
gl.viewport(0, 0, width, height);
mat4.perspective(pMatrix, degToRad(45), width / height, 0.1, 500.0);
gl.uniformMatrix4fv(pMatrixUniform, false, pMatrix);
}
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
mat4.identity(mvMatrix);
mat4.translate(mvMatrix, mvMatrix, [(canvas.yRotAnim - 120.0) / 120.0,
(canvas.xRotAnim - 60.0) / 50.0,
-7.0]);
mat4.rotate(mvMatrix, mvMatrix, degToRad(canvas.xRotAnim), [0, 1, 0]);
mat4.rotate(mvMatrix, mvMatrix, degToRad(canvas.yRotAnim), [1, 0, 0]);
mat4.rotate(mvMatrix, mvMatrix, degToRad(canvas.zRotAnim), [0, 0, 1]);
gl.uniformMatrix4fv(mvMatrixUniform, false, mvMatrix);
mat4.invert(nMatrix, mvMatrix);
mat4.transpose(nMatrix, nMatrix);
gl.uniformMatrix4fv(nUniform, false, nMatrix);
gl.drawElements(gl.TRIANGLES, 36, gl.UNSIGNED_SHORT, 0);
}
function initBuffers()
{
var cubeVertexPositionBuffer = gl.createBuffer();
cubeVertexPositionBuffer.name = "cubeVertexPositionBuffer";
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer);
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array([// Front face
-1.0, -1.0, 1.0,
1.0, -1.0, 1.0,
1.0, 1.0, 1.0,
-1.0, 1.0, 1.0,
// Back face
-1.0, -1.0, -1.0,
-1.0, 1.0, -1.0,
1.0, 1.0, -1.0,
1.0, -1.0, -1.0,
// Top face
-1.0, 1.0, -1.0,
-1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
1.0, 1.0, -1.0,
// Bottom face
-1.0, -1.0, -1.0,
1.0, -1.0, -1.0,
1.0, -1.0, 1.0,
-1.0, -1.0, 1.0,
// Right face
1.0, -1.0, -1.0,
1.0, 1.0, -1.0,
1.0, 1.0, 1.0,
1.0, -1.0, 1.0,
// Left face
-1.0, -1.0, -1.0,
-1.0, -1.0, 1.0,
-1.0, 1.0, 1.0,
-1.0, 1.0, -1.0
]),
gl.STATIC_DRAW);
gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
var cubeVertexIndexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,
new Uint16Array([
0, 1, 2, 0, 2, 3, // front
4, 5, 6, 4, 6, 7, // back
8, 9, 10, 8, 10, 11, // top
12, 13, 14, 12, 14, 15, // bottom
16, 17, 18, 16, 18, 19, // right
20, 21, 22, 20, 22, 23 // left
]),
gl.STATIC_DRAW);
var cubeVerticesTextureCoordBuffer = gl.createBuffer();
cubeVerticesTextureCoordBuffer.name = "cubeVerticesTextureCoordBuffer";
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVerticesTextureCoordBuffer);
var textureCoordinates = [
// Front
1.0, 0.0,
0.0, 0.0,
0.0, 1.0,
1.0, 1.0,
// Back
1.0, 0.0,
0.0, 0.0,
0.0, 1.0,
1.0, 1.0,
// Top
1.0, 0.0,
0.0, 0.0,
0.0, 1.0,
1.0, 1.0,
// Bottom
1.0, 0.0,
0.0, 0.0,
0.0, 1.0,
1.0, 1.0,
// Right
1.0, 0.0,
0.0, 0.0,
0.0, 1.0,
1.0, 1.0,
// Left
1.0, 0.0,
0.0, 0.0,
0.0, 1.0,
1.0, 1.0
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoordinates),
gl.STATIC_DRAW);
gl.vertexAttribPointer(textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
var cubeVerticesNormalBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVerticesNormalBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
// Front
0.0, 0.0, 1.0,
0.0, 0.0, 1.0,
0.0, 0.0, 1.0,
0.0, 0.0, 1.0,
// Back
0.0, 0.0, -1.0,
0.0, 0.0, -1.0,
0.0, 0.0, -1.0,
0.0, 0.0, -1.0,
// Top
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
// Bottom
0.0, -1.0, 0.0,
0.0, -1.0, 0.0,
0.0, -1.0, 0.0,
0.0, -1.0, 0.0,
// Right
1.0, 0.0, 0.0,
1.0, 0.0, 0.0,
1.0, 0.0, 0.0,
1.0, 0.0, 0.0,
// Left
-1.0, 0.0, 0.0,
-1.0, 0.0, 0.0,
-1.0, 0.0, 0.0,
-1.0, 0.0, 0.0
]), gl.STATIC_DRAW);
gl.vertexAttribPointer(vertexNormalAttribute, 3, gl.FLOAT, false, 0, 0);
}
function initShaders()
{
var vertexShader = getShader(gl,
"attribute highp vec3 aVertexNormal; \
attribute highp vec3 aVertexPosition; \
attribute highp vec2 aTextureCoord; \
\
uniform highp mat4 uNormalMatrix; \
uniform mat4 uMVMatrix; \
uniform mat4 uPMatrix; \
\
varying mediump vec4 vColor; \
varying highp vec2 vTextureCoord; \
varying highp vec3 vLighting; \
\
void main(void) { \
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); \
vTextureCoord = aTextureCoord; \
highp vec3 ambientLight = vec3(0.5, 0.5, 0.5); \
highp vec3 directionalLightColor = vec3(0.75, 0.75, 0.75); \
highp vec3 directionalVector = vec3(0.85, 0.8, 0.75); \
highp vec4 transformedNormal = uNormalMatrix * vec4(aVertexNormal, 1.0); \
highp float directional = max(dot(transformedNormal.xyz, directionalVector), 0.0); \
vLighting = ambientLight + (directionalLightColor * directional); \
}", gl.VERTEX_SHADER);
var fragmentShader = getShader(gl,
"varying highp vec2 vTextureCoord; \
varying highp vec3 vLighting; \
\
uniform sampler2D uSampler; \
\
void main(void) { \
mediump vec3 texelColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t)).rgb; \
gl_FragColor = vec4(texelColor * vLighting, 1.0); \
}", gl.FRAGMENT_SHADER);
// Create the Program3D for shader
var shaderProgram = gl.createProgram();
// Attach the shader sources to the shader program
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
// Link the program
gl.linkProgram(shaderProgram);
// Check the linking status
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
console.log("Could not initialize shaders");
console.log(gl.getProgramInfoLog(shaderProgram));
}
// Take the shader program into use
gl.useProgram(shaderProgram);
// Look up where the vertex data needs to go
vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
gl.enableVertexAttribArray(vertexPositionAttribute);
textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord");
gl.enableVertexAttribArray(textureCoordAttribute);
vertexNormalAttribute = gl.getAttribLocation(shaderProgram, "aVertexNormal");
gl.enableVertexAttribArray(vertexNormalAttribute);
// Get the uniform locations
pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
nUniform = gl.getUniformLocation(shaderProgram, "uNormalMatrix");
// Setup texture sampler uniform
var textureSamplerUniform = gl.getUniformLocation(shaderProgram, "uSampler")
gl.activeTexture(gl.TEXTURE0);
gl.uniform1i(textureSamplerUniform, 0);
gl.bindTexture(gl.TEXTURE_2D, 0);
}
function getShader(gl, str, type) {
var shader = gl.createShader(type);
gl.shaderSource(shader, str);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
console.log("JS:Shader compile failed");
console.log(gl.getShaderInfoLog(shader));
return null;
}
return shader;
}
!include( ../../../examples.pri ) {
error( "Couldn't find the examples.pri file!" )
}
SOURCES += main.cpp
RESOURCES += quickitemtexture.qrc
OTHER_FILES += qml/quickitemtexture/* \
doc/src/* \
doc/images/*
<RCC>
<qresource prefix="/">
<file alias="gl-matrix.js">../3rdparty/gl-matrix.js</file>
<file alias="main.qml">qml/quickitemtexture/main.qml</file>
<file alias="quickitemtexture.js">qml/quickitemtexture/quickitemtexture.js</file>
</qresource>
</RCC>
......@@ -56,7 +56,7 @@
\snippet canvas3d/textureandlight/qml/textureandlight/main.qml 0
\dots
Inside it, we catch the \c initGL and \c renderGL signals to forward the
Inside it, we catch the \c initializeGL and \c paintGL signals to forward the
initialization and rendering calls to the js object:
\snippet canvas3d/textureandlight/qml/textureandlight/main.qml 1
......@@ -67,7 +67,7 @@
\snippet canvas3d/textureandlight/qml/textureandlight/main.qml 4
In the \c initGL function of the JavaScript, we initialize the OpenGL
In the \c initializeGL function of the JavaScript, we initialize the OpenGL
state. We also create the TextureImage and register handlers for image
load success and fail signals. If the load succeeds, the OpenGL texture
is created and filled with pixel data from the loaded image.
......@@ -83,9 +83,9 @@
\snippet canvas3d/textureandlight/qml/textureandlight/textureandlight.js 0
\section2 initGL Function
\section2 initializeGL Function
Let's take a closer look at the \c initGL function. It is called by
Let's take a closer look at the \c initializeGL function. It is called by
Canvas3D once the render node is ready.
First of all, we need to get a Context3D from our Canvas3D. We want
......@@ -98,7 +98,7 @@
\snippet canvas3d/textureandlight/qml/textureandlight/textureandlight.js 2
Next, let's take a look into shader initialization in the
\c initShaders function, which we call in \c{initGL}. First we define
\c initShaders function, which we call in \c{initializeGL}. First we define
the vertex shader:
\snippet canvas3d/textureandlight/qml/textureandlight/textureandlight.js 3
......@@ -125,16 +125,16 @@
Above, first we create the buffer, then bind it and finally insert the
data into it. Other buffers are all handled in a similar fashion.
As the final step in \c{initGL}, we create a texture image from
As the final step in \c{initializeGL}, we create a texture image from
TextureImageFactory, and register handlers for \c imageLoaded and
\c imageLoadingFailed signals. Once the texture image is successfully
loaded, we create the actual texture:
\snippet canvas3d/textureandlight/qml/textureandlight/textureandlight.js 8
\section2 renderGL Function
\section2 paintGL Function
\c renderGL is called by Canvas3D whenever it is ready to receive a new
\c paintGL is called by Canvas3D whenever it is ready to receive a new
frame. Let's go through the steps that are done in each render cycle.
First we check if canvas has been resized or if pixel ratio has changed,
......@@ -142,7 +142,7 @@
\snippet canvas3d/textureandlight/qml/textureandlight/textureandlight.js 9
Then we clear the render area using the clear color set in \c{initGL}:
Then we clear the render area using the clear color set in \c{initializeGL}:
\snippet canvas3d/textureandlight/qml/textureandlight/textureandlight.js 10
......
......@@ -41,11 +41,12 @@ import QtCanvas3D 1.0
import "textureandlight.js" as GLCode
//! [4]
Item {
Rectangle {
id: mainview
width: 1280
height: 768
visible: true
color: "#fafafa"
//! [0]
Canvas3D {
......
......@@ -95,7 +95,7 @@ Item {
id: heading1
text: ""
font.family: "Helvetica"
font.pixelSize: 3.125 * 16
font.pixelSize: 3.0 * 16
font.weight: Font.Light
color: "black"
......@@ -105,7 +105,7 @@ Item {
anchors.left: heading1.right
text: ""
font.family: "Helvetica"
font.pixelSize: 3.125 * 16
font.pixelSize: 3.0 * 16
font.weight: Font.Light
color: "#5caa15"
}
......@@ -121,6 +121,7 @@ Item {
Text {
id: description
text: ""
width: (infoSheet.width - infoSheet.anchors.leftMargin) * 0.3
font.family: "Helvetica"
font.pixelSize: 16
font.weight: Font.Light
......
......@@ -106,13 +106,13 @@ Text {
}
}
MouseArea {
id: mouseArea1
id: mouseArea
anchors.fill: parent
hoverEnabled: true
onPressed: {
menubarItem.state = "mouseover";
}
onReleased: {
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleGetInfoString</key>
<string>Created by Qt/QMake</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleExecutable</key>
<string>oneqt</string>
<key>CFBundleIdentifier</key>
<string>com.theqtcompany.${PRODUCT_NAME:rfc1034identifier}</string>
<key>CFBundleDisplayName</key>
<string>One Qt</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>CFBundleIcons</key>
<dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>OneQtIcon29x29.png</string>
<string>OneQtIcon29x29@2x.png</string>
<string>OneQtIcon40x40@2x.png</string>
<string>OneQtIcon57x57.png</string>
<string>OneQtIcon57x57@2x.png</string>
<string>OneQtIcon60x60@2x.png</string>
</array>
</dict>
</dict>
<key>CFBundleIcons~ipad</key>
<dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string>OneQtIcon29x29.png</string>
<string>OneQtIcon29x29@2x.png</string>
<string>OneQtIcon40x40@2x.png</string>
<string>OneQtIcon57x57.png</string>
<string>OneQtIcon57x57@2x.png</string>
<string>OneQtIcon60x60@2x.png</string>
<string>OneQtIcon29x29~ipad.png</string>
<string>OneQtIcon29x29@2x~ipad.png</string>
<string>OneQtIcon40x40~ipad.png</string>
<string>OneQtIcon40x40@2x~ipad.png</string>
<string>OneQtIcon50x50~ipad.png</string>
<string>OneQtIcon50x50@2x~ipad.png</string>
<string>OneQtIcon72x72~ipad.png</string>
<string>OneQtIcon72x72@2x~ipad.png</string>
<string>OneQtIcon76x76~ipad.png</string>
<string>OneQtIcon76x76@2x~ipad.png</string>
</array>
</dict>
</dict>
</dict>
</plist>