/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCanvas3D module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** 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 https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of The Qt Company Ltd nor the names of its
**     contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/

/*!
    \example textureandlight
    \since QtCanvas3D 1.0
    \title Lit and Textured Cube Example
    \ingroup qtcanvas3d-examples
    \brief A simple cube with texturing and lighting.

    The Lit and Textured Cube example goes through the basics of using
    Qt Canvas 3D.

    \image textureandlight-example.png

    \section1 Qt Quick Implementation

    \section2 Creating Canvas3D

    In \l{textureandlight/qml/textureandlight/main.qml}{main.qml}, we add a
    Canvas3D under the root \c Item:

    \snippet textureandlight/qml/textureandlight/main.qml 0
    \dots

    Inside it, we catch the \c initializeGL and \c paintGL signals to forward the
    initialization and rendering calls to the js object:

    \snippet textureandlight/qml/textureandlight/main.qml 1

    \section2 Importing the JavaScript File

    We import the JavaScript file in the QML:

    \snippet textureandlight/qml/textureandlight/main.qml 4

    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.

    \section1 JavaScript Implementation

    \section2 Matrix Library

    In \l {textureandlight/qml/textureandlight/textureandlight.js}
    {textureandlight.js}, we first include a fast matrix library. Using this
    makes it a lot easier to handle 3D math operations such as matrix
    transformations:

    \snippet textureandlight/qml/textureandlight/textureandlight.js 0

    \section2 initializeGL Function

    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
    a context that supports depth buffer and antialising:

    \snippet textureandlight/qml/textureandlight/textureandlight.js 1

    Then we initialize the OpenGL state for the context:

    \snippet 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{initializeGL}. First we define
    the vertex shader:

    \snippet textureandlight/qml/textureandlight/textureandlight.js 3

    We follow that up by defining a fragment shader:

    \snippet textureandlight/qml/textureandlight/textureandlight.js 4

    Then we need to create the shader program (Canvas3DProgram), attach the shaders
    to it, and then link and use the program:

    \snippet textureandlight/qml/textureandlight/textureandlight.js 5

    And finally, look up and store the vertex attributes and uniform locations:

    \snippet textureandlight/qml/textureandlight/textureandlight.js 6

    After initializing the shader program, we set up the vertex buffer in
    \c initBuffers function. Let's look at the vertex index buffer creation
    as an example:

    \snippet textureandlight/qml/textureandlight/textureandlight.js 7

    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{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 textureandlight/qml/textureandlight/textureandlight.js 8

    \section2 paintGL Function

    \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,
    and update the projection matrix if necessary:

    \snippet textureandlight/qml/textureandlight/textureandlight.js 9

    Then we clear the render area using the clear color set in \c{initializeGL}:

    \snippet textureandlight/qml/textureandlight/textureandlight.js 10

    Next we reset the model view matrix and apply translation and rotations:

    \snippet textureandlight/qml/textureandlight/textureandlight.js 11

    As we have a lit cube, we invert and transpose the model view matrix to
    be used for lighting calculations:

    \snippet textureandlight/qml/textureandlight/textureandlight.js 12

    And finally we draw the cube:

    \snippet textureandlight/qml/textureandlight/textureandlight.js 13

    \section1 Logging

    Qt Canvas 3D uses Qt's categorized logging feature. This example enables
    all Qt Canvas 3D log output with the code shown below. For more on
    Canvas3D's logging features refer to \l {Qt Canvas 3D Logging}.

    \snippet textureandlight/main.cpp 0
*/
