qt 6.5.1 original
BIN
examples/opengl/doc/images/2dpainting-example.png
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
examples/opengl/doc/images/cube.png
Normal file
After Width: | Height: | Size: 40 KiB |
BIN
examples/opengl/doc/images/cube_faces.png
Normal file
After Width: | Height: | Size: 62 KiB |
BIN
examples/opengl/doc/images/hellogl2-example.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
examples/opengl/doc/images/hellogles3-example.png
Normal file
After Width: | Height: | Size: 60 KiB |
BIN
examples/opengl/doc/images/stereoexample-leftbuffer.png
Normal file
After Width: | Height: | Size: 9.8 KiB |
BIN
examples/opengl/doc/images/stereoexample-rightbuffer.png
Normal file
After Width: | Height: | Size: 9.8 KiB |
BIN
examples/opengl/doc/images/textures-example.png
Normal file
After Width: | Height: | Size: 46 KiB |
184
examples/opengl/doc/src/2dpainting.qdoc
Normal file
@ -0,0 +1,184 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
|
||||
|
||||
/*!
|
||||
\example 2dpainting
|
||||
\title 2D Painting Example
|
||||
\ingroup examples-widgets-opengl
|
||||
|
||||
\brief The 2D Painting example shows how QPainter and QOpenGLWidget can be
|
||||
used together to display accelerated 2D graphics on supported hardware.
|
||||
|
||||
\image 2dpainting-example.png
|
||||
|
||||
The QPainter class is used to draw 2D graphics primitives onto
|
||||
paint devices provided by QPaintDevice subclasses, such as QWidget
|
||||
and QImage.
|
||||
|
||||
Since QOpenGLWidget is a subclass of QWidget, it is possible
|
||||
to reimplement its \l{QWidget::paintEvent()}{paintEvent()} and use
|
||||
QPainter to draw on the device, just as you would with a QWidget.
|
||||
The only difference is that the painting operations will be accelerated
|
||||
in hardware if it is supported by your system's OpenGL drivers.
|
||||
|
||||
In this example, we perform the same painting operations on a
|
||||
QWidget and a QOpenGLWidget. The QWidget is shown with anti-aliasing
|
||||
enabled, and the QOpenGLWidget will also use anti-aliasing if the
|
||||
required extensions are supported by your system's OpenGL driver.
|
||||
|
||||
\section1 Overview
|
||||
|
||||
To be able to compare the results of painting onto a QOpenGLWidget subclass
|
||||
with native drawing in a QWidget subclass, we want to show both kinds
|
||||
of widget side by side. To do this, we derive subclasses of QWidget and
|
||||
QOpenGLWidget, using a separate \c Helper class to perform the same painting
|
||||
operations for each, and lay them out in a top-level widget, itself
|
||||
provided a the \c Window class.
|
||||
|
||||
\section1 Helper Class Definition
|
||||
|
||||
In this example, the painting operations are performed by a helper class.
|
||||
We do this because we want the same painting operations to be performed
|
||||
for both our QWidget subclass and the QOpenGLWidget subclass.
|
||||
|
||||
The \c Helper class is minimal:
|
||||
|
||||
\snippet 2dpainting/helper.h 0
|
||||
|
||||
Apart from the constructor, it only provides a \c paint() function to paint
|
||||
using a painter supplied by one of our widget subclasses.
|
||||
|
||||
\section1 Helper Class Implementation
|
||||
|
||||
The constructor of the class sets up the resources it needs to paint
|
||||
content onto a widget:
|
||||
|
||||
\snippet 2dpainting/helper.cpp 0
|
||||
|
||||
The actual painting is performed in the \c paint() function. This takes
|
||||
a QPainter that has already been set up to paint onto a paint device
|
||||
(either a QWidget or a QOpenGLWidget), a QPaintEvent that provides information
|
||||
about the region to be painted, and a measure of the elapsed time (in
|
||||
milliseconds) since the paint device was last updated.
|
||||
|
||||
\snippet 2dpainting/helper.cpp 1
|
||||
|
||||
We begin painting by filling in the region contained in the paint event
|
||||
before translating the origin of the coordinate system so that the rest
|
||||
of the painting operations will be displaced towards the center of the
|
||||
paint device.
|
||||
|
||||
We draw a spiral pattern of circles, using the elapsed time specified to
|
||||
animate them so that they appear to move outward and around the coordinate
|
||||
system's origin:
|
||||
|
||||
\snippet 2dpainting/helper.cpp 2
|
||||
|
||||
Since the coordinate system is rotated many times during
|
||||
this process, we \l{QPainter::save()}{save()} the QPainter's state
|
||||
beforehand and \l{QPainter::restore()}{restore()} it afterwards.
|
||||
|
||||
\snippet 2dpainting/helper.cpp 3
|
||||
|
||||
We draw some text at the origin to complete the effect.
|
||||
|
||||
\section1 Widget Class Definition
|
||||
|
||||
The \c Widget class provides a basic custom widget that we use to
|
||||
display the simple animation painted by the \c Helper class.
|
||||
|
||||
\snippet 2dpainting/widget.h 0
|
||||
|
||||
Apart from the constructor, it only contains a
|
||||
\l{QWidget::paintEvent()}{paintEvent()} function, that lets us draw
|
||||
customized content, and a slot that is used to animate its contents.
|
||||
One member variable keeps track of the \c Helper that the widget uses
|
||||
to paint its contents, and the other records the elapsed time since
|
||||
it was last updated.
|
||||
|
||||
\section1 Widget Class Implementation
|
||||
|
||||
The constructor only initializes the member variables, storing the
|
||||
\c Helper object supplied and calling the base class's constructor,
|
||||
and enforces a fixed size for the widget:
|
||||
|
||||
\snippet 2dpainting/widget.cpp 0
|
||||
|
||||
The \c animate() slot is called whenever a timer, which we define later, times
|
||||
out:
|
||||
|
||||
\snippet 2dpainting/widget.cpp 1
|
||||
|
||||
Here, we determine the interval that has elapsed since the timer last
|
||||
timed out, and we add it to any existing value before repainting the
|
||||
widget. Since the animation used in the \c Helper class loops every second,
|
||||
we can use the modulo operator to ensure that the \c elapsed variable is
|
||||
always less than 1000.
|
||||
|
||||
Since the \c Helper class does all of the actual painting, we only have
|
||||
to implement a paint event that sets up a QPainter for the widget and calls
|
||||
the helper's \c paint() function:
|
||||
|
||||
\snippet 2dpainting/widget.cpp 2
|
||||
|
||||
\section1 GLWidget Class Definition
|
||||
|
||||
The \c GLWidget class definition is basically the same as the \c Widget
|
||||
class except that it is derived from QOpenGLWidget.
|
||||
|
||||
\snippet 2dpainting/glwidget.h 0
|
||||
|
||||
Again, the member variables record the \c Helper used to paint the
|
||||
widget and the elapsed time since the previous update.
|
||||
|
||||
\section1 GLWidget Class Implementation
|
||||
|
||||
The constructor differs a little from the \c Widget class's constructor:
|
||||
|
||||
\snippet 2dpainting/glwidget.cpp 0
|
||||
|
||||
The \c elapsed member variable is initialized and the \c Helper object used
|
||||
to paint the widget is stored.
|
||||
|
||||
The \c animate() slot is exactly the same as that provided by the \c Widget
|
||||
class:
|
||||
|
||||
\snippet 2dpainting/glwidget.cpp 1
|
||||
|
||||
The \c paintEvent() is almost the same as that found in the \c Widget class:
|
||||
|
||||
\snippet 2dpainting/glwidget.cpp 2
|
||||
|
||||
Since anti-aliasing will be enabled if available, we only need to set up
|
||||
a QPainter on the widget and call the helper's \c paint() function to display
|
||||
the widget's contents.
|
||||
|
||||
\section1 Window Class Definition
|
||||
|
||||
The \c Window class has a basic, minimal definition:
|
||||
|
||||
\snippet 2dpainting/window.h 0
|
||||
|
||||
It contains a single \c Helper object that will be shared between all
|
||||
widgets.
|
||||
|
||||
\section1 Window Class Implementation
|
||||
|
||||
The constructor does all the work, creating a widget of each type and
|
||||
inserting them with labels into a layout:
|
||||
|
||||
\snippet 2dpainting/window.cpp 0
|
||||
|
||||
A timer with a 50 millisecond time out is constructed for animation purposes,
|
||||
and connected to the \c animate() slots of the \c Widget and \c GLWidget objects.
|
||||
Once started, the widgets should be updated at around 20 frames per second.
|
||||
|
||||
\section1 Running the Example
|
||||
|
||||
The example shows the same painting operations performed at the same time
|
||||
in a \c Widget and a \c GLWidget. The quality and speed of rendering in the
|
||||
\c GLWidget depends on the level of support for multisampling and hardware
|
||||
acceleration that your system's OpenGL driver provides. If support for either
|
||||
of these is lacking, the driver may fall back on a software renderer that
|
||||
may trade quality for speed.
|
||||
*/
|
142
examples/opengl/doc/src/cube.qdoc
Normal file
@ -0,0 +1,142 @@
|
||||
// Copyright (C) 2020 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
|
||||
|
||||
/*!
|
||||
\example cube
|
||||
\ingroup examples-widgets-opengl
|
||||
\title Cube OpenGL ES 2.0 example
|
||||
|
||||
\brief The Cube OpenGL ES 2.0 example shows how to write mouse rotatable
|
||||
textured 3D cube using OpenGL ES 2.0 with Qt. It shows how to handle
|
||||
polygon geometries efficiently and how to write simple vertex and
|
||||
fragment shader for programmable graphics pipeline. In addition it
|
||||
shows how to use quaternions for representing 3D object orientation.
|
||||
|
||||
This example has been written for OpenGL ES 2.0 but it works also on
|
||||
desktop OpenGL because this example is simple enough and for the
|
||||
most parts desktop OpenGL API is same. It compiles also without OpenGL
|
||||
support but then it just shows a label stating that OpenGL support is
|
||||
required.
|
||||
|
||||
\image cube.png Screenshot of the Cube example running on N900
|
||||
|
||||
The example consist of two classes:
|
||||
|
||||
\list
|
||||
\li \c MainWidget extends QOpenGLWidget and contains OpenGL ES 2.0
|
||||
initialization and drawing and mouse and timer event handling
|
||||
\li \c GeometryEngine handles polygon geometries. Transfers polygon geometry
|
||||
to vertex buffer objects and draws geometries from vertex buffer objects.
|
||||
\endlist
|
||||
|
||||
We'll start by initializing OpenGL ES 2.0 in \c MainWidget.
|
||||
|
||||
\tableofcontents
|
||||
|
||||
\section1 Initializing OpenGL ES 2.0
|
||||
|
||||
Since OpenGL ES 2.0 doesn't support fixed graphics pipeline anymore it has to
|
||||
be implemented by ourselves. This makes graphics pipeline very flexible but
|
||||
in the same time it becomes more difficult because user has to implement graphics
|
||||
pipeline to get even the simplest example running. It also makes graphics pipeline
|
||||
more efficient because user can decide what kind of pipeline is needed for the
|
||||
application.
|
||||
|
||||
First we have to implement vertex shader. It gets vertex data and
|
||||
model-view-projection matrix (MVP) as parameters. It transforms vertex position
|
||||
using MVP matrix to screen space and passes texture coordinate to
|
||||
fragment shader. Texture coordinate will be automatically interpolated on polygon
|
||||
faces.
|
||||
|
||||
\snippet cube/vshader.glsl 0
|
||||
|
||||
After that we need to implement second part of the graphics pipeline - fragment
|
||||
shader. For this exercise we need to implement fragment shader that handles
|
||||
texturing. It gets interpolated texture coordinate as a parameter and looks up
|
||||
fragment color from the given texture.
|
||||
|
||||
\snippet cube/fshader.glsl 0
|
||||
|
||||
Using QOpenGLShaderProgram we can compile, link and bind shader code to
|
||||
graphics pipeline. This code uses Qt Resource files to access shader source code.
|
||||
|
||||
\snippet cube/mainwidget.cpp 3
|
||||
|
||||
The following code enables depth buffering and back face culling.
|
||||
|
||||
\snippet cube/mainwidget.cpp 2
|
||||
|
||||
\section1 Loading Textures from Qt Resource Files
|
||||
|
||||
The \c QOpenGLWidget interface implements methods for loading textures from QImage
|
||||
to OpenGL texture memory. We still need to use OpenGL provided functions for
|
||||
specifying the OpenGL texture unit and configuring texture filtering options.
|
||||
|
||||
\snippet cube/mainwidget.cpp 4
|
||||
|
||||
\section1 Cube Geometry
|
||||
|
||||
There are many ways to render polygons in OpenGL but the most efficient way is
|
||||
to use only triangle strip primitives and render vertices from graphics hardware
|
||||
memory. OpenGL has a mechanism to create buffer objects to this memory area and
|
||||
transfer vertex data to these buffers. In OpenGL terminology these are referred
|
||||
as Vertex Buffer Objects (VBO).
|
||||
|
||||
\image cube_faces.png Cube faces and vertices
|
||||
|
||||
This is how cube faces break down to triangles. Vertices are ordered this way
|
||||
to get vertex ordering correct using triangle strips. OpenGL determines triangle
|
||||
front and back face based on vertex ordering. By default OpenGL uses
|
||||
counter-clockwise order for front faces. This information is used by back face
|
||||
culling which improves rendering performance by not rendering back faces of the
|
||||
triangles. This way graphics pipeline can omit rendering sides of the triangle that
|
||||
aren't facing towards screen.
|
||||
|
||||
Creating vertex buffer objects and transferring data to them is quite simple using
|
||||
QOpenGLBuffer. MainWidget makes sure the GeometryEngine instance is created and
|
||||
destroyed with the OpenGL context current. This way we can use OpenGL resources
|
||||
in the constructor and perform proper cleanup in the destructor.
|
||||
|
||||
\snippet cube/geometryengine.cpp 0
|
||||
|
||||
\snippet cube/geometryengine.cpp 1
|
||||
|
||||
Drawing primitives from VBOs and telling programmable graphics pipeline how to
|
||||
locate vertex data requires few steps. First we need to bind VBOs to be used.
|
||||
After that we bind shader program attribute names and configure what
|
||||
kind of data it has in the bound VBO. Finally we'll draw triangle
|
||||
strip primitives using indices from the other VBO.
|
||||
|
||||
\snippet cube/geometryengine.cpp 2
|
||||
|
||||
\section1 Perspective Projection
|
||||
|
||||
Using \c QMatrix4x4 helper methods it's really easy to calculate perpective
|
||||
projection matrix. This matrix is used to project vertices to screen space.
|
||||
|
||||
\snippet cube/mainwidget.cpp 5
|
||||
|
||||
\section1 Orientation of the 3D Object
|
||||
|
||||
Quaternions are handy way to represent orientation of the 3D object. Quaternions
|
||||
involve quite complex mathematics but fortunately all the necessary mathematics
|
||||
behind quaternions is implemented in \c QQuaternion. That allows us to store
|
||||
cube orientation in quaternion and rotating cube around given axis is quite
|
||||
simple.
|
||||
|
||||
The following code calculates rotation axis and angular speed based on mouse events.
|
||||
|
||||
\snippet cube/mainwidget.cpp 0
|
||||
|
||||
\c QBasicTimer is used to animate scene and update cube orientation. Rotations
|
||||
can be concatenated simply by multiplying quaternions.
|
||||
|
||||
\snippet cube/mainwidget.cpp 1
|
||||
|
||||
Model-view matrix is calculated using the quaternion and by moving world by Z axis.
|
||||
This matrix is multiplied with the projection matrix to get MVP matrix for shader
|
||||
program.
|
||||
|
||||
\snippet cube/mainwidget.cpp 6
|
||||
|
||||
*/
|
19
examples/opengl/doc/src/hellogl2.qdoc
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
|
||||
|
||||
/*!
|
||||
\example hellogl2
|
||||
\title Hello GL2 Example
|
||||
\ingroup examples-widgets-opengl
|
||||
|
||||
\brief The Hello GL2 example demonstrates the basic use of the OpenGL-related classes
|
||||
provided with Qt.
|
||||
|
||||
\image hellogl2-example.png
|
||||
|
||||
Qt provides the QOpenGLWidget class to enable OpenGL graphics to be rendered
|
||||
within a standard application user interface. By subclassing this class, and
|
||||
providing reimplementations of event handler functions, 3D scenes can be
|
||||
displayed on widgets that can be placed in layouts, connected to other
|
||||
objects using signals and slots, and manipulated like any other widget.
|
||||
*/
|
28
examples/opengl/doc/src/hellogles3.qdoc
Normal file
@ -0,0 +1,28 @@
|
||||
// Copyright (C) 2018 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
|
||||
|
||||
/*!
|
||||
\example hellogles3
|
||||
\title Hello GLES3 Example
|
||||
\ingroup examples-widgets-opengl
|
||||
|
||||
\brief The Hello GLES3 example demonstrates easy, cross-platform usage of
|
||||
OpenGL ES 3.0 functions via QOpenGLExtraFunctions in an application that
|
||||
works identically on desktop platforms with OpenGL 3.3 and mobile/embedded
|
||||
devices with OpenGL ES 3.0.
|
||||
|
||||
The code is always the same, with the exception of two places:
|
||||
\list
|
||||
\li The OpenGL context creation has to have a sufficiently high version
|
||||
number for the features that are in use.
|
||||
\li The shader code's version directive is different.
|
||||
\endlist
|
||||
|
||||
This example has no QWidget dependencies. Instead, it uses QOpenGLWindow, a
|
||||
convenience subclass of QWindow that allows easy implementation of windows
|
||||
that contain OpenGL-rendered content. In this sense it complements the
|
||||
\l{OpenGL Window Example}, which shows the implementation of an OpenGL-based
|
||||
QWindow without using the convenience subclass.
|
||||
|
||||
\image hellogles3-example.png
|
||||
*/
|
136
examples/opengl/doc/src/openglwindow.qdoc
Normal file
@ -0,0 +1,136 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
|
||||
|
||||
/*!
|
||||
\example openglwindow
|
||||
\title OpenGL Window Example
|
||||
|
||||
\brief This example shows how to create a minimal QWindow based application
|
||||
for the purpose of using OpenGL.
|
||||
|
||||
\image openglwindow-example.png Screenshot of the OpenGLWindow example
|
||||
|
||||
\note This is a low level example of how to use QWindow with OpenGL.
|
||||
In practice you should consider using the higher level QOpenGLWindow class.
|
||||
See the \l{Hello GLES3 Example} for a demonstration of the QOpenGLWindow
|
||||
convenience class.
|
||||
|
||||
\section1 OpenGLWindow Super Class
|
||||
|
||||
Our OpenGLWindow class acts as an API which is then subclassed to do the
|
||||
actual rendering. It has functions to make a request for render() to be
|
||||
called, either immediately with renderNow() or as soon as the event loop
|
||||
has finished processing the current batch of events with renderLater().
|
||||
The OpenGLWindow subclass can either reimplement render() for OpenGL based
|
||||
rendering, or render(QPainter *) for rendering with a QPainter. Use
|
||||
OpenGLWindow::setAnimating(true) for render() to be called at the vertical
|
||||
refresh rate, assuming vertical sync is enabled in the underlying OpenGL
|
||||
drivers.
|
||||
|
||||
In the class that does the OpenGL rendering you will typically want to
|
||||
inherit from QOpenGLFunctions, as our OpenGLWindow does, in order to get
|
||||
platform independent access to OpenGL ES 2.0 functions. By inheriting from
|
||||
QOpenGLFunctions the OpenGL functions it contains will get precedence, and
|
||||
you will not have to worry about resolving those functions if you want your
|
||||
application to work with OpenGL as well as OpenGL ES 2.0.
|
||||
|
||||
\snippet openglwindow/openglwindow.h 1
|
||||
|
||||
The window's surface type must be set to QSurface::OpenGLSurface to
|
||||
indicate that the window is to be used for OpenGL rendering and not for
|
||||
rendering raster content with QPainter using a QBackingStore.
|
||||
|
||||
\snippet openglwindow/openglwindow.cpp 1
|
||||
|
||||
Any OpenGL initialization needed can be done by overriding the initialize()
|
||||
function, which is called once before the first call to render(), with a
|
||||
valid current QOpenGLContext. As can be seen in the following code snippet,
|
||||
the default render(QPainter *) and initialize() implementations are empty,
|
||||
whereas the default render() implementation initializes a
|
||||
QOpenGLPaintDevice and then calls into render(QPainter *).
|
||||
|
||||
\snippet openglwindow/openglwindow.cpp 2
|
||||
|
||||
The renderLater() function simply calls QWindow::requestUpdate() to schedule
|
||||
an update for when the system is ready to repaint.
|
||||
|
||||
We also call renderNow() when we get an expose event. The exposeEvent() is
|
||||
the notification to the window that its exposure, meaning visibility, on
|
||||
the screen has changed. When the expose event is received you can query
|
||||
QWindow::isExposed() to find out whether or not the window is currently
|
||||
exposed. Do not render to or call QOpenGLContext::swapBuffers() on a window
|
||||
before it has received its first expose event, as before then its final
|
||||
size might be unknown, and in addition what is rendered might not even end
|
||||
up on the screen.
|
||||
|
||||
\snippet openglwindow/openglwindow.cpp 3
|
||||
|
||||
In renderNow() we return if we are not currently exposed, in which case
|
||||
rendering is delayed until we actually get an expose event. If we have not
|
||||
yet done so, we create the QOpenGLContext with the same QSurfaceFormat as
|
||||
was set on the OpenGLWindow, and call initialize() for the sake of the sub
|
||||
class, and initializeOpenGLFunctions() in order for the QOpenGLFunctions
|
||||
super class to be associated with the correct QOpenGLContext. In any case
|
||||
we make the context current by calling QOpenGLContext::makeCurrent(), call
|
||||
render() to do the actual rendering, and finally we schedule for the
|
||||
rendered contents to be made visible by calling
|
||||
QOpenGLContext::swapBuffers() with the OpenGLWindow as parameter.
|
||||
|
||||
Once the rendering of a frame using an OpenGL context is initiated by
|
||||
calling QOpenGLContext::makeCurrent(), giving the surface on which to
|
||||
render as a parameter, OpenGL commands can be issued. The commands can be
|
||||
issued either directly by including <qopengl.h>, which also includes the
|
||||
system's OpenGL headers, or as by using QOpenGLFunctions, which can
|
||||
either be inherited from for convenience, or accessed using
|
||||
QOpenGLContext::functions(). QOpenGLFunctions gives access to all the
|
||||
OpenGL ES 2.0 level OpenGL calls that are not already standard in both
|
||||
OpenGL ES 2.0 and desktop OpenGL. For more information about the OpenGL and
|
||||
OpenGL ES APIs, refer to the official \l{http://www.opengl.org/registry/}{OpenGL Registry} and
|
||||
\l {http://www.khronos.org/registry/gles/}{Khronos OpenGL ES API Registry}.
|
||||
|
||||
If animation has been enabled with OpenGLWindow::setAnimating(true), we
|
||||
call renderLater() to schedule another update request.
|
||||
|
||||
\snippet openglwindow/openglwindow.cpp 4
|
||||
|
||||
Enabling animation also schedules an update request as shown in the
|
||||
following code snippet.
|
||||
|
||||
\snippet openglwindow/openglwindow.cpp 5
|
||||
|
||||
\section1 Example OpenGL Rendering Sub Class
|
||||
|
||||
Here we sub class OpenGLWindow to show how to do OpenGL to render a
|
||||
rotating triangle. By indirectly sub classing QOpenGLFunctions we gain
|
||||
access to all OpenGL ES 2.0 level functionality.
|
||||
|
||||
\snippet openglwindow/main.cpp 1
|
||||
|
||||
In our main function we initialize QGuiApplication and instantiate our
|
||||
TriangleOpenGLWindow. We give it a QSurfaceFormat specifying that we want
|
||||
four samples of multisample antialiasing, as well as a default geometry.
|
||||
Since we want to have animation we call the above mentioned setAnimating()
|
||||
function with an argument of true.
|
||||
|
||||
\snippet openglwindow/main.cpp 2
|
||||
|
||||
The following code snippet shows the OpenGL shader program used in this
|
||||
example. The vertex and fragment shaders are relatively simple, doing
|
||||
vertex transformation and interpolated vertex coloring.
|
||||
|
||||
\snippet openglwindow/main.cpp 3
|
||||
|
||||
Here is the code that loads the shaders and initializes the shader program
|
||||
By using QOpenGLShaderProgram instead of raw OpenGL we get the convenience
|
||||
that strips out the highp, mediump, and lowp qualifiers on desktop OpenGL,
|
||||
where they are not part of the standard. We store the attribute and uniform
|
||||
locations in member variables to avoid having to do the location lookup
|
||||
each frame.
|
||||
|
||||
\snippet openglwindow/main.cpp 4
|
||||
|
||||
Finally, here is our render() function, where we use OpenGL to set up the
|
||||
viewport, clear the background, and render a rotating triangle.
|
||||
|
||||
\snippet openglwindow/main.cpp 5
|
||||
*/
|
41
examples/opengl/doc/src/stereoqopenglwidget.qdoc
Normal file
@ -0,0 +1,41 @@
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
|
||||
|
||||
/*!
|
||||
\example stereoqopenglwidget
|
||||
\title QOpenGLWidget Stereoscopic Rendering Example
|
||||
|
||||
\brief This example shows how to create a minimal QOpenGLWidget based application
|
||||
with stereoscopic rendering support.
|
||||
|
||||
\image stereoexample-leftbuffer.png
|
||||
|
||||
The above image is what will be rendered to the left buffer.
|
||||
|
||||
\image stereoexample-rightbuffer.png
|
||||
|
||||
The above image is what will be rendered to the right buffer.
|
||||
|
||||
\note Support for stereoscopic rendering has certain hardware requirements, like
|
||||
your graphics card needs stereo support.
|
||||
|
||||
\section1 Setting the correct surface flag
|
||||
To enable stereoscopic rendering you need to set the flag
|
||||
QSurfaceFormat::StereoBuffers globally. Just doing it on the widget is not enough
|
||||
because of how the flag is handled internally. The safest is to do it on
|
||||
QSurfaceFormat::SetDefaultFormat prior to starting the application.
|
||||
|
||||
\snippet stereoqopenglwidget/main.cpp 1
|
||||
|
||||
\section1 Rendering twice
|
||||
After QSurfaceFormat::StereoBuffers is set, then paintGL() will be called twice,
|
||||
once for each buffer. In paintGL() you can call currentTargetBuffer() to query
|
||||
which TargetBuffer is currently active.
|
||||
|
||||
In the following snippet we slightly translate the matrix to not render the
|
||||
vertices on top of each other. This is a simple example just too see that if the
|
||||
necessary support is there, at runtime you should see two objects, one on the left
|
||||
and one on the right.
|
||||
|
||||
\snippet stereoqopenglwidget/glwidget.cpp 1
|
||||
*/
|
13
examples/opengl/doc/src/textures.qdoc
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
|
||||
|
||||
/*!
|
||||
\example textures
|
||||
\title Textures Example
|
||||
\ingroup examples-widgets-opengl
|
||||
|
||||
\brief The Textures example demonstrates the use of Qt's image classes as textures in
|
||||
applications that use both OpenGL and Qt to display graphics.
|
||||
|
||||
\image textures-example.png
|
||||
*/
|