Merge branch 'quick_ui'
1
.gitignore
vendored
|
@ -22,3 +22,4 @@ ui_*.h
|
||||||
/paysages3d-linux/
|
/paysages3d-linux/
|
||||||
/paysages3d-linux.tar.bz2
|
/paysages3d-linux.tar.bz2
|
||||||
/config.vim
|
/config.vim
|
||||||
|
/callgrind.out.*
|
||||||
|
|
3
Makefile
|
@ -45,6 +45,9 @@ endif
|
||||||
run_cli:build
|
run_cli:build
|
||||||
LD_LIBRARY_PATH=$(LIBRARY_PATH) ${RUNNER} ${BUILDPATH}/interface/commandline/paysages-cli $(ARGS)
|
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
|
run:build
|
||||||
LD_LIBRARY_PATH=$(LIBRARY_PATH) ${RUNNER} ${BUILDPATH}/interface/desktop/paysages-gui $(ARGS)
|
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;
|
_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)
|
void AtmosphereDefinition::applyPreset(AtmospherePreset preset)
|
||||||
{
|
{
|
||||||
sun_color.r = 1.0;
|
sun_color.r = 1.0;
|
||||||
|
|
|
@ -46,6 +46,11 @@ public:
|
||||||
virtual void copy(BaseDefinition* destination) const override;
|
virtual void copy(BaseDefinition* destination) const override;
|
||||||
virtual void validate() override;
|
virtual void validate() override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the daytime from a 0.0-1.0 value.
|
||||||
|
*/
|
||||||
|
void setDaytime(double value);
|
||||||
|
|
||||||
void applyPreset(AtmospherePreset preset);
|
void applyPreset(AtmospherePreset preset);
|
||||||
void generateStars(int count);
|
void generateStars(int count);
|
||||||
|
|
||||||
|
|
|
@ -182,7 +182,7 @@ void Scenery::getWater(WaterDefinition* water)
|
||||||
void Scenery::checkCameraAboveGround()
|
void Scenery::checkCameraAboveGround()
|
||||||
{
|
{
|
||||||
Vector3 camera_location = camera->getLocation();
|
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;
|
double water_height = 1.5;
|
||||||
if (camera_location.y < water_height || camera_location.y < terrain_height)
|
if (camera_location.y < water_height || camera_location.y < terrain_height)
|
||||||
{
|
{
|
||||||
|
|
|
@ -82,7 +82,7 @@ void TerrainDefinition::load(PackStream* stream)
|
||||||
validate();
|
validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
double TerrainDefinition::getGridHeight(int x, int z, int with_painting)
|
double TerrainDefinition::getGridHeight(int x, int z, bool with_painting)
|
||||||
{
|
{
|
||||||
double h;
|
double h;
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ double TerrainDefinition::getGridHeight(int x, int z, int with_painting)
|
||||||
return h;
|
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;
|
double h;
|
||||||
x /= scaling;
|
x /= scaling;
|
||||||
|
|
|
@ -27,8 +27,8 @@ public:
|
||||||
virtual void copy(BaseDefinition* destination) const override;
|
virtual void copy(BaseDefinition* destination) const override;
|
||||||
virtual void validate() override;
|
virtual void validate() override;
|
||||||
|
|
||||||
double getGridHeight(int x, int z, int with_painting);
|
double getGridHeight(int x, int z, bool with_painting);
|
||||||
double getInterpolatedHeight(double x, double z, int scaled, int with_painting);
|
double getInterpolatedHeight(double x, double z, bool scaled, bool with_painting);
|
||||||
unsigned long getMemoryStats();
|
unsigned long getMemoryStats();
|
||||||
HeightInfo getHeightInfo();
|
HeightInfo getHeightInfo();
|
||||||
|
|
||||||
|
|
|
@ -135,7 +135,7 @@ void PaintingBrush::applyToTerrain(TerrainDefinition* terrain, double x, double
|
||||||
case PAINTING_BRUSH_FLATTEN:
|
case PAINTING_BRUSH_FLATTEN:
|
||||||
if (reverse)
|
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
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -218,7 +218,7 @@ void WidgetHeightMap::timerEvent(QTimerEvent*)
|
||||||
_last_time = new_time;
|
_last_time = new_time;
|
||||||
|
|
||||||
// Update top camera
|
// 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->setLocationCoords(target.x, target.y + 1.0, target.z + 0.1);
|
||||||
_top_camera->setTarget(target);
|
_top_camera->setTarget(target);
|
||||||
_top_camera->setZoomToTarget(_zoom);
|
_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/preview \
|
||||||
render/opengl \
|
render/opengl \
|
||||||
interface/commandline \
|
interface/commandline \
|
||||||
interface/desktop
|
interface/desktop \
|
||||||
|
interface/modeler
|
||||||
|
|
||||||
exists( tests/googletest/sources/src/gtest-all.cc ) {
|
exists( tests/googletest/sources/src/gtest-all.cc ) {
|
||||||
SUBDIRS += \
|
SUBDIRS += \
|
||||||
|
|
|
@ -85,7 +85,7 @@ bool ExplorerChunkTerrain::maintain()
|
||||||
double x = _startx + _tessellation_step * (float)i;
|
double x = _startx + _tessellation_step * (float)i;
|
||||||
double z = _startz + _tessellation_step * (float)j;
|
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)
|
if (height >= _water_height)
|
||||||
{
|
{
|
||||||
overwater = true;
|
overwater = true;
|
||||||
|
|
|
@ -16,6 +16,8 @@ OpenGLRenderer::OpenGLRenderer(Scenery* scenery):
|
||||||
SoftwareRenderer(scenery)
|
SoftwareRenderer(scenery)
|
||||||
{
|
{
|
||||||
ready = false;
|
ready = false;
|
||||||
|
vp_width = 1;
|
||||||
|
vp_height = 1;
|
||||||
|
|
||||||
render_quality = 3;
|
render_quality = 3;
|
||||||
|
|
||||||
|
@ -50,25 +52,7 @@ void OpenGLRenderer::initialize()
|
||||||
|
|
||||||
if (ready)
|
if (ready)
|
||||||
{
|
{
|
||||||
functions->glClearColor(0.0, 0.0, 0.0, 0.0);
|
prepareOpenGLState();
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
prepare();
|
prepare();
|
||||||
|
|
||||||
|
@ -92,28 +76,63 @@ void OpenGLRenderer::initialize()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLRenderer::resize(int width, int height)
|
void OpenGLRenderer::prepareOpenGLState()
|
||||||
{
|
{
|
||||||
if (ready)
|
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);
|
getScenery()->getCamera()->setRenderSize(width, height);
|
||||||
render_camera->setRenderSize(width, height);
|
render_camera->setRenderSize(width, height);
|
||||||
|
|
||||||
cameraChangeEvent(getScenery()->getCamera());
|
cameraChangeEvent(getScenery()->getCamera());
|
||||||
|
|
||||||
|
prepareOpenGLState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLRenderer::paint()
|
void OpenGLRenderer::paint()
|
||||||
{
|
{
|
||||||
if (ready)
|
if (ready)
|
||||||
{
|
{
|
||||||
functions->glClearColor(0.0, 0.0, 0.0, 0.0);
|
|
||||||
functions->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
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();
|
skybox->render();
|
||||||
terrain->render();
|
terrain->render();
|
||||||
water->render();
|
water->render();
|
||||||
|
|
|
@ -17,10 +17,21 @@ public:
|
||||||
OpenGLRenderer(Scenery* scenery=0);
|
OpenGLRenderer(Scenery* scenery=0);
|
||||||
virtual ~OpenGLRenderer();
|
virtual ~OpenGLRenderer();
|
||||||
|
|
||||||
|
inline OpenGLSkybox *getSkybox() const {return skybox;}
|
||||||
|
inline OpenGLWater *getWater() const {return water;}
|
||||||
|
inline OpenGLTerrain *getTerrain() const {return terrain;}
|
||||||
|
|
||||||
void initialize();
|
void initialize();
|
||||||
|
void prepareOpenGLState();
|
||||||
void resize(int width, int height);
|
void resize(int width, int height);
|
||||||
void paint();
|
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);
|
void cameraChangeEvent(CameraDefinition* camera);
|
||||||
|
|
||||||
inline OpenGLFunctions* getOpenGlFunctions() const {return functions;}
|
inline OpenGLFunctions* getOpenGlFunctions() const {return functions;}
|
||||||
|
@ -31,6 +42,8 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool ready;
|
bool ready;
|
||||||
|
int vp_width;
|
||||||
|
int vp_height;
|
||||||
|
|
||||||
OpenGLFunctions* functions;
|
OpenGLFunctions* functions;
|
||||||
OpenGLSharedState* shared_state;
|
OpenGLSharedState* shared_state;
|
||||||
|
|
|
@ -25,7 +25,7 @@ void OpenGLSkybox::initialize()
|
||||||
{
|
{
|
||||||
program = createShader("skybox");
|
program = createShader("skybox");
|
||||||
program->addVertexSource("skybox");
|
program->addVertexSource("skybox");
|
||||||
program->addFragmentSource("bruneton");
|
program->addFragmentSource("atmosphere");
|
||||||
program->addFragmentSource("tonemapping");
|
program->addFragmentSource("tonemapping");
|
||||||
program->addFragmentSource("skybox");
|
program->addFragmentSource("skybox");
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ void OpenGLTerrain::initialize()
|
||||||
// Prepare shader programs
|
// Prepare shader programs
|
||||||
program = createShader("terrain");
|
program = createShader("terrain");
|
||||||
program->addVertexSource("terrain");
|
program->addVertexSource("terrain");
|
||||||
program->addFragmentSource("bruneton");
|
program->addFragmentSource("atmosphere");
|
||||||
program->addFragmentSource("tonemapping");
|
program->addFragmentSource("tonemapping");
|
||||||
program->addFragmentSource("fadeout");
|
program->addFragmentSource("fadeout");
|
||||||
program->addFragmentSource("terrain");
|
program->addFragmentSource("terrain");
|
||||||
|
|
|
@ -24,7 +24,7 @@ void OpenGLWater::initialize()
|
||||||
{
|
{
|
||||||
program = createShader("water");
|
program = createShader("water");
|
||||||
program->addVertexSource("water");
|
program->addVertexSource("water");
|
||||||
program->addFragmentSource("bruneton");
|
program->addFragmentSource("atmosphere");
|
||||||
program->addFragmentSource("tonemapping");
|
program->addFragmentSource("tonemapping");
|
||||||
program->addFragmentSource("fadeout");
|
program->addFragmentSource("fadeout");
|
||||||
program->addFragmentSource("noise");
|
program->addFragmentSource("noise");
|
||||||
|
|
|
@ -224,3 +224,53 @@ vec4 getSkyColor(vec3 location, vec3 direction)
|
||||||
result += sunTransmittance + vec4(inscattering, 0.0);
|
result += sunTransmittance + vec4(inscattering, 0.0);
|
||||||
return result;
|
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>skybox.vert</file>
|
||||||
<file>water.frag</file>
|
<file>water.frag</file>
|
||||||
<file>water.vert</file>
|
<file>water.vert</file>
|
||||||
<file>bruneton.frag</file>
|
<file>atmosphere.frag</file>
|
||||||
<file>tonemapping.frag</file>
|
<file>tonemapping.frag</file>
|
||||||
<file>terrain.frag</file>
|
<file>terrain.frag</file>
|
||||||
<file>terrain.vert</file>
|
<file>terrain.vert</file>
|
||||||
|
|
|
@ -1,32 +1,11 @@
|
||||||
uniform vec4 waterColor;
|
uniform vec4 waterColor;
|
||||||
uniform float waterReflection;
|
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)
|
void main(void)
|
||||||
{
|
{
|
||||||
vec3 normal = noiseNormal2d(unprojected.xz, 0.001);
|
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);
|
vec3 reflected = reflect(unprojected - cameraLocation, normal);
|
||||||
reflected.y = max(reflected.y, 0.0);
|
reflected.y = max(reflected.y, 0.0);
|
||||||
|
|
|
@ -46,7 +46,7 @@ void SceneryTopDownPreviewRenderer::updateEvent()
|
||||||
Color SceneryTopDownPreviewRenderer::getColor2D(double x, double y, double scaling)
|
Color SceneryTopDownPreviewRenderer::getColor2D(double x, double y, double scaling)
|
||||||
{
|
{
|
||||||
Vector3 location;
|
Vector3 location;
|
||||||
double height = getTerrainRenderer()->getHeight(x, y, 1);
|
double height = getTerrainRenderer()->getHeight(x, y, true);
|
||||||
|
|
||||||
if (height < getWaterRenderer()->getHeightInfo().max_height)
|
if (height < getWaterRenderer()->getHeightInfo().max_height)
|
||||||
{
|
{
|
||||||
|
|
|
@ -57,7 +57,7 @@ Color TerrainShapePreviewRenderer::getColor2D(double x, double y, double scaling
|
||||||
{
|
{
|
||||||
double height;
|
double height;
|
||||||
|
|
||||||
height = getTerrainRenderer()->getHeight(x, y, 1);
|
height = getTerrainRenderer()->getHeight(x, y, true);
|
||||||
if (height > 0.0)
|
if (height > 0.0)
|
||||||
{
|
{
|
||||||
return getTerrainRenderer()->getFinalColor(Vector3(x, height, y), 0.000001);
|
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();
|
TexturesRenderer* textures_renderer = getTexturesRenderer();
|
||||||
TerrainRenderer* terrain_renderer = getTerrainRenderer();
|
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);
|
return Color(presence, presence, presence);
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,6 @@ void TexturesMixPreviewRenderer::updateEvent()
|
||||||
Color TexturesMixPreviewRenderer::getColor2D(double x, double y, double scaling)
|
Color TexturesMixPreviewRenderer::getColor2D(double x, double y, double scaling)
|
||||||
{
|
{
|
||||||
TerrainRenderer* terrain_renderer = getTerrainRenderer();
|
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);
|
return terrain_renderer->getFinalColor(location, scaling);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
SoftwareCanvasRenderer::SoftwareCanvasRenderer()
|
SoftwareCanvasRenderer::SoftwareCanvasRenderer()
|
||||||
{
|
{
|
||||||
started = false;
|
started = false;
|
||||||
|
finished = false;
|
||||||
interrupted = false;
|
interrupted = false;
|
||||||
canvas = new Canvas();
|
canvas = new Canvas();
|
||||||
progress = 0.0;
|
progress = 0.0;
|
||||||
|
@ -95,6 +96,7 @@ void SoftwareCanvasRenderer::render()
|
||||||
progress = (double)i / (double)n;
|
progress = (double)i / (double)n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
finished = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftwareCanvasRenderer::interrupt()
|
void SoftwareCanvasRenderer::interrupt()
|
||||||
|
|
|
@ -24,6 +24,7 @@ public:
|
||||||
|
|
||||||
inline const Canvas *getCanvas() const {return canvas;}
|
inline const Canvas *getCanvas() const {return canvas;}
|
||||||
inline double getProgress() const {return progress;}
|
inline double getProgress() const {return progress;}
|
||||||
|
inline bool isFinished() const {return finished;}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the renderer configuration.
|
* Set the renderer configuration.
|
||||||
|
@ -78,6 +79,7 @@ private:
|
||||||
int samples;
|
int samples;
|
||||||
std::vector<Rasterizer*> rasterizers;
|
std::vector<Rasterizer*> rasterizers;
|
||||||
bool started;
|
bool started;
|
||||||
|
bool finished;
|
||||||
bool interrupted;
|
bool interrupted;
|
||||||
|
|
||||||
ParallelWork *current_work;
|
ParallelWork *current_work;
|
||||||
|
|
|
@ -17,7 +17,7 @@ TerrainRasterizer::TerrainRasterizer(SoftwareRenderer* renderer, int client_id):
|
||||||
|
|
||||||
static inline Vector3 _getPoint(SoftwareRenderer* renderer, double x, double z)
|
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)
|
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.x = x;
|
||||||
ov1.z = z;
|
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.x = x;
|
||||||
ov2.z = z + size;
|
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.x = x + size;
|
||||||
ov3.z = z + 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.x = x + size;
|
||||||
ov4.z = z;
|
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)
|
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_nw = renderer->getTerrainRenderer()->getResult(x, z, true, displaced).location;
|
||||||
chunk->point_sw = renderer->getTerrainRenderer()->getResult(x, z + size, 1, displaced).location;
|
chunk->point_sw = renderer->getTerrainRenderer()->getResult(x, z + size, true, displaced).location;
|
||||||
chunk->point_se = renderer->getTerrainRenderer()->getResult(x + size, z + size, 1, displaced).location;
|
chunk->point_se = renderer->getTerrainRenderer()->getResult(x + size, z + size, true, displaced).location;
|
||||||
chunk->point_ne = renderer->getTerrainRenderer()->getResult(x + size, z, 1, displaced).location;
|
chunk->point_ne = renderer->getTerrainRenderer()->getResult(x + size, z, true, displaced).location;
|
||||||
|
|
||||||
double displacement_power;
|
double displacement_power;
|
||||||
if (displaced)
|
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;
|
TerrainChunkInfo chunk;
|
||||||
int chunk_factor, chunk_count, i;
|
int chunk_factor, chunk_count, i;
|
||||||
|
@ -199,7 +199,7 @@ void TerrainRasterizer::processChunk(CanvasPortion* canvas, TerrainChunkInfo* ch
|
||||||
|
|
||||||
void TerrainRasterizer::rasterizeToCanvas(CanvasPortion *canvas)
|
void TerrainRasterizer::rasterizeToCanvas(CanvasPortion *canvas)
|
||||||
{
|
{
|
||||||
getTessellationInfo(canvas, 0);
|
getTessellationInfo(canvas, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Color TerrainRasterizer::shadeFragment(const CanvasFragment &fragment) const
|
Color TerrainRasterizer::shadeFragment(const CanvasFragment &fragment) const
|
||||||
|
|
|
@ -34,7 +34,7 @@ public:
|
||||||
*
|
*
|
||||||
* The terrain will be broken in chunks, most detailed near the camera.
|
* 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.
|
* Tessellate a terrain chunk, pushing the quads in the render area.
|
||||||
|
|
|
@ -23,9 +23,9 @@ void TerrainRenderer::update()
|
||||||
walker->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)
|
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();
|
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;
|
TerrainResult result;
|
||||||
double detail = 0.001; /* TODO */
|
double detail = 0.001; /* TODO */
|
||||||
|
|
|
@ -27,8 +27,8 @@ public:
|
||||||
virtual void update();
|
virtual void update();
|
||||||
|
|
||||||
virtual RayCastingResult castRay(const Vector3 &start, const Vector3 &direction);
|
virtual RayCastingResult castRay(const Vector3 &start, const Vector3 &direction);
|
||||||
virtual double getHeight(double x, double z, int with_painting);
|
virtual double getHeight(double x, double z, bool with_painting);
|
||||||
virtual TerrainResult getResult(double x, double z, int with_painting, int with_textures);
|
virtual TerrainResult getResult(double x, double z, bool with_painting, bool with_textures);
|
||||||
virtual Color getFinalColor(const Vector3 &location, double precision);
|
virtual Color getFinalColor(const Vector3 &location, double precision);
|
||||||
virtual bool applyLightFilter(LightComponent &light, const Vector3 &at) override;
|
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 \
|
FractalNoise_Test.cpp \
|
||||||
Canvas_Test.cpp \
|
Canvas_Test.cpp \
|
||||||
CanvasPortion_Test.cpp \
|
CanvasPortion_Test.cpp \
|
||||||
CanvasPreview_Test.cpp
|
CanvasPreview_Test.cpp \
|
||||||
|
AtmosphereDefinition_Test.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
BaseTestCase.h
|
BaseTestCase.h
|
||||||
|
|