1
0
Fork 0

Merge branch 'next' into volumetric-clouds

This commit is contained in:
Fernando García Liñán 2019-12-01 14:41:48 +01:00
commit 9a8c28af1c
43 changed files with 292012 additions and 3801 deletions

View file

@ -0,0 +1,5 @@
<?xml version="1.0"?>
<PropertyList include="738-main.xml">
<texture-path>Textures/Icelandair</texture-path>
</PropertyList>

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 KiB

View file

@ -0,0 +1,9 @@
<?xml version="1.0"?>
<PropertyList include="73J-main.xml">
<texture-path>Textures/Icelandair</texture-path>
</PropertyList>

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

View file

@ -0,0 +1,9 @@
<?xml version="1.0"?>
<PropertyList include="76W-main.xml">
<texture-path>Textures/Icelandair</texture-path>
</PropertyList>

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 228 KiB

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 187 KiB

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 366 KiB

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 348 KiB

After

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 283 KiB

After

Width:  |  Height:  |  Size: 154 KiB

View file

@ -0,0 +1,9 @@
<?xml version="1.0"?>
<PropertyList include="ERJ170-main.xml">
<texture-path>Textures/United</texture-path>
</PropertyList>

View file

@ -0,0 +1,9 @@
<?xml version="1.0"?>
<PropertyList include="ERJ175-main.xml">
<texture-path>Textures/United</texture-path>
</PropertyList>

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

View file

@ -0,0 +1,7 @@
<?xml version="1.0"?>
<PropertyList include="ERJ145-main.xml">
<texture-path>Textures/AmericanEagle</texture-path>
</PropertyList>

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

View file

@ -355,7 +355,7 @@
</aircraft>
<alias>
<match>MD11</match>
<match>MF1</match>
<match>M1F</match>
<alias>M11</alias>
</alias>
<!-- McDonnell Douglas 80 all versions -->

18540
AI/Traffic/A/ASH.xml Normal file

File diff suppressed because it is too large Load diff

28514
AI/Traffic/C/CPZ.xml Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

39364
AI/Traffic/P/PDT.xml Normal file

File diff suppressed because it is too large Load diff

76480
AI/Traffic/R/RPA.xml Normal file

File diff suppressed because it is too large Load diff

51883
AI/Traffic/U/UPS.xml Normal file

File diff suppressed because it is too large Load diff

View file

@ -1335,10 +1335,20 @@ var CDU = {
formatSpeed: func(speed)
{
if (speed < 1.0)
return sprintf('.%3d', speed / 1000);
return sprintf('.%3d', speed * 1000);
sprintf(' %3d', speed);
},
formatSpeedMachKnots: func(mach, knots)
{
# tolerate either component being nil
var machStr = '----';
var knotsStr = '---';
if (mach) machStr = sprintf('.%03d', mach * 1000);
if (knots) knotsStr = sprintf('%3d', knots);
return machStr ~ '/' ~ knotsStr;
},
formatSpeedAltitude: func(speed, alt)
{
return me.formatSpeed(speed) ~ '/' ~ me.formatAltitude(alt);
@ -1364,6 +1374,33 @@ var CDU = {
return s;
},
formatTimeDistace: func(time, distance)
{
# the seperator slash is small, hence the markup
return me.formatTime(time) ~ '~/!' ~ me.formatDistanceNm(distance);
},
formatTime: func(time)
{
var hours = int(time / 3600.0);
var minutes = time - (hours * 3600.0);
# we want a single digit of minutes, so divide by 60 * 10
minutes = int(minutes / 600.0);
return sprintf('%04d.%d~Z', hours, minutes);
},
# this assumes a 6-char field, 4 digits for the value and 2 for 'NM'
formatDistance: func(d)
{
if (d < 10) {
# when distance is below 10nm, show decimal
return sprintf('%4.1f~NM', d);
}
return sprintf('%4d~NM', d);
},
# button / LSK functions
lsk: func(ident)
{

View file

@ -83,13 +83,13 @@
<name>forward</name>
<type>scene</type>
<effect-scheme>als-lighting</effect-scheme>
<!--
<clustered-shading>
<tile-size>128</tile-size>
<num-threads>4</num-threads>
<depth-slices>16</depth-slices>
</clustered-shading>
-->
<clustered-shading>
<tile-size>128</tile-size>
<num-threads>1</num-threads>
<depth-slices>1</depth-slices>
</clustered-shading>
<use-shadow-pass>csm0</use-shadow-pass>
<use-shadow-pass>csm1</use-shadow-pass>
<use-shadow-pass>csm2</use-shadow-pass>

View file

@ -481,6 +481,15 @@
<fragment-shader>Shaders/ALS/noise.frag</fragment-shader>
<fragment-shader>Shaders/ALS/filters.frag</fragment-shader>
<fragment-shader>Shaders/ALS/shadows-include.frag</fragment-shader>
<fragment-shader>Shaders/ALS/clustered-include.frag</fragment-shader>
<uniform-block-binding>
<name>PointLightBlock</name>
<index>5</index>
</uniform-block-binding>
<uniform-block-binding>
<name>SpotLightBlock</name>
<index>6</index>
</uniform-block-binding>
</program>
<uniform>
<name>visibility</name>

View file

@ -0,0 +1,136 @@
#version 120
#extension GL_ARB_uniform_buffer_object : enable
#extension GL_EXT_gpu_shader4 : enable
uniform usampler3D fg_ClusteredLightGrid;
uniform usamplerBuffer fg_ClusteredLightIndices;
uniform int fg_ClusteredTileSize;
uniform float fg_ClusteredSliceScale;
uniform float fg_ClusteredSliceBias;
const bool debug = true;
const float shininess = 16.0;
struct PointLight {
vec4 position;
vec4 ambient;
vec4 diffuse;
vec4 specular;
vec4 attenuation;
};
struct SpotLight {
vec4 position;
vec4 direction;
vec4 ambient;
vec4 diffuse;
vec4 specular;
vec4 attenuation;
float cos_cutoff;
float exponent;
};
layout (std140) uniform PointLightBlock {
PointLight pointLights[256];
};
layout (std140) uniform SpotLightBlock {
SpotLight spotLights[256];
};
vec3 addColors(vec3 a, vec3 b)
{
return 0.14 * log(exp(a/0.14) + exp(b/0.14));
}
// @param p Fragment position in view space.
// @param n Fragment normal in view space.
vec3 addClusteredLightsContribution(vec3 inputColor, vec3 p, vec3 n)
{
int slice = int(max(log2(-p.z) * fg_ClusteredSliceScale
+ fg_ClusteredSliceBias, 0.0));
ivec3 clusterCoord = ivec3(gl_FragCoord.xy / fg_ClusteredTileSize, slice);
uvec3 cluster = texelFetch3D(fg_ClusteredLightGrid,
clusterCoord,
0).rgb;
uint startIndex = cluster.r;
uint pointCount = cluster.g;
uint spotCount = cluster.b;
vec3 color = vec3(0.0);
for (uint i = uint(0); i < pointCount; ++i) {
uint lightListIndex = texelFetchBuffer(fg_ClusteredLightIndices,
int(startIndex + i)).r;
PointLight light = pointLights[lightListIndex];
float range = light.attenuation.w;
vec3 toLight = light.position.xyz - p;
// Ignore fragments outside the light volume
if (dot(toLight, toLight) > (range * range))
continue;
////////////////////////////////////////////////////////////////////////
// Actual lighting
float d = length(toLight);
float att = 1.0 / (light.attenuation.x // constant
+ light.attenuation.y * d // linear
+ light.attenuation.z * d * d); // quadratic
vec3 lightDir = normalize(toLight);
float NdotL = max(dot(n, lightDir), 0.0);
vec3 Iamb = light.ambient.rgb;
vec3 Idiff = light.diffuse.rgb * NdotL;
vec3 Ispec = vec3(0.0);
if (NdotL > 0.0) {
vec3 halfVector = normalize(lightDir + normalize(-p));
float NdotHV = max(dot(n, halfVector), 0.0);
Ispec = light.specular.rgb * att * pow(NdotHV, shininess);
}
color += addColors(color, (Iamb + Idiff + Ispec) * att);
}
for (uint i = uint(0); i < spotCount; ++i) {
uint lightListIndex = texelFetchBuffer(fg_ClusteredLightIndices,
int(startIndex + i)).r;
SpotLight light = spotLights[lightListIndex];
vec3 toLight = light.position.xyz - p;
////////////////////////////////////////////////////////////////////////
// Actual lighting
float d = length(toLight);
float att = 1.0 / (light.attenuation.x // constant
+ light.attenuation.y * d // linear
+ light.attenuation.z * d * d); // quadratic
vec3 lightDir = normalize(toLight);
float spotDot = dot(-lightDir, light.direction.xyz);
if (spotDot < light.cos_cutoff)
continue;
att *= pow(spotDot, light.exponent);
float NdotL = max(dot(n, lightDir), 0.0);
vec3 Iamb = light.ambient.rgb;
vec3 Idiff = light.diffuse.rgb * NdotL;
vec3 Ispec = vec3(0.0);
if (NdotL > 0.0) {
vec3 halfVector = normalize(lightDir + normalize(-p));
float NdotHV = max(dot(n, halfVector), 0.0);
Ispec = light.specular.rgb * att * pow(NdotHV, shininess);
}
color += (Iamb + Idiff + Ispec) * att;
}
return clamp(color + inputColor, 0.0, 1.0);
}

View file

@ -22,6 +22,7 @@
varying vec4 diffuse_term;
varying vec3 normal;
varying vec3 relPos;
varying vec4 ecPosition;
varying float yprime_alt;
varying float mie_angle;
@ -75,7 +76,7 @@ void main()
// this code is copied from default.vert
//vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex;
ecPosition = gl_ModelViewMatrix * gl_Vertex;
gl_Position = ftransform();
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
normal = gl_NormalMatrix * gl_Normal;

View file

@ -6,7 +6,7 @@
varying vec4 diffuse_term;
varying vec3 normal;
varying vec3 relPos;
varying vec4 ecPosition;
uniform sampler2D texture;
@ -57,6 +57,7 @@ vec3 landing_light(in float offset, in float offsetv);
vec3 filter_combined (in vec3 color) ;
float getShadowing();
vec3 addClusteredLightsContribution(vec3 inputColor, vec3 v, vec3 N);
float luminance(vec3 color)
{
@ -318,6 +319,7 @@ fragColor.rgb = mix(hazeColor + secondary_light * fog_backscatter(mvisibility),
}
fragColor.rgb = addClusteredLightsContribution(fragColor.rgb, ecPosition.xyz, normal);
fragColor.rgb = filter_combined(fragColor.rgb);
gl_FragColor = fragColor;

View file

@ -411,7 +411,7 @@ Where:
- H is the building height in meters, excluding any pitched roof
- P is the pitch height in meters. 0 for a flat roof
- S is the roof shape (only 0, 2, 4, 6 are implemented, others are approximated to those) :
0=flat 1=skillion 2=gabled 3=half-hipped 4=hipped 5=pyramidal 6=gambled
0=flat 1=skillion 2=gabled 3=half-hipped 4=hipped 5=pyramidal 6=gambrel
7=mansard 8=dome 9=onion 10=round 11=saltbox
- O is the roof ridge orientation :
0 = parallel to the front face of the building

View file

@ -208,19 +208,19 @@
<index>10</index>
</attribute>
<attribute>
<name>instanceScaleRotate</name>
<name>instanceScale</name>
<index>11</index>
</attribute>
<attribute>
<name>rotPitchWtex0x</name>
<name>rotPitchWtexX0</name>
<index>12</index>
</attribute>
<attribute>
<name>wtex0yTex1xTex1y</name>
<name>wtexY0FRtexx1FSRtexY1</name>
<index>13</index>
</attribute>
<attribute>
<name>rtex0xRtex0y</name>
<name>rtexX0RtexY0StexX1</name>
<index>14</index>
</attribute>
<attribute>
@ -302,19 +302,19 @@
<index>10</index>
</attribute>
<attribute>
<name>instanceScaleRotate</name>
<name>instanceScale</name>
<index>11</index>
</attribute>
<attribute>
<name>rotPitchWtex0x</name>
<name>rotPitchWtexX0</name>
<index>12</index>
</attribute>
<attribute>
<name>wtex0yTex1xTex1y</name>
<name>wtexY0FRtexx1FSRtexY1</name>
<index>13</index>
</attribute>
<attribute>
<name>rtex0xRtex0y</name>
<name>rtexX0RtexY0StexX1</name>
<index>14</index>
</attribute>
<attribute>
@ -385,19 +385,19 @@
<index>10</index>
</attribute>
<attribute>
<name>instanceScaleRotate</name>
<name>instanceScale</name>
<index>11</index>
</attribute>
<attribute>
<name>rotPitchWtex0x</name>
<name>rotPitchWtexX0</name>
<index>12</index>
</attribute>
<attribute>
<name>wtex0yTex1xTex1y</name>
<name>wtexY0FRtexx1FSRtexY1</name>
<index>13</index>
</attribute>
<attribute>
<name>rtex0xRtex0y</name>
<name>rtexX0RtexY0StexX1</name>
<index>14</index>
</attribute>
<attribute>
@ -523,19 +523,19 @@
<index>10</index>
</attribute>
<attribute>
<name>instanceScaleRotate</name>
<name>instanceScale</name>
<index>11</index>
</attribute>
<attribute>
<name>rotPitchWtex0x</name>
<name>rotPitchWtexX0</name>
<index>12</index>
</attribute>
<attribute>
<name>wtex0yTex1xTex1y</name>
<name>wtexY0FRtexx1FSRtexY1</name>
<index>13</index>
</attribute>
<attribute>
<name>rtex0xRtex0y</name>
<name>rtexX0RtexY0StexX1</name>
<index>14</index>
</attribute>
<attribute>
@ -587,19 +587,19 @@
<index>10</index>
</attribute>
<attribute>
<name>instanceScaleRotate</name>
<name>instanceScale</name>
<index>11</index>
</attribute>
<attribute>
<name>rotPitchWtex0x</name>
<name>rotPitchWtexX0</name>
<index>12</index>
</attribute>
<attribute>
<name>wtex0yTex1xTex1y</name>
<name>wtexY0FRtexx1FSRtexY1</name>
<index>13</index>
</attribute>
<attribute>
<name>rtex0xRtex0y</name>
<name>rtexX0RtexY0StexX1</name>
<index>14</index>
</attribute>
<attribute>
@ -709,19 +709,19 @@
<index>10</index>
</attribute>
<attribute>
<name>instanceScaleRotate</name>
<name>instanceScale</name>
<index>11</index>
</attribute>
<attribute>
<name>rotPitchWtex0x</name>
<name>rotPitchWtexX0</name>
<index>12</index>
</attribute>
<attribute>
<name>wtex0yTex1xTex1y</name>
<name>wtexY0FRtexx1FSRtexY1</name>
<index>13</index>
</attribute>
<attribute>
<name>rtex0xRtex0y</name>
<name>rtexX0RtexY0StexX1</name>
<index>14</index>
</attribute>
<attribute>

View file

@ -924,5 +924,39 @@
<a>1.0</a>
</emissive>
</material>
<material>
<name>OSMBuildings</name>
<building-small-ratio>0.4</building-small-ratio>
<building-medium-ratio>0.5</building-medium-ratio>
<building-large-ratio>0.1</building-large-ratio>
<building-small-pitch>0.8</building-small-pitch>
<building-medium-pitch>0.8</building-medium-pitch>
<building-large-pitch>0.4</building-large-pitch>
<building-small-min-floors>1</building-small-min-floors>
<building-small-max-floors>2</building-small-max-floors>
<building-medium-min-floors>2</building-medium-min-floors>
<building-medium-max-floors>3</building-medium-max-floors>
<building-large-min-floors>3</building-large-min-floors>
<building-large-max-floors>5</building-large-max-floors>
<building-small-min-width-m>9</building-small-min-width-m>
<building-small-max-width-m>14</building-small-max-width-m>
<building-small-min-depth-m>8</building-small-min-depth-m>
<building-small-max-depth-m>12</building-small-max-depth-m>
<building-medium-min-width-m>15</building-medium-min-width-m>
<building-medium-max-width-m>20</building-medium-max-width-m>
<building-medium-min-depth-m>10</building-medium-min-depth-m>
<building-medium-max-depth-m>15</building-medium-max-depth-m>
<building-large-min-width-m>15</building-large-min-width-m>
<building-large-max-width-m>22</building-large-max-width-m>
<building-large-min-depth-m>12</building-large-min-depth-m>
<building-large-max-depth-m>18</building-large-max-depth-m>
</material>
</PropertyList>

View file

@ -88,7 +88,9 @@ var Window = {
m.setInt("content-size[0]", size[0]);
m.setInt("content-size[1]", size[1]);
m.setDouble("aspect-ratio", size[0]/size[1]);
m.setBool("lock-aspect-ratio", 0);
# TODO better default position
m.move(0,0);
m.setFocus();
@ -289,6 +291,9 @@ var Window = {
me._canvas.set("view[" ~ i ~ "]", size);
}
},
lockAspectRatio: func (lock=1) {
me.setBool("lock-aspect-ratio", lock);
},
# protected:
_onStateChange: func
{
@ -317,6 +322,7 @@ var Window = {
.dispatchEvent(event);
},
# private:
#mode 0 = value changed, +-1 add/remove node
_propCallback: func(child, mode)
{
if( !me._node.equals(child.getParent()) )
@ -394,12 +400,28 @@ var Window = {
var x = me.get("tf/t[0]");
var y = me.get("tf/t[1]");
var old_size = [me.get("size[0]"), me.get("size[1]")];
if (me.get("lock-aspect-ratio"))
{
var old_csize = [me.get("content-size[0]"), me.get("content-size[1]")];
var dx = old_size[0] - old_csize[0];
var dy = old_size[1] - old_csize[1];
var ar = me.get("aspect-ratio");
if (name == "resize-right")
me.set("resize-bottom", (me.get("resize-right") - dx) / ar + dy);
if (name == "resize-bottom")
me.set("resize-right", (me.get("resize-bottom") - dy)* ar + dx);
if (name == "resize-left")
me.set("resize-top", (me.get("resize-left"))/ ar );
if (name == "resize-top")
me.set("resize-left", (me.get("resize-top"))* ar );
}
var l = x + math.min(me.get("resize-left"), old_size[0] - min_size[0]);
var t = y + math.min(me.get("resize-top"), old_size[1] - min_size[1]);
var r = x + math.max(me.get("resize-right"), min_size[0]);
var b = y + math.max(me.get("resize-bottom"), min_size[1]);
if( is_status )
{
me._resize = child.getValue();

View file

@ -22,6 +22,27 @@ var dirname = func(path) {
substr(path, 0, size(path) - size(basename(path)));
};
var is_directory = func(path) {
var tmp = stat(path);
if (tmp != nil and tmp[11] == "dir") return 1;
else return 0;
};
# <path> the path that should be searched for subdirectories
# returns a vector of subdirectory names
var subdirectories = func(path) {
if (!is_directory(path))
return;
var list = subvec(directory(path), 2);
var subdirs = [];
foreach (var entry; list) {
if (is_directory(path~"/"~entry)) {
append(subdirs, entry);
}
}
return subdirs;
}
# include(<filename>)
#
# Loads and executes a Nasal file in place. The file is searched for in the

View file

@ -17,10 +17,10 @@
#define MODE_AMBIENT_AND_DIFFUSE 2
attribute vec3 instancePosition; // (x,y,z)
attribute vec3 instanceScaleRotate; // (width, depth, height)
attribute vec3 rotPitchWtex0x; // (rotation, pitch height, texture x offset)
attribute vec3 wtex0yTex1xTex1y; // (wall texture y offset, wall/roof texture x gain, wall/roof texture y gain)
attribute vec3 rtex0xRtex0y; // (roof texture y offset, roof texture x gain, texture y gain)
attribute vec3 instanceScale; // (width, depth, height)
attribute vec3 rotPitchWtexX0; // (rotation, pitch height, wall texture x0)
attribute vec3 wtexY0FRtexx1FSRtexY1; // (wall texture y0, front/roof texture x1, front/side/roof texture y1)
attribute vec3 rtexX0RtexY0StexX1; // (roof texture x0, roof texture y0, side texture x1)
attribute vec3 rooftopscale; // (rooftop x scale, rooftop y scale)
// The constant term of the lighting equation that doesn't depend on
@ -83,8 +83,8 @@ void main()
vec3 shadedFogColor = vec3(0.55, 0.67, 0.88);
// Determine the rotation for the building.
float sr = sin(6.28 * rotPitchWtex0x.x);
float cr = cos(6.28 * rotPitchWtex0x.x);
float sr = sin(6.28 * rotPitchWtexX0.x);
float cr = cos(6.28 * rotPitchWtexX0.x);
vec3 position = gl_Vertex.xyz;
// Adjust the very top of the roof to match the rooftop scaling. This shapes
@ -93,10 +93,10 @@ void main()
position.y = (1.0 - gl_Color.z) * position.y + gl_Color.z * (position.y * rooftopscale.y);
// Adjust pitch of roof to the correct height. These vertices are identified by gl_Color.z
// Scale down by the building height (instanceScaleRotate.z) because
// Scale down by the building height (instanceScale.z) because
// immediately afterwards we will scale UP the vertex to the correct scale.
position.z = position.z + gl_Color.z * rotPitchWtex0x.y / instanceScaleRotate.z;
position = position * instanceScaleRotate.xyz;
position.z = position.z + gl_Color.z * rotPitchWtexX0.y / instanceScale.z;
position = position * instanceScale.xyz;
// Rotation of the building and movement into position
position.xy = vec2(dot(position.xy, vec2(cr, sr)), dot(position.xy, vec2(-sr, cr)));
@ -105,16 +105,31 @@ void main()
gl_Position = gl_ModelViewProjectionMatrix * vec4(position,1.0);
// Texture coordinates are stored as:
// - a separate offset for the wall (wtex0x, wtex0y), and roof (rtex0x, rtex0y)
// - a shared gain value (tex1x, tex1y)
// - a separate offset (x0, y0) for the wall (wtex0x, wtex0y), and roof (rtex0x, rtex0y)
// - a semi-shared (x1, y1) so that the front and side of the building can have
// different texture mappings
//
// The vertex color value selects between them, with glColor.x=1 indicating walls
// and glColor.y=1 indicating roofs.
// Finally, the roof texture is on the left of the texture sheet
vec2 tex0 = vec2(sign(gl_MultiTexCoord0.x) * (gl_Color.x*rotPitchWtex0x.z + gl_Color.y*rtex0xRtex0y.x),
gl_Color.x*wtex0yTex1xTex1y.x + gl_Color.y*rtex0xRtex0y.y);
gl_TexCoord[0].x = tex0.x + gl_MultiTexCoord0.x * wtex0yTex1xTex1y.y;
gl_TexCoord[0].y = tex0.y + gl_MultiTexCoord0.y * wtex0yTex1xTex1y.z;
// The vertex color value selects between them:
// gl_Color.x=1 indicates front/back walls
// gl_Color.y=1 indicates roof
// gl_Color.z=1 indicates top roof vertexs (used above)
// gl_Color.a=1 indicates sides
// Finally, the roof texture is on the right of the texture sheet
float wtex0x = rotPitchWtexX0.z; // Front/Side texture X0
float wtex0y = wtexY0FRtexx1FSRtexY1.x; // Front/Side texture Y0
float rtex0x = rtexX0RtexY0StexX1.x; // Roof texture X0
float rtex0y = rtexX0RtexY0StexX1.y; // Roof texture Y0
float wtex1x = wtexY0FRtexx1FSRtexY1.y; // Front/Roof texture X1
float stex1x = rtexX0RtexY0StexX1.z; // Side texture X1
float wtex1y = wtexY0FRtexx1FSRtexY1.z; // Front/Roof/Side texture Y1
vec2 tex0 = vec2(sign(gl_MultiTexCoord0.x) * (gl_Color.x*wtex0x + gl_Color.y*rtex0x + gl_Color.a*wtex0x),
gl_Color.x*wtex0y + gl_Color.y*rtex0y + gl_Color.a*wtex0y);
vec2 tex1 = vec2(gl_Color.x*wtex1x + gl_Color.y*wtex1x + gl_Color.a*stex1x,
wtex1y);
gl_TexCoord[0].x = tex0.x + gl_MultiTexCoord0.x * tex1.x;
gl_TexCoord[0].y = tex0.y + gl_MultiTexCoord0.y * tex1.y;
// Rotate the normal.
normal = gl_Normal;

View file

@ -14,10 +14,10 @@
#define MODE_AMBIENT_AND_DIFFUSE 2
attribute vec3 instancePosition; // (x,y,z)
attribute vec3 instanceScaleRotate; // (width, depth, height)
attribute vec3 rotPitchWtex0x; // (rotation, pitch height, wall texture x offset)
attribute vec3 wtex0yTex1xTex1y; // (wall texture y offset, wall/roof texture x gain, wall/roof texture y gain)
attribute vec3 rtex0xRtex0y; // (roof texture y offset, roof texture x gain, unused)
attribute vec3 instanceScale ; // (width, depth, height)
attribute vec3 rotPitchWtexX0; // (rotation, pitch height, wall texture x0)
attribute vec3 wtexY0FRtexx1FSRtexY1; // (wall texture y0, front/roof texture x1, front/side/roof texture y1)
attribute vec3 rtexX0RtexY0StexX1; // (roof texture x0, roof texture y0, side texture x1)
attribute vec3 rooftopscale; // (rooftop x scale, rooftop y scale)
// The constant term of the lighting equation that doesn't depend on
@ -38,8 +38,8 @@ uniform int colorMode;
void main()
{
// Determine the rotation for the building.
float sr = sin(6.28 * rotPitchWtex0x.x);
float cr = cos(6.28 * rotPitchWtex0x.x);
float sr = sin(6.28 * rotPitchWtexX0.x);
float cr = cos(6.28 * rotPitchWtexX0.x);
vec3 position = gl_Vertex.xyz;
// Adjust the very top of the roof to match the rooftop scaling. This shapes
@ -48,10 +48,10 @@ void main()
position.y = (1.0 - gl_Color.z) * position.y + gl_Color.z * (position.y * rooftopscale.y);
// Adjust pitch of roof to the correct height. These vertices are identified by gl_Color.z
// Scale down by the building height (instanceScaleRotate.z) because
// Scale down by the building height (instanceScale.z) because
// immediately afterwards we will scale UP the vertex to the correct scale.
position.z = position.z + gl_Color.z * rotPitchWtex0x.y / instanceScaleRotate.z;
position = position * instanceScaleRotate.xyz;
position.z = position.z + gl_Color.z * rotPitchWtexX0.y / instanceScale.z;
position = position * instanceScale.xyz;
// Rotation of the building and movement into position
position.xy = vec2(dot(position.xy, vec2(cr, sr)), dot(position.xy, vec2(-sr, cr)));
@ -60,20 +60,31 @@ void main()
gl_Position = gl_ModelViewProjectionMatrix * vec4(position,1.0);
// Texture coordinates are stored as:
// - a separate offset for the wall (wtex0x, wtex0y), and roof (rtex0x, rtex0y)
// - a shared gain value (tex1x, tex1y)
// - a separate offset (x0, y0) for the wall (wtex0x, wtex0y), and roof (rtex0x, rtex0y)
// - a semi-shared (x1, y1) so that the front and side of the building can have
// different texture mappings
//
// The vertex color value selects between them, with glColor.x=1 indicating walls
// and glColor.y=1 indicating roofs.
// Finally, the roof texture is on the left of the texture sheet
float wtex0x = rotPitchWtex0x.z;
float wtex0y = wtex0yTex1xTex1y.x;
float rtex0x = rtex0xRtex0y.x;
float rtex0y = rtex0xRtex0y.y;
vec2 tex0 = vec2(sign(gl_MultiTexCoord0.x) * (gl_Color.x*wtex0x + gl_Color.y*rtex0x),
gl_Color.x*wtex0y + gl_Color.y*rtex0y);
gl_TexCoord[0].x = tex0.x + gl_MultiTexCoord0.x * wtex0yTex1xTex1y.y;
gl_TexCoord[0].y = tex0.y + gl_MultiTexCoord0.y * wtex0yTex1xTex1y.z;
// The vertex color value selects between them:
// gl_Color.x=1 indicates front/back walls
// gl_Color.y=1 indicates roof
// gl_Color.z=1 indicates top roof vertexs (used above)
// gl_Color.a=1 indicates sides
// Finally, the roof texture is on the right of the texture sheet
float wtex0x = rotPitchWtexX0.z; // Front/Side texture X0
float wtex0y = wtexY0FRtexx1FSRtexY1.x; // Front/Side texture Y0
float rtex0x = rtexX0RtexY0StexX1.x; // Roof texture X0
float rtex0y = rtexX0RtexY0StexX1.y; // Roof texture Y0
float wtex1x = wtexY0FRtexx1FSRtexY1.y; // Front/Roof texture X1
float stex1x = rtexX0RtexY0StexX1.z; // Side texture X1
float wtex1y = wtexY0FRtexx1FSRtexY1.z; // Front/Roof/Side texture Y1
vec2 tex0 = vec2(sign(gl_MultiTexCoord0.x) * (gl_Color.x*wtex0x + gl_Color.y*rtex0x + gl_Color.a*wtex0x),
gl_Color.x*wtex0y + gl_Color.y*rtex0y + gl_Color.a*wtex0y);
vec2 tex1 = vec2(gl_Color.x*wtex1x + gl_Color.y*wtex1x + gl_Color.a*stex1x,
wtex1y);
gl_TexCoord[0].x = tex0.x + gl_MultiTexCoord0.x * tex1.x;
gl_TexCoord[0].y = tex0.y + gl_MultiTexCoord0.y * tex1.y;
// Rotate the normal.
normal = gl_Normal;

View file

@ -7,9 +7,9 @@
attribute vec3 instancePosition; // (x,y,z)
attribute vec3 instanceScaleRotate; // (width, depth, height)
attribute vec3 rotPitchWtex0x; // (rotation, pitch height, texture x offset)
attribute vec3 wtex0yTex1xTex1y; // (wall texture y offset, wall/roof texture x gain, wall/roof texture y gain)
attribute vec3 rtex0xRtex0y; // (roof texture y offset, roof texture x gain, texture y gain)
attribute vec3 rotPitchWtexX0; // (rotation, pitch height, wall texture x0)
attribute vec3 wtexY0FRtexx1FSRtexY1; // (wall texture y0, front/roof texture x1, front/side/roof texture y1)
attribute vec3 rtexX0RtexY0StexX1; // (roof texture x0, roof texture y0, side texture x1)
attribute vec3 rooftopscale; // (rooftop x scale, rooftop y scale)
varying vec3 ecNormal;
@ -17,8 +17,8 @@ varying float alpha;
void main() {
// Determine the rotation for the building.
float sr = sin(6.28 * rotPitchWtex0x.x);
float cr = cos(6.28 * rotPitchWtex0x.x);
float sr = sin(6.28 * rotPitchWtexX0.x);
float cr = cos(6.28 * rotPitchWtexX0.x);
vec3 position = gl_Vertex.xyz;
// Adjust the very top of the roof to match the rooftop scaling. This shapes
@ -29,7 +29,7 @@ void main() {
// Adjust pitch of roof to the correct height. These vertices are identified by gl_Color.z
// Scale down by the building height (instanceScaleRotate.z) because
// immediately afterwards we will scale UP the vertex to the correct scale.
position.z = position.z + gl_Color.z * rotPitchWtex0x.y / instanceScaleRotate.z;
position.z = position.z + gl_Color.z * rotPitchWtexX0.y / instanceScaleRotate.z;
position = position * instanceScaleRotate.xyz;
// Rotation of the building and movement into position
@ -39,17 +39,32 @@ void main() {
gl_Position = gl_ModelViewProjectionMatrix * vec4(position,1.0);
// Texture coordinates are stored as:
// - a separate offset for the wall (wtex0x, wtex0y), and roof (rtex0x, rtex0y)
// - a shared gain value (tex1x, tex1y)
// - a separate offset (x0, y0) for the wall (wtex0x, wtex0y), and roof (rtex0x, rtex0y)
// - a semi-shared (x1, y1) so that the front and side of the building can have
// different texture mappings
//
// The vertex color value selects between them, with glColor.x=1 indicating walls
// and glColor.y=1 indicating roofs.
// Finally, the roof texture is on the left of the texture sheet
vec2 tex0 = vec2(sign(gl_MultiTexCoord0.x) * (gl_Color.x*rotPitchWtex0x.z + gl_Color.y*rtex0xRtex0y.x),
gl_Color.x*wtex0yTex1xTex1y.x + gl_Color.y*rtex0xRtex0y.y);
gl_TexCoord[0].x = tex0.x + gl_MultiTexCoord0.x * wtex0yTex1xTex1y.y;
gl_TexCoord[0].y = tex0.y + gl_MultiTexCoord0.y * wtex0yTex1xTex1y.z;
// The vertex color value selects between them:
// gl_Color.x=1 indicates front/back walls
// gl_Color.y=1 indicates roof
// gl_Color.z=1 indicates top roof vertexs (used above)
// gl_Color.a=1 indicates sides
// Finally, the roof texture is on the right of the texture sheet
float wtex0x = rotPitchWtexX0.z; // Front/Side texture X0
float wtex0y = wtexY0FRtexx1FSRtexY1.x; // Front/Side texture Y0
float rtex0x = rtexX0RtexY0StexX1.x; // Roof texture X0
float rtex0y = rtexX0RtexY0StexX1.y; // Roof texture Y0
float wtex1x = wtexY0FRtexx1FSRtexY1.y; // Front/Roof texture X1
float stex1x = rtexX0RtexY0StexX1.z; // Side texture X1
float wtex1y = wtexY0FRtexx1FSRtexY1.z; // Front/Roof/Side texture Y1
vec2 tex0 = vec2(sign(gl_MultiTexCoord0.x) * (gl_Color.x*wtex0x + gl_Color.y*rtex0x + gl_Color.a*wtex0x),
gl_Color.x*wtex0y + gl_Color.y*rtex0y + gl_Color.a*wtex0y);
vec2 tex1 = vec2(gl_Color.x*wtex1x + gl_Color.y*wtex1x + gl_Color.a*stex1x,
wtex1y);
gl_TexCoord[0].x = tex0.x + gl_MultiTexCoord0.x * tex1.x;
gl_TexCoord[0].y = tex0.y + gl_MultiTexCoord0.y * tex1.y;
// Rotate the normal.
ecNormal = gl_Normal;
ecNormal.xy = vec2(dot(ecNormal.xy, vec2(cr, sr)), dot(ecNormal.xy, vec2(-sr, cr)));

View file

@ -4,10 +4,10 @@
#version 120
attribute vec3 instancePosition; // (x,y,z)
attribute vec3 instanceScaleRotate; // (width, depth, height)
attribute vec3 rotPitchWtex0x; // (rotation, pitch height, texture x offset)
attribute vec3 wtex0yTex1xTex1y; // (wall texture y offset, wall/roof texture x gain, wall/roof texture y gain)
attribute vec3 rtex0xRtex0y; // (roof texture y offset, roof texture x gain, texture y gain)
attribute vec3 instanceScale ; // (width, depth, height)
attribute vec3 rotPitchWtexX0; // (rotation, pitch height, wall texture x0)
attribute vec3 wtexY0FRtexx1FSRtexY1; // (wall texture y0, front/roof texture x1, front/side/roof texture y1)
attribute vec3 rtexX0RtexY0StexX1; // (roof texture x0, roof texture y0, side texture x1)
attribute vec3 rooftopscale; // (rooftop x scale, rooftop y scale)
varying vec3 rawpos;
@ -56,8 +56,8 @@ void rotationMatrixH(in float sinRz, in float cosRz, out mat4 rotmat)
void main(void)
{
// Determine the rotation for the building.
float sr = sin(6.28 * rotPitchWtex0x.x);
float cr = cos(6.28 * rotPitchWtex0x.x);
float sr = sin(6.28 * rotPitchWtexX0.x);
float cr = cos(6.28 * rotPitchWtexX0.x);
vec3 rawpos = gl_Vertex.xyz;
@ -67,10 +67,10 @@ void main(void)
rawpos.y = (1.0 - gl_Color.z) * rawpos.y + gl_Color.z * (rawpos.y * rooftopscale.y);
// Adjust pitch of roof to the correct height. These vertices are identified by gl_Color.z
// Scale down by the building height (instanceScaleRotate.z) because
// Scale down by the building height (instanceScale.z) because
// immediately afterwards we will scale UP the vertex to the correct scale.
rawpos.z = rawpos.z + gl_Color.z * rotPitchWtex0x.y / instanceScaleRotate.z;
rawpos = rawpos * instanceScaleRotate.xyz;
rawpos.z = rawpos.z + gl_Color.z * rotPitchWtexX0.y / instanceScale.z;
rawpos = rawpos * instanceScale.xyz;
// Rotation of the building and movement into rawpos
rawpos.xy = vec2(dot(rawpos.xy, vec2(cr, sr)), dot(rawpos.xy, vec2(-sr, cr)));
@ -78,16 +78,31 @@ void main(void)
vec4 ecPosition = gl_ModelViewMatrix * vec4(rawpos, 1.0);
// Texture coordinates are stored as:
// - a separate offset for the wall (wtex0x, wtex0y), and roof (rtex0x, rtex0y)
// - a shared gain value (tex1x, tex1y)
//
// The vertex color value selects between them, with glColor.x=1 indicating walls
// and glColor.y=1 indicating roofs.
// Finally, the roof texture is on the left of the texture sheet
vec2 tex0 = vec2(sign(gl_MultiTexCoord0.x) * (gl_Color.x*rotPitchWtex0x.z + gl_Color.y*rtex0xRtex0y.x),
gl_Color.x*wtex0yTex1xTex1y.x + gl_Color.y*rtex0xRtex0y.y);
gl_TexCoord[0].x = tex0.x + gl_MultiTexCoord0.x * wtex0yTex1xTex1y.y;
gl_TexCoord[0].y = tex0.y + gl_MultiTexCoord0.y * wtex0yTex1xTex1y.z;
// - a separate offset (x0, y0) for the wall (wtex0x, wtex0y), and roof (rtex0x, rtex0y)
// - a semi-shared (x1, y1) so that the front and side of the building can have
// different texture mappings
//
// The vertex color value selects between them:
// gl_Color.x=1 indicates front/back walls
// gl_Color.y=1 indicates roof
// gl_Color.z=1 indicates top roof vertexs (used above)
// gl_Color.a=1 indicates sides
// Finally, the roof texture is on the right of the texture sheet
float wtex0x = rotPitchWtexX0.z; // Front/Side texture X0
float wtex0y = wtexY0FRtexx1FSRtexY1.x; // Front/Side texture Y0
float rtex0x = rtexX0RtexY0StexX1.x; // Roof texture X0
float rtex0y = rtexX0RtexY0StexX1.y; // Roof texture Y0
float wtex1x = wtexY0FRtexx1FSRtexY1.y; // Front/Roof texture X1
float stex1x = rtexX0RtexY0StexX1.z; // Side texture X1
float wtex1y = wtexY0FRtexx1FSRtexY1.z; // Front/Roof/Side texture Y1
vec2 tex0 = vec2(sign(gl_MultiTexCoord0.x) * (gl_Color.x*wtex0x + gl_Color.y*rtex0x + gl_Color.a*wtex0x),
gl_Color.x*wtex0y + gl_Color.y*rtex0y + gl_Color.a*wtex0y);
vec2 tex1 = vec2(gl_Color.x*wtex1x + gl_Color.y*wtex1x + gl_Color.a*stex1x,
wtex1y);
gl_TexCoord[0].x = tex0.x + gl_MultiTexCoord0.x * tex1.x;
gl_TexCoord[0].y = tex0.y + gl_MultiTexCoord0.y * tex1.y;
// Rotate the normal.
vec3 normal = gl_Normal;

View file

@ -18,17 +18,17 @@ uniform int shader_qual;
uniform int rembrandt_enabled;
attribute vec3 instancePosition; // (x,y,z)
attribute vec3 instanceScaleRotate; // (width, depth, height)
attribute vec3 rotPitchWtex0x; // (rotation, pitch height, texture x offset)
attribute vec3 wtex0yTex1xTex1y; // (wall texture y offset, wall/roof texture x gain, wall/roof texture y gain)
attribute vec3 rtex0xRtex0y; // (roof texture y offset, roof texture x gain, texture y gain)
attribute vec3 instanceScale; // (width, depth, height)
attribute vec3 rotPitchWtexX0; // (rotation, pitch height, wall texture x0)
attribute vec3 wtexY0FRtexx1FSRtexY1; // (wall texture y0, front/roof texture x1, front/side/roof texture y1)
attribute vec3 rtexX0RtexY0StexX1; // (roof texture x0, roof texture y0, side texture x1)
attribute vec3 rooftopscale; // (rooftop x scale, rooftop y scale)
void main(void)
{
// Determine the rotation for the building.
float sr = sin(6.28 * rotPitchWtex0x.x);
float cr = cos(6.28 * rotPitchWtex0x.x);
float sr = sin(6.28 * rotPitchWtexX0.x);
float cr = cos(6.28 * rotPitchWtexX0.x);
vec3 position = gl_Vertex.xyz;
// Adjust the very top of the roof to match the rooftop scaling. This shapes
@ -37,10 +37,10 @@ void main(void)
position.y = (1.0 - gl_Color.z) * position.y + gl_Color.z * (position.y * rooftopscale.y);
// Adjust pitch of roof to the correct height. These vertices are identified by gl_Color.z
// Scale down by the building height (instanceScaleRotate.z) because
// Scale down by the building height (instanceScale.z) because
// immediately afterwards we will scale UP the vertex to the correct scale.
position.z = position.z + gl_Color.z * rotPitchWtex0x.y / instanceScaleRotate.z;
position = position * instanceScaleRotate.xyz;
position.z = position.z + gl_Color.z * rotPitchWtexX0.y / instanceScale.z;
position = position * instanceScale.xyz;
// Rotation of the building and movement into position
position.xy = vec2(dot(position.xy, vec2(cr, sr)), dot(position.xy, vec2(-sr, cr)));
@ -84,14 +84,28 @@ void main(void)
gl_ClipVertex = ecPosition;
// Texture coordinates are stored as:
// - a separate offset for the wall (wtex0x, wtex0y), and roof (rtex0x, rtex0y)
// - a shared gain value (tex1x, tex1y)
// - a separate offset (x0, y0) for the wall (wtex0x, wtex0y), and roof (rtex0x, rtex0y)
// - a semi-shared (x1, y1) so that the front and side of the building can have
// different texture mappings
//
// The vertex color value selects between them, with glColor.x=1 indicating walls
// and glColor.y=1 indicating roofs.
// Finally, the roof texture is on the left of the texture sheet
vec2 tex0 = vec2(sign(gl_MultiTexCoord0.x) * (gl_Color.x*rotPitchWtex0x.z + gl_Color.y*rtex0xRtex0y.x),
gl_Color.x*wtex0yTex1xTex1y.x + gl_Color.y*rtex0xRtex0y.y);
gl_TexCoord[0].x = tex0.x + gl_MultiTexCoord0.x * wtex0yTex1xTex1y.y;
gl_TexCoord[0].y = tex0.y + gl_MultiTexCoord0.y * wtex0yTex1xTex1y.z;
}
// The vertex color value selects between them:
// gl_Color.x=1 indicates front/back walls
// gl_Color.y=1 indicates roof
// gl_Color.z=1 indicates top roof vertexs (used above)
// gl_Color.a=1 indicates sides
// Finally, the roof texture is on the right of the texture sheet
float wtex0x = rotPitchWtexX0.z; // Front/Side texture X0
float wtex0y = wtexY0FRtexx1FSRtexY1.x; // Front/Side texture Y0
float rtex0x = rtexX0RtexY0StexX1.x; // Roof texture X0
float rtex0y = rtexX0RtexY0StexX1.y; // Roof texture Y0
float wtex1x = wtexY0FRtexx1FSRtexY1.y; // Front/Roof texture X1
float stex1x = rtexX0RtexY0StexX1.z; // Side texture X1
float wtex1y = wtexY0FRtexx1FSRtexY1.z; // Front/Roof/Side texture Y1
vec2 tex0 = vec2(sign(gl_MultiTexCoord0.x) * (gl_Color.x*wtex0x + gl_Color.y*rtex0x + gl_Color.a*wtex0x),
gl_Color.x*wtex0y + gl_Color.y*rtex0y + gl_Color.a*wtex0y);
vec2 tex1 = vec2(gl_Color.x*wtex1x + gl_Color.y*wtex1x + gl_Color.a*stex1x,
wtex1y);
gl_TexCoord[0].x = tex0.x + gl_MultiTexCoord0.x * tex1.x;
gl_TexCoord[0].y = tex0.y + gl_MultiTexCoord0.y * tex1.y;}

View file

@ -0,0 +1,52 @@
<?xml version="1.0"?>
<PropertyList>
<name>weather-metar-description</name>
<modal>false</modal>
<resizable>true</resizable>
<layout>vbox</layout>
<default-padding>3</default-padding>
<group>
<layout>hbox</layout>
<text>
<label>METAR Description</label>
</text>
<empty>
<stretch>true</stretch>
</empty>
<button>
<legend/>
<key>Esc</key>
<pref-width>16</pref-width>
<pref-height>16</pref-height>
<border>2</border>
<binding>
<command>dialog-close</command>
</binding>
</button>
</group>
<textbox>
<name>metar-string-human</name>
<halign>fill</halign>
<valign>fill</valign>
<stretch>true</stretch>
<pref-height>200</pref-height>
<slider>15</slider>
<editable>false</editable>
<wrap>true</wrap>
<top-line>0</top-line>
<property>/environment/metar/description</property>
</textbox>
<button>
<legend>Close</legend>
<equal>true</equal>
<default>true</default>
<key>Esc</key>
<binding>
<command>dialog-close</command>
</binding>
</button>
</PropertyList>

View file

@ -631,6 +631,29 @@
</group>
</group>
<textbox>
<name>description</name>
<halign>fill</halign>
<stretch>true</stretch>
<pref-width>450</pref-width>
<pref-height>100</pref-height>
<slider>15</slider>
<editable>false</editable>
<wrap>true</wrap>
<live>true</live>
<top-line>0</top-line>
<property>sim/gui/dialogs/metar/description[0]</property>
</textbox>
<!-- only for a gap -->
<group>
<layout>vbox</layout>
<default-padding>1</default-padding>
<text>
<label> </label>
</text>
</group>
<group>
<layout>hbox</layout>
<text>
@ -692,28 +715,18 @@
<group>
<layout>hbox</layout>
<text>
<label>Description</label>
</text>
<button>
<legend>METAR Description...</legend>
<binding>
<command>dialog-show</command>
<dialog-name>weather-metar-description</dialog-name>
</binding>
</button>
<empty>
<stretch>true</stretch>
</empty>
</group>
<textbox>
<name>description</name>
<halign>fill</halign>
<stretch>true</stretch>
<pref-width>450</pref-width>
<pref-height>100</pref-height>
<slider>15</slider>
<editable>false</editable>
<wrap>true</wrap>
<live>true</live>
<top-line>0</top-line>
<property>sim/gui/dialogs/metar/description[0]</property>
</textbox>
</group>
<!-- only for a gap -->