mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 18:42:58 +02:00
Switch to deferred lighting for metavoxels.
This commit is contained in:
parent
a02656070f
commit
21f3f2b90e
22 changed files with 670 additions and 535 deletions
26
interface/resources/shaders/directional_light.frag
Normal file
26
interface/resources/shaders/directional_light.frag
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
//
|
||||||
|
// directional_light.frag
|
||||||
|
// fragment shader
|
||||||
|
//
|
||||||
|
// Created by Andrzej Kapolka on 9/3/14.
|
||||||
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
// the diffuse texture
|
||||||
|
uniform sampler2D diffuseMap;
|
||||||
|
|
||||||
|
// the normal texture
|
||||||
|
uniform sampler2D normalMap;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
// compute the base color based on OpenGL lighting model
|
||||||
|
vec4 normal = texture2D(normalMap, gl_TexCoord[0].st);
|
||||||
|
gl_FragColor = vec4((texture2D(diffuseMap, gl_TexCoord[0].st) * (gl_FrontLightModelProduct.sceneColor +
|
||||||
|
gl_FrontLightProduct[0].ambient + gl_FrontLightProduct[0].diffuse * max(0.0, dot(normal * 2.0 -
|
||||||
|
vec4(1.0, 1.0, 1.0, 2.0), gl_LightSource[0].position)))).rgb, normal.a);
|
||||||
|
}
|
|
@ -1,10 +1,10 @@
|
||||||
#version 120
|
#version 120
|
||||||
|
|
||||||
//
|
//
|
||||||
// metavoxel_heightfield.frag
|
// directional_light.frag
|
||||||
// fragment shader
|
// fragment shader
|
||||||
//
|
//
|
||||||
// Created by Andrzej Kapolka on 7/28/14.
|
// Created by Andrzej Kapolka on 9/3/14.
|
||||||
// Copyright 2014 High Fidelity, Inc.
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
//
|
//
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
@ -14,6 +14,12 @@
|
||||||
// the diffuse texture
|
// the diffuse texture
|
||||||
uniform sampler2D diffuseMap;
|
uniform sampler2D diffuseMap;
|
||||||
|
|
||||||
|
// the normal texture
|
||||||
|
uniform sampler2D normalMap;
|
||||||
|
|
||||||
|
// the depth texture
|
||||||
|
uniform sampler2D depthMap;
|
||||||
|
|
||||||
// the shadow texture
|
// the shadow texture
|
||||||
uniform sampler2DShadow shadowMap;
|
uniform sampler2DShadow shadowMap;
|
||||||
|
|
||||||
|
@ -21,28 +27,39 @@ uniform sampler2DShadow shadowMap;
|
||||||
uniform vec3 shadowDistances;
|
uniform vec3 shadowDistances;
|
||||||
|
|
||||||
// the inverse of the size of the shadow map
|
// the inverse of the size of the shadow map
|
||||||
const float shadowScale = 1.0 / 2048.0;
|
uniform float shadowScale;
|
||||||
|
|
||||||
// the interpolated position
|
// the distance to the near clip plane
|
||||||
varying vec4 position;
|
uniform float near;
|
||||||
|
|
||||||
// the interpolated normal
|
// scale factor for depth: (far - near) / far
|
||||||
varying vec4 normal;
|
uniform float depthScale;
|
||||||
|
|
||||||
|
// offset for depth texture coordinates
|
||||||
|
uniform vec2 depthTexCoordOffset;
|
||||||
|
|
||||||
|
// scale for depth texture coordinates
|
||||||
|
uniform vec2 depthTexCoordScale;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
|
// compute the view space position using the depth
|
||||||
|
float z = near / (texture2D(depthMap, gl_TexCoord[0].st).r * depthScale - 1.0);
|
||||||
|
vec4 position = vec4((depthTexCoordOffset + gl_TexCoord[0].st * depthTexCoordScale) * z, z, 1.0);
|
||||||
|
|
||||||
// compute the index of the cascade to use and the corresponding texture coordinates
|
// compute the index of the cascade to use and the corresponding texture coordinates
|
||||||
int shadowIndex = int(dot(step(vec3(position.z), shadowDistances), vec3(1.0, 1.0, 1.0)));
|
int shadowIndex = int(dot(step(vec3(position.z), shadowDistances), vec3(1.0, 1.0, 1.0)));
|
||||||
vec3 shadowTexCoord = vec3(dot(gl_EyePlaneS[shadowIndex], position), dot(gl_EyePlaneT[shadowIndex], position),
|
vec3 shadowTexCoord = vec3(dot(gl_EyePlaneS[shadowIndex], position), dot(gl_EyePlaneT[shadowIndex], position),
|
||||||
dot(gl_EyePlaneR[shadowIndex], position));
|
dot(gl_EyePlaneR[shadowIndex], position));
|
||||||
|
|
||||||
// compute the base color based on OpenGL lighting model
|
// compute the color based on OpenGL lighting model, use the alpha from the normal map
|
||||||
float diffuse = dot(normalize(normal), gl_LightSource[0].position);
|
vec4 normal = texture2D(normalMap, gl_TexCoord[0].st);
|
||||||
|
float diffuse = dot(normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0), gl_LightSource[0].position);
|
||||||
float facingLight = step(0.0, diffuse) * 0.25 *
|
float facingLight = step(0.0, diffuse) * 0.25 *
|
||||||
(shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, -shadowScale, 0.0)).r +
|
(shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, -shadowScale, 0.0)).r +
|
||||||
shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, shadowScale, 0.0)).r +
|
shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, shadowScale, 0.0)).r +
|
||||||
shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, -shadowScale, 0.0)).r +
|
shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, -shadowScale, 0.0)).r +
|
||||||
shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, shadowScale, 0.0)).r);
|
shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, shadowScale, 0.0)).r);
|
||||||
vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient +
|
vec4 baseColor = texture2D(diffuseMap, gl_TexCoord[0].st) * (gl_FrontLightModelProduct.sceneColor +
|
||||||
gl_FrontLightProduct[0].diffuse * (diffuse * facingLight));
|
gl_FrontLightProduct[0].ambient + gl_FrontLightProduct[0].diffuse * (diffuse * facingLight));
|
||||||
gl_FragColor = base * texture2D(diffuseMap, gl_TexCoord[0].st);
|
gl_FragColor = vec4(baseColor.rgb, normal.a);
|
||||||
}
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
//
|
||||||
|
// directional_light.frag
|
||||||
|
// fragment shader
|
||||||
|
//
|
||||||
|
// Created by Andrzej Kapolka on 9/3/14.
|
||||||
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
// the diffuse texture
|
||||||
|
uniform sampler2D diffuseMap;
|
||||||
|
|
||||||
|
// the normal texture
|
||||||
|
uniform sampler2D normalMap;
|
||||||
|
|
||||||
|
// the depth texture
|
||||||
|
uniform sampler2D depthMap;
|
||||||
|
|
||||||
|
// the shadow texture
|
||||||
|
uniform sampler2DShadow shadowMap;
|
||||||
|
|
||||||
|
// the inverse of the size of the shadow map
|
||||||
|
uniform float shadowScale;
|
||||||
|
|
||||||
|
// the distance to the near clip plane
|
||||||
|
uniform float near;
|
||||||
|
|
||||||
|
// scale factor for depth: (far - near) / far
|
||||||
|
uniform float depthScale;
|
||||||
|
|
||||||
|
// offset for depth texture coordinates
|
||||||
|
uniform vec2 depthTexCoordOffset;
|
||||||
|
|
||||||
|
// scale for depth texture coordinates
|
||||||
|
uniform vec2 depthTexCoordScale;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
// compute the view space position using the depth
|
||||||
|
float z = near / (texture2D(depthMap, gl_TexCoord[0].st).r * depthScale - 1.0);
|
||||||
|
vec4 position = vec4((depthTexCoordOffset + gl_TexCoord[0].st * depthTexCoordScale) * z, z, 1.0);
|
||||||
|
|
||||||
|
// compute the corresponding texture coordinates
|
||||||
|
vec3 shadowTexCoord = vec3(dot(gl_EyePlaneS[0], position), dot(gl_EyePlaneT[0], position), dot(gl_EyePlaneR[0], position));
|
||||||
|
|
||||||
|
// compute the color based on OpenGL lighting model, use the alpha from the normal map
|
||||||
|
vec4 normal = texture2D(normalMap, gl_TexCoord[0].st);
|
||||||
|
float diffuse = dot(normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0), gl_LightSource[0].position);
|
||||||
|
float facingLight = step(0.0, diffuse) * 0.25 *
|
||||||
|
(shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, -shadowScale, 0.0)).r +
|
||||||
|
shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, shadowScale, 0.0)).r +
|
||||||
|
shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, -shadowScale, 0.0)).r +
|
||||||
|
shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, shadowScale, 0.0)).r);
|
||||||
|
vec4 baseColor = texture2D(diffuseMap, gl_TexCoord[0].st) * (gl_FrontLightModelProduct.sceneColor +
|
||||||
|
gl_FrontLightProduct[0].ambient + gl_FrontLightProduct[0].diffuse * (diffuse * facingLight));
|
||||||
|
gl_FragColor = vec4(baseColor.rgb, normal.a);
|
||||||
|
}
|
|
@ -1,25 +0,0 @@
|
||||||
#version 120
|
|
||||||
|
|
||||||
//
|
|
||||||
// metavoxel_heightfield.frag
|
|
||||||
// fragment shader
|
|
||||||
//
|
|
||||||
// Created by Andrzej Kapolka on 7/28/14.
|
|
||||||
// Copyright 2014 High Fidelity, Inc.
|
|
||||||
//
|
|
||||||
// Distributed under the Apache License, Version 2.0.
|
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
||||||
//
|
|
||||||
|
|
||||||
// the diffuse texture
|
|
||||||
uniform sampler2D diffuseMap;
|
|
||||||
|
|
||||||
// the interpolated normal
|
|
||||||
varying vec4 normal;
|
|
||||||
|
|
||||||
void main(void) {
|
|
||||||
// compute the base color based on OpenGL lighting model
|
|
||||||
vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient +
|
|
||||||
gl_FrontLightProduct[0].diffuse * max(0.0, dot(normalize(normal), gl_LightSource[0].position)));
|
|
||||||
gl_FragColor = base * texture2D(diffuseMap, gl_TexCoord[0].st);
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
#version 120
|
|
||||||
|
|
||||||
//
|
|
||||||
// metavoxel_heighfield.vert
|
|
||||||
// vertex shader
|
|
||||||
//
|
|
||||||
// Created by Andrzej Kapolka on 7/28/14.
|
|
||||||
// Copyright 2014 High Fidelity, Inc.
|
|
||||||
//
|
|
||||||
// Distributed under the Apache License, Version 2.0.
|
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
||||||
//
|
|
||||||
|
|
||||||
// the height texture
|
|
||||||
uniform sampler2D heightMap;
|
|
||||||
|
|
||||||
// the distance between height points in texture space
|
|
||||||
uniform float heightScale;
|
|
||||||
|
|
||||||
// the scale between height and color textures
|
|
||||||
uniform float colorScale;
|
|
||||||
|
|
||||||
// the interpolated position
|
|
||||||
varying vec4 position;
|
|
||||||
|
|
||||||
// the interpolated normal
|
|
||||||
varying vec4 normal;
|
|
||||||
|
|
||||||
void main(void) {
|
|
||||||
// transform and store the normal for interpolation
|
|
||||||
vec2 heightCoord = gl_MultiTexCoord0.st;
|
|
||||||
float deltaX = texture2D(heightMap, heightCoord - vec2(heightScale, 0.0)).r -
|
|
||||||
texture2D(heightMap, heightCoord + vec2(heightScale, 0.0)).r;
|
|
||||||
float deltaZ = texture2D(heightMap, heightCoord - vec2(0.0, heightScale)).r -
|
|
||||||
texture2D(heightMap, heightCoord + vec2(0.0, heightScale)).r;
|
|
||||||
normal = normalize(gl_ModelViewMatrix * vec4(deltaX, heightScale, deltaZ, 0.0));
|
|
||||||
|
|
||||||
// add the height to the position
|
|
||||||
float height = texture2D(heightMap, heightCoord).r;
|
|
||||||
position = gl_ModelViewMatrix * (gl_Vertex + vec4(0.0, height, 0.0, 0.0));
|
|
||||||
gl_Position = gl_ProjectionMatrix * position;
|
|
||||||
|
|
||||||
// the zero height should be invisible
|
|
||||||
gl_FrontColor = vec4(1.0, 1.0, 1.0, step(height, 0.0));
|
|
||||||
|
|
||||||
// pass along the scaled/offset texture coordinates
|
|
||||||
gl_TexCoord[0] = (gl_MultiTexCoord0 - vec4(heightScale, heightScale, 0.0, 0.0)) * colorScale;
|
|
||||||
|
|
||||||
// and the shadow texture coordinates
|
|
||||||
gl_TexCoord[1] = vec4(dot(gl_EyePlaneS[0], position), dot(gl_EyePlaneT[0], position), dot(gl_EyePlaneR[0], position), 1.0);
|
|
||||||
}
|
|
|
@ -14,7 +14,11 @@
|
||||||
// the diffuse texture
|
// the diffuse texture
|
||||||
uniform sampler2D diffuseMap;
|
uniform sampler2D diffuseMap;
|
||||||
|
|
||||||
|
// the interpolated normal
|
||||||
|
varying vec4 normal;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
// compute the base color based on OpenGL lighting model
|
// compute the base color based on OpenGL lighting model
|
||||||
gl_FragColor = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].st);
|
gl_FragData[0] = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].st);
|
||||||
|
gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,9 +20,20 @@ uniform float heightScale;
|
||||||
// the scale between height and color textures
|
// the scale between height and color textures
|
||||||
uniform float colorScale;
|
uniform float colorScale;
|
||||||
|
|
||||||
|
// the interpolated normal
|
||||||
|
varying vec4 normal;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
|
// transform and store the normal for interpolation
|
||||||
|
vec2 heightCoord = gl_MultiTexCoord0.st;
|
||||||
|
float deltaX = texture2D(heightMap, heightCoord - vec2(heightScale, 0.0)).r -
|
||||||
|
texture2D(heightMap, heightCoord + vec2(heightScale, 0.0)).r;
|
||||||
|
float deltaZ = texture2D(heightMap, heightCoord - vec2(0.0, heightScale)).r -
|
||||||
|
texture2D(heightMap, heightCoord + vec2(0.0, heightScale)).r;
|
||||||
|
normal = normalize(gl_ModelViewMatrix * vec4(deltaX, heightScale, deltaZ, 0.0));
|
||||||
|
|
||||||
// add the height to the position
|
// add the height to the position
|
||||||
float height = texture2D(heightMap, gl_MultiTexCoord0.st).r;
|
float height = texture2D(heightMap, heightCoord).r;
|
||||||
gl_Position = gl_ModelViewProjectionMatrix * (gl_Vertex + vec4(0.0, height, 0.0, 0.0));
|
gl_Position = gl_ModelViewProjectionMatrix * (gl_Vertex + vec4(0.0, height, 0.0, 0.0));
|
||||||
|
|
||||||
// the zero height should be invisible
|
// the zero height should be invisible
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
#version 120
|
|
||||||
|
|
||||||
//
|
|
||||||
// metavoxel_heightfield_light.frag
|
|
||||||
// fragment shader
|
|
||||||
//
|
|
||||||
// Created by Andrzej Kapolka on 8/20/14.
|
|
||||||
// Copyright 2014 High Fidelity, Inc.
|
|
||||||
//
|
|
||||||
// Distributed under the Apache License, Version 2.0.
|
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
||||||
//
|
|
||||||
|
|
||||||
// the interpolated normal
|
|
||||||
varying vec4 normal;
|
|
||||||
|
|
||||||
void main(void) {
|
|
||||||
// compute the base color based on OpenGL lighting model
|
|
||||||
gl_FragColor = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient +
|
|
||||||
gl_FrontLightProduct[0].diffuse * max(0.0, dot(normalize(normal), gl_LightSource[0].position)));
|
|
||||||
}
|
|
|
@ -1,45 +0,0 @@
|
||||||
#version 120
|
|
||||||
|
|
||||||
//
|
|
||||||
// metavoxel_heighfield_light.vert
|
|
||||||
// vertex shader
|
|
||||||
//
|
|
||||||
// Created by Andrzej Kapolka on 8/20/14.
|
|
||||||
// Copyright 2014 High Fidelity, Inc.
|
|
||||||
//
|
|
||||||
// Distributed under the Apache License, Version 2.0.
|
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
||||||
//
|
|
||||||
|
|
||||||
// the height texture
|
|
||||||
uniform sampler2D heightMap;
|
|
||||||
|
|
||||||
// the distance between height points in texture space
|
|
||||||
uniform float heightScale;
|
|
||||||
|
|
||||||
// the interpolated position
|
|
||||||
varying vec4 position;
|
|
||||||
|
|
||||||
// the interpolated normal
|
|
||||||
varying vec4 normal;
|
|
||||||
|
|
||||||
void main(void) {
|
|
||||||
// transform and store the normal for interpolation
|
|
||||||
vec2 heightCoord = gl_MultiTexCoord0.st;
|
|
||||||
float deltaX = texture2D(heightMap, heightCoord - vec2(heightScale, 0.0)).r -
|
|
||||||
texture2D(heightMap, heightCoord + vec2(heightScale, 0.0)).r;
|
|
||||||
float deltaZ = texture2D(heightMap, heightCoord - vec2(0.0, heightScale)).r -
|
|
||||||
texture2D(heightMap, heightCoord + vec2(0.0, heightScale)).r;
|
|
||||||
normal = normalize(gl_ModelViewMatrix * vec4(deltaX, heightScale, deltaZ, 0.0));
|
|
||||||
|
|
||||||
// add the height to the position
|
|
||||||
float height = texture2D(heightMap, heightCoord).r;
|
|
||||||
position = gl_ModelViewMatrix * (gl_Vertex + vec4(0.0, height, 0.0, 0.0));
|
|
||||||
gl_Position = gl_ProjectionMatrix * position;
|
|
||||||
|
|
||||||
// the zero height should be invisible
|
|
||||||
gl_FrontColor = vec4(1.0, 1.0, 1.0, step(height, 0.0));
|
|
||||||
|
|
||||||
// and the shadow texture coordinates
|
|
||||||
gl_TexCoord[1] = vec4(dot(gl_EyePlaneS[0], position), dot(gl_EyePlaneT[0], position), dot(gl_EyePlaneR[0], position), 1.0);
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
#version 120
|
|
||||||
|
|
||||||
//
|
|
||||||
// metavoxel_heightfield_light_cascaded_shadow_map.frag
|
|
||||||
// fragment shader
|
|
||||||
//
|
|
||||||
// Created by Andrzej Kapolka on 8/20/14.
|
|
||||||
// Copyright 2014 High Fidelity, Inc.
|
|
||||||
//
|
|
||||||
// Distributed under the Apache License, Version 2.0.
|
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
||||||
//
|
|
||||||
|
|
||||||
// the shadow texture
|
|
||||||
uniform sampler2DShadow shadowMap;
|
|
||||||
|
|
||||||
// the distances to the cascade sections
|
|
||||||
uniform vec3 shadowDistances;
|
|
||||||
|
|
||||||
// the inverse of the size of the shadow map
|
|
||||||
const float shadowScale = 1.0 / 2048.0;
|
|
||||||
|
|
||||||
// the interpolated position
|
|
||||||
varying vec4 position;
|
|
||||||
|
|
||||||
// the interpolated normal
|
|
||||||
varying vec4 normal;
|
|
||||||
|
|
||||||
void main(void) {
|
|
||||||
// compute the index of the cascade to use and the corresponding texture coordinates
|
|
||||||
int shadowIndex = int(dot(step(vec3(position.z), shadowDistances), vec3(1.0, 1.0, 1.0)));
|
|
||||||
vec3 shadowTexCoord = vec3(dot(gl_EyePlaneS[shadowIndex], position), dot(gl_EyePlaneT[shadowIndex], position),
|
|
||||||
dot(gl_EyePlaneR[shadowIndex], position));
|
|
||||||
|
|
||||||
// compute the base color based on OpenGL lighting model
|
|
||||||
float diffuse = dot(normalize(normal), gl_LightSource[0].position);
|
|
||||||
float facingLight = step(0.0, diffuse) * 0.25 *
|
|
||||||
(shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, -shadowScale, 0.0)).r +
|
|
||||||
shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, shadowScale, 0.0)).r +
|
|
||||||
shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, -shadowScale, 0.0)).r +
|
|
||||||
shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, shadowScale, 0.0)).r);
|
|
||||||
gl_FragColor = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient +
|
|
||||||
gl_FrontLightProduct[0].diffuse * (diffuse * facingLight));
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
#version 120
|
|
||||||
|
|
||||||
//
|
|
||||||
// metavoxel_heightfield_light_shadow_map.frag
|
|
||||||
// fragment shader
|
|
||||||
//
|
|
||||||
// Created by Andrzej Kapolka on 8/20/14.
|
|
||||||
// Copyright 2014 High Fidelity, Inc.
|
|
||||||
//
|
|
||||||
// Distributed under the Apache License, Version 2.0.
|
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
||||||
//
|
|
||||||
|
|
||||||
// the shadow texture
|
|
||||||
uniform sampler2DShadow shadowMap;
|
|
||||||
|
|
||||||
// the inverse of the size of the shadow map
|
|
||||||
const float shadowScale = 1.0 / 2048.0;
|
|
||||||
|
|
||||||
// the interpolated normal
|
|
||||||
varying vec4 normal;
|
|
||||||
|
|
||||||
void main(void) {
|
|
||||||
// compute the base color based on OpenGL lighting model
|
|
||||||
float diffuse = dot(normalize(normal), gl_LightSource[0].position);
|
|
||||||
float facingLight = step(0.0, diffuse) * 0.25 *
|
|
||||||
(shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(-shadowScale, -shadowScale, 0.0)).r +
|
|
||||||
shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(-shadowScale, shadowScale, 0.0)).r +
|
|
||||||
shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, -shadowScale, 0.0)).r +
|
|
||||||
shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, shadowScale, 0.0)).r);
|
|
||||||
gl_FragColor = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient +
|
|
||||||
gl_FrontLightProduct[0].diffuse * (diffuse * facingLight));
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
#version 120
|
|
||||||
|
|
||||||
//
|
|
||||||
// metavoxel_heightfield.frag
|
|
||||||
// fragment shader
|
|
||||||
//
|
|
||||||
// Created by Andrzej Kapolka on 7/28/14.
|
|
||||||
// Copyright 2014 High Fidelity, Inc.
|
|
||||||
//
|
|
||||||
// Distributed under the Apache License, Version 2.0.
|
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
||||||
//
|
|
||||||
|
|
||||||
// the diffuse texture
|
|
||||||
uniform sampler2D diffuseMap;
|
|
||||||
|
|
||||||
// the shadow texture
|
|
||||||
uniform sampler2DShadow shadowMap;
|
|
||||||
|
|
||||||
// the inverse of the size of the shadow map
|
|
||||||
const float shadowScale = 1.0 / 2048.0;
|
|
||||||
|
|
||||||
// the interpolated normal
|
|
||||||
varying vec4 normal;
|
|
||||||
|
|
||||||
void main(void) {
|
|
||||||
// compute the base color based on OpenGL lighting model
|
|
||||||
float diffuse = dot(normalize(normal), gl_LightSource[0].position);
|
|
||||||
float facingLight = step(0.0, diffuse) * 0.25 *
|
|
||||||
(shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(-shadowScale, -shadowScale, 0.0)).r +
|
|
||||||
shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(-shadowScale, shadowScale, 0.0)).r +
|
|
||||||
shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, -shadowScale, 0.0)).r +
|
|
||||||
shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, shadowScale, 0.0)).r);
|
|
||||||
vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient +
|
|
||||||
gl_FrontLightProduct[0].diffuse * (diffuse * facingLight));
|
|
||||||
gl_FragColor = base * texture2D(diffuseMap, gl_TexCoord[0].st);
|
|
||||||
}
|
|
21
interface/resources/shaders/metavoxel_voxel_base.frag
Normal file
21
interface/resources/shaders/metavoxel_voxel_base.frag
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
//
|
||||||
|
// metavoxel_voxel_base.frag
|
||||||
|
// fragment shader
|
||||||
|
//
|
||||||
|
// Created by Andrzej Kapolka on 9/4/14.
|
||||||
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
// the interpolated normal
|
||||||
|
varying vec4 normal;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
// store the interpolated color and normal
|
||||||
|
gl_FragData[0] = gl_Color;
|
||||||
|
gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0);
|
||||||
|
}
|
26
interface/resources/shaders/metavoxel_voxel_base.vert
Normal file
26
interface/resources/shaders/metavoxel_voxel_base.vert
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
//
|
||||||
|
// metavoxel_voxel_base.vert
|
||||||
|
// vertex shader
|
||||||
|
//
|
||||||
|
// Created by Andrzej Kapolka on 9/4/14.
|
||||||
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
// the interpolated normal
|
||||||
|
varying vec4 normal;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
// transform and store the normal for interpolation
|
||||||
|
normal = vec4(normalize(gl_NormalMatrix * gl_Normal), 0.0);
|
||||||
|
|
||||||
|
// use the fixed-function position
|
||||||
|
gl_Position = ftransform();
|
||||||
|
|
||||||
|
// copy the color for interpolation
|
||||||
|
gl_FrontColor = vec4(gl_Color.rgb, 0.0);
|
||||||
|
}
|
29
interface/resources/shaders/metavoxel_voxel_splat.frag
Normal file
29
interface/resources/shaders/metavoxel_voxel_splat.frag
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
//
|
||||||
|
// metavoxel_voxel_splat.frag
|
||||||
|
// fragment shader
|
||||||
|
//
|
||||||
|
// Created by Andrzej Kapolka on 9/4/14.
|
||||||
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
// the number of splats per pass
|
||||||
|
const int SPLAT_COUNT = 4;
|
||||||
|
|
||||||
|
// the splat textures
|
||||||
|
uniform sampler2D diffuseMaps[SPLAT_COUNT];
|
||||||
|
|
||||||
|
// alpha values for the four splat textures
|
||||||
|
varying vec4 alphaValues;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
// blend the splat textures
|
||||||
|
gl_FragColor = (texture2D(diffuseMaps[0], gl_TexCoord[0].st) * alphaValues.x +
|
||||||
|
texture2D(diffuseMaps[1], gl_TexCoord[1].st) * alphaValues.y +
|
||||||
|
texture2D(diffuseMaps[2], gl_TexCoord[2].st) * alphaValues.z +
|
||||||
|
texture2D(diffuseMaps[3], gl_TexCoord[3].st) * alphaValues.w);
|
||||||
|
}
|
62
interface/resources/shaders/metavoxel_voxel_splat.vert
Normal file
62
interface/resources/shaders/metavoxel_voxel_splat.vert
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
//
|
||||||
|
// metavoxel_voxel_splat.vert
|
||||||
|
// vertex shader
|
||||||
|
//
|
||||||
|
// Created by Andrzej Kapolka on 9/4/14.
|
||||||
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
// the splat textures scales on the S axis
|
||||||
|
uniform vec4 splatTextureScalesS;
|
||||||
|
|
||||||
|
// the splat texture scales on the T axis
|
||||||
|
uniform vec4 splatTextureScalesT;
|
||||||
|
|
||||||
|
// the lower bounds of the values corresponding to the splat textures
|
||||||
|
uniform vec4 textureValueMinima;
|
||||||
|
|
||||||
|
// the upper bounds of the values corresponding to the splat textures
|
||||||
|
uniform vec4 textureValueMaxima;
|
||||||
|
|
||||||
|
// the materials to apply to the vertex
|
||||||
|
attribute vec4 materials;
|
||||||
|
|
||||||
|
// the weights of each material
|
||||||
|
attribute vec4 materialWeights;
|
||||||
|
|
||||||
|
// alpha values for the four splat textures
|
||||||
|
varying vec4 alphaValues;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
// use the fixed-function position
|
||||||
|
gl_Position = ftransform();
|
||||||
|
|
||||||
|
// pass along the scaled/offset texture coordinates
|
||||||
|
vec4 textureSpacePosition = vec4(gl_Vertex.xz, 0.0, 1.0);
|
||||||
|
gl_TexCoord[0] = textureSpacePosition * vec4(splatTextureScalesS[0], splatTextureScalesT[0], 0.0, 1.0);
|
||||||
|
gl_TexCoord[1] = textureSpacePosition * vec4(splatTextureScalesS[1], splatTextureScalesT[1], 0.0, 1.0);
|
||||||
|
gl_TexCoord[2] = textureSpacePosition * vec4(splatTextureScalesS[2], splatTextureScalesT[2], 0.0, 1.0);
|
||||||
|
gl_TexCoord[3] = textureSpacePosition * vec4(splatTextureScalesS[3], splatTextureScalesT[3], 0.0, 1.0);
|
||||||
|
|
||||||
|
// compute the alpha values for each texture
|
||||||
|
float value = materials[0];
|
||||||
|
vec4 valueVector = vec4(value, value, value, value);
|
||||||
|
alphaValues = step(textureValueMinima, valueVector) * step(valueVector, textureValueMaxima) * materialWeights[0];
|
||||||
|
|
||||||
|
value = materials[1];
|
||||||
|
valueVector = vec4(value, value, value, value);
|
||||||
|
alphaValues += step(textureValueMinima, valueVector) * step(valueVector, textureValueMaxima) * materialWeights[1];
|
||||||
|
|
||||||
|
value = materials[2];
|
||||||
|
valueVector = vec4(value, value, value, value);
|
||||||
|
alphaValues += step(textureValueMinima, valueVector) * step(valueVector, textureValueMaxima) * materialWeights[2];
|
||||||
|
|
||||||
|
value = materials[3];
|
||||||
|
valueVector = vec4(value, value, value, value);
|
||||||
|
alphaValues += step(textureValueMinima, valueVector) * step(valueVector, textureValueMaxima) * materialWeights[3];
|
||||||
|
}
|
|
@ -9,7 +9,11 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// include this before QOpenGLFramebufferObject, which includes an earlier version of OpenGL
|
||||||
|
#include "InterfaceConfig.h"
|
||||||
|
|
||||||
#include <QMutexLocker>
|
#include <QMutexLocker>
|
||||||
|
#include <QOpenGLFramebufferObject>
|
||||||
#include <QReadLocker>
|
#include <QReadLocker>
|
||||||
#include <QWriteLocker>
|
#include <QWriteLocker>
|
||||||
#include <QtDebug>
|
#include <QtDebug>
|
||||||
|
@ -24,6 +28,7 @@
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "MetavoxelSystem.h"
|
#include "MetavoxelSystem.h"
|
||||||
#include "renderer/Model.h"
|
#include "renderer/Model.h"
|
||||||
|
#include "renderer/RenderUtil.h"
|
||||||
|
|
||||||
REGISTER_META_OBJECT(DefaultMetavoxelRendererImplementation)
|
REGISTER_META_OBJECT(DefaultMetavoxelRendererImplementation)
|
||||||
REGISTER_META_OBJECT(SphereRenderer)
|
REGISTER_META_OBJECT(SphereRenderer)
|
||||||
|
@ -46,6 +51,12 @@ void MetavoxelSystem::init() {
|
||||||
new BufferDataAttribute("voxelBuffer"));
|
new BufferDataAttribute("voxelBuffer"));
|
||||||
_voxelBufferAttribute->setLODThresholdMultiplier(
|
_voxelBufferAttribute->setLODThresholdMultiplier(
|
||||||
AttributeRegistry::getInstance()->getVoxelColorAttribute()->getLODThresholdMultiplier());
|
AttributeRegistry::getInstance()->getVoxelColorAttribute()->getLODThresholdMultiplier());
|
||||||
|
|
||||||
|
loadLightProgram("shaders/directional_light.frag", _directionalLight, _directionalLightLocations);
|
||||||
|
loadLightProgram("shaders/directional_light_shadow_map.frag", _directionalLightShadowMap,
|
||||||
|
_directionalLightShadowMapLocations);
|
||||||
|
loadLightProgram("shaders/directional_light_cascaded_shadow_map.frag", _directionalLightCascadedShadowMap,
|
||||||
|
_directionalLightCascadedShadowMapLocations);
|
||||||
}
|
}
|
||||||
|
|
||||||
MetavoxelLOD MetavoxelSystem::getLOD() {
|
MetavoxelLOD MetavoxelSystem::getLOD() {
|
||||||
|
@ -116,6 +127,10 @@ int RenderVisitor::visit(MetavoxelInfo& info) {
|
||||||
return STOP_RECURSION;
|
return STOP_RECURSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const GLenum COLOR_DRAW_BUFFERS[] = { GL_COLOR_ATTACHMENT0 };
|
||||||
|
const GLenum NORMAL_DRAW_BUFFERS[] = { GL_COLOR_ATTACHMENT1 };
|
||||||
|
const GLenum COLOR_NORMAL_DRAW_BUFFERS[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
|
||||||
|
|
||||||
void MetavoxelSystem::render() {
|
void MetavoxelSystem::render() {
|
||||||
// update the frustum
|
// update the frustum
|
||||||
ViewFrustum* viewFrustum = Application::getInstance()->getViewFrustum();
|
ViewFrustum* viewFrustum = Application::getInstance()->getViewFrustum();
|
||||||
|
@ -123,8 +138,128 @@ void MetavoxelSystem::render() {
|
||||||
viewFrustum->getFarBottomRight(), viewFrustum->getNearTopLeft(), viewFrustum->getNearTopRight(),
|
viewFrustum->getFarBottomRight(), viewFrustum->getNearTopLeft(), viewFrustum->getNearTopRight(),
|
||||||
viewFrustum->getNearBottomLeft(), viewFrustum->getNearBottomRight());
|
viewFrustum->getNearBottomLeft(), viewFrustum->getNearBottomRight());
|
||||||
|
|
||||||
|
_needToLight = false;
|
||||||
|
|
||||||
|
// clear the normal buffer
|
||||||
|
glDrawBuffers(sizeof(NORMAL_DRAW_BUFFERS) / sizeof(NORMAL_DRAW_BUFFERS[0]), NORMAL_DRAW_BUFFERS);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
glDrawBuffers(sizeof(COLOR_DRAW_BUFFERS) / sizeof(COLOR_DRAW_BUFFERS[0]), COLOR_DRAW_BUFFERS);
|
||||||
|
|
||||||
RenderVisitor renderVisitor(getLOD());
|
RenderVisitor renderVisitor(getLOD());
|
||||||
guideToAugmented(renderVisitor, true);
|
guideToAugmented(renderVisitor, true);
|
||||||
|
|
||||||
|
// give external parties a chance to join in
|
||||||
|
emit rendering();
|
||||||
|
|
||||||
|
if (!_needToLight) {
|
||||||
|
return; // skip lighting if not needed
|
||||||
|
}
|
||||||
|
|
||||||
|
// perform deferred lighting, rendering to free fbo
|
||||||
|
glPushMatrix();
|
||||||
|
glLoadIdentity();
|
||||||
|
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glPushMatrix();
|
||||||
|
glLoadIdentity();
|
||||||
|
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
glDisable(GL_LIGHTING);
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
glDepthMask(false);
|
||||||
|
|
||||||
|
QOpenGLFramebufferObject* primaryFBO = Application::getInstance()->getTextureCache()->getPrimaryFramebufferObject();
|
||||||
|
primaryFBO->release();
|
||||||
|
|
||||||
|
QOpenGLFramebufferObject* freeFBO = Application::getInstance()->getGlowEffect()->getFreeFramebufferObject();
|
||||||
|
freeFBO->bind();
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, primaryFBO->texture());
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimaryNormalTextureID());
|
||||||
|
|
||||||
|
if (Menu::getInstance()->getShadowsEnabled()) {
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimaryDepthTextureID());
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE3);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getShadowDepthTextureID());
|
||||||
|
|
||||||
|
ProgramObject* program = &_directionalLightShadowMap;
|
||||||
|
const LightLocations* locations = &_directionalLightShadowMapLocations;
|
||||||
|
if (Menu::getInstance()->isOptionChecked(MenuOption::CascadedShadows)) {
|
||||||
|
program = &_directionalLightCascadedShadowMap;
|
||||||
|
locations = &_directionalLightCascadedShadowMapLocations;
|
||||||
|
_directionalLightCascadedShadowMap.bind();
|
||||||
|
_directionalLightCascadedShadowMap.setUniform(locations->shadowDistances,
|
||||||
|
Application::getInstance()->getShadowDistances());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
program->bind();
|
||||||
|
}
|
||||||
|
program->setUniformValue(locations->shadowScale,
|
||||||
|
1.0f / Application::getInstance()->getTextureCache()->getShadowFramebufferObject()->width());
|
||||||
|
|
||||||
|
float left, right, bottom, top, nearVal, farVal;
|
||||||
|
glm::vec4 nearClipPlane, farClipPlane;
|
||||||
|
Application::getInstance()->computeOffAxisFrustum(
|
||||||
|
left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
|
||||||
|
program->setUniformValue(locations->near, nearVal);
|
||||||
|
program->setUniformValue(locations->depthScale, (farVal - nearVal) / farVal);
|
||||||
|
float nearScale = -1.0f / nearVal;
|
||||||
|
program->setUniformValue(locations->depthTexCoordOffset, left * nearScale, bottom * nearScale);
|
||||||
|
program->setUniformValue(locations->depthTexCoordScale, (right - left) * nearScale, (top - bottom) * nearScale);
|
||||||
|
|
||||||
|
renderFullscreenQuad();
|
||||||
|
|
||||||
|
program->release();
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
_directionalLight.bind();
|
||||||
|
renderFullscreenQuad();
|
||||||
|
_directionalLight.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
|
freeFBO->release();
|
||||||
|
|
||||||
|
// now transfer the lit region to the primary fbo
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
|
||||||
|
primaryFBO->bind();
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, freeFBO->texture());
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
|
||||||
|
renderFullscreenQuad();
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
glEnable(GL_LIGHTING);
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
glDepthMask(true);
|
||||||
|
|
||||||
|
glDisable(GL_ALPHA_TEST);
|
||||||
|
|
||||||
|
glPopMatrix();
|
||||||
|
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
class RayHeightfieldIntersectionVisitor : public RayIntersectionVisitor {
|
class RayHeightfieldIntersectionVisitor : public RayIntersectionVisitor {
|
||||||
|
@ -484,6 +619,24 @@ void MetavoxelSystem::guideToAugmented(MetavoxelVisitor& visitor, bool render) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MetavoxelSystem::loadLightProgram(const char* name, ProgramObject& program, LightLocations& locations) {
|
||||||
|
program.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + name);
|
||||||
|
program.link();
|
||||||
|
|
||||||
|
program.bind();
|
||||||
|
program.setUniformValue("diffuseMap", 0);
|
||||||
|
program.setUniformValue("normalMap", 1);
|
||||||
|
program.setUniformValue("depthMap", 2);
|
||||||
|
program.setUniformValue("shadowMap", 3);
|
||||||
|
locations.shadowDistances = program.uniformLocation("shadowDistances");
|
||||||
|
locations.shadowScale = program.uniformLocation("shadowScale");
|
||||||
|
locations.near = program.uniformLocation("near");
|
||||||
|
locations.depthScale = program.uniformLocation("depthScale");
|
||||||
|
locations.depthTexCoordOffset = program.uniformLocation("depthTexCoordOffset");
|
||||||
|
locations.depthTexCoordScale = program.uniformLocation("depthTexCoordScale");
|
||||||
|
program.release();
|
||||||
|
}
|
||||||
|
|
||||||
MetavoxelSystemClient::MetavoxelSystemClient(const SharedNodePointer& node, MetavoxelUpdater* updater) :
|
MetavoxelSystemClient::MetavoxelSystemClient(const SharedNodePointer& node, MetavoxelUpdater* updater) :
|
||||||
MetavoxelClient(node, updater) {
|
MetavoxelClient(node, updater) {
|
||||||
}
|
}
|
||||||
|
@ -807,7 +960,6 @@ void HeightfieldBuffer::render(bool cursor) {
|
||||||
glDrawRangeElements(GL_TRIANGLES, 0, vertexCount - 1, indexCount, GL_UNSIGNED_INT, 0);
|
glDrawRangeElements(GL_TRIANGLES, 0, vertexCount - 1, indexCount, GL_UNSIGNED_INT, 0);
|
||||||
|
|
||||||
} else if (!_materials.isEmpty()) {
|
} else if (!_materials.isEmpty()) {
|
||||||
DefaultMetavoxelRendererImplementation::getBaseHeightfieldProgram().bind();
|
|
||||||
DefaultMetavoxelRendererImplementation::getBaseHeightfieldProgram().setUniformValue(
|
DefaultMetavoxelRendererImplementation::getBaseHeightfieldProgram().setUniformValue(
|
||||||
DefaultMetavoxelRendererImplementation::getBaseHeightScaleLocation(), 1.0f / _heightSize);
|
DefaultMetavoxelRendererImplementation::getBaseHeightScaleLocation(), 1.0f / _heightSize);
|
||||||
DefaultMetavoxelRendererImplementation::getBaseHeightfieldProgram().setUniformValue(
|
DefaultMetavoxelRendererImplementation::getBaseHeightfieldProgram().setUniformValue(
|
||||||
|
@ -817,6 +969,8 @@ void HeightfieldBuffer::render(bool cursor) {
|
||||||
|
|
||||||
glDrawRangeElements(GL_TRIANGLES, 0, vertexCount - 1, indexCount, GL_UNSIGNED_INT, 0);
|
glDrawRangeElements(GL_TRIANGLES, 0, vertexCount - 1, indexCount, GL_UNSIGNED_INT, 0);
|
||||||
|
|
||||||
|
glDrawBuffers(sizeof(COLOR_DRAW_BUFFERS) / sizeof(COLOR_DRAW_BUFFERS[0]), COLOR_DRAW_BUFFERS);
|
||||||
|
|
||||||
glDepthFunc(GL_LEQUAL);
|
glDepthFunc(GL_LEQUAL);
|
||||||
glDepthMask(false);
|
glDepthMask(false);
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
|
@ -825,18 +979,18 @@ void HeightfieldBuffer::render(bool cursor) {
|
||||||
glPolygonOffset(-1.0f, -1.0f);
|
glPolygonOffset(-1.0f, -1.0f);
|
||||||
|
|
||||||
DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().bind();
|
DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().bind();
|
||||||
|
const DefaultMetavoxelRendererImplementation::SplatLocations& locations =
|
||||||
|
DefaultMetavoxelRendererImplementation::getSplatHeightfieldLocations();
|
||||||
DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniformValue(
|
DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniformValue(
|
||||||
DefaultMetavoxelRendererImplementation::getSplatHeightScaleLocation(), 1.0f / _heightSize);
|
locations.heightScale, 1.0f / _heightSize);
|
||||||
DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniformValue(
|
DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniformValue(
|
||||||
DefaultMetavoxelRendererImplementation::getSplatTextureScaleLocation(), (float)_heightSize / innerSize);
|
locations.textureScale, (float)_heightSize / innerSize);
|
||||||
DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniformValue(
|
DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniformValue(
|
||||||
DefaultMetavoxelRendererImplementation::getSplatTextureOffsetLocation(),
|
locations.splatTextureOffset, _translation.x / _scale, _translation.z / _scale);
|
||||||
_translation.x / _scale, _translation.z / _scale);
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, _materialTextureID);
|
glBindTexture(GL_TEXTURE_2D, _materialTextureID);
|
||||||
|
|
||||||
const int TEXTURES_PER_SPLAT = 4;
|
for (int i = 0; i < _materials.size(); i += SPLAT_COUNT) {
|
||||||
for (int i = 0; i < _materials.size(); i += TEXTURES_PER_SPLAT) {
|
|
||||||
QVector4D scalesS, scalesT;
|
QVector4D scalesS, scalesT;
|
||||||
|
|
||||||
for (int j = 0; j < SPLAT_COUNT; j++) {
|
for (int j = 0; j < SPLAT_COUNT; j++) {
|
||||||
|
@ -858,23 +1012,20 @@ void HeightfieldBuffer::render(bool cursor) {
|
||||||
}
|
}
|
||||||
const float QUARTER_STEP = 0.25f * EIGHT_BIT_MAXIMUM_RECIPROCAL;
|
const float QUARTER_STEP = 0.25f * EIGHT_BIT_MAXIMUM_RECIPROCAL;
|
||||||
DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniformValue(
|
DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniformValue(
|
||||||
DefaultMetavoxelRendererImplementation::getSplatTextureScalesSLocation(), scalesS);
|
locations.splatTextureScalesS, scalesS);
|
||||||
DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniformValue(
|
DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniformValue(
|
||||||
DefaultMetavoxelRendererImplementation::getSplatTextureScalesTLocation(), scalesT);
|
locations.splatTextureScalesT, scalesT);
|
||||||
DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniformValue(
|
DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniformValue(
|
||||||
DefaultMetavoxelRendererImplementation::getSplatTextureValueMinimaLocation(),
|
locations.textureValueMinima,
|
||||||
(i + 1) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP, (i + 2) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP,
|
(i + 1) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP, (i + 2) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP,
|
||||||
(i + 3) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP, (i + 4) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP);
|
(i + 3) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP, (i + 4) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP);
|
||||||
DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniformValue(
|
DefaultMetavoxelRendererImplementation::getSplatHeightfieldProgram().setUniformValue(
|
||||||
DefaultMetavoxelRendererImplementation::getSplatTextureValueMaximaLocation(),
|
locations.textureValueMaxima,
|
||||||
(i + 1) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP, (i + 2) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP,
|
(i + 1) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP, (i + 2) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP,
|
||||||
(i + 3) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP, (i + 4) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP);
|
(i + 3) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP, (i + 4) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP);
|
||||||
glDrawRangeElements(GL_TRIANGLES, 0, vertexCount - 1, indexCount, GL_UNSIGNED_INT, 0);
|
glDrawRangeElements(GL_TRIANGLES, 0, vertexCount - 1, indexCount, GL_UNSIGNED_INT, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
glEnable(GL_ALPHA_TEST);
|
|
||||||
glBlendFunc(GL_DST_COLOR, GL_ZERO);
|
|
||||||
|
|
||||||
for (int i = 0; i < SPLAT_COUNT; i++) {
|
for (int i = 0; i < SPLAT_COUNT; i++) {
|
||||||
glActiveTexture(GL_TEXTURE0 + SPLAT_TEXTURE_UNITS[i]);
|
glActiveTexture(GL_TEXTURE0 + SPLAT_TEXTURE_UNITS[i]);
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
@ -883,52 +1034,23 @@ void HeightfieldBuffer::render(bool cursor) {
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::SimpleShadows)) {
|
|
||||||
DefaultMetavoxelRendererImplementation::getShadowLightHeightfieldProgram().bind();
|
|
||||||
DefaultMetavoxelRendererImplementation::getShadowLightHeightfieldProgram().setUniformValue(
|
|
||||||
DefaultMetavoxelRendererImplementation::getShadowLightHeightScaleLocation(), 1.0f / _heightSize);
|
|
||||||
glDrawRangeElements(GL_TRIANGLES, 0, vertexCount - 1, indexCount, GL_UNSIGNED_INT, 0);
|
|
||||||
DefaultMetavoxelRendererImplementation::getShadowMapHeightfieldProgram().bind();
|
|
||||||
|
|
||||||
} else if (Menu::getInstance()->isOptionChecked(MenuOption::CascadedShadows)) {
|
|
||||||
DefaultMetavoxelRendererImplementation::getCascadedShadowLightHeightfieldProgram().bind();
|
|
||||||
DefaultMetavoxelRendererImplementation::getCascadedShadowLightHeightfieldProgram().setUniformValue(
|
|
||||||
DefaultMetavoxelRendererImplementation::getCascadedShadowLightHeightScaleLocation(), 1.0f / _heightSize);
|
|
||||||
glDrawRangeElements(GL_TRIANGLES, 0, vertexCount - 1, indexCount, GL_UNSIGNED_INT, 0);
|
|
||||||
DefaultMetavoxelRendererImplementation::getCascadedShadowMapHeightfieldProgram().bind();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
DefaultMetavoxelRendererImplementation::getLightHeightfieldProgram().bind();
|
|
||||||
DefaultMetavoxelRendererImplementation::getLightHeightfieldProgram().setUniformValue(
|
|
||||||
DefaultMetavoxelRendererImplementation::getLightHeightScaleLocation(), 1.0f / _heightSize);
|
|
||||||
glDrawRangeElements(GL_TRIANGLES, 0, vertexCount - 1, indexCount, GL_UNSIGNED_INT, 0);
|
|
||||||
DefaultMetavoxelRendererImplementation::getHeightfieldProgram().bind();
|
|
||||||
}
|
|
||||||
|
|
||||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
|
||||||
glDisable(GL_BLEND);
|
|
||||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE);
|
|
||||||
glDepthFunc(GL_LESS);
|
|
||||||
glDepthMask(true);
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
} else {
|
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||||
int heightScaleLocation = DefaultMetavoxelRendererImplementation::getHeightScaleLocation();
|
glEnable(GL_ALPHA_TEST);
|
||||||
int colorScaleLocation = DefaultMetavoxelRendererImplementation::getColorScaleLocation();
|
glDisable(GL_BLEND);
|
||||||
ProgramObject* program = &DefaultMetavoxelRendererImplementation::getHeightfieldProgram();
|
glDepthMask(true);
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::SimpleShadows)) {
|
glDepthFunc(GL_LESS);
|
||||||
heightScaleLocation = DefaultMetavoxelRendererImplementation::getShadowMapHeightScaleLocation();
|
|
||||||
colorScaleLocation = DefaultMetavoxelRendererImplementation::getShadowMapColorScaleLocation();
|
|
||||||
program = &DefaultMetavoxelRendererImplementation::getShadowMapHeightfieldProgram();
|
|
||||||
|
|
||||||
} else if (Menu::getInstance()->isOptionChecked(MenuOption::CascadedShadows)) {
|
glDrawBuffers(sizeof(COLOR_NORMAL_DRAW_BUFFERS) / sizeof(COLOR_NORMAL_DRAW_BUFFERS[0]), COLOR_NORMAL_DRAW_BUFFERS);
|
||||||
heightScaleLocation = DefaultMetavoxelRendererImplementation::getCascadedShadowMapHeightScaleLocation();
|
|
||||||
colorScaleLocation = DefaultMetavoxelRendererImplementation::getCascadedShadowMapColorScaleLocation();
|
DefaultMetavoxelRendererImplementation::getBaseHeightfieldProgram().bind();
|
||||||
program = &DefaultMetavoxelRendererImplementation::getCascadedShadowMapHeightfieldProgram();
|
|
||||||
}
|
} else {
|
||||||
program->setUniformValue(heightScaleLocation, 1.0f / _heightSize);
|
DefaultMetavoxelRendererImplementation::getBaseHeightfieldProgram().setUniformValue(
|
||||||
program->setUniformValue(colorScaleLocation, (float)_heightSize / innerSize);
|
DefaultMetavoxelRendererImplementation::getBaseHeightScaleLocation(), 1.0f / _heightSize);
|
||||||
|
DefaultMetavoxelRendererImplementation::getBaseHeightfieldProgram().setUniformValue(
|
||||||
|
DefaultMetavoxelRendererImplementation::getBaseColorScaleLocation(), (float)_heightSize / innerSize);
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
glBindTexture(GL_TEXTURE_2D, _colorTextureID);
|
glBindTexture(GL_TEXTURE_2D, _colorTextureID);
|
||||||
|
|
||||||
|
@ -944,6 +1066,8 @@ void HeightfieldBuffer::render(bool cursor) {
|
||||||
|
|
||||||
bufferPair.first.release();
|
bufferPair.first.release();
|
||||||
bufferPair.second.release();
|
bufferPair.second.release();
|
||||||
|
|
||||||
|
Application::getInstance()->getMetavoxels()->noteNeedToLight();
|
||||||
}
|
}
|
||||||
|
|
||||||
QHash<int, HeightfieldBuffer::BufferPair> HeightfieldBuffer::_bufferPairs;
|
QHash<int, HeightfieldBuffer::BufferPair> HeightfieldBuffer::_bufferPairs;
|
||||||
|
@ -959,7 +1083,7 @@ void HeightfieldPreview::render(const glm::vec3& translation, float scale) const
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
|
||||||
DefaultMetavoxelRendererImplementation::getHeightfieldProgram().bind();
|
DefaultMetavoxelRendererImplementation::getBaseHeightfieldProgram().bind();
|
||||||
|
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glTranslatef(translation.x, translation.y, translation.z);
|
glTranslatef(translation.x, translation.y, translation.z);
|
||||||
|
@ -971,7 +1095,7 @@ void HeightfieldPreview::render(const glm::vec3& translation, float scale) const
|
||||||
|
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
|
||||||
DefaultMetavoxelRendererImplementation::getHeightfieldProgram().release();
|
DefaultMetavoxelRendererImplementation::getBaseHeightfieldProgram().release();
|
||||||
|
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
|
@ -1025,8 +1149,89 @@ void VoxelBuffer::render(bool cursor) {
|
||||||
|
|
||||||
glDrawRangeElements(GL_QUADS, 0, _vertexCount - 1, _indexCount, GL_UNSIGNED_INT, 0);
|
glDrawRangeElements(GL_QUADS, 0, _vertexCount - 1, _indexCount, GL_UNSIGNED_INT, 0);
|
||||||
|
|
||||||
|
if (!_materials.isEmpty()) {
|
||||||
|
glDrawBuffers(sizeof(COLOR_DRAW_BUFFERS) / sizeof(COLOR_DRAW_BUFFERS[0]), COLOR_DRAW_BUFFERS);
|
||||||
|
|
||||||
|
glDepthFunc(GL_LEQUAL);
|
||||||
|
glDepthMask(false);
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glDisable(GL_ALPHA_TEST);
|
||||||
|
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||||
|
glPolygonOffset(-1.0f, -1.0f);
|
||||||
|
|
||||||
|
DefaultMetavoxelRendererImplementation::getSplatVoxelProgram().bind();
|
||||||
|
const DefaultMetavoxelRendererImplementation::SplatLocations& locations =
|
||||||
|
DefaultMetavoxelRendererImplementation::getSplatVoxelLocations();
|
||||||
|
|
||||||
|
DefaultMetavoxelRendererImplementation::getSplatVoxelProgram().setAttributeBuffer(locations.materials,
|
||||||
|
GL_UNSIGNED_BYTE, (qint64)&point->materials, SPLAT_COUNT, sizeof(VoxelPoint));
|
||||||
|
DefaultMetavoxelRendererImplementation::getSplatVoxelProgram().enableAttributeArray(locations.materials);
|
||||||
|
|
||||||
|
DefaultMetavoxelRendererImplementation::getSplatVoxelProgram().setAttributeBuffer(locations.materialWeights,
|
||||||
|
GL_UNSIGNED_BYTE, (qint64)&point->materialWeights, SPLAT_COUNT, sizeof(VoxelPoint));
|
||||||
|
DefaultMetavoxelRendererImplementation::getSplatVoxelProgram().enableAttributeArray(locations.materialWeights);
|
||||||
|
|
||||||
|
for (int i = 0; i < _materials.size(); i += SPLAT_COUNT) {
|
||||||
|
QVector4D scalesS, scalesT;
|
||||||
|
|
||||||
|
for (int j = 0; j < SPLAT_COUNT; j++) {
|
||||||
|
glActiveTexture(GL_TEXTURE0 + SPLAT_TEXTURE_UNITS[j]);
|
||||||
|
int index = i + j;
|
||||||
|
if (index < _networkTextures.size()) {
|
||||||
|
const NetworkTexturePointer& texture = _networkTextures.at(index);
|
||||||
|
if (texture) {
|
||||||
|
MaterialObject* material = static_cast<MaterialObject*>(_materials.at(index).data());
|
||||||
|
scalesS[j] = 1.0f / material->getScaleS();
|
||||||
|
scalesT[j] = 1.0f / material->getScaleT();
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texture->getID());
|
||||||
|
} else {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const float QUARTER_STEP = 0.25f * EIGHT_BIT_MAXIMUM_RECIPROCAL;
|
||||||
|
DefaultMetavoxelRendererImplementation::getSplatVoxelProgram().setUniformValue(
|
||||||
|
locations.splatTextureScalesS, scalesS);
|
||||||
|
DefaultMetavoxelRendererImplementation::getSplatVoxelProgram().setUniformValue(
|
||||||
|
locations.splatTextureScalesT, scalesT);
|
||||||
|
DefaultMetavoxelRendererImplementation::getSplatVoxelProgram().setUniformValue(
|
||||||
|
locations.textureValueMinima,
|
||||||
|
(i + 1) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP, (i + 2) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP,
|
||||||
|
(i + 3) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP, (i + 4) * EIGHT_BIT_MAXIMUM_RECIPROCAL - QUARTER_STEP);
|
||||||
|
DefaultMetavoxelRendererImplementation::getSplatVoxelProgram().setUniformValue(
|
||||||
|
locations.textureValueMaxima,
|
||||||
|
(i + 1) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP, (i + 2) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP,
|
||||||
|
(i + 3) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP, (i + 4) * EIGHT_BIT_MAXIMUM_RECIPROCAL + QUARTER_STEP);
|
||||||
|
glDrawRangeElements(GL_QUADS, 0, _vertexCount - 1, _indexCount, GL_UNSIGNED_INT, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < SPLAT_COUNT; i++) {
|
||||||
|
glActiveTexture(GL_TEXTURE0 + SPLAT_TEXTURE_UNITS[i]);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
|
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||||
|
glEnable(GL_ALPHA_TEST);
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
glDepthMask(true);
|
||||||
|
glDepthFunc(GL_LESS);
|
||||||
|
|
||||||
|
glDrawBuffers(sizeof(COLOR_NORMAL_DRAW_BUFFERS) / sizeof(COLOR_NORMAL_DRAW_BUFFERS[0]), COLOR_NORMAL_DRAW_BUFFERS);
|
||||||
|
|
||||||
|
DefaultMetavoxelRendererImplementation::getSplatVoxelProgram().disableAttributeArray(locations.materials);
|
||||||
|
DefaultMetavoxelRendererImplementation::getSplatVoxelProgram().disableAttributeArray(locations.materialWeights);
|
||||||
|
|
||||||
|
DefaultMetavoxelRendererImplementation::getBaseVoxelProgram().bind();
|
||||||
|
}
|
||||||
|
|
||||||
_vertexBuffer.release();
|
_vertexBuffer.release();
|
||||||
_indexBuffer.release();
|
_indexBuffer.release();
|
||||||
|
|
||||||
|
Application::getInstance()->getMetavoxels()->noteNeedToLight();
|
||||||
}
|
}
|
||||||
|
|
||||||
BufferDataAttribute::BufferDataAttribute(const QString& name) :
|
BufferDataAttribute::BufferDataAttribute(const QString& name) :
|
||||||
|
@ -1056,48 +1261,6 @@ void DefaultMetavoxelRendererImplementation::init() {
|
||||||
_pointScaleLocation = _pointProgram.uniformLocation("pointScale");
|
_pointScaleLocation = _pointProgram.uniformLocation("pointScale");
|
||||||
_pointProgram.release();
|
_pointProgram.release();
|
||||||
|
|
||||||
_heightfieldProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() +
|
|
||||||
"shaders/metavoxel_heightfield.vert");
|
|
||||||
_heightfieldProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() +
|
|
||||||
"shaders/metavoxel_heightfield.frag");
|
|
||||||
_heightfieldProgram.link();
|
|
||||||
|
|
||||||
_heightfieldProgram.bind();
|
|
||||||
_heightfieldProgram.setUniformValue("heightMap", 0);
|
|
||||||
_heightfieldProgram.setUniformValue("diffuseMap", 1);
|
|
||||||
_heightScaleLocation = _heightfieldProgram.uniformLocation("heightScale");
|
|
||||||
_colorScaleLocation = _heightfieldProgram.uniformLocation("colorScale");
|
|
||||||
_heightfieldProgram.release();
|
|
||||||
|
|
||||||
_shadowMapHeightfieldProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() +
|
|
||||||
"shaders/metavoxel_heightfield.vert");
|
|
||||||
_shadowMapHeightfieldProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() +
|
|
||||||
"shaders/metavoxel_heightfield_shadow_map.frag");
|
|
||||||
_shadowMapHeightfieldProgram.link();
|
|
||||||
|
|
||||||
_shadowMapHeightfieldProgram.bind();
|
|
||||||
_shadowMapHeightfieldProgram.setUniformValue("heightMap", 0);
|
|
||||||
_shadowMapHeightfieldProgram.setUniformValue("diffuseMap", 1);
|
|
||||||
_shadowMapHeightfieldProgram.setUniformValue("shadowMap", 2);
|
|
||||||
_shadowMapHeightScaleLocation = _shadowMapHeightfieldProgram.uniformLocation("heightScale");
|
|
||||||
_shadowMapColorScaleLocation = _shadowMapHeightfieldProgram.uniformLocation("colorScale");
|
|
||||||
_shadowMapHeightfieldProgram.release();
|
|
||||||
|
|
||||||
_cascadedShadowMapHeightfieldProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() +
|
|
||||||
"shaders/metavoxel_heightfield.vert");
|
|
||||||
_cascadedShadowMapHeightfieldProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() +
|
|
||||||
"shaders/metavoxel_heightfield_cascaded_shadow_map.frag");
|
|
||||||
_cascadedShadowMapHeightfieldProgram.link();
|
|
||||||
|
|
||||||
_cascadedShadowMapHeightfieldProgram.bind();
|
|
||||||
_cascadedShadowMapHeightfieldProgram.setUniformValue("heightMap", 0);
|
|
||||||
_cascadedShadowMapHeightfieldProgram.setUniformValue("diffuseMap", 1);
|
|
||||||
_cascadedShadowMapHeightfieldProgram.setUniformValue("shadowMap", 2);
|
|
||||||
_cascadedShadowMapHeightScaleLocation = _cascadedShadowMapHeightfieldProgram.uniformLocation("heightScale");
|
|
||||||
_cascadedShadowMapColorScaleLocation = _cascadedShadowMapHeightfieldProgram.uniformLocation("colorScale");
|
|
||||||
_shadowDistancesLocation = _cascadedShadowMapHeightfieldProgram.uniformLocation("shadowDistances");
|
|
||||||
_cascadedShadowMapHeightfieldProgram.release();
|
|
||||||
|
|
||||||
_baseHeightfieldProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() +
|
_baseHeightfieldProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() +
|
||||||
"shaders/metavoxel_heightfield_base.vert");
|
"shaders/metavoxel_heightfield_base.vert");
|
||||||
_baseHeightfieldProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() +
|
_baseHeightfieldProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() +
|
||||||
|
@ -1111,60 +1274,7 @@ void DefaultMetavoxelRendererImplementation::init() {
|
||||||
_baseColorScaleLocation = _baseHeightfieldProgram.uniformLocation("colorScale");
|
_baseColorScaleLocation = _baseHeightfieldProgram.uniformLocation("colorScale");
|
||||||
_baseHeightfieldProgram.release();
|
_baseHeightfieldProgram.release();
|
||||||
|
|
||||||
_splatHeightfieldProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() +
|
loadSplatProgram("heightfield", _splatHeightfieldProgram, _splatHeightfieldLocations);
|
||||||
"shaders/metavoxel_heightfield_splat.vert");
|
|
||||||
_splatHeightfieldProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() +
|
|
||||||
"shaders/metavoxel_heightfield_splat.frag");
|
|
||||||
_splatHeightfieldProgram.link();
|
|
||||||
|
|
||||||
_splatHeightfieldProgram.bind();
|
|
||||||
_splatHeightfieldProgram.setUniformValue("heightMap", 0);
|
|
||||||
_splatHeightfieldProgram.setUniformValue("textureMap", 1);
|
|
||||||
_splatHeightfieldProgram.setUniformValueArray("diffuseMaps", SPLAT_TEXTURE_UNITS, SPLAT_COUNT);
|
|
||||||
_splatHeightScaleLocation = _splatHeightfieldProgram.uniformLocation("heightScale");
|
|
||||||
_splatTextureScaleLocation = _splatHeightfieldProgram.uniformLocation("textureScale");
|
|
||||||
_splatTextureOffsetLocation = _splatHeightfieldProgram.uniformLocation("splatTextureOffset");
|
|
||||||
_splatTextureScalesSLocation = _splatHeightfieldProgram.uniformLocation("splatTextureScalesS");
|
|
||||||
_splatTextureScalesTLocation = _splatHeightfieldProgram.uniformLocation("splatTextureScalesT");
|
|
||||||
_splatTextureValueMinimaLocation = _splatHeightfieldProgram.uniformLocation("textureValueMinima");
|
|
||||||
_splatTextureValueMaximaLocation = _splatHeightfieldProgram.uniformLocation("textureValueMaxima");
|
|
||||||
_splatHeightfieldProgram.release();
|
|
||||||
|
|
||||||
_lightHeightfieldProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() +
|
|
||||||
"shaders/metavoxel_heightfield_light.vert");
|
|
||||||
_lightHeightfieldProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() +
|
|
||||||
"shaders/metavoxel_heightfield_light.frag");
|
|
||||||
_lightHeightfieldProgram.link();
|
|
||||||
|
|
||||||
_lightHeightfieldProgram.bind();
|
|
||||||
_lightHeightfieldProgram.setUniformValue("heightMap", 0);
|
|
||||||
_lightHeightScaleLocation = _lightHeightfieldProgram.uniformLocation("heightScale");
|
|
||||||
_lightHeightfieldProgram.release();
|
|
||||||
|
|
||||||
_shadowLightHeightfieldProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() +
|
|
||||||
"shaders/metavoxel_heightfield_light.vert");
|
|
||||||
_shadowLightHeightfieldProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() +
|
|
||||||
"shaders/metavoxel_heightfield_light_shadow_map.frag");
|
|
||||||
_shadowLightHeightfieldProgram.link();
|
|
||||||
|
|
||||||
_shadowLightHeightfieldProgram.bind();
|
|
||||||
_shadowLightHeightfieldProgram.setUniformValue("heightMap", 0);
|
|
||||||
_shadowLightHeightfieldProgram.setUniformValue("shadowMap", 2);
|
|
||||||
_shadowLightHeightScaleLocation = _shadowLightHeightfieldProgram.uniformLocation("heightScale");
|
|
||||||
_shadowLightHeightfieldProgram.release();
|
|
||||||
|
|
||||||
_cascadedShadowLightHeightfieldProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() +
|
|
||||||
"shaders/metavoxel_heightfield_light.vert");
|
|
||||||
_cascadedShadowLightHeightfieldProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() +
|
|
||||||
"shaders/metavoxel_heightfield_light_cascaded_shadow_map.frag");
|
|
||||||
_cascadedShadowLightHeightfieldProgram.link();
|
|
||||||
|
|
||||||
_cascadedShadowLightHeightfieldProgram.bind();
|
|
||||||
_cascadedShadowLightHeightfieldProgram.setUniformValue("heightMap", 0);
|
|
||||||
_cascadedShadowLightHeightfieldProgram.setUniformValue("shadowMap", 2);
|
|
||||||
_cascadedShadowLightHeightScaleLocation = _cascadedShadowLightHeightfieldProgram.uniformLocation("heightScale");
|
|
||||||
_shadowLightDistancesLocation = _cascadedShadowLightHeightfieldProgram.uniformLocation("shadowDistances");
|
|
||||||
_cascadedShadowLightHeightfieldProgram.release();
|
|
||||||
|
|
||||||
_heightfieldCursorProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() +
|
_heightfieldCursorProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() +
|
||||||
"shaders/metavoxel_heightfield_cursor.vert");
|
"shaders/metavoxel_heightfield_cursor.vert");
|
||||||
|
@ -1175,6 +1285,14 @@ void DefaultMetavoxelRendererImplementation::init() {
|
||||||
_heightfieldCursorProgram.bind();
|
_heightfieldCursorProgram.bind();
|
||||||
_heightfieldCursorProgram.setUniformValue("heightMap", 0);
|
_heightfieldCursorProgram.setUniformValue("heightMap", 0);
|
||||||
_heightfieldCursorProgram.release();
|
_heightfieldCursorProgram.release();
|
||||||
|
|
||||||
|
_baseVoxelProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() +
|
||||||
|
"shaders/metavoxel_voxel_base.vert");
|
||||||
|
_baseVoxelProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() +
|
||||||
|
"shaders/metavoxel_voxel_base.frag");
|
||||||
|
_baseVoxelProgram.link();
|
||||||
|
|
||||||
|
loadSplatProgram("voxel", _splatVoxelProgram, _splatVoxelLocations);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1844,7 +1962,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
||||||
glm::vec3 center;
|
glm::vec3 center;
|
||||||
glm::vec3 normal;
|
glm::vec3 normal;
|
||||||
const int MAX_MATERIALS_PER_VERTEX = 4;
|
const int MAX_MATERIALS_PER_VERTEX = 4;
|
||||||
quint8 materials[4];
|
quint8 materials[] = { 0, 0, 0, 0 };
|
||||||
glm::vec4 materialWeights;
|
glm::vec4 materialWeights;
|
||||||
float totalWeight = 0.0f;
|
float totalWeight = 0.0f;
|
||||||
int red = 0, green = 0, blue = 0;
|
int red = 0, green = 0, blue = 0;
|
||||||
|
@ -1865,7 +1983,7 @@ int VoxelAugmentVisitor::visit(MetavoxelInfo& info) {
|
||||||
totalWeight += 1.0f;
|
totalWeight += 1.0f;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
} else if (materials[j] == 0.0f) {
|
} else if (materials[j] == 0) {
|
||||||
materials[j] = crossing.material;
|
materials[j] = crossing.material;
|
||||||
materialWeights[j] = 1.0f;
|
materialWeights[j] = 1.0f;
|
||||||
totalWeight += 1.0f;
|
totalWeight += 1.0f;
|
||||||
|
@ -2149,38 +2267,22 @@ void DefaultMetavoxelRendererImplementation::render(MetavoxelData& data, Metavox
|
||||||
|
|
||||||
_pointProgram.release();
|
_pointProgram.release();
|
||||||
|
|
||||||
|
glDrawBuffers(sizeof(COLOR_NORMAL_DRAW_BUFFERS) / sizeof(COLOR_NORMAL_DRAW_BUFFERS[0]), COLOR_NORMAL_DRAW_BUFFERS);
|
||||||
|
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
glEnable(GL_ALPHA_TEST);
|
glEnable(GL_ALPHA_TEST);
|
||||||
glAlphaFunc(GL_EQUAL, 0.0f);
|
glAlphaFunc(GL_EQUAL, 0.0f);
|
||||||
|
|
||||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
|
||||||
ProgramObject* program = &_heightfieldProgram;
|
_baseHeightfieldProgram.bind();
|
||||||
if (Menu::getInstance()->getShadowsEnabled()) {
|
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::CascadedShadows)) {
|
|
||||||
_cascadedShadowLightHeightfieldProgram.bind();
|
|
||||||
_cascadedShadowLightHeightfieldProgram.setUniform(_shadowLightDistancesLocation,
|
|
||||||
Application::getInstance()->getShadowDistances());
|
|
||||||
program = &_cascadedShadowMapHeightfieldProgram;
|
|
||||||
program->bind();
|
|
||||||
program->setUniform(_shadowDistancesLocation, Application::getInstance()->getShadowDistances());
|
|
||||||
|
|
||||||
} else {
|
|
||||||
program = &_shadowMapHeightfieldProgram;
|
|
||||||
}
|
|
||||||
glActiveTexture(GL_TEXTURE2);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getShadowDepthTextureID());
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
}
|
|
||||||
|
|
||||||
program->bind();
|
|
||||||
|
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
|
|
||||||
BufferRenderVisitor heightfieldRenderVisitor(Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute());
|
BufferRenderVisitor heightfieldRenderVisitor(Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute());
|
||||||
data.guide(heightfieldRenderVisitor);
|
data.guide(heightfieldRenderVisitor);
|
||||||
|
|
||||||
program->release();
|
_baseHeightfieldProgram.release();
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE2);
|
glActiveTexture(GL_TEXTURE2);
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
@ -2189,57 +2291,63 @@ void DefaultMetavoxelRendererImplementation::render(MetavoxelData& data, Metavox
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
|
|
||||||
glDisable(GL_ALPHA_TEST);
|
|
||||||
glDisable(GL_CULL_FACE);
|
|
||||||
glEnable(GL_BLEND);
|
|
||||||
|
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
glEnableClientState(GL_COLOR_ARRAY);
|
glEnableClientState(GL_COLOR_ARRAY);
|
||||||
glEnableClientState(GL_NORMAL_ARRAY);
|
glEnableClientState(GL_NORMAL_ARRAY);
|
||||||
|
|
||||||
glEnable(GL_CULL_FACE);
|
_baseVoxelProgram.bind();
|
||||||
|
|
||||||
BufferRenderVisitor voxelRenderVisitor(Application::getInstance()->getMetavoxels()->getVoxelBufferAttribute());
|
BufferRenderVisitor voxelRenderVisitor(Application::getInstance()->getMetavoxels()->getVoxelBufferAttribute());
|
||||||
data.guide(voxelRenderVisitor);
|
data.guide(voxelRenderVisitor);
|
||||||
|
|
||||||
|
_baseVoxelProgram.release();
|
||||||
|
|
||||||
|
glDisable(GL_ALPHA_TEST);
|
||||||
glDisable(GL_CULL_FACE);
|
glDisable(GL_CULL_FACE);
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
glDisableClientState(GL_COLOR_ARRAY);
|
glDisableClientState(GL_COLOR_ARRAY);
|
||||||
glDisableClientState(GL_NORMAL_ARRAY);
|
glDisableClientState(GL_NORMAL_ARRAY);
|
||||||
|
|
||||||
|
glDrawBuffers(sizeof(COLOR_DRAW_BUFFERS) / sizeof(COLOR_DRAW_BUFFERS[0]), COLOR_DRAW_BUFFERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DefaultMetavoxelRendererImplementation::loadSplatProgram(const char* type,
|
||||||
|
ProgramObject& program, SplatLocations& locations) {
|
||||||
|
program.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() +
|
||||||
|
"shaders/metavoxel_" + type + "_splat.vert");
|
||||||
|
program.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() +
|
||||||
|
"shaders/metavoxel_" + type + "_splat.frag");
|
||||||
|
program.link();
|
||||||
|
|
||||||
|
program.bind();
|
||||||
|
program.setUniformValue("heightMap", 0);
|
||||||
|
program.setUniformValue("textureMap", 1);
|
||||||
|
program.setUniformValueArray("diffuseMaps", SPLAT_TEXTURE_UNITS, SPLAT_COUNT);
|
||||||
|
locations.heightScale = program.uniformLocation("heightScale");
|
||||||
|
locations.textureScale = program.uniformLocation("textureScale");
|
||||||
|
locations.splatTextureOffset = program.uniformLocation("splatTextureOffset");
|
||||||
|
locations.splatTextureScalesS = program.uniformLocation("splatTextureScalesS");
|
||||||
|
locations.splatTextureScalesT = program.uniformLocation("splatTextureScalesT");
|
||||||
|
locations.textureValueMinima = program.uniformLocation("textureValueMinima");
|
||||||
|
locations.textureValueMaxima = program.uniformLocation("textureValueMaxima");
|
||||||
|
locations.materials = program.attributeLocation("materials");
|
||||||
|
locations.materialWeights = program.attributeLocation("materialWeights");
|
||||||
|
program.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
ProgramObject DefaultMetavoxelRendererImplementation::_pointProgram;
|
ProgramObject DefaultMetavoxelRendererImplementation::_pointProgram;
|
||||||
int DefaultMetavoxelRendererImplementation::_pointScaleLocation;
|
int DefaultMetavoxelRendererImplementation::_pointScaleLocation;
|
||||||
ProgramObject DefaultMetavoxelRendererImplementation::_heightfieldProgram;
|
|
||||||
int DefaultMetavoxelRendererImplementation::_heightScaleLocation;
|
|
||||||
int DefaultMetavoxelRendererImplementation::_colorScaleLocation;
|
|
||||||
ProgramObject DefaultMetavoxelRendererImplementation::_shadowMapHeightfieldProgram;
|
|
||||||
int DefaultMetavoxelRendererImplementation::_shadowMapHeightScaleLocation;
|
|
||||||
int DefaultMetavoxelRendererImplementation::_shadowMapColorScaleLocation;
|
|
||||||
ProgramObject DefaultMetavoxelRendererImplementation::_cascadedShadowMapHeightfieldProgram;
|
|
||||||
int DefaultMetavoxelRendererImplementation::_cascadedShadowMapHeightScaleLocation;
|
|
||||||
int DefaultMetavoxelRendererImplementation::_cascadedShadowMapColorScaleLocation;
|
|
||||||
int DefaultMetavoxelRendererImplementation::_shadowDistancesLocation;
|
|
||||||
ProgramObject DefaultMetavoxelRendererImplementation::_baseHeightfieldProgram;
|
ProgramObject DefaultMetavoxelRendererImplementation::_baseHeightfieldProgram;
|
||||||
int DefaultMetavoxelRendererImplementation::_baseHeightScaleLocation;
|
int DefaultMetavoxelRendererImplementation::_baseHeightScaleLocation;
|
||||||
int DefaultMetavoxelRendererImplementation::_baseColorScaleLocation;
|
int DefaultMetavoxelRendererImplementation::_baseColorScaleLocation;
|
||||||
ProgramObject DefaultMetavoxelRendererImplementation::_splatHeightfieldProgram;
|
ProgramObject DefaultMetavoxelRendererImplementation::_splatHeightfieldProgram;
|
||||||
int DefaultMetavoxelRendererImplementation::_splatHeightScaleLocation;
|
DefaultMetavoxelRendererImplementation::SplatLocations DefaultMetavoxelRendererImplementation::_splatHeightfieldLocations;
|
||||||
int DefaultMetavoxelRendererImplementation::_splatTextureScaleLocation;
|
|
||||||
int DefaultMetavoxelRendererImplementation::_splatTextureOffsetLocation;
|
|
||||||
int DefaultMetavoxelRendererImplementation::_splatTextureScalesSLocation;
|
|
||||||
int DefaultMetavoxelRendererImplementation::_splatTextureScalesTLocation;
|
|
||||||
int DefaultMetavoxelRendererImplementation::_splatTextureValueMinimaLocation;
|
|
||||||
int DefaultMetavoxelRendererImplementation::_splatTextureValueMaximaLocation;
|
|
||||||
ProgramObject DefaultMetavoxelRendererImplementation::_lightHeightfieldProgram;
|
|
||||||
int DefaultMetavoxelRendererImplementation::_lightHeightScaleLocation;
|
|
||||||
ProgramObject DefaultMetavoxelRendererImplementation::_shadowLightHeightfieldProgram;
|
|
||||||
int DefaultMetavoxelRendererImplementation::_shadowLightHeightScaleLocation;
|
|
||||||
ProgramObject DefaultMetavoxelRendererImplementation::_cascadedShadowLightHeightfieldProgram;
|
|
||||||
int DefaultMetavoxelRendererImplementation::_cascadedShadowLightHeightScaleLocation;
|
|
||||||
int DefaultMetavoxelRendererImplementation::_shadowLightDistancesLocation;
|
|
||||||
ProgramObject DefaultMetavoxelRendererImplementation::_heightfieldCursorProgram;
|
ProgramObject DefaultMetavoxelRendererImplementation::_heightfieldCursorProgram;
|
||||||
|
ProgramObject DefaultMetavoxelRendererImplementation::_baseVoxelProgram;
|
||||||
|
ProgramObject DefaultMetavoxelRendererImplementation::_splatVoxelProgram;
|
||||||
|
DefaultMetavoxelRendererImplementation::SplatLocations DefaultMetavoxelRendererImplementation::_splatVoxelLocations;
|
||||||
|
|
||||||
static void enableClipPlane(GLenum plane, float x, float y, float z, float w) {
|
static void enableClipPlane(GLenum plane, float x, float y, float z, float w) {
|
||||||
GLdouble coefficients[] = { x, y, z, w };
|
GLdouble coefficients[] = { x, y, z, w };
|
||||||
|
|
|
@ -52,6 +52,12 @@ public:
|
||||||
|
|
||||||
Q_INVOKABLE void deleteTextures(int heightID, int colorID, int textureID);
|
Q_INVOKABLE void deleteTextures(int heightID, int colorID, int textureID);
|
||||||
|
|
||||||
|
void noteNeedToLight() { _needToLight = true; }
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
void rendering();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual MetavoxelClient* createClient(const SharedNodePointer& node);
|
virtual MetavoxelClient* createClient(const SharedNodePointer& node);
|
||||||
|
@ -60,6 +66,18 @@ private:
|
||||||
|
|
||||||
void guideToAugmented(MetavoxelVisitor& visitor, bool render = false);
|
void guideToAugmented(MetavoxelVisitor& visitor, bool render = false);
|
||||||
|
|
||||||
|
class LightLocations {
|
||||||
|
public:
|
||||||
|
int shadowDistances;
|
||||||
|
int shadowScale;
|
||||||
|
int near;
|
||||||
|
int depthScale;
|
||||||
|
int depthTexCoordOffset;
|
||||||
|
int depthTexCoordScale;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void loadLightProgram(const char* name, ProgramObject& program, LightLocations& locations);
|
||||||
|
|
||||||
AttributePointer _pointBufferAttribute;
|
AttributePointer _pointBufferAttribute;
|
||||||
AttributePointer _heightfieldBufferAttribute;
|
AttributePointer _heightfieldBufferAttribute;
|
||||||
AttributePointer _voxelBufferAttribute;
|
AttributePointer _voxelBufferAttribute;
|
||||||
|
@ -67,6 +85,14 @@ private:
|
||||||
MetavoxelLOD _lod;
|
MetavoxelLOD _lod;
|
||||||
QReadWriteLock _lodLock;
|
QReadWriteLock _lodLock;
|
||||||
Frustum _frustum;
|
Frustum _frustum;
|
||||||
|
bool _needToLight;
|
||||||
|
|
||||||
|
ProgramObject _directionalLight;
|
||||||
|
LightLocations _directionalLightLocations;
|
||||||
|
ProgramObject _directionalLightShadowMap;
|
||||||
|
LightLocations _directionalLightShadowMapLocations;
|
||||||
|
ProgramObject _directionalLightCascadedShadowMap;
|
||||||
|
LightLocations _directionalLightCascadedShadowMapLocations;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Describes contents of a point in a point buffer.
|
/// Describes contents of a point in a point buffer.
|
||||||
|
@ -266,42 +292,33 @@ public:
|
||||||
|
|
||||||
static void init();
|
static void init();
|
||||||
|
|
||||||
static ProgramObject& getHeightfieldProgram() { return _heightfieldProgram; }
|
|
||||||
static int getHeightScaleLocation() { return _heightScaleLocation; }
|
|
||||||
static int getColorScaleLocation() { return _colorScaleLocation; }
|
|
||||||
|
|
||||||
static ProgramObject& getShadowMapHeightfieldProgram() { return _shadowMapHeightfieldProgram; }
|
|
||||||
static int getShadowMapHeightScaleLocation() { return _shadowMapHeightScaleLocation; }
|
|
||||||
static int getShadowMapColorScaleLocation() { return _shadowMapColorScaleLocation; }
|
|
||||||
|
|
||||||
static ProgramObject& getCascadedShadowMapHeightfieldProgram() { return _cascadedShadowMapHeightfieldProgram; }
|
|
||||||
static int getCascadedShadowMapHeightScaleLocation() { return _cascadedShadowMapHeightScaleLocation; }
|
|
||||||
static int getCascadedShadowMapColorScaleLocation() { return _cascadedShadowMapColorScaleLocation; }
|
|
||||||
|
|
||||||
static ProgramObject& getBaseHeightfieldProgram() { return _baseHeightfieldProgram; }
|
static ProgramObject& getBaseHeightfieldProgram() { return _baseHeightfieldProgram; }
|
||||||
static int getBaseHeightScaleLocation() { return _baseHeightScaleLocation; }
|
static int getBaseHeightScaleLocation() { return _baseHeightScaleLocation; }
|
||||||
static int getBaseColorScaleLocation() { return _baseColorScaleLocation; }
|
static int getBaseColorScaleLocation() { return _baseColorScaleLocation; }
|
||||||
|
|
||||||
|
class SplatLocations {
|
||||||
|
public:
|
||||||
|
int heightScale;
|
||||||
|
int textureScale;
|
||||||
|
int splatTextureOffset;
|
||||||
|
int splatTextureScalesS;
|
||||||
|
int splatTextureScalesT;
|
||||||
|
int textureValueMinima;
|
||||||
|
int textureValueMaxima;
|
||||||
|
int materials;
|
||||||
|
int materialWeights;
|
||||||
|
};
|
||||||
|
|
||||||
static ProgramObject& getSplatHeightfieldProgram() { return _splatHeightfieldProgram; }
|
static ProgramObject& getSplatHeightfieldProgram() { return _splatHeightfieldProgram; }
|
||||||
static int getSplatHeightScaleLocation() { return _splatHeightScaleLocation; }
|
static const SplatLocations& getSplatHeightfieldLocations() { return _splatHeightfieldLocations; }
|
||||||
static int getSplatTextureScaleLocation() { return _splatTextureScaleLocation; }
|
|
||||||
static int getSplatTextureOffsetLocation() { return _splatTextureOffsetLocation; }
|
|
||||||
static int getSplatTextureScalesSLocation() { return _splatTextureScalesSLocation; }
|
|
||||||
static int getSplatTextureScalesTLocation() { return _splatTextureScalesTLocation; }
|
|
||||||
static int getSplatTextureValueMinimaLocation() { return _splatTextureValueMinimaLocation; }
|
|
||||||
static int getSplatTextureValueMaximaLocation() { return _splatTextureValueMaximaLocation; }
|
|
||||||
|
|
||||||
static ProgramObject& getLightHeightfieldProgram() { return _lightHeightfieldProgram; }
|
|
||||||
static int getLightHeightScaleLocation() { return _lightHeightScaleLocation; }
|
|
||||||
|
|
||||||
static ProgramObject& getShadowLightHeightfieldProgram() { return _shadowLightHeightfieldProgram; }
|
|
||||||
static int getShadowLightHeightScaleLocation() { return _shadowLightHeightScaleLocation; }
|
|
||||||
|
|
||||||
static ProgramObject& getCascadedShadowLightHeightfieldProgram() { return _cascadedShadowLightHeightfieldProgram; }
|
|
||||||
static int getCascadedShadowLightHeightScaleLocation() { return _cascadedShadowLightHeightScaleLocation; }
|
|
||||||
|
|
||||||
static ProgramObject& getHeightfieldCursorProgram() { return _heightfieldCursorProgram; }
|
static ProgramObject& getHeightfieldCursorProgram() { return _heightfieldCursorProgram; }
|
||||||
|
|
||||||
|
static ProgramObject& getBaseVoxelProgram() { return _baseVoxelProgram; }
|
||||||
|
|
||||||
|
static ProgramObject& getSplatVoxelProgram() { return _splatVoxelProgram; }
|
||||||
|
static const SplatLocations& getSplatVoxelLocations() { return _splatVoxelLocations; }
|
||||||
|
|
||||||
Q_INVOKABLE DefaultMetavoxelRendererImplementation();
|
Q_INVOKABLE DefaultMetavoxelRendererImplementation();
|
||||||
|
|
||||||
virtual void augment(MetavoxelData& data, const MetavoxelData& previous, MetavoxelInfo& info, const MetavoxelLOD& lod);
|
virtual void augment(MetavoxelData& data, const MetavoxelData& previous, MetavoxelInfo& info, const MetavoxelLOD& lod);
|
||||||
|
@ -310,27 +327,18 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
static void loadSplatProgram(const char* type, ProgramObject& program, SplatLocations& locations);
|
||||||
|
|
||||||
static ProgramObject _pointProgram;
|
static ProgramObject _pointProgram;
|
||||||
static int _pointScaleLocation;
|
static int _pointScaleLocation;
|
||||||
|
|
||||||
static ProgramObject _heightfieldProgram;
|
|
||||||
static int _heightScaleLocation;
|
|
||||||
static int _colorScaleLocation;
|
|
||||||
|
|
||||||
static ProgramObject _shadowMapHeightfieldProgram;
|
|
||||||
static int _shadowMapHeightScaleLocation;
|
|
||||||
static int _shadowMapColorScaleLocation;
|
|
||||||
|
|
||||||
static ProgramObject _cascadedShadowMapHeightfieldProgram;
|
|
||||||
static int _cascadedShadowMapHeightScaleLocation;
|
|
||||||
static int _cascadedShadowMapColorScaleLocation;
|
|
||||||
static int _shadowDistancesLocation;
|
|
||||||
|
|
||||||
static ProgramObject _baseHeightfieldProgram;
|
static ProgramObject _baseHeightfieldProgram;
|
||||||
static int _baseHeightScaleLocation;
|
static int _baseHeightScaleLocation;
|
||||||
static int _baseColorScaleLocation;
|
static int _baseColorScaleLocation;
|
||||||
|
|
||||||
static ProgramObject _splatHeightfieldProgram;
|
static ProgramObject _splatHeightfieldProgram;
|
||||||
|
static SplatLocations _splatHeightfieldLocations;
|
||||||
|
|
||||||
static int _splatHeightScaleLocation;
|
static int _splatHeightScaleLocation;
|
||||||
static int _splatTextureScaleLocation;
|
static int _splatTextureScaleLocation;
|
||||||
static int _splatTextureOffsetLocation;
|
static int _splatTextureOffsetLocation;
|
||||||
|
@ -339,17 +347,11 @@ private:
|
||||||
static int _splatTextureValueMinimaLocation;
|
static int _splatTextureValueMinimaLocation;
|
||||||
static int _splatTextureValueMaximaLocation;
|
static int _splatTextureValueMaximaLocation;
|
||||||
|
|
||||||
static ProgramObject _lightHeightfieldProgram;
|
|
||||||
static int _lightHeightScaleLocation;
|
|
||||||
|
|
||||||
static ProgramObject _shadowLightHeightfieldProgram;
|
|
||||||
static int _shadowLightHeightScaleLocation;
|
|
||||||
|
|
||||||
static ProgramObject _cascadedShadowLightHeightfieldProgram;
|
|
||||||
static int _cascadedShadowLightHeightScaleLocation;
|
|
||||||
static int _shadowLightDistancesLocation;
|
|
||||||
|
|
||||||
static ProgramObject _heightfieldCursorProgram;
|
static ProgramObject _heightfieldCursorProgram;
|
||||||
|
|
||||||
|
static ProgramObject _baseVoxelProgram;
|
||||||
|
static ProgramObject _splatVoxelProgram;
|
||||||
|
static SplatLocations _splatVoxelLocations;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Base class for spanner renderers; provides clipping.
|
/// Base class for spanner renderers; provides clipping.
|
||||||
|
|
|
@ -29,6 +29,7 @@ TextureCache::TextureCache() :
|
||||||
_whiteTextureID(0),
|
_whiteTextureID(0),
|
||||||
_blueTextureID(0),
|
_blueTextureID(0),
|
||||||
_primaryDepthTextureID(0),
|
_primaryDepthTextureID(0),
|
||||||
|
_primaryNormalTextureID(0),
|
||||||
_primaryFramebufferObject(NULL),
|
_primaryFramebufferObject(NULL),
|
||||||
_secondaryFramebufferObject(NULL),
|
_secondaryFramebufferObject(NULL),
|
||||||
_tertiaryFramebufferObject(NULL),
|
_tertiaryFramebufferObject(NULL),
|
||||||
|
@ -46,6 +47,7 @@ TextureCache::~TextureCache() {
|
||||||
}
|
}
|
||||||
if (_primaryFramebufferObject) {
|
if (_primaryFramebufferObject) {
|
||||||
glDeleteTextures(1, &_primaryDepthTextureID);
|
glDeleteTextures(1, &_primaryDepthTextureID);
|
||||||
|
glDeleteTextures(1, &_primaryNormalTextureID);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_primaryFramebufferObject) {
|
if (_primaryFramebufferObject) {
|
||||||
|
@ -71,6 +73,8 @@ void TextureCache::setFrameBufferSize(QSize frameBufferSize) {
|
||||||
_primaryFramebufferObject = NULL;
|
_primaryFramebufferObject = NULL;
|
||||||
glDeleteTextures(1, &_primaryDepthTextureID);
|
glDeleteTextures(1, &_primaryDepthTextureID);
|
||||||
_primaryDepthTextureID = 0;
|
_primaryDepthTextureID = 0;
|
||||||
|
glDeleteTextures(1, &_primaryNormalTextureID);
|
||||||
|
_primaryNormalTextureID = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_secondaryFramebufferObject) {
|
if (_secondaryFramebufferObject) {
|
||||||
|
@ -205,15 +209,22 @@ QOpenGLFramebufferObject* TextureCache::getPrimaryFramebufferObject() {
|
||||||
|
|
||||||
glGenTextures(1, &_primaryDepthTextureID);
|
glGenTextures(1, &_primaryDepthTextureID);
|
||||||
glBindTexture(GL_TEXTURE_2D, _primaryDepthTextureID);
|
glBindTexture(GL_TEXTURE_2D, _primaryDepthTextureID);
|
||||||
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, _frameBufferSize.width(), _frameBufferSize.height(),
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, _frameBufferSize.width(), _frameBufferSize.height(),
|
||||||
0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
|
0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
|
||||||
|
glGenTextures(1, &_primaryNormalTextureID);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, _primaryNormalTextureID);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _frameBufferSize.width(), _frameBufferSize.height(),
|
||||||
|
0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
_primaryFramebufferObject->bind();
|
_primaryFramebufferObject->bind();
|
||||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, _primaryDepthTextureID, 0);
|
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, _primaryDepthTextureID, 0);
|
||||||
|
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, _primaryNormalTextureID, 0);
|
||||||
_primaryFramebufferObject->release();
|
_primaryFramebufferObject->release();
|
||||||
}
|
}
|
||||||
return _primaryFramebufferObject;
|
return _primaryFramebufferObject;
|
||||||
|
@ -225,6 +236,12 @@ GLuint TextureCache::getPrimaryDepthTextureID() {
|
||||||
return _primaryDepthTextureID;
|
return _primaryDepthTextureID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLuint TextureCache::getPrimaryNormalTextureID() {
|
||||||
|
// ensure that the primary framebuffer object is initialized before returning the normal texture id
|
||||||
|
getPrimaryFramebufferObject();
|
||||||
|
return _primaryNormalTextureID;
|
||||||
|
}
|
||||||
|
|
||||||
QOpenGLFramebufferObject* TextureCache::getSecondaryFramebufferObject() {
|
QOpenGLFramebufferObject* TextureCache::getSecondaryFramebufferObject() {
|
||||||
if (!_secondaryFramebufferObject) {
|
if (!_secondaryFramebufferObject) {
|
||||||
_secondaryFramebufferObject = createFramebufferObject();
|
_secondaryFramebufferObject = createFramebufferObject();
|
||||||
|
@ -278,6 +295,7 @@ bool TextureCache::eventFilter(QObject* watched, QEvent* event) {
|
||||||
delete _primaryFramebufferObject;
|
delete _primaryFramebufferObject;
|
||||||
_primaryFramebufferObject = NULL;
|
_primaryFramebufferObject = NULL;
|
||||||
glDeleteTextures(1, &_primaryDepthTextureID);
|
glDeleteTextures(1, &_primaryDepthTextureID);
|
||||||
|
glDeleteTextures(1, &_primaryNormalTextureID);
|
||||||
}
|
}
|
||||||
if (_secondaryFramebufferObject && _secondaryFramebufferObject->size() != size) {
|
if (_secondaryFramebufferObject && _secondaryFramebufferObject->size() != size) {
|
||||||
delete _secondaryFramebufferObject;
|
delete _secondaryFramebufferObject;
|
||||||
|
|
|
@ -61,6 +61,9 @@ public:
|
||||||
/// Returns the ID of the primary framebuffer object's depth texture. This contains the Z buffer used in rendering.
|
/// Returns the ID of the primary framebuffer object's depth texture. This contains the Z buffer used in rendering.
|
||||||
GLuint getPrimaryDepthTextureID();
|
GLuint getPrimaryDepthTextureID();
|
||||||
|
|
||||||
|
/// Returns the ID of the primary framebuffer object's normal texture.
|
||||||
|
GLuint getPrimaryNormalTextureID();
|
||||||
|
|
||||||
/// Returns a pointer to the secondary framebuffer object, used as an additional render target when performing full
|
/// Returns a pointer to the secondary framebuffer object, used as an additional render target when performing full
|
||||||
/// screen effects.
|
/// screen effects.
|
||||||
QOpenGLFramebufferObject* getSecondaryFramebufferObject();
|
QOpenGLFramebufferObject* getSecondaryFramebufferObject();
|
||||||
|
@ -95,6 +98,7 @@ private:
|
||||||
QHash<QUrl, QWeakPointer<NetworkTexture> > _dilatableNetworkTextures;
|
QHash<QUrl, QWeakPointer<NetworkTexture> > _dilatableNetworkTextures;
|
||||||
|
|
||||||
GLuint _primaryDepthTextureID;
|
GLuint _primaryDepthTextureID;
|
||||||
|
GLuint _primaryNormalTextureID;
|
||||||
QOpenGLFramebufferObject* _primaryFramebufferObject;
|
QOpenGLFramebufferObject* _primaryFramebufferObject;
|
||||||
QOpenGLFramebufferObject* _secondaryFramebufferObject;
|
QOpenGLFramebufferObject* _secondaryFramebufferObject;
|
||||||
QOpenGLFramebufferObject* _tertiaryFramebufferObject;
|
QOpenGLFramebufferObject* _tertiaryFramebufferObject;
|
||||||
|
|
|
@ -971,11 +971,9 @@ ImportHeightfieldTool::ImportHeightfieldTool(MetavoxelEditor* editor) :
|
||||||
connect(_height, &QAbstractButton::clicked, this, &ImportHeightfieldTool::selectHeightFile);
|
connect(_height, &QAbstractButton::clicked, this, &ImportHeightfieldTool::selectHeightFile);
|
||||||
_form->addRow("Color:", _color = new QPushButton());
|
_form->addRow("Color:", _color = new QPushButton());
|
||||||
connect(_color, &QAbstractButton::clicked, this, &ImportHeightfieldTool::selectColorFile);
|
connect(_color, &QAbstractButton::clicked, this, &ImportHeightfieldTool::selectColorFile);
|
||||||
}
|
|
||||||
|
|
||||||
void ImportHeightfieldTool::render() {
|
connect(Application::getInstance()->getMetavoxels(), &MetavoxelSystem::rendering,
|
||||||
HeightfieldTool::render();
|
this, &ImportHeightfieldTool::renderPreview);
|
||||||
_preview.render(_translation->getValue(), _translation->getSingleStep());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImportHeightfieldTool::apply() {
|
void ImportHeightfieldTool::apply() {
|
||||||
|
@ -1084,6 +1082,12 @@ void ImportHeightfieldTool::updatePreview() {
|
||||||
_preview.setBuffers(buffers);
|
_preview.setBuffers(buffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImportHeightfieldTool::renderPreview() {
|
||||||
|
if (isVisible()) {
|
||||||
|
_preview.render(_translation->getValue(), _translation->getSingleStep());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
EraseHeightfieldTool::EraseHeightfieldTool(MetavoxelEditor* editor) :
|
EraseHeightfieldTool::EraseHeightfieldTool(MetavoxelEditor* editor) :
|
||||||
HeightfieldTool(editor, "Erase Heightfield") {
|
HeightfieldTool(editor, "Erase Heightfield") {
|
||||||
|
|
||||||
|
|
|
@ -283,8 +283,6 @@ public:
|
||||||
|
|
||||||
ImportHeightfieldTool(MetavoxelEditor* editor);
|
ImportHeightfieldTool(MetavoxelEditor* editor);
|
||||||
|
|
||||||
virtual void render();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual void apply();
|
virtual void apply();
|
||||||
|
@ -294,6 +292,7 @@ private slots:
|
||||||
void selectHeightFile();
|
void selectHeightFile();
|
||||||
void selectColorFile();
|
void selectColorFile();
|
||||||
void updatePreview();
|
void updatePreview();
|
||||||
|
void renderPreview();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue