Merge branch 'quick_ui'
1
.gitignore
vendored
|
@ -22,3 +22,4 @@ ui_*.h
|
|||
/paysages3d-linux/
|
||||
/paysages3d-linux.tar.bz2
|
||||
/config.vim
|
||||
/callgrind.out.*
|
||||
|
|
3
Makefile
|
@ -45,6 +45,9 @@ endif
|
|||
run_cli:build
|
||||
LD_LIBRARY_PATH=$(LIBRARY_PATH) ${RUNNER} ${BUILDPATH}/interface/commandline/paysages-cli $(ARGS)
|
||||
|
||||
run_modeler:build
|
||||
LD_LIBRARY_PATH=$(LIBRARY_PATH) ${RUNNER} ${BUILDPATH}/interface/modeler/quickapp/paysages-modeler $(ARGS)
|
||||
|
||||
run:build
|
||||
LD_LIBRARY_PATH=$(LIBRARY_PATH) ${RUNNER} ${BUILDPATH}/interface/desktop/paysages-gui $(ARGS)
|
||||
|
||||
|
|
BIN
graphics/icons.png
Normal file
After Width: | Height: | Size: 43 KiB |
196
graphics/icons.svg
Normal file
|
@ -0,0 +1,196 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="210mm"
|
||||
height="297mm"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="icons.svg"
|
||||
inkscape:export-filename="/home/michael/workspace/paysages3d/graphics/icons.png"
|
||||
inkscape:export-xdpi="154.89854"
|
||||
inkscape:export-ydpi="154.89854">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.979899"
|
||||
inkscape:cx="468.77289"
|
||||
inkscape:cy="831.55692"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="g3986"
|
||||
showgrid="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1030"
|
||||
inkscape:window-x="1440"
|
||||
inkscape:window-y="25"
|
||||
inkscape:window-maximized="1"
|
||||
showguides="true"
|
||||
inkscape:snap-object-midpoints="false">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid3004" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Calque 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<path
|
||||
style="fill:#000000;stroke:#000000;stroke-width:3.7;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
d="m 55,32.362183 c -10,35 -25,40 -25,50 0,10 5.355339,25.254827 23.790623,25.254827 C 72.225907,107.61701 80,92.362183 80,82.362183 c 0,-10 -15,-15 -25,-50 z"
|
||||
id="path3006"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="czzzc" />
|
||||
<path
|
||||
style="fill:#ffffff;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 46.711902,68.575386 c -4.70494,1.249464 -15,15 -10,15 5,0 10,5 10,5 -1.6011,-6.345755 4.41534,-10.613999 10,-15 0,0 -5.29506,-6.249464 -10,-5 z"
|
||||
id="path3776"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="zzccz" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:4.319;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 140.61815,83.142861 c 0,0 10.6138,-9.86109 20.06933,-9.708785 17.76848,0.286206 17.35284,19.13136 35.12131,19.417571 18.91107,0.304603 21.21711,-19.417571 40.13865,-19.417571 18.92154,0 21.2171,19.417571 40.13864,19.417571 9.46077,0 20.06933,-9.708786 20.06933,-9.708786"
|
||||
id="path3780"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="caaaac" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:4.319;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 153.97268,88.56225 c 0,0 10.6138,-9.861089 20.06933,-9.708784 17.76847,0.286206 17.35284,19.13136 35.12131,19.417571 18.91106,0.304603 21.21711,-19.417571 40.13865,-19.417571 18.92153,0 21.2171,19.417571 40.13864,19.417571 9.46077,0 20.06933,-9.708787 20.06933,-9.708787"
|
||||
id="path3780-5"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="caaaac" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:4.319;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 167.88393,94.110016 c 0,0 10.6138,-9.86109 20.06933,-9.708785 17.76847,0.286206 17.35284,19.131359 35.12131,19.417569 18.91106,0.30461 21.21711,-19.417569 40.13865,-19.417569 18.92153,0 21.2171,19.417569 40.13864,19.417569 9.46077,0 20.06933,-9.708784 20.06933,-9.708784"
|
||||
id="path3780-3"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="caaaac" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:3.58400011;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 185.73773,125.20138 0,-77.092101 -25.69737,0 38.54605,-32.121711 38.54605,32.121711 -25.69736,0 0,77.092101 25.69736,0 -38.54605,32.12171 -38.54605,-32.12171 z"
|
||||
id="path3807"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccccccc" />
|
||||
<g
|
||||
id="g3986">
|
||||
<g
|
||||
id="g3969">
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:3.58400011;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
id="path3819"
|
||||
sodipodi:cx="70"
|
||||
sodipodi:cy="187.36218"
|
||||
sodipodi:rx="35"
|
||||
sodipodi:ry="35"
|
||||
d="m 105,187.36218 c 0,19.32997 -15.670034,35 -35,35 -19.329966,0 -35,-15.67003 -35,-35 0,-19.32996 15.670034,-35 35,-35 19.329966,0 35,15.67004 35,35 z"
|
||||
transform="translate(5.3571428,58.571429)" />
|
||||
<g
|
||||
id="g3961">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3821"
|
||||
d="m 75,182.36218 0,20"
|
||||
style="fill:none;stroke:#000000;stroke-width:6.4000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3821-7"
|
||||
d="m 75,290.21932 0,20"
|
||||
style="fill:none;stroke:#000000;stroke-width:6.4000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:6.4000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 19.636234,214.32646 17.320508,10"
|
||||
id="path3862"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:6.4000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 113.04326,268.25503 17.32051,10"
|
||||
id="path3864"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3866"
|
||||
d="m 19.636235,278.25503 17.320508,-10"
|
||||
style="fill:none;stroke:#000000;stroke-width:6.4000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3868"
|
||||
d="m 113.04326,224.32646 17.32051,-10"
|
||||
style="fill:none;stroke:#000000;stroke-width:6.4000001;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="g3979">
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:7.0999999;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:14.2, 28.4;stroke-dashoffset:0"
|
||||
d="m 194.28571,244.50504 -85,125"
|
||||
id="path3884"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:7.0999999;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:14.2, 28.4;stroke-dashoffset:0"
|
||||
d="m 212.82124,240.1624 -85,125"
|
||||
id="path3884-5"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:7.0999999;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:14.2, 28.4;stroke-dashoffset:0"
|
||||
d="m 213.12327,258.90099 -85,125"
|
||||
id="path3884-2"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:7.0999999;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:14.2, 28.4;stroke-dashoffset:0"
|
||||
d="m 236.40754,248.54565 -85,125"
|
||||
id="path3884-9"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:7.0999999;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:14.2, 28.4;stroke-dashoffset:0"
|
||||
d="m 241.60804,265.97206 -85,125"
|
||||
id="path3884-7"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
xlink:href="#g3969"
|
||||
id="use4014"
|
||||
transform="translate(329.54824,-14.835395)"
|
||||
width="744.09448"
|
||||
height="1052.3622" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:7.0999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
|
||||
d="m 589.06344,183.95535 c -3.46775,0 -6.83723,0.35694 -10.09375,1.0625 21.37557,4.63457 37.40625,23.67418 37.40625,46.4375 0,22.76332 -16.03068,41.77168 -37.40625,46.40625 3.25652,0.70556 6.626,1.09375 10.09375,1.09375 26.23353,0 47.5,-21.26647 47.5,-47.5 0,-26.23353 -21.26647,-47.5 -47.5,-47.5 z"
|
||||
id="path4016"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:5.1;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:10.2,10.2;stroke-dashoffset:0"
|
||||
d="m 440,292.36218 65,95 70,-95"
|
||||
id="path4025"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 9.9 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
|
@ -105,6 +105,22 @@ void AtmosphereDefinition::validate()
|
|||
_daytime = (double)hour / 24.0 + (double)minute / 1440.0;
|
||||
}
|
||||
|
||||
void AtmosphereDefinition::setDaytime(double value)
|
||||
{
|
||||
if (value >= 0.0)
|
||||
{
|
||||
value = fmod(value, 1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = 1.0 - fmod(-value, 1.0);
|
||||
}
|
||||
value *= 1440.0;
|
||||
hour = value / 60.0;
|
||||
minute = value - 60.0 * hour;
|
||||
validate();
|
||||
}
|
||||
|
||||
void AtmosphereDefinition::applyPreset(AtmospherePreset preset)
|
||||
{
|
||||
sun_color.r = 1.0;
|
||||
|
|
|
@ -46,6 +46,11 @@ public:
|
|||
virtual void copy(BaseDefinition* destination) const override;
|
||||
virtual void validate() override;
|
||||
|
||||
/**
|
||||
* Set the daytime from a 0.0-1.0 value.
|
||||
*/
|
||||
void setDaytime(double value);
|
||||
|
||||
void applyPreset(AtmospherePreset preset);
|
||||
void generateStars(int count);
|
||||
|
||||
|
|
|
@ -182,7 +182,7 @@ void Scenery::getWater(WaterDefinition* water)
|
|||
void Scenery::checkCameraAboveGround()
|
||||
{
|
||||
Vector3 camera_location = camera->getLocation();
|
||||
double terrain_height = terrain->getInterpolatedHeight(camera_location.x, camera_location.z, 1, 1) + 2.0;
|
||||
double terrain_height = terrain->getInterpolatedHeight(camera_location.x, camera_location.z, true, true) + 2.0;
|
||||
double water_height = 1.5;
|
||||
if (camera_location.y < water_height || camera_location.y < terrain_height)
|
||||
{
|
||||
|
|
|
@ -82,7 +82,7 @@ void TerrainDefinition::load(PackStream* stream)
|
|||
validate();
|
||||
}
|
||||
|
||||
double TerrainDefinition::getGridHeight(int x, int z, int with_painting)
|
||||
double TerrainDefinition::getGridHeight(int x, int z, bool with_painting)
|
||||
{
|
||||
double h;
|
||||
|
||||
|
@ -94,7 +94,7 @@ double TerrainDefinition::getGridHeight(int x, int z, int with_painting)
|
|||
return h;
|
||||
}
|
||||
|
||||
double TerrainDefinition::getInterpolatedHeight(double x, double z, int scaled, int with_painting)
|
||||
double TerrainDefinition::getInterpolatedHeight(double x, double z, bool scaled, bool with_painting)
|
||||
{
|
||||
double h;
|
||||
x /= scaling;
|
||||
|
|
|
@ -27,8 +27,8 @@ public:
|
|||
virtual void copy(BaseDefinition* destination) const override;
|
||||
virtual void validate() override;
|
||||
|
||||
double getGridHeight(int x, int z, int with_painting);
|
||||
double getInterpolatedHeight(double x, double z, int scaled, int with_painting);
|
||||
double getGridHeight(int x, int z, bool with_painting);
|
||||
double getInterpolatedHeight(double x, double z, bool scaled, bool with_painting);
|
||||
unsigned long getMemoryStats();
|
||||
HeightInfo getHeightInfo();
|
||||
|
||||
|
|
|
@ -135,7 +135,7 @@ void PaintingBrush::applyToTerrain(TerrainDefinition* terrain, double x, double
|
|||
case PAINTING_BRUSH_FLATTEN:
|
||||
if (reverse)
|
||||
{
|
||||
_height = terrain->getInterpolatedHeight(x * terrain->scaling, z * terrain->scaling, 0, 1);
|
||||
_height = terrain->getInterpolatedHeight(x * terrain->scaling, z * terrain->scaling, false, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -218,7 +218,7 @@ void WidgetHeightMap::timerEvent(QTimerEvent*)
|
|||
_last_time = new_time;
|
||||
|
||||
// Update top camera
|
||||
Vector3 target = {_target_x, _terrain->getInterpolatedHeight(_target_x, _target_z, 1, 1), _target_z};
|
||||
Vector3 target = {_target_x, _terrain->getInterpolatedHeight(_target_x, _target_z, true, true), _target_z};
|
||||
_top_camera->setLocationCoords(target.x, target.y + 1.0, target.z + 0.1);
|
||||
_top_camera->setTarget(target);
|
||||
_top_camera->setZoomToTarget(_zoom);
|
||||
|
|
35
src/interface/modeler/extension/extension.pro
Normal file
|
@ -0,0 +1,35 @@
|
|||
TEMPLATE = lib
|
||||
TARGET = extension
|
||||
QT += qml quick
|
||||
CONFIG += qt plugin
|
||||
|
||||
TARGET = $$qtLibraryTarget($$TARGET)
|
||||
uri = Paysages
|
||||
|
||||
# Input
|
||||
SOURCES += \
|
||||
extension_plugin.cpp \
|
||||
paysages.cpp
|
||||
|
||||
HEADERS += \
|
||||
extension_plugin.h \
|
||||
paysages.h
|
||||
|
||||
OTHER_FILES = qmldir
|
||||
|
||||
!equals(_PRO_FILE_PWD_, $$OUT_PWD) {
|
||||
copy_qmldir.target = $$OUT_PWD/qmldir
|
||||
copy_qmldir.depends = $$_PRO_FILE_PWD_/qmldir
|
||||
copy_qmldir.commands = $(COPY_FILE) \"$$replace(copy_qmldir.depends, /, $$QMAKE_DIR_SEP)\" \"$$replace(copy_qmldir.target, /, $$QMAKE_DIR_SEP)\"
|
||||
QMAKE_EXTRA_TARGETS += copy_qmldir
|
||||
PRE_TARGETDEPS += $$copy_qmldir.target
|
||||
}
|
||||
|
||||
qmldir.files = qmldir
|
||||
unix {
|
||||
installPath = $$[QT_INSTALL_QML]/$$replace(uri, \\., /)
|
||||
qmldir.path = $$installPath
|
||||
target.path = $$installPath
|
||||
INSTALLS += target qmldir
|
||||
}
|
||||
|
12
src/interface/modeler/extension/extension_plugin.cpp
Normal file
|
@ -0,0 +1,12 @@
|
|||
#include "extension_plugin.h"
|
||||
#include "paysages.h"
|
||||
|
||||
#include <qqml.h>
|
||||
|
||||
void ExtensionPlugin::registerTypes(const char *uri)
|
||||
{
|
||||
// @uri Paysages
|
||||
qmlRegisterType<Paysages>(uri, 1, 0, "Paysages");
|
||||
}
|
||||
|
||||
|
16
src/interface/modeler/extension/extension_plugin.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef EXTENSION_PLUGIN_H
|
||||
#define EXTENSION_PLUGIN_H
|
||||
|
||||
#include <QQmlExtensionPlugin>
|
||||
|
||||
class ExtensionPlugin : public QQmlExtensionPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
|
||||
|
||||
public:
|
||||
void registerTypes(const char *uri);
|
||||
};
|
||||
|
||||
#endif // EXTENSION_PLUGIN_H
|
||||
|
16
src/interface/modeler/extension/paysages.cpp
Normal file
|
@ -0,0 +1,16 @@
|
|||
#include "paysages.h"
|
||||
|
||||
Paysages::Paysages(QQuickItem *parent):
|
||||
QQuickItem(parent)
|
||||
{
|
||||
// By default, QQuickItem does not draw anything. If you subclass
|
||||
// QQuickItem to create a visual item, you will need to uncomment the
|
||||
// following line and re-implement updatePaintNode()
|
||||
|
||||
// setFlag(ItemHasContents, true);
|
||||
}
|
||||
|
||||
Paysages::~Paysages()
|
||||
{
|
||||
}
|
||||
|
17
src/interface/modeler/extension/paysages.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#ifndef PAYSAGES_H
|
||||
#define PAYSAGES_H
|
||||
|
||||
#include <QQuickItem>
|
||||
|
||||
class Paysages : public QQuickItem
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_DISABLE_COPY(Paysages)
|
||||
|
||||
public:
|
||||
Paysages(QQuickItem *parent = 0);
|
||||
~Paysages();
|
||||
};
|
||||
|
||||
#endif // PAYSAGES_H
|
||||
|
3
src/interface/modeler/extension/qmldir
Normal file
|
@ -0,0 +1,3 @@
|
|||
module Paysages
|
||||
plugin extension
|
||||
|
5
src/interface/modeler/modeler.pro
Normal file
|
@ -0,0 +1,5 @@
|
|||
TEMPLATE = subdirs
|
||||
|
||||
SUBDIRS = \
|
||||
quickapp \
|
||||
extension
|
26
src/interface/modeler/quickapp/AtmosphereModeler.cpp
Normal file
|
@ -0,0 +1,26 @@
|
|||
#include "AtmosphereModeler.h"
|
||||
|
||||
#include "MainModelerWindow.h"
|
||||
#include "Scenery.h"
|
||||
#include "AtmosphereDefinition.h"
|
||||
#include "OpenGLRenderer.h"
|
||||
#include "OpenGLSkybox.h"
|
||||
|
||||
AtmosphereModeler::AtmosphereModeler(MainModelerWindow *main):
|
||||
main(main)
|
||||
{
|
||||
QObject *item = main->findQmlObject("atmosphere_daytime");
|
||||
if (item)
|
||||
{
|
||||
connect(item, SIGNAL(changed(double)), this, SLOT(daytimeChanged(double)));
|
||||
}
|
||||
}
|
||||
|
||||
void AtmosphereModeler::daytimeChanged(double value)
|
||||
{
|
||||
main->getScenery()->getAtmosphere()->setDaytime(value);
|
||||
|
||||
main->getRenderer()->getScenery()->setAtmosphere(main->getScenery()->getAtmosphere());
|
||||
|
||||
main->getRenderer()->getSkybox()->update();
|
||||
}
|
27
src/interface/modeler/quickapp/AtmosphereModeler.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
#ifndef ATMOSPHEREMODELER_H
|
||||
#define ATMOSPHEREMODELER_H
|
||||
|
||||
#include "modeler_global.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
namespace paysages {
|
||||
namespace modeler {
|
||||
|
||||
class AtmosphereModeler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AtmosphereModeler(MainModelerWindow *main);
|
||||
|
||||
public slots:
|
||||
void daytimeChanged(double value);
|
||||
|
||||
private:
|
||||
MainModelerWindow *main;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // ATMOSPHEREMODELER_H
|
76
src/interface/modeler/quickapp/MainModelerWindow.cpp
Normal file
|
@ -0,0 +1,76 @@
|
|||
#include "MainModelerWindow.h"
|
||||
|
||||
#include "OpenGLView.h"
|
||||
#include "Scenery.h"
|
||||
#include "OpenGLRenderer.h"
|
||||
#include "AtmosphereModeler.h"
|
||||
#include "WaterModeler.h"
|
||||
#include "ModelerCameras.h"
|
||||
#include "RenderPreviewProvider.h"
|
||||
#include "RenderProcess.h"
|
||||
#include "RenderConfig.h"
|
||||
|
||||
#include <QQmlEngine>
|
||||
|
||||
MainModelerWindow::MainModelerWindow()
|
||||
{
|
||||
scenery = new Scenery();
|
||||
scenery->autoPreset();
|
||||
renderer = new OpenGLRenderer(scenery);
|
||||
|
||||
render_preview_provider = new RenderPreviewProvider();
|
||||
render_process = new RenderProcess(render_preview_provider);
|
||||
|
||||
qmlRegisterType<OpenGLView>("Paysages", 1, 0, "OpenGLView");
|
||||
engine()->addImageProvider("renderpreviewprovider", render_preview_provider);
|
||||
|
||||
setMinimumSize(QSize(1000, 800));
|
||||
setTitle(QObject::tr("Paysages 3D"));
|
||||
setResizeMode(QQuickView::SizeRootObjectToView);
|
||||
setSource(QUrl("qrc:///main.qml"));
|
||||
|
||||
cameras = new ModelerCameras(this);
|
||||
atmosphere = new AtmosphereModeler(this);
|
||||
water = new WaterModeler(this);
|
||||
}
|
||||
|
||||
MainModelerWindow::~MainModelerWindow()
|
||||
{
|
||||
delete atmosphere;
|
||||
delete water;
|
||||
delete cameras;
|
||||
|
||||
delete render_preview_provider;
|
||||
delete render_process;
|
||||
|
||||
delete renderer;
|
||||
delete scenery;
|
||||
}
|
||||
|
||||
QObject *MainModelerWindow::findQmlObject(const QString &objectName)
|
||||
{
|
||||
return rootObject()->findChild<QObject *>(objectName);
|
||||
}
|
||||
|
||||
void MainModelerWindow::keyReleaseEvent(QKeyEvent *event)
|
||||
{
|
||||
if (event->key() == Qt::Key_F5)
|
||||
{
|
||||
// Start render in a thread
|
||||
render_process->startRender(scenery, RenderConfig(400, 300, 1, 3));
|
||||
|
||||
// Resize preview
|
||||
QSize preview_size = render_process->getPreviewSize();
|
||||
findQmlObject("preview_image")->setProperty("width", preview_size.width());
|
||||
findQmlObject("preview_image")->setProperty("height", preview_size.height());
|
||||
|
||||
// Show render dialog
|
||||
rootObject()->setProperty("state", QString("Render Dialog"));
|
||||
}
|
||||
else if (event->key() == Qt::Key_Escape)
|
||||
{
|
||||
render_process->stopRender();
|
||||
|
||||
rootObject()->setProperty("state", QString("Init"));
|
||||
}
|
||||
}
|
43
src/interface/modeler/quickapp/MainModelerWindow.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
#ifndef MAINMODELERWINDOW_H
|
||||
#define MAINMODELERWINDOW_H
|
||||
|
||||
#include "modeler_global.h"
|
||||
|
||||
#include <QQuickView>
|
||||
|
||||
namespace paysages {
|
||||
namespace modeler {
|
||||
|
||||
class MainModelerWindow: public QQuickView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MainModelerWindow();
|
||||
virtual ~MainModelerWindow();
|
||||
|
||||
QObject *findQmlObject(const QString& objectName);
|
||||
|
||||
inline Scenery *getScenery() const {return scenery;}
|
||||
inline OpenGLRenderer *getRenderer() const {return renderer;}
|
||||
inline ModelerCameras *getCamera() const {return cameras;}
|
||||
|
||||
protected:
|
||||
virtual void keyReleaseEvent(QKeyEvent *event) override;
|
||||
|
||||
private:
|
||||
OpenGLRenderer *renderer;
|
||||
Scenery *scenery;
|
||||
|
||||
AtmosphereModeler *atmosphere;
|
||||
WaterModeler *water;
|
||||
|
||||
ModelerCameras *cameras;
|
||||
|
||||
RenderPreviewProvider *render_preview_provider;
|
||||
RenderProcess *render_process;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // MAINMODELERWINDOW_H
|
64
src/interface/modeler/quickapp/ModelerCameras.cpp
Normal file
|
@ -0,0 +1,64 @@
|
|||
#include "ModelerCameras.h"
|
||||
|
||||
#include "MainModelerWindow.h"
|
||||
#include "OpenGLRenderer.h"
|
||||
#include "Scenery.h"
|
||||
#include "CameraDefinition.h"
|
||||
|
||||
ModelerCameras::ModelerCameras(MainModelerWindow *parent):
|
||||
QObject(parent), parent(parent)
|
||||
{
|
||||
render = new CameraDefinition();
|
||||
topdown = new CameraDefinition();
|
||||
current = new CameraDefinition();
|
||||
active = render;
|
||||
|
||||
topdown->strafeForward(-10.0);
|
||||
topdown->strafeUp(25.0);
|
||||
topdown->rotatePitch(-0.8);
|
||||
|
||||
// Watch GUI choice
|
||||
QObject *widget = parent->findQmlObject("camera_choice");
|
||||
connect(widget, SIGNAL(stateChanged(QString)), this, SLOT(changeActiveCamera(QString)));
|
||||
|
||||
// Start update timer
|
||||
startTimer(50);
|
||||
}
|
||||
|
||||
ModelerCameras::~ModelerCameras()
|
||||
{
|
||||
delete current;
|
||||
delete render;
|
||||
delete topdown;
|
||||
}
|
||||
|
||||
void ModelerCameras::processZoom(double value)
|
||||
{
|
||||
active->strafeForward(value);
|
||||
}
|
||||
|
||||
void ModelerCameras::processScroll(double xvalue, double yvalue)
|
||||
{
|
||||
active->strafeRight(xvalue);
|
||||
active->strafeUp(yvalue);
|
||||
}
|
||||
|
||||
void ModelerCameras::timerEvent(QTimerEvent *)
|
||||
{
|
||||
OpenGLRenderer *renderer = parent->getRenderer();
|
||||
|
||||
current->transitionToAnother(active, 0.3);
|
||||
renderer->setCamera(current);
|
||||
}
|
||||
|
||||
void ModelerCameras::changeActiveCamera(const QString &name)
|
||||
{
|
||||
if (name == "Render camera")
|
||||
{
|
||||
active = render;
|
||||
}
|
||||
else if (name == "Top-down camera")
|
||||
{
|
||||
active = topdown;
|
||||
}
|
||||
}
|
49
src/interface/modeler/quickapp/ModelerCameras.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
#ifndef MODELERCAMERAS_H
|
||||
#define MODELERCAMERAS_H
|
||||
|
||||
#include "modeler_global.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
namespace paysages {
|
||||
namespace modeler {
|
||||
|
||||
/**
|
||||
* Storage for modeler cameras.
|
||||
*/
|
||||
class ModelerCameras: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ModelerCameras(MainModelerWindow *parent);
|
||||
~ModelerCameras();
|
||||
|
||||
/**
|
||||
* Process a zoom request.
|
||||
*/
|
||||
void processZoom(double value);
|
||||
|
||||
/**
|
||||
* Process a scroll request.
|
||||
*/
|
||||
void processScroll(double xvalue, double yvalue);
|
||||
|
||||
protected:
|
||||
void timerEvent(QTimerEvent *event);
|
||||
|
||||
public slots:
|
||||
void changeActiveCamera(const QString &name);
|
||||
|
||||
private:
|
||||
MainModelerWindow *parent;
|
||||
CameraDefinition *active;
|
||||
CameraDefinition *current;
|
||||
CameraDefinition *render;
|
||||
CameraDefinition *topdown;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // MODELERCAMERAS_H
|
92
src/interface/modeler/quickapp/OpenGLView.cpp
Normal file
|
@ -0,0 +1,92 @@
|
|||
#include "OpenGLView.h"
|
||||
|
||||
#include <QQuickWindow>
|
||||
#include <QHoverEvent>
|
||||
#include "MainModelerWindow.h"
|
||||
#include "OpenGLRenderer.h"
|
||||
#include "ModelerCameras.h"
|
||||
|
||||
OpenGLView::OpenGLView(QQuickItem *parent) :
|
||||
QQuickItem(parent)
|
||||
{
|
||||
initialized = false;
|
||||
window = NULL;
|
||||
renderer = NULL;
|
||||
|
||||
setAcceptedMouseButtons(Qt::AllButtons);
|
||||
|
||||
mouse_button = Qt::NoButton;
|
||||
|
||||
connect(this, SIGNAL(windowChanged(QQuickWindow*)), this, SLOT(handleWindowChanged(QQuickWindow*)));
|
||||
startTimer(50);
|
||||
}
|
||||
|
||||
void OpenGLView::handleWindowChanged(QQuickWindow *win)
|
||||
{
|
||||
if (win)
|
||||
{
|
||||
window = qobject_cast<MainModelerWindow *>(win);
|
||||
if (window)
|
||||
{
|
||||
renderer = window->getRenderer();
|
||||
|
||||
connect(win, SIGNAL(beforeRendering()), this, SLOT(paint()), Qt::DirectConnection);
|
||||
|
||||
win->setClearBeforeRendering(false);
|
||||
|
||||
initialized = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLView::paint()
|
||||
{
|
||||
if (not initialized or not renderer)
|
||||
{
|
||||
renderer->initialize();
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
renderer->resize(width(), height());
|
||||
renderer->prepareOpenGLState();
|
||||
renderer->paint();
|
||||
|
||||
if (window)
|
||||
{
|
||||
window->resetOpenGLState();
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLView::wheelEvent(QWheelEvent *event)
|
||||
{
|
||||
window->getCamera()->processZoom(0.1 * (double)event->angleDelta().y());
|
||||
}
|
||||
|
||||
void OpenGLView::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
mouse_button = event->button();
|
||||
mouse_pos = event->windowPos();
|
||||
}
|
||||
|
||||
void OpenGLView::mouseReleaseEvent(QMouseEvent *)
|
||||
{
|
||||
mouse_button = Qt::NoButton;
|
||||
}
|
||||
|
||||
void OpenGLView::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
QPointF diff = event->windowPos() - mouse_pos;
|
||||
if (mouse_button == Qt::MidButton)
|
||||
{
|
||||
window->getCamera()->processScroll(-0.1 * diff.x(), 0.1 * diff.y());
|
||||
}
|
||||
mouse_pos = event->windowPos();
|
||||
}
|
||||
|
||||
void OpenGLView::timerEvent(QTimerEvent *)
|
||||
{
|
||||
if (window)
|
||||
{
|
||||
window->update();
|
||||
}
|
||||
}
|
40
src/interface/modeler/quickapp/OpenGLView.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
#ifndef OPENGLVIEW_H
|
||||
#define OPENGLVIEW_H
|
||||
|
||||
#include "modeler_global.h"
|
||||
|
||||
#include <QQuickItem>
|
||||
|
||||
namespace paysages {
|
||||
namespace modeler {
|
||||
|
||||
class OpenGLView : public QQuickItem
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit OpenGLView(QQuickItem *parent = 0);
|
||||
|
||||
public slots:
|
||||
void handleWindowChanged(QQuickWindow *win);
|
||||
void paint();
|
||||
|
||||
protected:
|
||||
virtual void wheelEvent(QWheelEvent *event) override;
|
||||
virtual void mousePressEvent(QMouseEvent *event) override;
|
||||
virtual void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
virtual void mouseMoveEvent(QMouseEvent *event) override;
|
||||
virtual void timerEvent(QTimerEvent *event) override;
|
||||
|
||||
private:
|
||||
bool initialized;
|
||||
MainModelerWindow *window;
|
||||
OpenGLRenderer *renderer;
|
||||
|
||||
Qt::MouseButton mouse_button;
|
||||
QPointF mouse_pos;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // OPENGLVIEW_H
|
85
src/interface/modeler/quickapp/RenderPreviewProvider.cpp
Normal file
|
@ -0,0 +1,85 @@
|
|||
#include "RenderPreviewProvider.h"
|
||||
|
||||
#include "Canvas.h"
|
||||
#include "CanvasPreview.h"
|
||||
#include "Color.h"
|
||||
|
||||
static inline QColor colorToQColor(Color color)
|
||||
{
|
||||
color.normalize();
|
||||
return QColor(color.r * 255.0, color.g * 255.0, color.b * 255.0, color.a * 255.0);
|
||||
}
|
||||
|
||||
RenderPreviewProvider::RenderPreviewProvider() :
|
||||
QQuickImageProvider(QQuickImageProvider::Image)
|
||||
{
|
||||
canvas = NULL;
|
||||
pixbuf = new QImage(1, 1, QImage::Format_ARGB32);
|
||||
}
|
||||
|
||||
RenderPreviewProvider::~RenderPreviewProvider()
|
||||
{
|
||||
delete pixbuf;
|
||||
}
|
||||
|
||||
QImage RenderPreviewProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
|
||||
{
|
||||
if (canvas)
|
||||
{
|
||||
canvas->getPreview()->updateLive(this);
|
||||
}
|
||||
|
||||
if (size)
|
||||
{
|
||||
*size = pixbuf->size();
|
||||
}
|
||||
|
||||
return *pixbuf;
|
||||
}
|
||||
|
||||
void RenderPreviewProvider::setCanvas(const Canvas *canvas)
|
||||
{
|
||||
if (not this->canvas)
|
||||
{
|
||||
this->canvas = canvas;
|
||||
canvas->getPreview()->initLive(this);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderPreviewProvider::releaseCanvas()
|
||||
{
|
||||
if (canvas)
|
||||
{
|
||||
canvas->getPreview()->updateLive(this);
|
||||
canvas = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void RenderPreviewProvider::setToneMapping(const ColorProfile &profile)
|
||||
{
|
||||
if (canvas)
|
||||
{
|
||||
canvas->getPreview()->setToneMapping(profile);
|
||||
canvas->getPreview()->updateLive(this);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderPreviewProvider::canvasResized(int width, int height)
|
||||
{
|
||||
if (QSize(width, height) != pixbuf->size())
|
||||
{
|
||||
delete pixbuf;
|
||||
pixbuf = new QImage(width, height, QImage::Format_ARGB32);
|
||||
pixbuf->fill(Qt::black);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderPreviewProvider::canvasCleared(const Color &col)
|
||||
{
|
||||
pixbuf->fill(colorToQColor(col));
|
||||
}
|
||||
|
||||
void RenderPreviewProvider::canvasPainted(int x, int y, const Color &col)
|
||||
{
|
||||
pixbuf->setPixel(x, pixbuf->height() - 1 - y, colorToQColor(col).rgb());
|
||||
}
|
53
src/interface/modeler/quickapp/RenderPreviewProvider.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
#ifndef RENDERPREVIEWPROVIDER_H
|
||||
#define RENDERPREVIEWPROVIDER_H
|
||||
|
||||
#include "modeler_global.h"
|
||||
|
||||
#include <QQuickImageProvider>
|
||||
#include "CanvasLiveClient.h"
|
||||
|
||||
namespace paysages {
|
||||
namespace modeler {
|
||||
|
||||
/**
|
||||
* Provider for a Qml Image content, filled from a canvas rendering.
|
||||
*/
|
||||
class RenderPreviewProvider : public QQuickImageProvider, public CanvasLiveClient
|
||||
{
|
||||
public:
|
||||
RenderPreviewProvider();
|
||||
virtual ~RenderPreviewProvider();
|
||||
|
||||
/**
|
||||
* Set the canvas to watch and display, null to stop watching.
|
||||
*
|
||||
* This function must be called from the graphics thread.
|
||||
*/
|
||||
void setCanvas(const Canvas *canvas);
|
||||
|
||||
/**
|
||||
* Release the bound canvas.
|
||||
*/
|
||||
void releaseCanvas();
|
||||
|
||||
/**
|
||||
* Set the tone mapping to apply to pixel colors.
|
||||
*/
|
||||
void setToneMapping(const ColorProfile &profile);
|
||||
|
||||
protected:
|
||||
virtual QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize) override;
|
||||
|
||||
virtual void canvasResized(int width, int height) override;
|
||||
virtual void canvasCleared(const Color &col) override;
|
||||
virtual void canvasPainted(int x, int y, const Color &col) override;
|
||||
|
||||
private:
|
||||
QImage* pixbuf;
|
||||
const Canvas *canvas;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // RENDERPREVIEWPROVIDER_H
|
111
src/interface/modeler/quickapp/RenderProcess.cpp
Normal file
|
@ -0,0 +1,111 @@
|
|||
#include "RenderProcess.h"
|
||||
|
||||
#include <QSize>
|
||||
#include "SoftwareCanvasRenderer.h"
|
||||
#include "RenderPreviewProvider.h"
|
||||
#include "RenderConfig.h"
|
||||
#include "Thread.h"
|
||||
#include "Canvas.h"
|
||||
#include "CanvasPreview.h"
|
||||
|
||||
class RenderThread: public Thread
|
||||
{
|
||||
public:
|
||||
RenderThread(SoftwareCanvasRenderer *renderer): renderer(renderer)
|
||||
{
|
||||
}
|
||||
virtual void run() override
|
||||
{
|
||||
renderer->render();
|
||||
}
|
||||
private:
|
||||
SoftwareCanvasRenderer *renderer;
|
||||
};
|
||||
|
||||
RenderProcess::RenderProcess(RenderPreviewProvider *destination):
|
||||
destination(destination)
|
||||
{
|
||||
rendering = false;
|
||||
renderer = NULL;
|
||||
render_thread = NULL;
|
||||
|
||||
startTimer(100);
|
||||
}
|
||||
|
||||
RenderProcess::~RenderProcess()
|
||||
{
|
||||
if (rendering)
|
||||
{
|
||||
renderer->interrupt();
|
||||
}
|
||||
|
||||
rendering = false;
|
||||
|
||||
if (render_thread)
|
||||
{
|
||||
render_thread->join();
|
||||
delete render_thread;
|
||||
}
|
||||
|
||||
if (renderer)
|
||||
{
|
||||
delete renderer;
|
||||
}
|
||||
}
|
||||
|
||||
void RenderProcess::startRender(Scenery *scenery, const RenderConfig &config)
|
||||
{
|
||||
if (rendering)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
rendering = true;
|
||||
|
||||
if (renderer)
|
||||
{
|
||||
delete renderer;
|
||||
}
|
||||
|
||||
renderer = new SoftwareCanvasRenderer();
|
||||
renderer->setScenery(scenery);
|
||||
renderer->setConfig(config);
|
||||
|
||||
destination->setCanvas(renderer->getCanvas());
|
||||
|
||||
render_thread = new RenderThread(renderer);
|
||||
render_thread->start();
|
||||
}
|
||||
|
||||
void RenderProcess::stopRender()
|
||||
{
|
||||
if (rendering)
|
||||
{
|
||||
renderer->interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
const QSize RenderProcess::getPreviewSize()
|
||||
{
|
||||
if (renderer)
|
||||
{
|
||||
return QSize(renderer->getCanvas()->getPreview()->getWidth(), renderer->getCanvas()->getPreview()->getHeight());
|
||||
}
|
||||
else
|
||||
{
|
||||
return QSize(10, 10);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderProcess::timerEvent(QTimerEvent *)
|
||||
{
|
||||
if (rendering and renderer->isFinished())
|
||||
{
|
||||
destination->releaseCanvas();
|
||||
rendering = false;
|
||||
|
||||
render_thread->join();
|
||||
delete render_thread;
|
||||
render_thread = NULL;
|
||||
}
|
||||
}
|
47
src/interface/modeler/quickapp/RenderProcess.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
#ifndef RENDERPROCESS_H
|
||||
#define RENDERPROCESS_H
|
||||
|
||||
#include "modeler_global.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
namespace paysages {
|
||||
namespace modeler {
|
||||
|
||||
class RenderProcess: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
RenderProcess(RenderPreviewProvider *destination);
|
||||
virtual ~RenderProcess();
|
||||
|
||||
/**
|
||||
* Start the rendering process in a separate thread.
|
||||
*/
|
||||
void startRender(Scenery *scenery, const RenderConfig &config);
|
||||
|
||||
/**
|
||||
* Stop any currently running render.
|
||||
*/
|
||||
void stopRender();
|
||||
|
||||
/**
|
||||
* Get the size of the preview image.
|
||||
*/
|
||||
const QSize getPreviewSize();
|
||||
|
||||
protected:
|
||||
virtual void timerEvent(QTimerEvent *event) override;
|
||||
|
||||
private:
|
||||
RenderPreviewProvider *destination;
|
||||
bool rendering;
|
||||
SoftwareCanvasRenderer *renderer;
|
||||
Thread *render_thread;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // RENDERPROCESS_H
|
19
src/interface/modeler/quickapp/WaterModeler.cpp
Normal file
|
@ -0,0 +1,19 @@
|
|||
#include "WaterModeler.h"
|
||||
|
||||
#include "MainModelerWindow.h"
|
||||
|
||||
WaterModeler::WaterModeler(MainModelerWindow *main):
|
||||
main(main)
|
||||
{
|
||||
QObject *item = main->findQmlObject("water_level");
|
||||
if (item)
|
||||
{
|
||||
connect(item, SIGNAL(changed(double)), this, SLOT(waterLevelChanged(double)));
|
||||
}
|
||||
}
|
||||
|
||||
void WaterModeler::waterLevelChanged(double value)
|
||||
{
|
||||
// TODO
|
||||
//qDebug() << "water level : " << value;
|
||||
}
|
27
src/interface/modeler/quickapp/WaterModeler.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
#ifndef WATERMODELER_H
|
||||
#define WATERMODELER_H
|
||||
|
||||
#include "modeler_global.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
namespace paysages {
|
||||
namespace modeler {
|
||||
|
||||
class WaterModeler: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
WaterModeler(MainModelerWindow *main);
|
||||
|
||||
public slots:
|
||||
void waterLevelChanged(double value);
|
||||
|
||||
private:
|
||||
MainModelerWindow *main;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // WATERMODELER_H
|
27
src/interface/modeler/quickapp/deployment.pri
Normal file
|
@ -0,0 +1,27 @@
|
|||
android-no-sdk {
|
||||
target.path = /data/user/qt
|
||||
export(target.path)
|
||||
INSTALLS += target
|
||||
} else:android {
|
||||
x86 {
|
||||
target.path = /libs/x86
|
||||
} else: armeabi-v7a {
|
||||
target.path = /libs/armeabi-v7a
|
||||
} else {
|
||||
target.path = /libs/armeabi
|
||||
}
|
||||
export(target.path)
|
||||
INSTALLS += target
|
||||
} else:unix {
|
||||
isEmpty(target.path) {
|
||||
qnx {
|
||||
target.path = /tmp/$${TARGET}/bin
|
||||
} else {
|
||||
target.path = /opt/$${TARGET}/bin
|
||||
}
|
||||
export(target.path)
|
||||
}
|
||||
INSTALLS += target
|
||||
}
|
||||
|
||||
export(INSTALLS)
|
10
src/interface/modeler/quickapp/images.qrc
Normal file
|
@ -0,0 +1,10 @@
|
|||
<RCC>
|
||||
<qresource prefix="/toolbar/primary">
|
||||
<file>images/tab_atmosphere.png</file>
|
||||
<file>images/tab_terrain.png</file>
|
||||
<file>images/tab_textures.png</file>
|
||||
<file>images/tab_water.png</file>
|
||||
<file>images/tab_clouds.png</file>
|
||||
<file>images/tab_render.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
13
src/interface/modeler/quickapp/main.cpp
Normal file
|
@ -0,0 +1,13 @@
|
|||
#include <QGuiApplication>
|
||||
|
||||
#include "MainModelerWindow.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QGuiApplication app(argc, argv);
|
||||
|
||||
MainModelerWindow view;
|
||||
view.show();
|
||||
|
||||
return app.exec();
|
||||
}
|
25
src/interface/modeler/quickapp/modeler_global.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
#ifndef MODELER_GLOBAL_H
|
||||
#define MODELER_GLOBAL_H
|
||||
|
||||
#include "definition_global.h"
|
||||
#include "software_global.h"
|
||||
#include "opengl_global.h"
|
||||
|
||||
namespace paysages {
|
||||
namespace modeler {
|
||||
class MainModelerWindow;
|
||||
class OpenGLView;
|
||||
|
||||
class AtmosphereModeler;
|
||||
class WaterModeler;
|
||||
|
||||
class RenderPreviewProvider;
|
||||
class RenderProcess;
|
||||
|
||||
class ModelerCameras;
|
||||
}
|
||||
}
|
||||
|
||||
using namespace paysages::modeler;
|
||||
|
||||
#endif // MODELER_GLOBAL_H
|
7
src/interface/modeler/quickapp/qml.qrc
Normal file
|
@ -0,0 +1,7 @@
|
|||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>qml/main.qml</file>
|
||||
<file>qml/ToolbarButton.qml</file>
|
||||
<file>qml/OpenGLView.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
29
src/interface/modeler/quickapp/qml/BaseChoice.qml
Normal file
|
@ -0,0 +1,29 @@
|
|||
import QtQuick 2.0
|
||||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Layouts 1.1
|
||||
|
||||
Item {
|
||||
default property alias children : inner_layout.children
|
||||
property int value
|
||||
width: 100
|
||||
height: 32
|
||||
|
||||
ExclusiveGroup {
|
||||
id: choice_group
|
||||
|
||||
onCurrentChanged: value = current.value
|
||||
}
|
||||
|
||||
Row {
|
||||
id: inner_layout
|
||||
spacing: 5
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
onChildrenChanged: {
|
||||
for (var i = 0; i < children.length; i++)
|
||||
{
|
||||
children[i].exclusiveGroup = choice_group;
|
||||
}
|
||||
}
|
||||
}
|
50
src/interface/modeler/quickapp/qml/BaseChoiceItem.qml
Normal file
|
@ -0,0 +1,50 @@
|
|||
import QtQuick 2.0
|
||||
import QtQuick.Controls 1.1
|
||||
|
||||
Rectangle {
|
||||
id: choice_item
|
||||
property string icon
|
||||
property bool checked: false
|
||||
property ExclusiveGroup exclusiveGroup: null
|
||||
property int value
|
||||
|
||||
color: "#333333"
|
||||
|
||||
signal toggled(bool value)
|
||||
|
||||
width: 20
|
||||
height: 20
|
||||
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
source: parent.icon
|
||||
antialiasing: true
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: checked = true
|
||||
}
|
||||
|
||||
onExclusiveGroupChanged: {
|
||||
if (exclusiveGroup) {
|
||||
exclusiveGroup.bindCheckable(choice_item);
|
||||
}
|
||||
}
|
||||
|
||||
onCheckedChanged: choice_item.toggled(checked)
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "Checked"
|
||||
when: checked
|
||||
|
||||
PropertyChanges {
|
||||
target: choice_item
|
||||
color: "#999999"
|
||||
}
|
||||
}
|
||||
|
||||
]
|
||||
}
|
35
src/interface/modeler/quickapp/qml/BasePanel.qml
Normal file
|
@ -0,0 +1,35 @@
|
|||
import QtQuick 2.0
|
||||
|
||||
Rectangle {
|
||||
property ToolbarButton tool
|
||||
id: panel
|
||||
|
||||
opacity: 0
|
||||
width: 200
|
||||
height: parent.height - 100
|
||||
color: "#a0909090"
|
||||
enabled: visible
|
||||
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
Behavior on opacity {
|
||||
PropertyAnimation {
|
||||
duration: 200
|
||||
}
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "Active"
|
||||
when: tool.selected
|
||||
|
||||
PropertyChanges {
|
||||
target: panel
|
||||
visible: true
|
||||
opacity: 1
|
||||
}
|
||||
}
|
||||
|
||||
]
|
||||
}
|
7
src/interface/modeler/quickapp/qml/BaseSlider.qml
Normal file
|
@ -0,0 +1,7 @@
|
|||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.2
|
||||
|
||||
Slider {
|
||||
signal changed(real value)
|
||||
onValueChanged: changed(value)
|
||||
}
|
39
src/interface/modeler/quickapp/qml/CameraChoice.qml
Normal file
|
@ -0,0 +1,39 @@
|
|||
import QtQuick 2.0
|
||||
|
||||
Rectangle {
|
||||
id: camera_choice
|
||||
width: 200
|
||||
height: 50
|
||||
color: "#90888888"
|
||||
objectName: "camera_choice"
|
||||
|
||||
Row {
|
||||
id: inner_space
|
||||
anchors.centerIn: parent
|
||||
spacing: 15
|
||||
|
||||
ToolbarButton {
|
||||
id: camera_choice_render
|
||||
picture: "images/tab_display.png"
|
||||
hovertext: qsTr("Switch to the final camera")
|
||||
selected: true
|
||||
}
|
||||
|
||||
ToolbarButton {
|
||||
id: camera_choice_topdown
|
||||
picture: "images/display_topdown.png"
|
||||
hovertext: qsTr("Switch to the top-down camera")
|
||||
}
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "Render camera"
|
||||
when: camera_choice_render.selected
|
||||
},
|
||||
State {
|
||||
name: "Top-down camera"
|
||||
when: camera_choice_topdown.selected
|
||||
}
|
||||
]
|
||||
}
|
6
src/interface/modeler/quickapp/qml/OpenGLView.qml
Normal file
|
@ -0,0 +1,6 @@
|
|||
import QtQuick 2.0
|
||||
|
||||
Rectangle {
|
||||
width: 100
|
||||
height: 62
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
import QtQuick 2.0
|
||||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Layouts 1.1
|
||||
|
||||
BasePanel {
|
||||
width: 70
|
||||
|
||||
objectName: "atmosphere_daytime"
|
||||
default property real value: day_night.value == 2 ? 1.0 : slider.value * 0.54 + 0.23;
|
||||
signal changed(real value)
|
||||
|
||||
onValueChanged: changed(value)
|
||||
|
||||
ColumnLayout
|
||||
{
|
||||
anchors.fill: parent
|
||||
anchors.margins: 10
|
||||
spacing: 20
|
||||
|
||||
BaseChoice {
|
||||
id: day_night
|
||||
width: parent.width
|
||||
|
||||
Layout.alignment: Qt.AlignTop | Qt.AlignHCenter
|
||||
|
||||
BaseChoiceItem {
|
||||
icon: "images/icon_atmosphere_day.png"
|
||||
value: 1
|
||||
checked: true
|
||||
}
|
||||
BaseChoiceItem {
|
||||
icon: "images/icon_atmosphere_night.png"
|
||||
value: 2
|
||||
}
|
||||
}
|
||||
|
||||
BaseSlider {
|
||||
id: slider
|
||||
orientation: Qt.Vertical
|
||||
Layout.maximumWidth: 15
|
||||
Layout.fillHeight: true
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
visible: day_night.value == 1
|
||||
}
|
||||
}
|
||||
}
|
11
src/interface/modeler/quickapp/qml/PanelWaterLevel.qml
Normal file
|
@ -0,0 +1,11 @@
|
|||
import QtQuick 2.2
|
||||
|
||||
BasePanel {
|
||||
width: 20
|
||||
|
||||
BaseSlider {
|
||||
objectName: "water_level"
|
||||
orientation: Qt.Vertical
|
||||
anchors.fill: parent
|
||||
}
|
||||
}
|
27
src/interface/modeler/quickapp/qml/RenderDialog.qml
Normal file
|
@ -0,0 +1,27 @@
|
|||
import QtQuick 2.2
|
||||
|
||||
Rectangle {
|
||||
width: 400
|
||||
height: 300
|
||||
|
||||
Image {
|
||||
id: preview_image
|
||||
objectName: "preview_image"
|
||||
anchors.centerIn: parent
|
||||
width: 100
|
||||
height: 100
|
||||
source: ""
|
||||
cache: false
|
||||
}
|
||||
|
||||
Timer {
|
||||
interval: 500
|
||||
running: true
|
||||
repeat: true
|
||||
|
||||
onTriggered: {
|
||||
preview_image.source = "";
|
||||
preview_image.source = "image://renderpreviewprovider/live";
|
||||
}
|
||||
}
|
||||
}
|
32
src/interface/modeler/quickapp/qml/Toolbar.qml
Normal file
|
@ -0,0 +1,32 @@
|
|||
import QtQuick 2.0
|
||||
|
||||
Rectangle {
|
||||
|
||||
default property alias children : inner_space.children
|
||||
width: 70
|
||||
height: parent.height
|
||||
color: "#50888888"
|
||||
enabled: opacity > 0
|
||||
|
||||
Column {
|
||||
id: inner_space
|
||||
spacing: (parent.height - children.length * tool_terrain.height) / (children.length + 1)
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
||||
Behavior on opacity {
|
||||
PropertyAnimation {
|
||||
duration: 200
|
||||
}
|
||||
}
|
||||
|
||||
onEnabledChanged: {
|
||||
if (!enabled)
|
||||
{
|
||||
for (var i = 0; i < children.length; i++)
|
||||
{
|
||||
children[i].selected = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
87
src/interface/modeler/quickapp/qml/ToolbarButton.qml
Normal file
|
@ -0,0 +1,87 @@
|
|||
import QtQuick 2.0
|
||||
import QtGraphicalEffects 1.0
|
||||
|
||||
Item {
|
||||
property string picture
|
||||
property bool selected: false
|
||||
property bool hovered: false
|
||||
property string helptext
|
||||
property string hovertext
|
||||
|
||||
width: image.width + 10
|
||||
height: image.height + 10
|
||||
|
||||
Rectangle {
|
||||
id: glow
|
||||
anchors.fill: parent
|
||||
color: "#cccccc"
|
||||
radius: 8
|
||||
|
||||
opacity: parent.selected ? 1.0 : (parent.hovered ? 0.5 : 0.0)
|
||||
Behavior on opacity {
|
||||
PropertyAnimation {
|
||||
duration: 200
|
||||
}
|
||||
}
|
||||
RectangularGlow {
|
||||
anchors.fill: glow
|
||||
glowRadius: 8
|
||||
spread: 0.2
|
||||
color: "white"
|
||||
cornerRadius: glow.radius + glowRadius
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
id: image
|
||||
source: parent.picture
|
||||
anchors.centerIn: parent
|
||||
width: 32
|
||||
height: 32
|
||||
antialiasing: true
|
||||
}
|
||||
DropShadow {
|
||||
anchors.fill: image
|
||||
horizontalOffset: 2
|
||||
verticalOffset: 2
|
||||
radius: 4.0
|
||||
samples: 16
|
||||
color: "#80000000"
|
||||
source: image
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
|
||||
onEntered: {
|
||||
parent.hovered = true;
|
||||
tooltip_widget.hovertext = hovertext;
|
||||
}
|
||||
onExited: {
|
||||
parent.hovered = false;
|
||||
tooltip_widget.hovertext = "";
|
||||
}
|
||||
onClicked: {
|
||||
parent.selected = !parent.selected;
|
||||
if (parent.selected)
|
||||
{
|
||||
var toolbar = parent.parent;
|
||||
for (var i = 0; i < toolbar.children.length; ++i)
|
||||
{
|
||||
var child = toolbar.children[i]
|
||||
if (child !== parent)
|
||||
{
|
||||
child.selected = false;
|
||||
}
|
||||
}
|
||||
tooltip_widget.helptext = helptext;
|
||||
}
|
||||
else
|
||||
{
|
||||
tooltip_widget.helptext = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
16
src/interface/modeler/quickapp/qml/Tooltip.qml
Normal file
|
@ -0,0 +1,16 @@
|
|||
import QtQuick 2.0
|
||||
|
||||
Rectangle {
|
||||
property string helptext
|
||||
property string hovertext
|
||||
width: content.width
|
||||
height: content.height
|
||||
|
||||
color: "#99000000"
|
||||
|
||||
Text {
|
||||
id: content
|
||||
color: "white"
|
||||
text: parent.helptext || parent.hovertext
|
||||
}
|
||||
}
|
31
src/interface/modeler/quickapp/qml/app.qrc
Normal file
|
@ -0,0 +1,31 @@
|
|||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>ToolbarButton.qml</file>
|
||||
<file>main.qml</file>
|
||||
<file>images/tab_atmosphere.png</file>
|
||||
<file>images/tab_clouds.png</file>
|
||||
<file>images/tab_render.png</file>
|
||||
<file>images/tab_terrain.png</file>
|
||||
<file>images/tab_textures.png</file>
|
||||
<file>images/tab_water.png</file>
|
||||
<file>images/tab_display.png</file>
|
||||
<file>Toolbar.qml</file>
|
||||
<file>images/display_topdown.png</file>
|
||||
<file>images/help.png</file>
|
||||
<file>Tooltip.qml</file>
|
||||
<file>images/icon_water.png</file>
|
||||
<file>images/icon_water_level.png</file>
|
||||
<file>BasePanel.qml</file>
|
||||
<file>PanelWaterLevel.qml</file>
|
||||
<file>images/icon_atmosphere.png</file>
|
||||
<file>images/icon_atmosphere_daytime.png</file>
|
||||
<file>BaseSlider.qml</file>
|
||||
<file>PanelAtmosphereDaytime.qml</file>
|
||||
<file>images/icon_atmosphere_day.png</file>
|
||||
<file>images/icon_atmosphere_night.png</file>
|
||||
<file>BaseChoice.qml</file>
|
||||
<file>BaseChoiceItem.qml</file>
|
||||
<file>RenderDialog.qml</file>
|
||||
<file>CameraChoice.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
BIN
src/interface/modeler/quickapp/qml/images/display_topdown.png
Normal file
After Width: | Height: | Size: 7.6 KiB |
BIN
src/interface/modeler/quickapp/qml/images/help.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
src/interface/modeler/quickapp/qml/images/icon_atmosphere.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 927 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 871 B |
BIN
src/interface/modeler/quickapp/qml/images/icon_water.png
Normal file
After Width: | Height: | Size: 875 B |
BIN
src/interface/modeler/quickapp/qml/images/icon_water_level.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
src/interface/modeler/quickapp/qml/images/tab_atmosphere.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
src/interface/modeler/quickapp/qml/images/tab_clouds.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
src/interface/modeler/quickapp/qml/images/tab_display.png
Normal file
After Width: | Height: | Size: 5.9 KiB |
BIN
src/interface/modeler/quickapp/qml/images/tab_render.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
src/interface/modeler/quickapp/qml/images/tab_terrain.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
src/interface/modeler/quickapp/qml/images/tab_textures.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
src/interface/modeler/quickapp/qml/images/tab_water.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
158
src/interface/modeler/quickapp/qml/main.qml
Normal file
|
@ -0,0 +1,158 @@
|
|||
import QtQuick 2.2
|
||||
import Paysages 1.0
|
||||
|
||||
OpenGLView {
|
||||
id: main_ui
|
||||
state: "Init"
|
||||
|
||||
width: 800
|
||||
height: 600
|
||||
|
||||
Tooltip {
|
||||
id: tooltip_widget
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
}
|
||||
|
||||
Toolbar {
|
||||
id: primary_toolbar
|
||||
color: "#90888888"
|
||||
|
||||
anchors.left: parent.left
|
||||
|
||||
ToolbarButton {
|
||||
id: tool_display
|
||||
picture: "images/tab_display.png"
|
||||
hovertext: qsTr("Display options")
|
||||
}
|
||||
ToolbarButton {
|
||||
id: tool_terrain
|
||||
picture: "images/tab_terrain.png"
|
||||
}
|
||||
ToolbarButton {
|
||||
id: tool_textures
|
||||
picture: "images/tab_textures.png"
|
||||
}
|
||||
ToolbarButton {
|
||||
id: tool_water
|
||||
picture: "images/icon_water.png"
|
||||
hovertext: "Water tools"
|
||||
}
|
||||
ToolbarButton {
|
||||
id: tool_atmosphere
|
||||
picture: "images/icon_atmosphere.png"
|
||||
hovertext: "Atmosphere/weather tools"
|
||||
}
|
||||
ToolbarButton {
|
||||
id: tool_clouds
|
||||
picture: "images/tab_clouds.png"
|
||||
}
|
||||
ToolbarButton {
|
||||
id: tool_render
|
||||
picture: "images/tab_render.png"
|
||||
}
|
||||
}
|
||||
|
||||
Toolbar {
|
||||
id: display_toolbar
|
||||
opacity: 0
|
||||
anchors.left: primary_toolbar.right
|
||||
|
||||
ToolbarButton {
|
||||
id: tool_display_topdown
|
||||
picture: "images/display_topdown.png"
|
||||
hovertext: qsTr("Top-down view")
|
||||
helptext: qsTr("Drag the mouse on the map to change the viewpoint.")
|
||||
}
|
||||
}
|
||||
|
||||
Toolbar {
|
||||
id: water_toolbar
|
||||
opacity: 0
|
||||
anchors.left: primary_toolbar.right
|
||||
|
||||
ToolbarButton {
|
||||
id: tool_water_level
|
||||
picture: "images/icon_water_level.png"
|
||||
hovertext: qsTr("Change the water altitude")
|
||||
}
|
||||
}
|
||||
|
||||
Toolbar {
|
||||
id: atmosphere_toolbar
|
||||
opacity: 0
|
||||
anchors.left: primary_toolbar.right
|
||||
|
||||
ToolbarButton {
|
||||
id: tool_atmosphere_daytime
|
||||
picture: "images/icon_atmosphere_daytime.png"
|
||||
hovertext: qsTr("Change the time of day")
|
||||
}
|
||||
}
|
||||
|
||||
CameraChoice {
|
||||
id: camera_choice
|
||||
anchors.bottom: main_ui.bottom
|
||||
anchors.horizontalCenter: main_ui.horizontalCenter
|
||||
}
|
||||
|
||||
RenderDialog {
|
||||
id: render_dialog
|
||||
opacity: 0
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
PanelWaterLevel {
|
||||
id: panel_water_level
|
||||
tool: tool_water_level
|
||||
}
|
||||
PanelAtmosphereDaytime {
|
||||
id: panel_atmosphere_daytime
|
||||
tool: tool_atmosphere_daytime
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "Display Mode"
|
||||
when: tool_display.selected
|
||||
|
||||
PropertyChanges {
|
||||
target: display_toolbar
|
||||
opacity: 1
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "Water Mode"
|
||||
when: tool_water.selected
|
||||
|
||||
PropertyChanges {
|
||||
target: water_toolbar
|
||||
opacity: 1
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "Atmosphere Mode"
|
||||
when: tool_atmosphere.selected
|
||||
|
||||
PropertyChanges {
|
||||
target: atmosphere_toolbar
|
||||
opacity: 1
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "Render Dialog"
|
||||
when: tool_display.selected
|
||||
|
||||
PropertyChanges {
|
||||
target: primary_toolbar
|
||||
opacity: 0
|
||||
}
|
||||
PropertyChanges {
|
||||
target: render_dialog
|
||||
opacity: 1
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
}
|
80
src/interface/modeler/quickapp/quickapp.pro
Normal file
|
@ -0,0 +1,80 @@
|
|||
TEMPLATE = app
|
||||
|
||||
QT += qml quick widgets
|
||||
|
||||
include(../../../common.pri)
|
||||
|
||||
SOURCES += main.cpp \
|
||||
OpenGLView.cpp \
|
||||
MainModelerWindow.cpp \
|
||||
WaterModeler.cpp \
|
||||
AtmosphereModeler.cpp \
|
||||
RenderPreviewProvider.cpp \
|
||||
RenderProcess.cpp \
|
||||
ModelerCameras.cpp
|
||||
|
||||
RESOURCES += \
|
||||
qml/app.qrc
|
||||
|
||||
TARGET = paysages-modeler
|
||||
|
||||
# Additional import path used to resolve QML modules in Qt Creator's code model
|
||||
QML_IMPORT_PATH = ../extension
|
||||
|
||||
# Default rules for deployment.
|
||||
include(deployment.pri)
|
||||
|
||||
HEADERS += \
|
||||
OpenGLView.h \
|
||||
modeler_global.h \
|
||||
MainModelerWindow.h \
|
||||
WaterModeler.h \
|
||||
AtmosphereModeler.h \
|
||||
RenderPreviewProvider.h \
|
||||
RenderProcess.h \
|
||||
ModelerCameras.h
|
||||
|
||||
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../../../system/release/ -lpaysages_system
|
||||
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../../../system/debug/ -lpaysages_system
|
||||
else:unix: LIBS += -L$$OUT_PWD/../../../system/ -lpaysages_system
|
||||
INCLUDEPATH += $$PWD/../../../system
|
||||
DEPENDPATH += $$PWD/../../../system
|
||||
|
||||
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../../../basics/release/ -lpaysages_basics
|
||||
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../../../basics/debug/ -lpaysages_basics
|
||||
else:unix: LIBS += -L$$OUT_PWD/../../../basics/ -lpaysages_basics
|
||||
INCLUDEPATH += $$PWD/../../../basics
|
||||
DEPENDPATH += $$PWD/../../../basics
|
||||
|
||||
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../../../definition/release/ -lpaysages_definition
|
||||
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../../../definition/debug/ -lpaysages_definition
|
||||
else:unix: LIBS += -L$$OUT_PWD/../../../definition/ -lpaysages_definition
|
||||
INCLUDEPATH += $$PWD/../../../definition
|
||||
DEPENDPATH += $$PWD/../../../definition
|
||||
|
||||
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../../../render/software/release/ -lpaysages_render_software
|
||||
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../../../render/software/debug/ -lpaysages_render_software
|
||||
else:unix: LIBS += -L$$OUT_PWD/../../../render/software/ -lpaysages_render_software
|
||||
INCLUDEPATH += $$PWD/../../../render/software
|
||||
DEPENDPATH += $$PWD/../../../render/software
|
||||
|
||||
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../../../render/opengl/release/ -lpaysages_render_opengl
|
||||
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../../../render/opengl/debug/ -lpaysages_render_opengl
|
||||
else:unix: LIBS += -L$$OUT_PWD/../../../render/opengl/ -lpaysages_render_opengl
|
||||
INCLUDEPATH += $$PWD/../../../render/opengl
|
||||
DEPENDPATH += $$PWD/../../../render/opengl
|
||||
|
||||
OTHER_FILES += \
|
||||
qml/main.qml \
|
||||
qml/ToolbarButton.qml \
|
||||
qml/OpenGLView.qml \
|
||||
qml/Toolbar.qml \
|
||||
qml/Tooltip.qml \
|
||||
qml/BasePanel.qml \
|
||||
qml/PanelWaterLevel.qml \
|
||||
qml/PanelAtmosphereDaytime.qml \
|
||||
qml/BaseSlider.qml \
|
||||
qml/BaseChoice.qml \
|
||||
qml/BaseChoiceItem.qml \
|
||||
qml/RenderDialog.qml \
|
||||
qml/CameraChoice.qml
|
|
@ -9,7 +9,8 @@ SUBDIRS = \
|
|||
render/preview \
|
||||
render/opengl \
|
||||
interface/commandline \
|
||||
interface/desktop
|
||||
interface/desktop \
|
||||
interface/modeler
|
||||
|
||||
exists( tests/googletest/sources/src/gtest-all.cc ) {
|
||||
SUBDIRS += \
|
||||
|
|
|
@ -85,7 +85,7 @@ bool ExplorerChunkTerrain::maintain()
|
|||
double x = _startx + _tessellation_step * (float)i;
|
||||
double z = _startz + _tessellation_step * (float)j;
|
||||
|
||||
double height = _renderer->getTerrainRenderer()->getHeight(x, z, 1);
|
||||
double height = _renderer->getTerrainRenderer()->getHeight(x, z, true);
|
||||
if (height >= _water_height)
|
||||
{
|
||||
overwater = true;
|
||||
|
|
|
@ -16,6 +16,8 @@ OpenGLRenderer::OpenGLRenderer(Scenery* scenery):
|
|||
SoftwareRenderer(scenery)
|
||||
{
|
||||
ready = false;
|
||||
vp_width = 1;
|
||||
vp_height = 1;
|
||||
|
||||
render_quality = 3;
|
||||
|
||||
|
@ -50,25 +52,7 @@ void OpenGLRenderer::initialize()
|
|||
|
||||
if (ready)
|
||||
{
|
||||
functions->glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
functions->glDisable(GL_LIGHTING);
|
||||
|
||||
functions->glFrontFace(GL_CCW);
|
||||
functions->glCullFace(GL_BACK);
|
||||
functions->glEnable(GL_CULL_FACE);
|
||||
|
||||
functions->glDepthFunc(GL_LESS);
|
||||
functions->glDepthMask(1);
|
||||
functions->glEnable(GL_DEPTH_TEST);
|
||||
|
||||
functions->glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
functions->glEnable(GL_LINE_SMOOTH);
|
||||
functions->glLineWidth(1.0);
|
||||
|
||||
functions->glDisable(GL_FOG);
|
||||
|
||||
functions->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
prepareOpenGLState();
|
||||
|
||||
prepare();
|
||||
|
||||
|
@ -92,28 +76,63 @@ void OpenGLRenderer::initialize()
|
|||
}
|
||||
}
|
||||
|
||||
void OpenGLRenderer::resize(int width, int height)
|
||||
void OpenGLRenderer::prepareOpenGLState()
|
||||
{
|
||||
if (ready)
|
||||
{
|
||||
functions->glViewport(0, 0, width, height);
|
||||
functions->glDisable(GL_LIGHTING);
|
||||
|
||||
functions->glFrontFace(GL_CCW);
|
||||
functions->glCullFace(GL_BACK);
|
||||
functions->glEnable(GL_CULL_FACE);
|
||||
|
||||
functions->glDepthFunc(GL_LESS);
|
||||
functions->glDepthMask(1);
|
||||
functions->glEnable(GL_DEPTH_TEST);
|
||||
|
||||
functions->glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
functions->glEnable(GL_LINE_SMOOTH);
|
||||
functions->glLineWidth(1.0);
|
||||
|
||||
functions->glDisable(GL_FOG);
|
||||
|
||||
functions->glEnable(GL_BLEND);
|
||||
functions->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
functions->glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
functions->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
functions->glViewport(0, 0, vp_width, vp_height);
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLRenderer::setCamera(CameraDefinition *camera)
|
||||
{
|
||||
camera->copy(render_camera);
|
||||
getScenery()->setCamera(camera);
|
||||
getScenery()->getCamera(camera);
|
||||
cameraChangeEvent(camera);
|
||||
}
|
||||
|
||||
void OpenGLRenderer::resize(int width, int height)
|
||||
{
|
||||
vp_width = width;
|
||||
vp_height = height;
|
||||
|
||||
getScenery()->getCamera()->setRenderSize(width, height);
|
||||
render_camera->setRenderSize(width, height);
|
||||
|
||||
cameraChangeEvent(getScenery()->getCamera());
|
||||
|
||||
prepareOpenGLState();
|
||||
}
|
||||
|
||||
void OpenGLRenderer::paint()
|
||||
{
|
||||
if (ready)
|
||||
{
|
||||
functions->glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
functions->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
functions->glEnable(GL_BLEND);
|
||||
functions->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
skybox->render();
|
||||
terrain->render();
|
||||
water->render();
|
||||
|
|
|
@ -17,10 +17,21 @@ public:
|
|||
OpenGLRenderer(Scenery* scenery=0);
|
||||
virtual ~OpenGLRenderer();
|
||||
|
||||
inline OpenGLSkybox *getSkybox() const {return skybox;}
|
||||
inline OpenGLWater *getWater() const {return water;}
|
||||
inline OpenGLTerrain *getTerrain() const {return terrain;}
|
||||
|
||||
void initialize();
|
||||
void prepareOpenGLState();
|
||||
void resize(int width, int height);
|
||||
void paint();
|
||||
|
||||
/**
|
||||
* Change the camera location.
|
||||
*
|
||||
* This may change the camera passed as argument (to stay above ground for example).
|
||||
*/
|
||||
void setCamera(CameraDefinition *camera);
|
||||
void cameraChangeEvent(CameraDefinition* camera);
|
||||
|
||||
inline OpenGLFunctions* getOpenGlFunctions() const {return functions;}
|
||||
|
@ -31,6 +42,8 @@ public:
|
|||
|
||||
private:
|
||||
bool ready;
|
||||
int vp_width;
|
||||
int vp_height;
|
||||
|
||||
OpenGLFunctions* functions;
|
||||
OpenGLSharedState* shared_state;
|
||||
|
|
|
@ -25,7 +25,7 @@ void OpenGLSkybox::initialize()
|
|||
{
|
||||
program = createShader("skybox");
|
||||
program->addVertexSource("skybox");
|
||||
program->addFragmentSource("bruneton");
|
||||
program->addFragmentSource("atmosphere");
|
||||
program->addFragmentSource("tonemapping");
|
||||
program->addFragmentSource("skybox");
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ void OpenGLTerrain::initialize()
|
|||
// Prepare shader programs
|
||||
program = createShader("terrain");
|
||||
program->addVertexSource("terrain");
|
||||
program->addFragmentSource("bruneton");
|
||||
program->addFragmentSource("atmosphere");
|
||||
program->addFragmentSource("tonemapping");
|
||||
program->addFragmentSource("fadeout");
|
||||
program->addFragmentSource("terrain");
|
||||
|
|
|
@ -24,7 +24,7 @@ void OpenGLWater::initialize()
|
|||
{
|
||||
program = createShader("water");
|
||||
program->addVertexSource("water");
|
||||
program->addFragmentSource("bruneton");
|
||||
program->addFragmentSource("atmosphere");
|
||||
program->addFragmentSource("tonemapping");
|
||||
program->addFragmentSource("fadeout");
|
||||
program->addFragmentSource("noise");
|
||||
|
|
|
@ -224,3 +224,53 @@ vec4 getSkyColor(vec3 location, vec3 direction)
|
|||
result += sunTransmittance + vec4(inscattering, 0.0);
|
||||
return result;
|
||||
}
|
||||
|
||||
vec4 applyLighting(vec3 location, vec3 normal, vec4 color, float shininess)
|
||||
{
|
||||
float material_hardness = 0.3;
|
||||
float material_reflection = 1.0;
|
||||
|
||||
float r0 = Rg + location.y * WORLD_SCALING;
|
||||
vec3 sun_position = sunDirection * SUN_DISTANCE;
|
||||
float muS = dot(vec3(0.0, 1.0, 0.0), normalize(sun_position - vec3(0.0, r0, 0.0)));
|
||||
|
||||
vec4 light_color = _transmittanceWithShadow(r0, muS);
|
||||
|
||||
vec4 result = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
|
||||
/* diffused light */
|
||||
float diffuse = dot(sunDirection, normal);
|
||||
float sign = (diffuse < 0.0) ? -1.0 : 1.0;
|
||||
if (material_hardness <= 0.5)
|
||||
{
|
||||
float hardness = material_hardness * 2.0;
|
||||
diffuse = (1.0 - hardness) * (diffuse * diffuse) * sign + hardness * diffuse;
|
||||
}
|
||||
else if (diffuse != 0.0)
|
||||
{
|
||||
float hardness = (material_hardness - 0.5) * 2.0;
|
||||
diffuse = (1.0 - hardness) * diffuse + hardness * sign * sqrt(abs(diffuse));
|
||||
}
|
||||
if (diffuse > 0.0)
|
||||
{
|
||||
result += diffuse * color * light_color;
|
||||
}
|
||||
|
||||
/* specular reflection */
|
||||
if (shininess > 0.0 && material_reflection > 0.0)
|
||||
{
|
||||
vec3 view = normalize(location - cameraLocation);
|
||||
vec3 reflect = sunDirection - normal * 2.0 * dot(sunDirection, normal);
|
||||
float specular = dot(reflect, view);
|
||||
if (specular > 0.0)
|
||||
{
|
||||
specular = pow(specular, shininess) * material_reflection;
|
||||
if (specular > 0.0)
|
||||
{
|
||||
result += specular * light_color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
<file>skybox.vert</file>
|
||||
<file>water.frag</file>
|
||||
<file>water.vert</file>
|
||||
<file>bruneton.frag</file>
|
||||
<file>atmosphere.frag</file>
|
||||
<file>tonemapping.frag</file>
|
||||
<file>terrain.frag</file>
|
||||
<file>terrain.vert</file>
|
||||
|
|
|
@ -1,32 +1,11 @@
|
|||
uniform vec4 waterColor;
|
||||
uniform float waterReflection;
|
||||
|
||||
vec4 applyLighting(vec3 location, vec3 normal, vec4 color, float shininess)
|
||||
{
|
||||
// TEMP phong lighting implementation for testing
|
||||
vec3 N = normalize(normal);
|
||||
vec3 L = sunDirection;
|
||||
vec3 E = normalize(cameraLocation - location);
|
||||
vec3 R = normalize(-reflect(L, N));
|
||||
|
||||
//calculate Ambient Term:
|
||||
vec4 Iamb = vec4(0.1, 0.1, 0.1, 1.0);
|
||||
|
||||
//calculate Diffuse Term:
|
||||
vec4 Idiff = vec4(3.0, 3.0, 3.0, 1.0) * color * max(dot(N, L), 0.0);
|
||||
|
||||
// calculate Specular Term:
|
||||
vec4 Ispec = vec4(3.0, 3.0, 3.0, 1.0) * pow(max(dot(R,E),0.0),0.3*shininess);
|
||||
|
||||
// write Total Color:
|
||||
return Iamb + Idiff + Ispec;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec3 normal = noiseNormal2d(unprojected.xz, 0.001);
|
||||
|
||||
gl_FragColor = applyLighting(unprojected, normal, waterColor, 100.0);
|
||||
gl_FragColor = applyLighting(unprojected, normal, waterColor, 16.0);
|
||||
|
||||
vec3 reflected = reflect(unprojected - cameraLocation, normal);
|
||||
reflected.y = max(reflected.y, 0.0);
|
||||
|
|
|
@ -46,7 +46,7 @@ void SceneryTopDownPreviewRenderer::updateEvent()
|
|||
Color SceneryTopDownPreviewRenderer::getColor2D(double x, double y, double scaling)
|
||||
{
|
||||
Vector3 location;
|
||||
double height = getTerrainRenderer()->getHeight(x, y, 1);
|
||||
double height = getTerrainRenderer()->getHeight(x, y, true);
|
||||
|
||||
if (height < getWaterRenderer()->getHeightInfo().max_height)
|
||||
{
|
||||
|
|
|
@ -57,7 +57,7 @@ Color TerrainShapePreviewRenderer::getColor2D(double x, double y, double scaling
|
|||
{
|
||||
double height;
|
||||
|
||||
height = getTerrainRenderer()->getHeight(x, y, 1);
|
||||
height = getTerrainRenderer()->getHeight(x, y, true);
|
||||
if (height > 0.0)
|
||||
{
|
||||
return getTerrainRenderer()->getFinalColor(Vector3(x, height, y), 0.000001);
|
||||
|
|
|
@ -53,7 +53,7 @@ Color TextureLayerCoveragePreviewRenderer::getColor2D(double x, double y, double
|
|||
TexturesRenderer* textures_renderer = getTexturesRenderer();
|
||||
TerrainRenderer* terrain_renderer = getTerrainRenderer();
|
||||
|
||||
double presence = textures_renderer->getBasePresence(layer, terrain_renderer->getResult(x, y, 1, 0));
|
||||
double presence = textures_renderer->getBasePresence(layer, terrain_renderer->getResult(x, y, true, false));
|
||||
|
||||
return Color(presence, presence, presence);
|
||||
}
|
||||
|
|
|
@ -53,6 +53,6 @@ void TexturesMixPreviewRenderer::updateEvent()
|
|||
Color TexturesMixPreviewRenderer::getColor2D(double x, double y, double scaling)
|
||||
{
|
||||
TerrainRenderer* terrain_renderer = getTerrainRenderer();
|
||||
Vector3 location(x, terrain_renderer->getHeight(x, y, 1), y);
|
||||
Vector3 location(x, terrain_renderer->getHeight(x, y, true), y);
|
||||
return terrain_renderer->getFinalColor(location, scaling);
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
SoftwareCanvasRenderer::SoftwareCanvasRenderer()
|
||||
{
|
||||
started = false;
|
||||
finished = false;
|
||||
interrupted = false;
|
||||
canvas = new Canvas();
|
||||
progress = 0.0;
|
||||
|
@ -95,6 +96,7 @@ void SoftwareCanvasRenderer::render()
|
|||
progress = (double)i / (double)n;
|
||||
}
|
||||
}
|
||||
finished = true;
|
||||
}
|
||||
|
||||
void SoftwareCanvasRenderer::interrupt()
|
||||
|
|
|
@ -24,6 +24,7 @@ public:
|
|||
|
||||
inline const Canvas *getCanvas() const {return canvas;}
|
||||
inline double getProgress() const {return progress;}
|
||||
inline bool isFinished() const {return finished;}
|
||||
|
||||
/**
|
||||
* Set the renderer configuration.
|
||||
|
@ -78,6 +79,7 @@ private:
|
|||
int samples;
|
||||
std::vector<Rasterizer*> rasterizers;
|
||||
bool started;
|
||||
bool finished;
|
||||
bool interrupted;
|
||||
|
||||
ParallelWork *current_work;
|
||||
|
|
|
@ -17,7 +17,7 @@ TerrainRasterizer::TerrainRasterizer(SoftwareRenderer* renderer, int client_id):
|
|||
|
||||
static inline Vector3 _getPoint(SoftwareRenderer* renderer, double x, double z)
|
||||
{
|
||||
return Vector3(x, renderer->getTerrainRenderer()->getHeight(x, z, 1), z);
|
||||
return Vector3(x, renderer->getTerrainRenderer()->getHeight(x, z, true), z);
|
||||
}
|
||||
|
||||
void TerrainRasterizer::tessellateChunk(CanvasPortion* canvas, TerrainChunkInfo* chunk, int detail)
|
||||
|
@ -52,19 +52,19 @@ void TerrainRasterizer::renderQuad(CanvasPortion *canvas, double x, double z, do
|
|||
|
||||
ov1.x = x;
|
||||
ov1.z = z;
|
||||
dv1 = renderer->getTerrainRenderer()->getResult(x, z, 1, 1).location;
|
||||
dv1 = renderer->getTerrainRenderer()->getResult(x, z, true, true).location;
|
||||
|
||||
ov2.x = x;
|
||||
ov2.z = z + size;
|
||||
dv2 = renderer->getTerrainRenderer()->getResult(x, z + size, 1, 1).location;
|
||||
dv2 = renderer->getTerrainRenderer()->getResult(x, z + size, true, true).location;
|
||||
|
||||
ov3.x = x + size;
|
||||
ov3.z = z + size;
|
||||
dv3 = renderer->getTerrainRenderer()->getResult(x + size, z + size, 1, 1).location;
|
||||
dv3 = renderer->getTerrainRenderer()->getResult(x + size, z + size, true, true).location;
|
||||
|
||||
ov4.x = x + size;
|
||||
ov4.z = z;
|
||||
dv4 = renderer->getTerrainRenderer()->getResult(x + size, z, 1, 1).location;
|
||||
dv4 = renderer->getTerrainRenderer()->getResult(x + size, z, true, true).location;
|
||||
|
||||
if (dv1.y > water_height || dv2.y > water_height || dv3.y > water_height || dv4.y > water_height)
|
||||
{
|
||||
|
@ -72,12 +72,12 @@ void TerrainRasterizer::renderQuad(CanvasPortion *canvas, double x, double z, do
|
|||
}
|
||||
}
|
||||
|
||||
static void _getChunk(SoftwareRenderer* renderer, TerrainRasterizer::TerrainChunkInfo* chunk, double x, double z, double size, int displaced)
|
||||
static void _getChunk(SoftwareRenderer* renderer, TerrainRasterizer::TerrainChunkInfo* chunk, double x, double z, double size, bool displaced)
|
||||
{
|
||||
chunk->point_nw = renderer->getTerrainRenderer()->getResult(x, z, 1, displaced).location;
|
||||
chunk->point_sw = renderer->getTerrainRenderer()->getResult(x, z + size, 1, displaced).location;
|
||||
chunk->point_se = renderer->getTerrainRenderer()->getResult(x + size, z + size, 1, displaced).location;
|
||||
chunk->point_ne = renderer->getTerrainRenderer()->getResult(x + size, z, 1, displaced).location;
|
||||
chunk->point_nw = renderer->getTerrainRenderer()->getResult(x, z, true, displaced).location;
|
||||
chunk->point_sw = renderer->getTerrainRenderer()->getResult(x, z + size, true, displaced).location;
|
||||
chunk->point_se = renderer->getTerrainRenderer()->getResult(x + size, z + size, true, displaced).location;
|
||||
chunk->point_ne = renderer->getTerrainRenderer()->getResult(x + size, z, true, displaced).location;
|
||||
|
||||
double displacement_power;
|
||||
if (displaced)
|
||||
|
@ -125,7 +125,7 @@ static void _getChunk(SoftwareRenderer* renderer, TerrainRasterizer::TerrainChun
|
|||
}
|
||||
}
|
||||
|
||||
void TerrainRasterizer::getTessellationInfo(CanvasPortion* canvas, int displaced)
|
||||
void TerrainRasterizer::getTessellationInfo(CanvasPortion* canvas, bool displaced)
|
||||
{
|
||||
TerrainChunkInfo chunk;
|
||||
int chunk_factor, chunk_count, i;
|
||||
|
@ -199,7 +199,7 @@ void TerrainRasterizer::processChunk(CanvasPortion* canvas, TerrainChunkInfo* ch
|
|||
|
||||
void TerrainRasterizer::rasterizeToCanvas(CanvasPortion *canvas)
|
||||
{
|
||||
getTessellationInfo(canvas, 0);
|
||||
getTessellationInfo(canvas, false);
|
||||
}
|
||||
|
||||
Color TerrainRasterizer::shadeFragment(const CanvasFragment &fragment) const
|
||||
|
|
|
@ -34,7 +34,7 @@ public:
|
|||
*
|
||||
* The terrain will be broken in chunks, most detailed near the camera.
|
||||
*/
|
||||
void getTessellationInfo(CanvasPortion* canvas, int displaced);
|
||||
void getTessellationInfo(CanvasPortion* canvas, bool displaced);
|
||||
|
||||
/**
|
||||
* Tessellate a terrain chunk, pushing the quads in the render area.
|
||||
|
|
|
@ -23,9 +23,9 @@ void TerrainRenderer::update()
|
|||
walker->update();
|
||||
}
|
||||
|
||||
double TerrainRenderer::getHeight(double x, double z, int with_painting)
|
||||
double TerrainRenderer::getHeight(double x, double z, bool with_painting)
|
||||
{
|
||||
return parent->getScenery()->getTerrain()->getInterpolatedHeight(x, z, 1, with_painting);
|
||||
return parent->getScenery()->getTerrain()->getInterpolatedHeight(x, z, true, with_painting);
|
||||
}
|
||||
|
||||
static inline Vector3 _getNormal4(Vector3 center, Vector3 north, Vector3 east, Vector3 south, Vector3 west)
|
||||
|
@ -50,7 +50,7 @@ static inline Vector3 _getNormal2(Vector3 center, Vector3 east, Vector3 south)
|
|||
return south.sub(center).crossProduct(east.sub(center)).normalize();
|
||||
}
|
||||
|
||||
TerrainRenderer::TerrainResult TerrainRenderer::getResult(double x, double z, int with_painting, int with_textures)
|
||||
TerrainRenderer::TerrainResult TerrainRenderer::getResult(double x, double z, bool with_painting, bool with_textures)
|
||||
{
|
||||
TerrainResult result;
|
||||
double detail = 0.001; /* TODO */
|
||||
|
|
|
@ -27,8 +27,8 @@ public:
|
|||
virtual void update();
|
||||
|
||||
virtual RayCastingResult castRay(const Vector3 &start, const Vector3 &direction);
|
||||
virtual double getHeight(double x, double z, int with_painting);
|
||||
virtual TerrainResult getResult(double x, double z, int with_painting, int with_textures);
|
||||
virtual double getHeight(double x, double z, bool with_painting);
|
||||
virtual TerrainResult getResult(double x, double z, bool with_painting, bool with_textures);
|
||||
virtual Color getFinalColor(const Vector3 &location, double precision);
|
||||
virtual bool applyLightFilter(LightComponent &light, const Vector3 &at) override;
|
||||
|
||||
|
|
36
src/tests/AtmosphereDefinition_Test.cpp
Normal file
|
@ -0,0 +1,36 @@
|
|||
#include "BaseTestCase.h"
|
||||
|
||||
#include "AtmosphereDefinition.h"
|
||||
|
||||
TEST(AtmosphereDefinition, setDaytime)
|
||||
{
|
||||
AtmosphereDefinition atmo(NULL);
|
||||
|
||||
atmo.setDaytime(0.0);
|
||||
EXPECT_EQ(atmo.hour, 0);
|
||||
EXPECT_EQ(atmo.minute, 0);
|
||||
|
||||
atmo.setDaytime(0.1);
|
||||
EXPECT_EQ(atmo.hour, 2);
|
||||
EXPECT_EQ(atmo.minute, 24);
|
||||
|
||||
atmo.setDaytime(0.25);
|
||||
EXPECT_EQ(atmo.hour, 6);
|
||||
EXPECT_EQ(atmo.minute, 0);
|
||||
|
||||
atmo.setDaytime(0.5);
|
||||
EXPECT_EQ(atmo.hour, 12);
|
||||
EXPECT_EQ(atmo.minute, 0);
|
||||
|
||||
atmo.setDaytime(1.0);
|
||||
EXPECT_EQ(atmo.hour, 0);
|
||||
EXPECT_EQ(atmo.minute, 0);
|
||||
|
||||
atmo.setDaytime(-0.5);
|
||||
EXPECT_EQ(atmo.hour, 12);
|
||||
EXPECT_EQ(atmo.minute, 0);
|
||||
|
||||
atmo.setDaytime(1.5);
|
||||
EXPECT_EQ(atmo.hour, 12);
|
||||
EXPECT_EQ(atmo.minute, 0);
|
||||
}
|
|
@ -20,7 +20,8 @@ SOURCES += main.cpp \
|
|||
FractalNoise_Test.cpp \
|
||||
Canvas_Test.cpp \
|
||||
CanvasPortion_Test.cpp \
|
||||
CanvasPreview_Test.cpp
|
||||
CanvasPreview_Test.cpp \
|
||||
AtmosphereDefinition_Test.cpp
|
||||
|
||||
HEADERS += \
|
||||
BaseTestCase.h
|
||||
|
|